Skip to content

Commit 58c4758

Browse files
committed
rf: Split resampling and masking out from morphometrics workflow
1 parent 15a72b0 commit 58c4758

File tree

1 file changed

+131
-49
lines changed

1 file changed

+131
-49
lines changed

smriprep/workflows/surfaces.py

+131-49
Original file line numberDiff line numberDiff line change
@@ -1447,7 +1447,6 @@ def init_morph_grayords_wf(
14471447
thickness_fsLR
14481448
HCP-style thickness file in CIFTI-2 format, resampled to fsLR
14491449
"""
1450-
import templateflow.api as tf
14511450
from niworkflows.engine.workflows import LiterateWorkflow as Workflow
14521451

14531452
from smriprep.interfaces.cifti import GenerateDScalar
@@ -1458,8 +1457,6 @@ def init_morph_grayords_wf(
14581457
resampled onto fsLR using the Connectome Workbench [@hcppipelines].
14591458
"""
14601459

1461-
fslr_density = '32k' if grayord_density == '91k' else '59k'
1462-
14631460
inputnode = pe.Node(
14641461
niu.IdentityInterface(
14651462
fields=[
@@ -1498,18 +1495,121 @@ def init_morph_grayords_wf(
14981495
name='outputnode',
14991496
)
15001497

1501-
atlases = smriprep.load_data('atlases')
1498+
for metric in ('curv', 'sulc', 'thickness'):
1499+
resample_and_mask_wf = init_resample_and_mask_wf(
1500+
grayord_density=grayord_density,
1501+
omp_nthreads=omp_nthreads,
1502+
mem_gb=1,
1503+
name=f'resample_and_mask_{metric}_wf',
1504+
)
1505+
cifti_metric = pe.JoinNode(
1506+
GenerateDScalar(grayordinates=grayord_density, scalar_name=metric),
1507+
name=f'cifti_{metric}',
1508+
joinfield=['scalar_surfs'],
1509+
joinsource='hemisource',
1510+
)
1511+
1512+
workflow.connect([
1513+
(inputnode, resample_and_mask_wf, [
1514+
(metric, 'inputnode.in_file'),
1515+
('midthickness', 'inputnode.midthickness'),
1516+
('midthickness_fsLR', 'inputnode.midthickness_fsLR'),
1517+
('sphere_reg_fsLR', 'inputnode.sphere_reg_fsLR'),
1518+
('roi', 'inputnode.cortex_mask'),
1519+
]),
1520+
(hemisource, resample_and_mask_wf, [('hemi', 'inputnode.hemi')]),
1521+
(resample_and_mask_wf, cifti_metric, [('outputnode.out_file', 'scalar_surfs')]),
1522+
(cifti_metric, outputnode, [
1523+
('out_file', f'{metric}_fsLR'),
1524+
('out_metadata', f'{metric}_metadata'),
1525+
]),
1526+
]) # fmt:skip
1527+
1528+
return workflow
1529+
1530+
1531+
def init_resample_and_mask_wf(
1532+
grayord_density: ty.Literal['91k', '170k'],
1533+
omp_nthreads: int,
1534+
mem_gb: float,
1535+
name: str = 'resample_and_mask_wf',
1536+
):
1537+
"""Resample GIFTI surfaces to fsLR space and mask with fsLR ROI.
1538+
1539+
Workflow Graph
1540+
.. workflow::
1541+
:graph2use: colored
1542+
:simple_form: yes
1543+
1544+
from smriprep.workflows.surfaces import init_resample_and_mask_wf
1545+
wf = init_resample_and_mask_wf(
1546+
grayord_density='91k',
1547+
omp_nthreads=1,
1548+
mem_gb=1,
1549+
)
1550+
1551+
Parameters
1552+
----------
1553+
grayord_density : :class:`str`
1554+
Either ``"91k"`` or ``"170k"``, representing the total *grayordinates*.
1555+
omp_nthreads : :class:`int`
1556+
Maximum number of threads an individual process may use
1557+
mem_gb : :class:`float`
1558+
Size of BOLD file in GB
1559+
name : :class:`str`
1560+
Name of workflow (default: ``"resample_and_mask_wf"``)
1561+
1562+
Inputs
1563+
------
1564+
midthickness : :class:`list` of :class:`str`
1565+
Path to left and right hemisphere midthickness GIFTI surfaces.
1566+
midthickness_fsLR : :class:`list` of :class:`str`
1567+
Path to left and right hemisphere midthickness GIFTI surfaces in fsLR space.
1568+
sphere_reg_fsLR : :class:`list` of :class:`str`
1569+
Path to left and right hemisphere sphere.reg GIFTI surfaces, mapping from subject to fsLR
1570+
1571+
Outputs
1572+
-------
1573+
metric_fsLR : :class:`list` of :class:`str`
1574+
Path to metrics resampled as GIFTI files in fsLR space
1575+
1576+
"""
1577+
import templateflow.api as tf
1578+
from nipype.pipeline import engine as pe
1579+
from niworkflows.interfaces.utility import KeySelect
1580+
1581+
fslr_density = '32k' if grayord_density == '91k' else '59k'
1582+
1583+
workflow = pe.Workflow(name=name)
1584+
1585+
inputnode = pe.Node(
1586+
niu.IdentityInterface(
1587+
fields=[
1588+
'in_file',
1589+
'hemi',
1590+
'midthickness',
1591+
'midthickness_fsLR',
1592+
'sphere_reg_fsLR',
1593+
'cortex_mask',
1594+
]
1595+
),
1596+
name='inputnode',
1597+
)
1598+
1599+
outputnode = pe.Node(
1600+
niu.IdentityInterface(fields=['out_file']),
1601+
name='outputnode',
1602+
)
1603+
15021604
select_surfaces = pe.Node(
15031605
KeySelect(
15041606
fields=[
1505-
'curv',
1506-
'sulc',
1507-
'thickness',
1508-
'roi',
1607+
'in_file',
15091608
'midthickness',
15101609
'midthickness_fsLR',
15111610
'sphere_reg_fsLR',
15121611
'template_sphere',
1612+
'cortex_mask',
15131613
'template_roi',
15141614
],
15151615
keys=['L', 'R'],
@@ -1530,60 +1630,42 @@ def init_morph_grayords_wf(
15301630
)
15311631
for hemi in ['L', 'R']
15321632
]
1633+
atlases = smriprep.load_data('atlases')
15331634
select_surfaces.inputs.template_roi = [
15341635
str(atlases / f'L.atlasroi.{fslr_density}_fs_LR.shape.gii'),
15351636
str(atlases / f'R.atlasroi.{fslr_density}_fs_LR.shape.gii'),
15361637
]
15371638

1639+
resample_to_fsLR = pe.Node(
1640+
MetricResample(method='ADAP_BARY_AREA', area_surfs=True),
1641+
name='resample_to_fsLR',
1642+
mem_gb=1,
1643+
n_procs=omp_nthreads,
1644+
)
1645+
mask_fsLR = pe.Node(MetricMask(), name='mask_fsLR')
1646+
15381647
workflow.connect([
15391648
(inputnode, select_surfaces, [
1540-
('curv', 'curv'),
1541-
('sulc', 'sulc'),
1542-
('thickness', 'thickness'),
1543-
('roi', 'roi'),
1649+
('in_file', 'in_file'),
15441650
('midthickness', 'midthickness'),
15451651
('midthickness_fsLR', 'midthickness_fsLR'),
15461652
('sphere_reg_fsLR', 'sphere_reg_fsLR'),
1653+
('cortex_mask', 'cortex_mask'),
1654+
('hemi', 'key'),
1655+
]),
1656+
(select_surfaces, resample_to_fsLR, [
1657+
('in_file', 'in_file'),
1658+
('sphere_reg_fsLR', 'current_sphere'),
1659+
('template_sphere', 'new_sphere'),
1660+
('midthickness', 'current_area'),
1661+
('midthickness_fsLR', 'new_area'),
1662+
('cortex_mask', 'roi_metric'),
15471663
]),
1548-
(hemisource, select_surfaces, [('hemi', 'key')]),
1664+
(select_surfaces, mask_fsLR, [('template_roi', 'mask')]),
1665+
(resample_to_fsLR, mask_fsLR, [('out_file', 'in_file')]),
1666+
(mask_fsLR, outputnode, [('out_file', 'out_file')]),
15491667
]) # fmt:skip
15501668

1551-
for metric in ('curv', 'sulc', 'thickness'):
1552-
resampler = pe.Node(
1553-
MetricResample(method='ADAP_BARY_AREA', area_surfs=True),
1554-
name=f'resample_{metric}',
1555-
n_procs=omp_nthreads,
1556-
)
1557-
mask_fsLR = pe.Node(
1558-
MetricMask(),
1559-
name=f'mask_{metric}',
1560-
n_procs=omp_nthreads,
1561-
)
1562-
cifti_metric = pe.JoinNode(
1563-
GenerateDScalar(grayordinates=grayord_density, scalar_name=metric),
1564-
name=f'cifti_{metric}',
1565-
joinfield=['scalar_surfs'],
1566-
joinsource='hemisource',
1567-
)
1568-
1569-
workflow.connect([
1570-
(select_surfaces, resampler, [
1571-
(metric, 'in_file'),
1572-
('sphere_reg_fsLR', 'current_sphere'),
1573-
('template_sphere', 'new_sphere'),
1574-
('midthickness', 'current_area'),
1575-
('midthickness_fsLR', 'new_area'),
1576-
('roi', 'roi_metric'),
1577-
]),
1578-
(select_surfaces, mask_fsLR, [('template_roi', 'mask')]),
1579-
(resampler, mask_fsLR, [('out_file', 'in_file')]),
1580-
(mask_fsLR, cifti_metric, [('out_file', 'scalar_surfs')]),
1581-
(cifti_metric, outputnode, [
1582-
('out_file', f'{metric}_fsLR'),
1583-
('out_metadata', f'{metric}_metadata'),
1584-
]),
1585-
]) # fmt:skip
1586-
15871669
return workflow
15881670

15891671

0 commit comments

Comments
 (0)