Skip to content

Commit 4361953

Browse files
committed
FIX: Adjust for potential MCRIBS inputs
1 parent 94a7bac commit 4361953

File tree

2 files changed

+99
-89
lines changed

2 files changed

+99
-89
lines changed

nibabies/workflows/bold/base.py

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -949,13 +949,14 @@ def init_func_preproc_wf(bold_file, spaces, has_fieldmap=False, existing_derivat
949949
)
950950
from .resampling import init_bold_fsLR_resampling_wf, init_bold_grayords_wf
951951

952-
# key = get_MNIInfant_key(spaces)
953-
# # BOLD/ROIs should be in MNIInfant space
954-
# cifti_select_std = pe.Node(
955-
# KeySelect(fields=["bold_std", "bold_aseg_std"], key=key),
956-
# name="cifti_select_std",
957-
# run_without_submitting=True,
958-
# )
952+
# Anatomical -> fsLR surfaces
953+
bold_fsLR_resampling_wf = init_bold_fsLR_resampling_wf(
954+
estimate_goodvoxels=project_goodvoxels,
955+
grayord_density=config.workflow.cifti_output,
956+
omp_nthreads=omp_nthreads,
957+
mem_gb=mem_gb["resampled"],
958+
mcribs=config.workflow.surface_recon_method == 'mcribs',
959+
)
959960

960961
subcortical_rois_wf = init_subcortical_rois_wf()
961962
subcortical_mni_alignment_wf = init_subcortical_mni_alignment_wf()
@@ -965,30 +966,35 @@ def init_func_preproc_wf(bold_file, spaces, has_fieldmap=False, existing_derivat
965966
repetition_time=metadata["RepetitionTime"],
966967
)
967968

