Skip to content

Commit

Permalink
ENH: Add MSMSulc
Browse files Browse the repository at this point in the history
  • Loading branch information
mgxd committed Sep 11, 2023
1 parent 83576ea commit b83d424
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 12 deletions.
6 changes: 6 additions & 0 deletions nibabies/cli/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,12 @@ def _slice_time_ref(value, parser):
dest="hires",
help="disable sub-millimeter (hires) reconstruction",
)
g_surfs.add_argument(
"--no-msm",
action="store_false",
dest="run_msmsulc",
help="Disable Multimodal Surface Matching surface registration.",
)
g_surfs_xor = g_surfs.add_mutually_exclusive_group()
g_surfs_xor.add_argument(
"--cifti-output",
Expand Down
8 changes: 8 additions & 0 deletions nibabies/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,8 @@ class workflow(_Config):
"""Threshold for DVARS."""
regressors_fd_th = None
"""Threshold for :abbr:`FD (frame-wise displacement)`."""
run_msmsulc = False
"""Run Multimodal Surface Matching surface registration."""
run_reconall = True
"""Run FreeSurfer's surface reconstruction."""
skull_strip_fixed_seed = False
Expand Down Expand Up @@ -597,6 +599,12 @@ class workflow(_Config):
"""Run *fieldmap-less* susceptibility-derived distortions estimation
in the absence of any alternatives."""

@classmethod
def init(cls):
# Avoid additional runtime if not required
if not cls.cifti_output:
cls.run_msmsulc = False


class loggers:
"""Keep loggers easily accessible (see :py:func:`init`)."""
Expand Down
5 changes: 3 additions & 2 deletions nibabies/workflows/anatomical/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def init_infant_anat_wf(
freesurfer: bool,
hires: bool | None,
longitudinal: bool,
msm_sulc: bool,
omp_nthreads: int,
output_dir: str | Path,
segmentation_atlases: str | Path | None,
Expand Down Expand Up @@ -486,7 +487,7 @@ def init_infant_anat_wf(
mcribs_dir=str(config.execution.mcribs_dir), # Needed to preserve runs
)
# M-CRIB-S to dHCP42week (32k)
sphere_reg_wf = init_mcribs_sphere_reg_wf()
sphere_reg_wf = init_mcribs_sphere_reg_wf(sloppy=sloppy, msm_sulc=msm_sulc)

# fmt:off
wf.connect([
Expand All @@ -505,7 +506,7 @@ def init_infant_anat_wf(
from smriprep.workflows.surfaces import init_sphere_reg_wf

# fsaverage to fsLR
sphere_reg_wf = init_sphere_reg_wf()
sphere_reg_wf = init_sphere_reg_wf(msm_sulc=msm_sulc)

# fmt:off
wf.connect([
Expand Down
53 changes: 43 additions & 10 deletions nibabies/workflows/anatomical/surfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,19 +202,22 @@ def init_mcribs_surface_recon_wf(
return wf


def init_mcribs_sphere_reg_wf(*, name="mcribs_sphere_reg_wf"):
def init_mcribs_sphere_reg_wf(
*, msm_sulc: bool = False, sloppy: bool = False, name="mcribs_sphere_reg_wf"
):
"""
Generate GIFTI registration sphere files from MCRIBS template to dHCP42 (32k).
TODO: Clarify any distinction with fsLR
"""
from smriprep.interfaces.surf import FixGiftiMetadata
from smriprep.interfaces.workbench import SurfaceSphereProjectUnproject
from smriprep.workflows.surfaces import init_msm_sulc_wf

workflow = LiterateWorkflow(name=name)

inputnode = pe.Node(
niu.IdentityInterface(["subjects_dir", "subject_id"]),
niu.IdentityInterface(["subjects_dir", "subject_id", "sulc"]),
name="inputnode",
)
outputnode = pe.Node(
Expand All @@ -228,14 +231,16 @@ def init_mcribs_sphere_reg_wf(*, name="mcribs_sphere_reg_wf"):
run_without_submitting=True,
)

get_surfaces = pe.Node(nio.FreeSurferSource(), name="get_surfaces")

# Via FreeSurfer2CaretConvertAndRegisterNonlinear.sh#L270-L273
#
# See https://github.com/DCAN-Labs/DCAN-HCP/tree/9291324
sphere_gii = pe.MapNode(
fs.MRIsConvert(out_datatype="gii"), iterfield="in_file", name="sphere_gii"
sphere_reg_gii = pe.MapNode(
fs.MRIsConvert(out_datatype="gii"), iterfield="in_file", name="sphere_reg_gii"
)

fix_meta = pe.MapNode(FixGiftiMetadata(), iterfield="in_file", name="fix_meta")
fix_reg_meta = pe.MapNode(FixGiftiMetadata(), iterfield="in_file", name="fix_reg_meta")

# load template files
atlases = load_resource('atlases')
Expand Down Expand Up @@ -266,14 +271,42 @@ def init_mcribs_sphere_reg_wf(*, name="mcribs_sphere_reg_wf"):
('subjects_dir', 'subjects_dir'),
('subject_id', 'subject_id'),
]),
(get_spheres, sphere_gii, [(('out', _sorted_by_basename), 'in_file')]),
(sphere_gii, fix_meta, [('converted', 'in_file')]),
(fix_meta, project_unproject, [('out_file', 'sphere_in')]),
(sphere_gii, outputnode, [('converted', 'sphere_reg')]),
(project_unproject, outputnode, [('sphere_out', 'sphere_reg_fsLR')]),
(inputnode, get_surfaces, [
('subjects_dir', 'subjects_dir'),
('subject_id', 'subject_id'),
]),
(get_spheres, sphere_reg_gii, [(('out', _sorted_by_basename), 'in_file')]),
(sphere_reg_gii, fix_reg_meta, [('converted', 'in_file')]),
(fix_reg_meta, project_unproject, [('out_file', 'sphere_in')]),
(sphere_reg_gii, outputnode, [('converted', 'sphere_reg')]),
])
# fmt:on

if not msm_sulc:
workflow.connect(project_unproject, 'sphere_out', outputnode, 'sphere_reg_fsLR')
return workflow

sphere_gii = pe.MapNode(
fs.MRIsConvert(out_datatype='gii'),
iterfield='in_file',
name='sphere_gii',
)
fix_sphere_meta = pe.MapNode(
FixGiftiMetadata(),
iterfield='in_file',
name='fix_sphere_meta',
)
msm_sulc_wf = init_msm_sulc_wf(sloppy=sloppy)
# fmt:off
workflow.connect([
(get_surfaces, sphere_gii, [(('sphere', _sorted_by_basename), 'in_file')]),
(sphere_gii, fix_sphere_meta, [('converted', 'in_file')]),
(fix_sphere_meta, msm_sulc_wf, [('out_file', 'inputnode.sphere')]),
(inputnode, msm_sulc_wf, [('sulc', 'inputnode.sulc')]),
(project_unproject, msm_sulc_wf, [('sphere_out', 'inputnode.sphere_reg_fsLR')]),
(msm_sulc_wf, outputnode, [('outputnode.sphere_reg_fsLR', 'sphere_reg_fsLR')]),
])
# fmt:on
return workflow


Expand Down
1 change: 1 addition & 0 deletions nibabies/workflows/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ def init_single_subject_wf(
freesurfer=config.workflow.run_reconall,
hires=config.workflow.hires,
longitudinal=config.workflow.longitudinal,
msm_sulc=config.workflow.run_msmsulc,
omp_nthreads=config.nipype.omp_nthreads,
output_dir=nibabies_dir,
segmentation_atlases=config.execution.segmentation_atlases_dir,
Expand Down

0 comments on commit b83d424

Please sign in to comment.