30
30
31
31
import typing as ty
32
32
33
+ from nibabel .processing import fwhm2sigma
33
34
from nipype .interfaces import freesurfer as fs
34
35
from nipype .interfaces import io as nio
35
36
from nipype .interfaces import utility as niu
54
55
)
55
56
56
57
import smriprep
58
+ from smriprep .interfaces .cifti import GenerateDScalar
57
59
from smriprep .interfaces .surf import MakeRibbon
58
60
from smriprep .interfaces .workbench import SurfaceResample
59
61
@@ -1449,8 +1451,6 @@ def init_morph_grayords_wf(
1449
1451
"""
1450
1452
from niworkflows .engine .workflows import LiterateWorkflow as Workflow
1451
1453
1452
- from smriprep .interfaces .cifti import GenerateDScalar
1453
-
1454
1454
workflow = Workflow (name = name )
1455
1455
workflow .__desc__ = f"""\
1456
1456
*Grayordinate* "dscalar" files containing { grayord_density } samples were
@@ -1495,7 +1495,14 @@ def init_morph_grayords_wf(
1495
1495
name = 'outputnode' ,
1496
1496
)
1497
1497
1498
- for metric in ('curv' , 'sulc' , 'thickness' ):
1498
+ metrics = ['curv' , 'sulc' , 'thickness' ]
1499
+ select_surfaces = pe .Node (
1500
+ KeySelect (fields = metrics , keys = ['L' , 'R' ]),
1501
+ name = 'select_surfaces' ,
1502
+ run_without_submitting = True ,
1503
+ )
1504
+
1505
+ for metric in metrics :
1499
1506
resample_and_mask_wf = init_resample_and_mask_wf (
1500
1507
grayord_density = grayord_density ,
1501
1508
omp_nthreads = omp_nthreads ,
@@ -1510,14 +1517,16 @@ def init_morph_grayords_wf(
1510
1517
)
1511
1518
1512
1519
workflow .connect ([
1520
+ (inputnode , select_surfaces , [(metric , metric )]),
1521
+ (hemisource , select_surfaces , [('hemi' , 'key' )]),
1513
1522
(inputnode , resample_and_mask_wf , [
1514
- (metric , 'inputnode.in_file' ),
1515
1523
('midthickness' , 'inputnode.midthickness' ),
1516
1524
('midthickness_fsLR' , 'inputnode.midthickness_fsLR' ),
1517
1525
('sphere_reg_fsLR' , 'inputnode.sphere_reg_fsLR' ),
1518
1526
('roi' , 'inputnode.cortex_mask' ),
1519
1527
]),
1520
1528
(hemisource , resample_and_mask_wf , [('hemi' , 'inputnode.hemi' )]),
1529
+ (select_surfaces , resample_and_mask_wf , [(metric , 'inputnode.in_file' )]),
1521
1530
(resample_and_mask_wf , cifti_metric , [('outputnode.out_file' , 'scalar_surfs' )]),
1522
1531
(cifti_metric , outputnode , [
1523
1532
('out_file' , f'{ metric } _fsLR' ),
@@ -1528,6 +1537,156 @@ def init_morph_grayords_wf(
1528
1537
return workflow
1529
1538
1530
1539
1540
+ def init_myelinmap_fsLR_wf (
1541
+ grayord_density : ty .Literal ['91k' , '170k' ],
1542
+ omp_nthreads : int ,
1543
+ mem_gb : float ,
1544
+ name : str = 'myelinmap_fsLR_wf' ,
1545
+ ):
1546
+ """Resample myelinmap volume to fsLR surface.
1547
+
1548
+ Workflow Graph
1549
+ .. workflow::
1550
+ :graph2use: colored
1551
+ :simple_form: yes
1552
+
1553
+ from smriprep.workflows.surfaces import init_myelinmap_fsLR_wf
1554
+ wf = init_myelinmap_fsLR_wf(grayord_density='91k', omp_nthreads=1, mem_gb=1)
1555
+
1556
+ Parameters
1557
+ ----------
1558
+ grayord_density : :class:`str`
1559
+ Either ``"91k"`` or ``"170k"``, representing the total *grayordinates*.
1560
+ omp_nthreads : :class:`int`
1561
+ Maximum number of threads an individual process may use
1562
+ mem_gb : :class:`float`
1563
+ Size of BOLD file in GB
1564
+ name : :class:`str`
1565
+ Name of workflow (default: ``"myelinmap_fsLR_wf"``)
1566
+
1567
+ Inputs
1568
+ ------
1569
+ in_file : :class:`str`
1570
+ Path to the myelin map in subject volume space
1571
+ thickness : :class:`list` of :class:`str`
1572
+ Path to left and right hemisphere thickness GIFTI shape files
1573
+ midthickness : :class:`list` of :class:`str`
1574
+ Path to left and right hemisphere midthickness GIFTI surface files
1575
+ midthickness_fsLR : :class:`list` of :class:`str`
1576
+ Path to left and right hemisphere midthickness GIFTI surface files in fsLR space
1577
+ sphere_reg_fsLR : :class:`list` of :class:`str`
1578
+ Path to left and right hemisphere sphere.reg GIFTI surface files,
1579
+ mapping from subject to fsLR
1580
+ cortex_mask : :class:`list` of :class:`str`
1581
+ Path to left and right hemisphere cortex mask GIFTI files
1582
+
1583
+ Outputs
1584
+ -------
1585
+ out_fsLR : :class:`str`
1586
+ Path to the resampled myelin map in fsLR space
1587
+
1588
+ """
1589
+ from niworkflows .engine .workflows import LiterateWorkflow as Workflow
1590
+ from niworkflows .interfaces .utility import KeySelect
1591
+ from niworkflows .interfaces .workbench import VolumeToSurfaceMapping
1592
+
1593
+ workflow = Workflow (name = name )
1594
+
1595
+ inputnode = pe .Node (
1596
+ niu .IdentityInterface (
1597
+ fields = [
1598
+ 'in_file' ,
1599
+ 'thickness' ,
1600
+ 'midthickness' ,
1601
+ 'midthickness_fsLR' ,
1602
+ 'sphere_reg_fsLR' ,
1603
+ 'cortex_mask' ,
1604
+ 'volume_roi' ,
1605
+ ]
1606
+ ),
1607
+ name = 'inputnode' ,
1608
+ )
1609
+
1610
+ outputnode = pe .Node (
1611
+ niu .IdentityInterface (fields = ['out_file' , 'out_metadata' ]),
1612
+ name = 'outputnode' ,
1613
+ )
1614
+
1615
+ hemisource = pe .Node (
1616
+ niu .IdentityInterface (fields = ['hemi' ]),
1617
+ name = 'hemisource' ,
1618
+ iterables = [('hemi' , ['L' , 'R' ])],
1619
+ )
1620
+
1621
+ select_surfaces = pe .Node (
1622
+ KeySelect (
1623
+ fields = [
1624
+ 'thickness' ,
1625
+ 'midthickness' ,
1626
+ ],
1627
+ keys = ['L' , 'R' ],
1628
+ ),
1629
+ name = 'select_surfaces' ,
1630
+ run_without_submitting = True ,
1631
+ )
1632
+
1633
+ volume_to_surface = pe .Node (
1634
+ VolumeToSurfaceMapping (method = 'myelin-style' , sigma = fwhm2sigma (5 )),
1635
+ name = 'volume_to_surface' ,
1636
+ mem_gb = mem_gb * 3 ,
1637
+ n_procs = omp_nthreads ,
1638
+ )
1639
+ # smooth = pe.Node(
1640
+ # MetricSmooth(sigma=fwhm2sigma(4), nearest=True),
1641
+ # name='metric_dilate',
1642
+ # mem_gb=1,
1643
+ # n_procs=omp_nthreads,
1644
+ # )
1645
+ resample_and_mask_wf = init_resample_and_mask_wf (
1646
+ grayord_density = grayord_density ,
1647
+ omp_nthreads = omp_nthreads ,
1648
+ mem_gb = mem_gb ,
1649
+ )
1650
+ cifti_myelinmap = pe .JoinNode (
1651
+ GenerateDScalar (grayordinates = grayord_density , scalar_name = 'MyelinMap' ),
1652
+ name = 'cifti_myelinmap' ,
1653
+ joinfield = ['scalar_surfs' ],
1654
+ joinsource = 'hemisource' ,
1655
+ )
1656
+
1657
+ workflow .connect ([
1658
+ (inputnode , select_surfaces , [
1659
+ ('midthickness' , 'midthickness' ),
1660
+ ('thickness' , 'thickness' ),
1661
+ ]),
1662
+ (hemisource , select_surfaces , [('hemi' , 'key' )]),
1663
+ # Resample volume to native surface
1664
+ (inputnode , volume_to_surface , [
1665
+ ('in_file' , 'volume_file' ),
1666
+ ('ribbon_file' , 'ribbon_roi' ),
1667
+ ]),
1668
+ (select_surfaces , volume_to_surface , [
1669
+ ('midthickness' , 'surface_file' ),
1670
+ ('thickness' , 'thickness' ),
1671
+ ]),
1672
+ (inputnode , resample_and_mask_wf , [
1673
+ ('midthickness' , 'inputnode.midthickness' ),
1674
+ ('midthickness_fsLR' , 'inputnode.midthickness_fsLR' ),
1675
+ ('sphere_reg_fsLR' , 'inputnode.sphere_reg_fsLR' ),
1676
+ ('cortex_mask' , 'inputnode.cortex_mask' ),
1677
+ ]),
1678
+ (hemisource , resample_and_mask_wf , [('hemi' , 'inputnode.hemi' )]),
1679
+ (volume_to_surface , resample_and_mask_wf , [('out_file' , 'inputnode.in_file' )]),
1680
+ (resample_and_mask_wf , cifti_myelinmap , [('outputnode.out_file' , 'scalar_surfs' )]),
1681
+ (cifti_myelinmap , outputnode , [
1682
+ ('out_file' , 'out_file' ),
1683
+ ('out_metadata' , 'out_metadata' ),
1684
+ ]),
1685
+ ]) # fmt:skip
1686
+
1687
+ return workflow
1688
+
1689
+
1531
1690
def init_resample_and_mask_wf (
1532
1691
grayord_density : ty .Literal ['91k' , '170k' ],
1533
1692
omp_nthreads : int ,
@@ -1561,17 +1720,23 @@ def init_resample_and_mask_wf(
1561
1720
1562
1721
Inputs
1563
1722
------
1723
+ in_file : :class:`str`
1724
+ Path to metric file in subject space
1725
+ hemi : :class:`str`
1726
+ Hemisphere identifier (``"L"`` or ``"R"``)
1564
1727
midthickness : :class:`list` of :class:`str`
1565
1728
Path to left and right hemisphere midthickness GIFTI surfaces.
1566
1729
midthickness_fsLR : :class:`list` of :class:`str`
1567
1730
Path to left and right hemisphere midthickness GIFTI surfaces in fsLR space.
1568
1731
sphere_reg_fsLR : :class:`list` of :class:`str`
1569
1732
Path to left and right hemisphere sphere.reg GIFTI surfaces, mapping from subject to fsLR
1733
+ cortex_mask : :class:`list` of :class:`str`
1734
+ Path to left and right hemisphere cortex mask GIFTI files
1570
1735
1571
1736
Outputs
1572
1737
-------
1573
- metric_fsLR : :class:`list` of :class:` str`
1574
- Path to metrics resampled as GIFTI files in fsLR space
1738
+ metric_fsLR : :class:`str`
1739
+ Path to metric resampled as GIFTI file in fsLR space
1575
1740
1576
1741
"""
1577
1742
import templateflow .api as tf
@@ -1604,7 +1769,6 @@ def init_resample_and_mask_wf(
1604
1769
select_surfaces = pe .Node (
1605
1770
KeySelect (
1606
1771
fields = [
1607
- 'in_file' ,
1608
1772
'midthickness' ,
1609
1773
'midthickness_fsLR' ,
1610
1774
'sphere_reg_fsLR' ,
@@ -1646,15 +1810,14 @@ def init_resample_and_mask_wf(
1646
1810
1647
1811
workflow .connect ([
1648
1812
(inputnode , select_surfaces , [
1649
- ('in_file' , 'in_file' ),
1650
1813
('midthickness' , 'midthickness' ),
1651
1814
('midthickness_fsLR' , 'midthickness_fsLR' ),
1652
1815
('sphere_reg_fsLR' , 'sphere_reg_fsLR' ),
1653
1816
('cortex_mask' , 'cortex_mask' ),
1654
1817
('hemi' , 'key' ),
1655
1818
]),
1819
+ (inputnode , resample_to_fsLR , [('in_file' , 'in_file' )]),
1656
1820
(select_surfaces , resample_to_fsLR , [
1657
- ('in_file' , 'in_file' ),
1658
1821
('sphere_reg_fsLR' , 'current_sphere' ),
1659
1822
('template_sphere' , 'new_sphere' ),
1660
1823
('midthickness' , 'current_area' ),
0 commit comments