54
54
)
55
55
56
56
import smriprep
57
+ from smriprep .interfaces .cifti import GenerateDScalar
57
58
from smriprep .interfaces .surf import MakeRibbon
58
59
from smriprep .interfaces .workbench import SurfaceResample
59
60
@@ -1476,19 +1477,14 @@ def init_morph_grayords_wf(
1476
1477
thickness_fsLR
1477
1478
HCP-style thickness file in CIFTI-2 format, resampled to fsLR
1478
1479
"""
1479
- import templateflow .api as tf
1480
1480
from niworkflows .engine .workflows import LiterateWorkflow as Workflow
1481
1481
1482
- from smriprep .interfaces .cifti import GenerateDScalar
1483
-
1484
1482
workflow = Workflow (name = name )
1485
1483
workflow .__desc__ = f"""\
1486
1484
*Grayordinate* "dscalar" files containing { grayord_density } samples were
1487
1485
resampled onto fsLR using the Connectome Workbench [@hcppipelines].
1488
1486
"""
1489
1487
1490
- fslr_density = '32k' if grayord_density == '91k' else '59k'
1491
-
1492
1488
inputnode = pe .Node (
1493
1489
niu .IdentityInterface (
1494
1490
fields = [
@@ -1527,18 +1523,138 @@ def init_morph_grayords_wf(
1527
1523
name = 'outputnode' ,
1528
1524
)
1529
1525
1530
- atlases = smriprep .load_data ('atlases' )
1526
+ metrics = ['curv' , 'sulc' , 'thickness' ]
1527
+ select_surfaces = pe .Node (
1528
+ KeySelect (fields = metrics , keys = ['L' , 'R' ]),
1529
+ name = 'select_surfaces' ,
1530
+ run_without_submitting = True ,
1531
+ )
1532
+
1533
+ workflow .connect ([
1534
+ (hemisource , select_surfaces , [('hemi' , 'key' )]),
1535
+ ]) # fmt:skip
1536
+
1537
+ for metric in metrics :
1538
+ resample_and_mask_wf = init_resample_and_mask_wf (
1539
+ grayord_density = grayord_density ,
1540
+ omp_nthreads = omp_nthreads ,
1541
+ mem_gb = 1 ,
1542
+ name = f'resample_and_mask_{ metric } _wf' ,
1543
+ )
1544
+ cifti_metric = pe .JoinNode (
1545
+ GenerateDScalar (grayordinates = grayord_density , scalar_name = metric ),
1546
+ name = f'cifti_{ metric } ' ,
1547
+ joinfield = ['scalar_surfs' ],
1548
+ joinsource = 'hemisource' ,
1549
+ )
1550
+
1551
+ workflow .connect ([
1552
+ (inputnode , select_surfaces , [(metric , metric )]),
1553
+ (inputnode , resample_and_mask_wf , [
1554
+ ('midthickness' , 'inputnode.midthickness' ),
1555
+ ('midthickness_fsLR' , 'inputnode.midthickness_fsLR' ),
1556
+ ('sphere_reg_fsLR' , 'inputnode.sphere_reg_fsLR' ),
1557
+ ('roi' , 'inputnode.cortex_mask' ),
1558
+ ]),
1559
+ (hemisource , resample_and_mask_wf , [('hemi' , 'inputnode.hemi' )]),
1560
+ (select_surfaces , resample_and_mask_wf , [(metric , 'inputnode.in_file' )]),
1561
+ (resample_and_mask_wf , cifti_metric , [('outputnode.out_file' , 'scalar_surfs' )]),
1562
+ (cifti_metric , outputnode , [
1563
+ ('out_file' , f'{ metric } _fsLR' ),
1564
+ ('out_metadata' , f'{ metric } _metadata' ),
1565
+ ]),
1566
+ ]) # fmt:skip
1567
+
1568
+ return workflow
1569
+
1570
+
1571
+ def init_resample_and_mask_wf (
1572
+ grayord_density : ty .Literal ['91k' , '170k' ],
1573
+ omp_nthreads : int ,
1574
+ mem_gb : float ,
1575
+ name : str = 'resample_and_mask_wf' ,
1576
+ ):
1577
+ """Resample GIFTI surfaces to fsLR space and mask with fsLR ROI.
1578
+
1579
+ Workflow Graph
1580
+ .. workflow::
1581
+ :graph2use: colored
1582
+ :simple_form: yes
1583
+
1584
+ from smriprep.workflows.surfaces import init_resample_and_mask_wf
1585
+ wf = init_resample_and_mask_wf(
1586
+ grayord_density='91k',
1587
+ omp_nthreads=1,
1588
+ mem_gb=1,
1589
+ )
1590
+
1591
+ Parameters
1592
+ ----------
1593
+ grayord_density : :class:`str`
1594
+ Either ``"91k"`` or ``"170k"``, representing the total *grayordinates*.
1595
+ omp_nthreads : :class:`int`
1596
+ Maximum number of threads an individual process may use
1597
+ mem_gb : :class:`float`
1598
+ Size of BOLD file in GB
1599
+ name : :class:`str`
1600
+ Name of workflow (default: ``"resample_and_mask_wf"``)
1601
+
1602
+ Inputs
1603
+ ------
1604
+ in_file : :class:`str`
1605
+ Path to metric file in subject space
1606
+ hemi : :class:`str`
1607
+ Hemisphere identifier (``"L"`` or ``"R"``)
1608
+ midthickness : :class:`list` of :class:`str`
1609
+ Path to left and right hemisphere midthickness GIFTI surfaces.
1610
+ midthickness_fsLR : :class:`list` of :class:`str`
1611
+ Path to left and right hemisphere midthickness GIFTI surfaces in fsLR space.
1612
+ sphere_reg_fsLR : :class:`list` of :class:`str`
1613
+ Path to left and right hemisphere sphere.reg GIFTI surfaces, mapping from subject to fsLR
1614
+ cortex_mask : :class:`list` of :class:`str`
1615
+ Path to left and right hemisphere cortex mask GIFTI files
1616
+
1617
+ Outputs
1618
+ -------
1619
+ metric_fsLR : :class:`str`
1620
+ Path to metric resampled as GIFTI file in fsLR space
1621
+
1622
+ """
1623
+ import templateflow .api as tf
1624
+ from nipype .pipeline import engine as pe
1625
+ from niworkflows .interfaces .utility import KeySelect
1626
+
1627
+ fslr_density = '32k' if grayord_density == '91k' else '59k'
1628
+
1629
+ workflow = pe .Workflow (name = name )
1630
+
1631
+ inputnode = pe .Node (
1632
+ niu .IdentityInterface (
1633
+ fields = [
1634
+ 'in_file' ,
1635
+ 'hemi' ,
1636
+ 'midthickness' ,
1637
+ 'midthickness_fsLR' ,
1638
+ 'sphere_reg_fsLR' ,
1639
+ 'cortex_mask' ,
1640
+ ]
1641
+ ),
1642
+ name = 'inputnode' ,
1643
+ )
1644
+
1645
+ outputnode = pe .Node (
1646
+ niu .IdentityInterface (fields = ['out_file' ]),
1647
+ name = 'outputnode' ,
1648
+ )
1649
+
1531
1650
select_surfaces = pe .Node (
1532
1651
KeySelect (
1533
1652
fields = [
1534
- 'curv' ,
1535
- 'sulc' ,
1536
- 'thickness' ,
1537
- 'roi' ,
1538
1653
'midthickness' ,
1539
1654
'midthickness_fsLR' ,
1540
1655
'sphere_reg_fsLR' ,
1541
1656
'template_sphere' ,
1657
+ 'cortex_mask' ,
1542
1658
'template_roi' ,
1543
1659
],
1544
1660
keys = ['L' , 'R' ],
@@ -1559,60 +1675,41 @@ def init_morph_grayords_wf(
1559
1675
)
1560
1676
for hemi in ['L' , 'R' ]
1561
1677
]
1678
+ atlases = smriprep .load_data ('atlases' )
1562
1679
select_surfaces .inputs .template_roi = [
1563
1680
str (atlases / f'L.atlasroi.{ fslr_density } _fs_LR.shape.gii' ),
1564
1681
str (atlases / f'R.atlasroi.{ fslr_density } _fs_LR.shape.gii' ),
1565
1682
]
1566
1683
1684
+ resample_to_fsLR = pe .Node (
1685
+ MetricResample (method = 'ADAP_BARY_AREA' , area_surfs = True ),
1686
+ name = 'resample_to_fsLR' ,
1687
+ mem_gb = 1 ,
1688
+ n_procs = omp_nthreads ,
1689
+ )
1690
+ mask_fsLR = pe .Node (MetricMask (), name = 'mask_fsLR' )
1691
+
1567
1692
workflow .connect ([
1568
1693
(inputnode , select_surfaces , [
1569
- ('curv' , 'curv' ),
1570
- ('sulc' , 'sulc' ),
1571
- ('thickness' , 'thickness' ),
1572
- ('roi' , 'roi' ),
1573
1694
('midthickness' , 'midthickness' ),
1574
1695
('midthickness_fsLR' , 'midthickness_fsLR' ),
1575
1696
('sphere_reg_fsLR' , 'sphere_reg_fsLR' ),
1697
+ ('cortex_mask' , 'cortex_mask' ),
1698
+ ('hemi' , 'key' ),
1576
1699
]),
1577
- (hemisource , select_surfaces , [('hemi' , 'key' )]),
1700
+ (inputnode , resample_to_fsLR , [('in_file' , 'in_file' )]),
1701
+ (select_surfaces , resample_to_fsLR , [
1702
+ ('sphere_reg_fsLR' , 'current_sphere' ),
1703
+ ('template_sphere' , 'new_sphere' ),
1704
+ ('midthickness' , 'current_area' ),
1705
+ ('midthickness_fsLR' , 'new_area' ),
1706
+ ('cortex_mask' , 'roi_metric' ),
1707
+ ]),
1708
+ (select_surfaces , mask_fsLR , [('template_roi' , 'mask' )]),
1709
+ (resample_to_fsLR , mask_fsLR , [('out_file' , 'in_file' )]),
1710
+ (mask_fsLR , outputnode , [('out_file' , 'out_file' )]),
1578
1711
]) # fmt:skip
1579
1712
1580
- for metric in ('curv' , 'sulc' , 'thickness' ):
1581
- resampler = pe .Node (
1582
- MetricResample (method = 'ADAP_BARY_AREA' , area_surfs = True ),
1583
- name = f'resample_{ metric } ' ,
1584
- n_procs = omp_nthreads ,
1585
- )
1586
- mask_fsLR = pe .Node (
1587
- MetricMask (),
1588
- name = f'mask_{ metric } ' ,
1589
- n_procs = omp_nthreads ,
1590
- )
1591
- cifti_metric = pe .JoinNode (
1592
- GenerateDScalar (grayordinates = grayord_density , scalar_name = metric ),
1593
- name = f'cifti_{ metric } ' ,
1594
- joinfield = ['scalar_surfs' ],
1595
- joinsource = 'hemisource' ,
1596
- )
1597
-
1598
- workflow .connect ([
1599
- (select_surfaces , resampler , [
1600
- (metric , 'in_file' ),
1601
- ('sphere_reg_fsLR' , 'current_sphere' ),
1602
- ('template_sphere' , 'new_sphere' ),
1603
- ('midthickness' , 'current_area' ),
1604
- ('midthickness_fsLR' , 'new_area' ),
1605
- ('roi' , 'roi_metric' ),
1606
- ]),
1607
- (select_surfaces , mask_fsLR , [('template_roi' , 'mask' )]),
1608
- (resampler , mask_fsLR , [('out_file' , 'in_file' )]),
1609
- (mask_fsLR , cifti_metric , [('out_file' , 'scalar_surfs' )]),
1610
- (cifti_metric , outputnode , [
1611
- ('out_file' , f'{ metric } _fsLR' ),
1612
- ('out_metadata' , f'{ metric } _metadata' ),
1613
- ]),
1614
- ]) # fmt:skip
1615
-
1616
1713
return workflow
1617
1714
1618
1715
0 commit comments