Skip to content

Commit 691f1a1

Browse files
committed
ENH: Resample BOLD series to volumetric templates
1 parent 6bda5ce commit 691f1a1

File tree

2 files changed

+85
-87
lines changed

2 files changed

+85
-87
lines changed

fmriprep/workflows/base.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ def init_single_subject_wf(subject_id: str):
151151
from niworkflows.utils.misc import fix_multi_T1w_source_name
152152
from niworkflows.utils.spaces import Reference
153153
from smriprep.workflows.anatomical import init_anat_fit_wf
154+
from smriprep.workflows.outputs import init_template_iterator_wf
154155

155156
from fmriprep.workflows.bold.base import init_bold_wf
156157

@@ -310,7 +311,6 @@ def init_single_subject_wf(subject_id: str):
310311
skull_strip_fixed_seed=config.workflow.skull_strip_fixed_seed,
311312
)
312313

313-
# fmt:off
314314
workflow.connect([
315315
(inputnode, anat_fit_wf, [('subjects_dir', 'inputnode.subjects_dir')]),
316316
(bidssrc, bids_info, [(('t1w', fix_multi_T1w_source_name), 'in_file')]),
@@ -329,8 +329,18 @@ def init_single_subject_wf(subject_id: str):
329329
(bidssrc, ds_report_about, [(('t1w', fix_multi_T1w_source_name), 'source_file')]),
330330
(summary, ds_report_summary, [('out_report', 'in_file')]),
331331
(about, ds_report_about, [('out_report', 'in_file')]),
332-
])
333-
# fmt:on
332+
]) # fmt:skip
333+
334+
# Set up the template iterator once, if used
335+
if config.workflow.level == "full":
336+
if spaces.get_spaces(nonstandard=False, dim=(3,)):
337+
template_iterator_wf = init_template_iterator_wf(spaces=spaces)
338+
workflow.connect([
339+
(anat_fit_wf, template_iterator_wf, [
340+
('outputnode.template', 'inputnode.template'),
341+
('outputnode.anat2std_xfm', 'inputnode.anat2std_xfm'),
342+
]),
343+
]) # fmt:skip
334344

335345
if config.workflow.anat_only:
336346
return clean_datasinks(workflow)
@@ -510,6 +520,18 @@ def init_single_subject_wf(subject_id: str):
510520
]),
511521
]) # fmt:skip
512522

523+
if config.workflow.level == "full":
524+
workflow.connect([
525+
(template_iterator_wf, bold_wf, [
526+
("outputnode.anat2std_xfm", "inputnode.anat2std_xfm"),
527+
("outputnode.space", "inputnode.std_space"),
528+
("outputnode.resolution", "inputnode.std_resolution"),
529+
("outputnode.cohort", "inputnode.std_cohort"),
530+
("outputnode.std_t1w", "inputnode.std_t1w"),
531+
("outputnode.std_mask", "inputnode.std_mask"),
532+
]),
533+
]) # fmt:skip
534+
513535
return clean_datasinks(workflow)
514536

515537

fmriprep/workflows/bold/base.py

Lines changed: 60 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,13 @@ def init_bold_wf(
198198
"fmap_mask",
199199
"fmap_id",
200200
"sdc_method",
201+
# Volumetric templates
202+
"anat2std_xfm",
203+
"std_space",
204+
"std_resolution",
205+
"std_cohort",
206+
"std_t1w",
207+
"std_mask",
201208
],
202209
),
203210
name="inputnode",
@@ -381,6 +388,59 @@ def init_bold_wf(
381388
(bold_anat_wf, ds_bold_t1_wf, [('outputnode.bold_file', 'inputnode.bold')]),
382389
]) # fmt:skip
383390

391+
if spaces.get_spaces(nonstandard=False, dim=(3,)):
392+
# Missing:
393+
# * Clipping BOLD after resampling
394+
# * Resampling parcellations
395+
bold_std_wf = init_bold_volumetric_resample_wf(
396+
metadata=all_metadata[0],
397+
fieldmap_id=fieldmap_id if not multiecho else None,
398+
omp_nthreads=omp_nthreads,
399+
name='bold_std_wf',
400+
)
401+
ds_bold_std_wf = init_ds_volumes_wf(
402+
bids_root=str(config.execution.bids_dir),
403+
output_dir=fmriprep_dir,
404+
multiecho=multiecho,
405+
metadata=all_metadata[0],
406+
name='ds_bold_std_wf',
407+
)
408+
ds_bold_std_wf.inputs.inputnode.source_files = bold_series
409+
410+
workflow.connect([
411+
(inputnode, bold_std_wf, [
412+
("std_t1w", "inputnode.target_ref_file"),
413+
("std_mask", "inputnode.target_mask"),
414+
("anat2std_xfm", "inputnode.anat2std_xfm"),
415+
("fmap_ref", "inputnode.fmap_ref"),
416+
("fmap_coeff", "inputnode.fmap_coeff"),
417+
("fmap_id", "inputnode.fmap_id"),
418+
]),
419+
(bold_fit_wf, bold_std_wf, [
420+
("outputnode.coreg_boldref", "inputnode.bold_ref_file"),
421+
("outputnode.boldref2fmap_xfm", "inputnode.boldref2fmap_xfm"),
422+
("outputnode.boldref2anat_xfm", "inputnode.boldref2anat_xfm"),
423+
]),
424+
(bold_native_wf, bold_std_wf, [
425+
("outputnode.bold_minimal", "inputnode.bold_file"),
426+
("outputnode.motion_xfm", "inputnode.motion_xfm"),
427+
]),
428+
(inputnode, ds_bold_std_wf, [
429+
('std_t1w', 'inputnode.ref_file'),
430+
('anat2std_xfm', 'inputnode.anat2std_xfm'),
431+
('std_space', 'inputnode.space'),
432+
('std_resolution', 'inputnode.resolution'),
433+
('std_cohort', 'inputnode.cohort'),
434+
]),
435+
(bold_fit_wf, ds_bold_std_wf, [
436+
('outputnode.bold_mask', 'inputnode.bold_mask'),
437+
('outputnode.coreg_boldref', 'inputnode.bold_ref'),
438+
('outputnode.boldref2anat_xfm', 'inputnode.boldref2anat_xfm'),
439+
]),
440+
(bold_native_wf, ds_bold_std_wf, [('outputnode.t2star_map', 'inputnode.t2star')]),
441+
(bold_std_wf, ds_bold_std_wf, [('outputnode.bold_file', 'inputnode.bold')]),
442+
]) # fmt:skip
443+
384444
# Fill-in datasinks of reportlets seen so far
385445
for node in workflow.list_node_names():
386446
if node.split(".")[-1].startswith("ds_report"):
@@ -629,90 +689,6 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False):
629689
)
630690
bold_confounds_wf.get_node("inputnode").inputs.t1_transform_flags = [False]
631691