969+
key = get_MNIInfant_key(spaces)
970+
# BOLD/ROIs should be in MNIInfant space
971+
cifti_select_std = pe.Node(
972+
KeySelect(fields=["bold_std", "bold_aseg_std"], key=key),
973+
name="cifti_select_std",
974+
run_without_submitting=True,
975+
)
976+
968977
# fmt:off
969978
workflow.connect([
970979
(inputnode, bold_fsLR_resampling_wf, [
971980
("surfaces", "inputnode.surfaces"),
972981
("morphometrics", "inputnode.morphometrics"),
973982
("sphere_reg_fsLR", "inputnode.sphere_reg_fsLR"),
974983
("anat_ribbon", "inputnode.anat_ribbon")]),
975-
# (bold_std_trans_wf, cifti_select_std, [
976-
# ("outputnode.bold_std", "bold_std"),
977-
# ("outputnode.bold_aseg_std", "bold_aseg_std"),
978-
# ("outputnode.spatial_reference", "keys")]),
979-
# (cifti_select_std, subcortical_rois_wf, [
980-
# ("bold_aseg_std", "inputnode.MNIInfant_aseg")]),
981-
# (cifti_select_std, subcortical_mni_alignment_wf, [
982-
# ("bold_std", "inputnode.MNIInfant_bold")]),
983-
# (subcortical_rois_wf, subcortical_mni_alignment_wf, [
984-
# ("outputnode.MNIInfant_rois", "inputnode.MNIInfant_rois"),
985-
# ("outputnode.MNI152_rois", "inputnode.MNI152_rois")]),
986-
# (subcortical_mni_alignment_wf, bold_grayords_wf, [
987-
# ("outputnode.subcortical_volume", "inputnode.subcortical_volume"),
988-
# ("outputnode.subcortical_labels", "inputnode.subcortical_labels")]),
989-
# (bold_surf_wf, bold_grayords_wf, [
990-
# ('outputnode.surfaces', 'inputnode.surf_files'),
991-
# ('outputnode.target', 'inputnode.surf_refs')]),
984+
(bold_std_trans_wf, cifti_select_std, [
985+
("outputnode.bold_std", "bold_std"),
986+
("outputnode.bold_aseg_std", "bold_aseg_std"),
987+
("outputnode.spatial_reference", "keys")]),
988+
(cifti_select_std, subcortical_rois_wf, [
989+
("bold_aseg_std", "inputnode.MNIInfant_aseg")]),
990+
(cifti_select_std, subcortical_mni_alignment_wf, [
991+
("bold_std", "inputnode.MNIInfant_bold")]),
992+
(subcortical_rois_wf, subcortical_mni_alignment_wf, [
993+
("outputnode.MNIInfant_rois", "inputnode.MNIInfant_rois"),
994+
("outputnode.MNI152_rois", "inputnode.MNI152_rois")]),
995+
(subcortical_mni_alignment_wf, bold_grayords_wf, [
996+
("outputnode.subcortical_volume", "inputnode.subcortical_volume"),
997+
("outputnode.subcortical_labels", "inputnode.subcortical_labels")]),
992998
(bold_t1_trans_wf, bold_fsLR_resampling_wf, [
993999
("outputnode.bold_t1", "inputnode.bold_file")]),
9941000
(bold_std_trans_wf, bold_grayords_wf, [

nibabies/workflows/bold/resampling.py

Lines changed: 69 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,25 @@
99
.. autofunction:: init_bold_preproc_trans_wf
1010
1111
"""
12+
from __future__ import annotations
1213

14+
import typing as ty
1315

14-
from os.path import basename
15-
16-
import nipype.interfaces.workbench as wb
16+
import templateflow.api as tf
1717
from nipype import Function
1818
from nipype.interfaces import freesurfer as fs
1919
from nipype.interfaces import fsl
2020
from nipype.interfaces import utility as niu
2121
from nipype.pipeline import engine as pe
2222
from niworkflows.interfaces.fixes import FixHeaderApplyTransforms as ApplyTransforms
2323
from niworkflows.interfaces.freesurfer import MedialNaNs
24+
from niworkflows.interfaces.workbench import MetricDilate, MetricMask, MetricResample
2425

2526
from nibabies.config import DEFAULT_MEMORY_MIN_GB
27+
from nibabies.data import load_resource
28+
29+
if ty.TYPE_CHECKING:
30+
from niworkflows.utils.spaces import SpatialReferences
2631

2732

2833
def init_bold_surf_wf(
@@ -82,8 +87,6 @@ def init_bold_surf_wf(
8287
from niworkflows.engine.workflows import LiterateWorkflow as Workflow
8388
from niworkflows.interfaces.surf import GiftiSetAnatomicalStructure
8489

85-
from ...interfaces.metric import MetricDilate
86-
8790
workflow = Workflow(name=name)
8891
workflow.__desc__ = """\
8992
The BOLD time-series were resampled onto the following surfaces
@@ -422,47 +425,6 @@ def _calc_lower_thr(in_stats):
422425
mem_gb=mem_gb,
423426
)
424427

425-
# make HCP-style "goodvoxels" mask in t1w space for filtering outlier voxels
426-
# in bold timeseries, based on modulated normalized covariance
427-
workflow.connect(
428-
[
429-
(inputnode, ribbon_boldsrc_xfm, [("anat_ribbon", "input_image")]),
430-
(inputnode, stdev_volume, [("bold_file", "in_file")]),
431-
(inputnode, mean_volume, [("bold_file", "in_file")]),
432-
(mean_volume, ribbon_boldsrc_xfm, [("out_file", "reference_image")]),
433-
(stdev_volume, cov_volume, [("out_file", "in_file")]),
434-
(mean_volume, cov_volume, [("out_file", "operand_file")]),
435-
(cov_volume, cov_ribbon, [("out_file", "in_file")]),
436-
(ribbon_boldsrc_xfm, cov_ribbon, [("output_image", "mask_file")]),
437-
(cov_ribbon, cov_ribbon_mean, [("out_file", "in_file")]),
438-
(cov_ribbon, cov_ribbon_std, [("out_file", "in_file")]),
439-
(cov_ribbon, cov_ribbon_norm, [("out_file", "in_file")]),
440-
(cov_ribbon_mean, cov_ribbon_norm, [("out_stat", "operand_value")]),
441-
(cov_ribbon_norm, smooth_norm, [("out_file", "in_file")]),
442-
(smooth_norm, merge_smooth_norm, [("out_file", "in1")]),
443-
(cov_ribbon_norm, cov_ribbon_norm_smooth, [("out_file", "in_file")]),
444-
(merge_smooth_norm, cov_ribbon_norm_smooth, [("out", "operand_files")]),
445-
(cov_ribbon_mean, cov_norm, [("out_stat", "operand_value")]),
446-
(cov_volume, cov_norm, [("out_file", "in_file")]),
447-
(cov_norm, cov_norm_modulate, [("out_file", "in_file")]),
448-
(cov_ribbon_norm_smooth, cov_norm_modulate, [("out_file", "operand_file")]),
449-
(cov_norm_modulate, cov_norm_modulate_ribbon, [("out_file", "in_file")]),
450-
(ribbon_boldsrc_xfm, cov_norm_modulate_ribbon, [("output_image", "mask_file")]),
451-
(cov_norm_modulate_ribbon, mod_ribbon_mean, [("out_file", "in_file")]),
452-
(cov_norm_modulate_ribbon, mod_ribbon_std, [("out_file", "in_file")]),
453-
(mod_ribbon_mean, merge_mod_ribbon_stats, [("out_stat", "in1")]),
454-
(mod_ribbon_std, merge_mod_ribbon_stats, [("out_stat", "in2")]),
455-
(merge_mod_ribbon_stats, upper_thr_val, [("out", "in_stats")]),
456-
(merge_mod_ribbon_stats, lower_thr_val, [("out", "in_stats")]),
457-
(mean_volume, bin_mean_volume, [("out_file", "in_file")]),
458-
(upper_thr_val, goodvoxels_thr, [("upper_thresh", "thresh")]),
459-
(cov_norm_modulate, goodvoxels_thr, [("out_file", "in_file")]),
460-
(bin_mean_volume, merge_goodvoxels_operands, [("out_file", "in1")]),
461-
(goodvoxels_thr, goodvoxels_mask, [("out_file", "in_file")]),
462-
(merge_goodvoxels_operands, goodvoxels_mask, [("out", "operand_files")]),
463-
]
464-
)
465-
466428
goodvoxels_ribbon_mask = pe.Node(
467429
fsl.ApplyMask(),
468430
name_source=['in_file'],
@@ -471,8 +433,44 @@ def _calc_lower_thr(in_stats):
471433
mem_gb=DEFAULT_MEMORY_MIN_GB,
472434
)
473435

436+
# make HCP-style "goodvoxels" mask in t1w space for filtering outlier voxels
437+
# in bold timeseries, based on modulated normalized covariance
474438
# fmt:off
475439
workflow.connect([
440+
(inputnode, ribbon_boldsrc_xfm, [("anat_ribbon", "input_image")]),
441+
(inputnode, stdev_volume, [("bold_file", "in_file")]),
442+
(inputnode, mean_volume, [("bold_file", "in_file")]),
443+
(mean_volume, ribbon_boldsrc_xfm, [("out_file", "reference_image")]),
444+
(stdev_volume, cov_volume, [("out_file", "in_file")]),
445+
(mean_volume, cov_volume, [("out_file", "operand_file")]),
446+
(cov_volume, cov_ribbon, [("out_file", "in_file")]),
447+
(ribbon_boldsrc_xfm, cov_ribbon, [("output_image", "mask_file")]),
448+
(cov_ribbon, cov_ribbon_mean, [("out_file", "in_file")]),
449+
(cov_ribbon, cov_ribbon_std, [("out_file", "in_file")]),
450+
(cov_ribbon, cov_ribbon_norm, [("out_file", "in_file")]),
451+
(cov_ribbon_mean, cov_ribbon_norm, [("out_stat", "operand_value")]),
452+
(cov_ribbon_norm, smooth_norm, [("out_file", "in_file")]),
453+
(smooth_norm, merge_smooth_norm, [("out_file", "in1")]),
454+
(cov_ribbon_norm, cov_ribbon_norm_smooth, [("out_file", "in_file")]),
455+
(merge_smooth_norm, cov_ribbon_norm_smooth, [("out", "operand_files")]),
456+
(cov_ribbon_mean, cov_norm, [("out_stat", "operand_value")]),
457+
(cov_volume, cov_norm, [("out_file", "in_file")]),
458+
(cov_norm, cov_norm_modulate, [("out_file", "in_file")]),
459+
(cov_ribbon_norm_smooth, cov_norm_modulate, [("out_file", "operand_file")]),
460+
(cov_norm_modulate, cov_norm_modulate_ribbon, [("out_file", "in_file")]),
461+
(ribbon_boldsrc_xfm, cov_norm_modulate_ribbon, [("output_image", "mask_file")]),
462+
(cov_norm_modulate_ribbon, mod_ribbon_mean, [("out_file", "in_file")]),
463+
(cov_norm_modulate_ribbon, mod_ribbon_std, [("out_file", "in_file")]),
464+
(mod_ribbon_mean, merge_mod_ribbon_stats, [("out_stat", "in1")]),
465+
(mod_ribbon_std, merge_mod_ribbon_stats, [("out_stat", "in2")]),
466+
(merge_mod_ribbon_stats, upper_thr_val, [("out", "in_stats")]),
467+
(merge_mod_ribbon_stats, lower_thr_val, [("out", "in_stats")]),
468+
(mean_volume, bin_mean_volume, [("out_file", "in_file")]),
469+
(upper_thr_val, goodvoxels_thr, [("upper_thresh", "thresh")]),
470+
(cov_norm_modulate, goodvoxels_thr, [("out_file", "in_file")]),
471+
(bin_mean_volume, merge_goodvoxels_operands, [("out_file", "in1")]),
472+
(goodvoxels_thr, goodvoxels_mask, [("out_file", "in_file")]),
473+
(merge_goodvoxels_operands, goodvoxels_mask, [("out", "operand_files")]),
476474
(goodvoxels_mask, goodvoxels_ribbon_mask, [("out_file", "in_file")]),
477475
(ribbon_boldsrc_xfm, goodvoxels_ribbon_mask, [("output_image", "mask_file")]),
478476
(goodvoxels_mask, outputnode, [("out_file", "goodvoxels_mask")]),
@@ -603,20 +601,31 @@ def init_bold_fsLR_resampling_wf(
603601
),
604602
name='select_surfaces',
605603
)
606-
select_surfaces.inputs.template_spheres = [
607-
str(sphere)
608-
for sphere in tf.get(
609-
template='fsLR',
610-
density=fslr_density,
611-
suffix='sphere',
612-
space=None,
613-
extension='.surf.gii',
614-
)
615-
]
616-
atlases = smriprep_data.load_resource('atlases')
604+
if mcribs:
605+
atlases = load_resource('atlases')
606+
# use dHCP 32k fsLR instead
607+
select_surfaces.inputs.template_spheres = [
608+
str(atlases / 'dHCP' / 'dHCP.week42.L.sphere.surf.gii'),
609+
str(atlases / 'dHCP' / 'dHCP.week42.R.sphere.surf.gii'),
610+
]
611+
612+
# TODO: different template ROIs?
613+
else:
614+
select_surfaces.inputs.template_spheres = [
615+
str(sphere)
616+
for sphere in tf.get(
617+
template='fsLR',
618+
density=fslr_density,
619+
suffix='sphere',
620+
space=None,
621+
extension='.surf.gii',
622+
)
623+
]
624+
625+
smriprep_atlases = smriprep_data.load_resource('atlases')
617626
select_surfaces.inputs.template_rois = [
618-
str(atlases / 'L.atlasroi.32k_fs_LR.shape.gii'),
619-
str(atlases / 'R.atlasroi.32k_fs_LR.shape.gii'),
627+
str(smriprep_atlases / 'L.atlasroi.32k_fs_LR.shape.gii'),
628+
str(smriprep_atlases / 'R.atlasroi.32k_fs_LR.shape.gii'),
620629
]
621630

622631
# Reimplements lines 282-290 of FreeSurfer2CaretConvertAndRegisterNonlinear.sh
@@ -1208,7 +1217,6 @@ def init_bold_grayords_wf(grayord_density, mem_gb, repetition_time, name="bold_g
12081217
BIDS metadata file corresponding to ``cifti_bold``.
12091218
12101219
"""
1211-
import templateflow as tf
12121220
from niworkflows.engine.workflows import LiterateWorkflow as Workflow
12131221
from niworkflows.interfaces.utility import KeySelect
12141222

@@ -1248,7 +1256,7 @@ def init_bold_grayords_wf(grayord_density, mem_gb, repetition_time, name="bold_g
12481256
)
12491257
gen_cifti = pe.Node(CiftiCreateDenseTimeseries(timestep=repetition_time), name="gen_cifti")
12501258
gen_cifti.inputs.volume_structure_labels = str(
1251-
tf.api.get("MNI152NLin6Asym", resolution=mni_density, atlas="HCP", suffix="dseg")
1259+
tf.get("MNI152NLin6Asym", resolution=mni_density, atlas="HCP", suffix="dseg")
12521260
)
12531261
gen_cifti_metadata = pe.Node(
12541262
niu.Function(function=_gen_metadata, output_names=["out_metadata"]),
@@ -1266,10 +1274,6 @@ def init_bold_grayords_wf(grayord_density, mem_gb, repetition_time, name="bold_g
12661274
(split_surfaces, gen_cifti, [
12671275
('left_surface', 'left_metric'),
12681276
('right_surface', 'right_metric')]),
1269-
# (resample, split_surfaces, [('out_file', 'in_surfaces')]),
1270-
# (split_surfaces, gen_cifti, [
1271-
# ('left_surface', 'left_metric'),
1272-
# ('right_surface', 'right_metric')]),
12731277
(gen_cifti, outputnode, [('out_file', 'cifti_bold')]),
12741278
(gen_cifti_metadata, outputnode, [('out_metadata', 'cifti_metadata')]),
12751279
])

0 commit comments

Comments
 (0)