632-
if spaces.get_spaces(nonstandard=False, dim=(3,)):
633-
# Apply transforms in 1 shot
634-
bold_std_trans_wf = init_bold_std_trans_wf(
635-
freesurfer=freesurfer,
636-
mem_gb=mem_gb["resampled"],
637-
omp_nthreads=omp_nthreads,
638-
spaces=spaces,
639-
multiecho=multiecho,
640-
name="bold_std_trans_wf",
641-
use_compression=not config.execution.low_mem,
642-
)
643-
bold_std_trans_wf.inputs.inputnode.fieldwarp = "identity"
644-
645-
# fmt:off
646-
workflow.connect([
647-
(inputnode, bold_std_trans_wf, [
648-
("template", "inputnode.templates"),
649-
("anat2std_xfm", "inputnode.anat2std_xfm"),
650-
("bold_file", "inputnode.name_source"),
651-
("t1w_aseg", "inputnode.bold_aseg"),
652-
("t1w_aparc", "inputnode.bold_aparc"),
653-
]),
654-
(bold_final, bold_std_trans_wf, [
655-
("mask", "inputnode.bold_mask"),
656-
("t2star", "inputnode.t2star"),
657-
]),
658-
(bold_reg_wf, bold_std_trans_wf, [
659-
("outputnode.itk_bold_to_t1", "inputnode.itk_bold_to_t1"),
660-
]),
661-
(bold_std_trans_wf, outputnode, [
662-
("outputnode.bold_std", "bold_std"),
663-
("outputnode.bold_std_ref", "bold_std_ref"),
664-
("outputnode.bold_mask_std", "bold_mask_std"),
665-
]),
666-
])
667-
# fmt:on
668-
669-
if freesurfer:
670-
# fmt:off
671-
workflow.connect([
672-
(bold_std_trans_wf, func_derivatives_wf, [
673-
("outputnode.bold_aseg_std", "inputnode.bold_aseg_std"),
674-
("outputnode.bold_aparc_std", "inputnode.bold_aparc_std"),
675-
]),
676-
(bold_std_trans_wf, outputnode, [
677-
("outputnode.bold_aseg_std", "bold_aseg_std"),
678-
("outputnode.bold_aparc_std", "bold_aparc_std"),
679-
]),
680-
])
681-
# fmt:on
682-
683-
if not multiecho:
684-
# fmt:off
685-
workflow.connect([
686-
(bold_split, bold_std_trans_wf, [("out_files", "inputnode.bold_split")]),
687-
(bold_hmc_wf, bold_std_trans_wf, [
688-
("outputnode.xforms", "inputnode.hmc_xforms"),
689-
]),
690-
])
691-
# fmt:on
692-
else:
693-
# fmt:off
694-
workflow.connect([
695-
(split_opt_comb, bold_std_trans_wf, [("out_files", "inputnode.bold_split")]),
696-
(bold_std_trans_wf, outputnode, [("outputnode.t2star_std", "t2star_std")]),
697-
])
698-
# fmt:on
699-
700-
# Already applied in bold_bold_trans_wf, which inputs to bold_t2s_wf
701-
bold_std_trans_wf.inputs.inputnode.hmc_xforms = "identity"
702-
703-
# fmt:off
704-
# func_derivatives_wf internally parametrizes over snapshotted spaces.
705-
workflow.connect([
706-
(bold_std_trans_wf, func_derivatives_wf, [
707-
("outputnode.template", "inputnode.template"),
708-
("outputnode.spatial_reference", "inputnode.spatial_reference"),
709-
("outputnode.bold_std_ref", "inputnode.bold_std_ref"),
710-
("outputnode.bold_std", "inputnode.bold_std"),
711-
("outputnode.bold_mask_std", "inputnode.bold_mask_std"),
712-
]),
713-
])
714-
# fmt:on
715-
716692
# SURFACES ##################################################################################
717693
# Freesurfer
718694
if freesurfer and freesurfer_spaces:

0 commit comments

Comments
 (0)