From abee6109bf66714c0f156f43815586fb7f312c1c Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 5 Jun 2020 23:54:17 -0400 Subject: [PATCH 01/15] Join bold masks and select first echo's mask for multi-echo data. --- fmriprep/utils/misc.py | 19 +++++++++ fmriprep/workflows/bold/base.py | 71 ++++++++++++++++++++++++++------- 2 files changed, 76 insertions(+), 14 deletions(-) diff --git a/fmriprep/utils/misc.py b/fmriprep/utils/misc.py index d69bf1f43..2ab9e10a0 100644 --- a/fmriprep/utils/misc.py +++ b/fmriprep/utils/misc.py @@ -11,3 +11,22 @@ def check_deps(workflow): for node in workflow._get_all_nodes() if (hasattr(node.interface, '_cmd') and which(node.interface._cmd.split()[0]) is None)) + + +def select_first(in_files): + """ + Select the first file from a list of filenames. + Used to grab the first echo's file when processing + multi-echo data through workflows that only accept + a single file. + + Examples + -------- + >>> select_first('some/file.nii.gz') + 'some/file.nii.gz' + >>> select_first(['some/file1.nii.gz', 'some/file2.nii.gz']) + 'some/file1.nii.gz' + """ + if isinstance(in_files, (list, tuple)): + return in_files[0] + return in_files diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 4b6e59716..513b6ebb0 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -18,6 +18,7 @@ from nipype.interfaces import utility as niu from ...utils.meepi import combine_meepi_source +from ...utils.misc import select_first from ...interfaces import DerivativesDataSink from ...interfaces.reports import FunctionalSummary @@ -122,7 +123,7 @@ def init_func_preproc_wf(bold_file): * :py:func:`~fmriprep.workflows.bold.t2s.init_bold_t2s_wf` * :py:func:`~fmriprep.workflows.bold.registration.init_bold_t1_trans_wf` * :py:func:`~fmriprep.workflows.bold.registration.init_bold_reg_wf` - * :py:func:`~fmriprep.workflows.bold.confounds.init_bold_confounds_wf` + * :py:func:`~fmriprep.workflows.bold.confounds.init_bold_confs_wf` * :py:func:`~fmriprep.workflows.bold.confounds.init_ica_aroma_wf` * :py:func:`~fmriprep.workflows.bold.resampling.init_bold_std_trans_wf` * :py:func:`~fmriprep.workflows.bold.resampling.init_bold_preproc_trans_wf` @@ -390,10 +391,11 @@ def init_func_preproc_wf(bold_file): inputnode.inputs.bold_file = ref_file # Replace reference w first echo - join_echos = pe.JoinNode(niu.IdentityInterface(fields=['bold_files']), + join_echos = pe.JoinNode(niu.IdentityInterface(fields=['bold_files', 'bold_masks']), joinsource=('meepi_echos' if run_stc is True else 'boldbuffer'), joinfield=['bold_files'], name='join_echos') + # join_echos2 = join_echos.clone(name='join_echos2') # create optimal combination, adaptive T2* map bold_t2s_wf = init_bold_t2s_wf(echo_times=tes, @@ -474,9 +476,6 @@ def init_func_preproc_wf(bold_file): ('outputnode.itk_t1_to_bold', 'inputnode.t1_bold_xform')]), (bold_reference_wf, bold_confounds_wf, [ ('outputnode.skip_vols', 'inputnode.skip_vols')]), - (bold_bold_trans_wf, bold_confounds_wf, [ - ('outputnode.bold_mask', 'inputnode.bold_mask'), - ]), (bold_confounds_wf, outputnode, [ ('outputnode.confounds_file', 'confounds'), ]), @@ -501,6 +500,9 @@ def init_func_preproc_wf(bold_file): ('outputnode.bold', 'inputnode.bold')]), (bold_split, bold_t1_trans_wf, [ ('out_files', 'inputnode.bold_split')]), + (bold_bold_trans_wf, bold_confounds_wf, [ + ('outputnode.bold_mask', 'inputnode.bold_mask'), + ]), ]) else: # for meepi, create and use optimal combination workflow.connect([ @@ -513,6 +515,11 @@ def init_func_preproc_wf(bold_file): ('outputnode.bold', 'inputnode.bold')]), (bold_t2s_wf, bold_t1_trans_wf, [ ('outputnode.bold', 'inputnode.bold_split')]), + (bold_bold_trans_wf, join_echos, [ + ('outputnode.bold_mask', 'bold_masks')]), + (join_echos, bold_confounds_wf, [ + (('bold_masks', select_first), 'inputnode.bold_mask') + ]) ]) if fmaps: @@ -588,20 +595,38 @@ def init_func_preproc_wf(bold_file): ('outputnode.itk_bold_to_t1', 'transforms')]), (bold_t1_trans_wf, boldmask_to_t1w, [ ('outputnode.bold_mask_t1', 'reference_image')]), - (bold_bold_trans_wf, boldmask_to_t1w, [ - ('outputnode.bold_mask', 'input_image')]), (boldmask_to_t1w, outputnode, [ ('output_image', 'bold_mask_t1')]), ]) + if not multiecho: + workflow.connect([ + (bold_bold_trans_wf, boldmask_to_t1w, [ + ('outputnode.bold_mask', 'input_image')]), + ]) + else: + workflow.connect([ + (join_echos, boldmask_to_t1w, [ + (('bold_masks', select_first), 'input_image')]), + ]) if nonstd_spaces.intersection(('func', 'run', 'bold', 'boldref', 'sbref')): workflow.connect([ (bold_bold_trans_wf, outputnode, [ ('outputnode.bold', 'bold_native')]), (bold_bold_trans_wf, func_derivatives_wf, [ - ('outputnode.bold_ref', 'inputnode.bold_native_ref'), - ('outputnode.bold_mask', 'inputnode.bold_mask_native')]), + ('outputnode.bold_ref', 'inputnode.bold_native_ref') + ]), ]) + if not multiecho: + workflow.connect([ + (bold_bold_trans_wf, func_derivatives_wf, [ + ('outputnode.bold_mask', 'inputnode.bold_mask_native')]), + ]) + else: + workflow.connect([ + (join_echos, func_derivatives_wf, [ + (('bold_masks', select_first), 'inputnode.bold_mask_native')]), + ]) if spaces.get_spaces(nonstandard=False, dim=(3,)): # Apply transforms in 1 shot @@ -626,8 +651,6 @@ def init_func_preproc_wf(bold_file): ('outputnode.xforms', 'inputnode.hmc_xforms')]), (bold_reg_wf, bold_std_trans_wf, [ ('outputnode.itk_bold_to_t1', 'inputnode.itk_bold_to_t1')]), - (bold_bold_trans_wf, bold_std_trans_wf, [ - ('outputnode.bold_mask', 'inputnode.bold_mask')]), (bold_sdc_wf, bold_std_trans_wf, [ ('outputnode.out_warp', 'inputnode.fieldwarp')]), (bold_std_trans_wf, outputnode, [('outputnode.bold_std', 'bold_std'), @@ -635,6 +658,17 @@ def init_func_preproc_wf(bold_file): ('outputnode.bold_mask_std', 'bold_mask_std')]), ]) + if not multiecho: + workflow.connect([ + (bold_bold_trans_wf, bold_std_trans_wf, [ + ('outputnode.bold_mask', 'inputnode.bold_mask')]), + ]) + else: + workflow.connect([ + (join_echos, func_derivatives_wf, [ + (('bold_masks', select_first), 'inputnode.bold_mask_native')]), + ]) + if freesurfer: workflow.connect([ (bold_std_trans_wf, func_derivatives_wf, [ @@ -798,15 +832,24 @@ def init_func_preproc_wf(bold_file): ('std2anat_xfm', 'inputnode.std2anat_xfm')]), (bold_bold_trans_wf if not multiecho else bold_t2s_wf, carpetplot_wf, [ ('outputnode.bold', 'inputnode.bold')]), - (bold_bold_trans_wf, carpetplot_wf, [ - ('outputnode.bold_mask', 'inputnode.bold_mask')]), (bold_reg_wf, carpetplot_wf, [ ('outputnode.itk_t1_to_bold', 'inputnode.t1_bold_xform')]), ]) + if not multiecho: + workflow.connect([ + (bold_bold_trans_wf, carpetplot_wf, [ + ('outputnode.bold_mask', 'inputnode.bold_mask')]), + ]) + else: + workflow.connect([ + (join_echos, carpetplot_wf, [ + (('bold_masks', select_first), 'inputnode.bold_mask')]), + ]) workflow.connect([ (bold_confounds_wf, carpetplot_wf, [ - ('outputnode.confounds_file', 'inputnode.confounds_file')]) + ('outputnode.confounds_file', 'inputnode.confounds_file') + ]) ]) # REPORTING ############################################################ From cd1925d1f691c3c7360156a9a2d4e80daf368c0a Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Sat, 6 Jun 2020 14:39:49 -0400 Subject: [PATCH 02/15] Fix and consolidate multi-echo-toggled connections. --- fmriprep/workflows/bold/base.py | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 513b6ebb0..e3bc60c63 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -662,11 +662,18 @@ def init_func_preproc_wf(bold_file): workflow.connect([ (bold_bold_trans_wf, bold_std_trans_wf, [ ('outputnode.bold_mask', 'inputnode.bold_mask')]), + (bold_split, bold_std_trans_wf, [ + ('out_files', 'inputnode.bold_split')]), ]) else: + split_opt_comb = bold_split.clone(name='split_opt_comb') workflow.connect([ - (join_echos, func_derivatives_wf, [ - (('bold_masks', select_first), 'inputnode.bold_mask_native')]), + (join_echos, bold_std_trans_wf, [ + (('bold_masks', select_first), 'inputnode.bold_mask')]), + (bold_t2s_wf, split_opt_comb, [ + ('outputnode.bold', 'in_file')]), + (split_opt_comb, bold_std_trans_wf, [ + ('out_files', 'inputnode.bold_split')]), ]) if freesurfer: @@ -680,21 +687,6 @@ def init_func_preproc_wf(bold_file): ('outputnode.bold_aparc_std', 'bold_aparc_std')]), ]) - if not multiecho: - workflow.connect([ - (bold_split, bold_std_trans_wf, [ - ('out_files', 'inputnode.bold_split')]) - ]) - else: - split_opt_comb = bold_split.clone(name='split_opt_comb') - workflow.connect([ - (bold_t2s_wf, split_opt_comb, [ - ('outputnode.bold', 'in_file')]), - (split_opt_comb, bold_std_trans_wf, [ - ('out_files', 'inputnode.bold_split') - ]) - ]) - # func_derivatives_wf internally parametrizes over snapshotted spaces. workflow.connect([ (bold_std_trans_wf, func_derivatives_wf, [ From a5e387d923629c3aa7709ad6bab71d456891222c Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Mon, 8 Jun 2020 20:51:50 -0400 Subject: [PATCH 03/15] Replace select_first with pop_file. --- fmriprep/utils/misc.py | 19 ------------------- fmriprep/workflows/bold/base.py | 11 +++++------ 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/fmriprep/utils/misc.py b/fmriprep/utils/misc.py index 3ba3064f1..52eae4b43 100644 --- a/fmriprep/utils/misc.py +++ b/fmriprep/utils/misc.py @@ -11,22 +11,3 @@ def check_deps(workflow): for node in workflow._get_all_nodes() if (hasattr(node.interface, '_cmd') and which(node.interface._cmd.split()[0]) is None)) - - -def select_first(in_files): - """ - Select the first file from a list of filenames. - Used to grab the first echo's file when processing - multi-echo data through workflows that only accept - a single file. - - Examples - -------- - >>> select_first('some/file.nii.gz') - 'some/file.nii.gz' - >>> select_first(['some/file1.nii.gz', 'some/file2.nii.gz']) - 'some/file1.nii.gz' - """ - if isinstance(in_files, (list, tuple)): - return in_files[0] - return in_files diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index ff6bbeab0..d833d9fcc 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -21,7 +21,6 @@ from ...utils.meepi import combine_meepi_source -from ...utils.misc import select_first from ...interfaces import DerivativesDataSink from ...interfaces.reports import FunctionalSummary @@ -526,7 +525,7 @@ def init_func_preproc_wf(bold_file): (bold_bold_trans_wf, join_echos, [ ('outputnode.bold_mask', 'bold_masks')]), (join_echos, bold_confounds_wf, [ - (('bold_masks', select_first), 'inputnode.bold_mask') + (('bold_masks', pop_file), 'inputnode.bold_mask') ]) ]) @@ -614,7 +613,7 @@ def init_func_preproc_wf(bold_file): else: workflow.connect([ (join_echos, boldmask_to_t1w, [ - (('bold_masks', select_first), 'input_image')]), + (('bold_masks', pop_file), 'input_image')]), ]) if nonstd_spaces.intersection(('func', 'run', 'bold', 'boldref', 'sbref')): @@ -633,7 +632,7 @@ def init_func_preproc_wf(bold_file): else: workflow.connect([ (join_echos, func_derivatives_wf, [ - (('bold_masks', select_first), 'inputnode.bold_mask_native')]), + (('bold_masks', pop_file), 'inputnode.bold_mask_native')]), ]) if spaces.get_spaces(nonstandard=False, dim=(3,)): @@ -677,7 +676,7 @@ def init_func_preproc_wf(bold_file): split_opt_comb = bold_split.clone(name='split_opt_comb') workflow.connect([ (join_echos, bold_std_trans_wf, [ - (('bold_masks', select_first), 'inputnode.bold_mask')]), + (('bold_masks', pop_file), 'inputnode.bold_mask')]), (bold_t2s_wf, split_opt_comb, [ ('outputnode.bold', 'in_file')]), (split_opt_comb, bold_std_trans_wf, [ @@ -843,7 +842,7 @@ def init_func_preproc_wf(bold_file): else: workflow.connect([ (join_echos, carpetplot_wf, [ - (('bold_masks', select_first), 'inputnode.bold_mask')]), + (('bold_masks', pop_file), 'inputnode.bold_mask')]), ]) workflow.connect([ From d3d3dab9707e81490c36dea13bd05b5fe18e3393 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 14 Aug 2020 21:48:29 -0400 Subject: [PATCH 04/15] Add freesurfer check back in. --- fmriprep/workflows/bold/base.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index c0cb2c6a0..62798a2b5 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -408,7 +408,6 @@ def init_func_preproc_wf(bold_file): joinsource=('meepi_echos' if run_stc is True else 'boldbuffer'), joinfield=['bold_files'], name='join_echos') - # join_echos2 = join_echos.clone(name='join_echos2') # create optimal combination, adaptive T2* map bold_t2s_wf = init_bold_t2s_wf(echo_times=tes, @@ -691,6 +690,17 @@ def init_func_preproc_wf(bold_file): bold_std_trans_wf.inputs.inputnode.fieldwarp = 'identity' bold_std_trans_wf.inputs.inputnode.hmc_xforms = 'identity' + if freesurfer: + workflow.connect([ + (bold_std_trans_wf, func_derivatives_wf, [ + ('outputnode.bold_aseg_std', 'inputnode.bold_aseg_std'), + ('outputnode.bold_aparc_std', 'inputnode.bold_aparc_std'), + ]), + (bold_std_trans_wf, outputnode, [ + ('outputnode.bold_aseg_std', 'bold_aseg_std'), + ('outputnode.bold_aparc_std', 'bold_aparc_std')]), + ]) + # func_derivatives_wf internally parametrizes over snapshotted spaces. workflow.connect([ (bold_std_trans_wf, func_derivatives_wf, [ From 5d8fe4880cbdd2e2ac7fffb7db0740adbfdcedfe Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 14 Aug 2020 21:54:51 -0400 Subject: [PATCH 05/15] Fix up merge. --- fmriprep/workflows/bold/base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 62798a2b5..6ac2d37b0 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -662,8 +662,6 @@ def init_func_preproc_wf(bold_file): ('t1w_aparc', 'inputnode.bold_aparc')]), (bold_reg_wf, bold_std_trans_wf, [ ('outputnode.itk_bold_to_t1', 'inputnode.itk_bold_to_t1')]), - (bold_bold_trans_wf, bold_std_trans_wf, [ - ('outputnode.bold_mask', 'inputnode.bold_mask')]), (bold_std_trans_wf, outputnode, [('outputnode.bold_std', 'bold_std'), ('outputnode.bold_std_ref', 'bold_std_ref'), ('outputnode.bold_mask_std', 'bold_mask_std')]), @@ -682,8 +680,10 @@ def init_func_preproc_wf(bold_file): ]) else: workflow.connect([ + (join_echos, bold_std_trans_wf, [ + (('bold_masks', pop_file), 'inputnode.bold_mask')]), (split_opt_comb, bold_std_trans_wf, [ - ('out_files', 'inputnode.bold_split')]) + ('out_files', 'inputnode.bold_split')]), ]) # Already applied in bold_bold_trans_wf, which inputs to bold_t2s_wf From 211c2982130ad9d1ca4e83bf9fe9fe42323d2aec Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Mon, 17 Aug 2020 12:50:46 -0400 Subject: [PATCH 06/15] Apply suggestions from code review Co-authored-by: Chris Markiewicz --- fmriprep/workflows/bold/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 6ac2d37b0..fef31b19a 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -628,7 +628,7 @@ def init_func_preproc_wf(bold_file): (bold_bold_trans_wf, outputnode, [ ('outputnode.bold', 'bold_native')]), (bold_bold_trans_wf, func_derivatives_wf, [ - ('outputnode.bold_ref', 'inputnode.bold_native_ref') + ('outputnode.bold_ref', 'inputnode.bold_native_ref'), ]), ]) if not multiecho: From 309a613ba5478b5c8621b4b8a7533d45b09fbdaf Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Mon, 17 Aug 2020 13:38:44 -0400 Subject: [PATCH 07/15] Move final boldref wf to init_func_preproc_wf. --- fmriprep/workflows/bold/base.py | 116 +++++++++++--------------- fmriprep/workflows/bold/resampling.py | 16 ---- 2 files changed, 51 insertions(+), 81 deletions(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index fef31b19a..39be2caef 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -17,7 +17,7 @@ from nipype.pipeline import engine as pe from nipype.interfaces import utility as niu -from niworkflows.utils.connections import pop_file, listify +from niworkflows.utils.connections import listify from ...utils.meepi import combine_meepi_source @@ -307,13 +307,14 @@ def init_func_preproc_wf(bold_file): ]) # Generate a tentative boldref - bold_reference_wf = init_bold_reference_wf( + initial_boldref_wf = init_bold_reference_wf( + name='initial_boldref_wf', omp_nthreads=omp_nthreads, bold_file=bold_file, sbref_files=sbref_files, multiecho=multiecho, ) - bold_reference_wf.inputs.inputnode.dummy_scans = config.workflow.dummy_scans + initial_boldref_wf.inputs.inputnode.dummy_scans = config.workflow.dummy_scans # Top-level BOLD splitter bold_split = pe.Node(FSLSplit(dimension='t'), name='bold_split', @@ -365,17 +366,25 @@ def init_func_preproc_wf(bold_file): ) bold_bold_trans_wf.inputs.inputnode.name_source = ref_file + # Generate a new BOLD reference + # This BOLD references *does not use* single-band reference images. + final_boldref_wf = init_bold_reference_wf( + name='final_boldref_wf', + omp_nthreads=omp_nthreads + ) + final_boldref_wf.__desc__ = None # Unset description to avoid second appearance + # SLICE-TIME CORRECTION (or bypass) ############################################# if run_stc is True: # bool('TooShort') == True, so check True explicitly bold_stc_wf = init_bold_stc_wf(name='bold_stc_wf', metadata=metadata) workflow.connect([ - (bold_reference_wf, bold_stc_wf, [ + (initial_boldref_wf, bold_stc_wf, [ ('outputnode.skip_vols', 'inputnode.skip_vols')]), (bold_stc_wf, boldbuffer, [('outputnode.stc_file', 'bold_file')]), ]) if not multiecho: workflow.connect([ - (bold_reference_wf, bold_stc_wf, [ + (initial_boldref_wf, bold_stc_wf, [ ('outputnode.bold_file', 'inputnode.bold_file')])]) else: # for meepi, iterate through stc_wf for all workflows meepi_echos = boldbuffer.clone(name='meepi_echos') @@ -385,7 +394,7 @@ def init_func_preproc_wf(bold_file): elif not multiecho: # STC is too short or False # bypass STC from original BOLD to the splitter through boldbuffer workflow.connect([ - (bold_reference_wf, boldbuffer, [('outputnode.bold_file', 'bold_file')])]) + (initial_boldref_wf, boldbuffer, [('outputnode.bold_file', 'bold_file')])]) else: # for meepi, iterate over all meepi echos to boldbuffer boldbuffer.iterables = ('bold_file', bold_file) @@ -404,10 +413,12 @@ def init_func_preproc_wf(bold_file): inputnode.inputs.bold_file = ref_file # Replace reference w first echo - join_echos = pe.JoinNode(niu.IdentityInterface(fields=['bold_files', 'bold_masks']), - joinsource=('meepi_echos' if run_stc is True else 'boldbuffer'), - joinfield=['bold_files'], - name='join_echos') + join_echos = pe.JoinNode( + niu.IdentityInterface(fields=['bold_files', 'skullstripped_bold_files']), + joinsource=('meepi_echos' if run_stc is True else 'boldbuffer'), + joinfield=['bold_files'], + name='join_echos' + ) # create optimal combination, adaptive T2* map bold_t2s_wf = init_bold_t2s_wf(echo_times=tes, @@ -422,10 +433,10 @@ def init_func_preproc_wf(bold_file): # BOLD buffer has slice-time corrected if it was run, original otherwise (boldbuffer, bold_split, [('bold_file', 'in_file')]), # HMC - (bold_reference_wf, bold_hmc_wf, [ + (initial_boldref_wf, bold_hmc_wf, [ ('outputnode.raw_ref_image', 'inputnode.raw_ref_image'), ('outputnode.bold_file', 'inputnode.bold_file')]), - (bold_reference_wf, summary, [ + (initial_boldref_wf, summary, [ ('outputnode.algo_dummy_scans', 'algo_dummy_scans')]), # EPI-T1 registration workflow (inputnode, bold_reg_wf, [ @@ -456,7 +467,7 @@ def init_func_preproc_wf(bold_file): # SDC (or pass-through workflow) (t1w_brain, bold_sdc_wf, [ ('out_file', 'inputnode.t1w_brain')]), - (bold_reference_wf, bold_sdc_wf, [ + (initial_boldref_wf, bold_sdc_wf, [ ('outputnode.ref_image', 'inputnode.epi_file'), ('outputnode.ref_image_brain', 'inputnode.epi_brain'), ('outputnode.bold_mask', 'inputnode.epi_mask')]), @@ -477,7 +488,7 @@ def init_func_preproc_wf(bold_file): ('outputnode.rmsd_file', 'inputnode.rmsd_file')]), (bold_reg_wf, bold_confounds_wf, [ ('outputnode.itk_t1_to_bold', 'inputnode.t1_bold_xform')]), - (bold_reference_wf, bold_confounds_wf, [ + (initial_boldref_wf, bold_confounds_wf, [ ('outputnode.skip_vols', 'inputnode.skip_vols')]), (bold_confounds_wf, outputnode, [ ('outputnode.confounds_file', 'confounds'), @@ -490,6 +501,8 @@ def init_func_preproc_wf(bold_file): ('out_files', 'inputnode.bold_file')]), (bold_hmc_wf, bold_bold_trans_wf, [ ('outputnode.xforms', 'inputnode.hmc_xforms')]), + (final_boldref_wf, bold_confounds_wf, [ + ('outputnode.bold_mask', 'inputnode.bold_mask')]), # Summary (outputnode, summary, [('confounds', 'confounds_file')]), ]) @@ -500,8 +513,9 @@ def init_func_preproc_wf(bold_file): (inputnode, func_derivatives_wf, [ ('bold_file', 'inputnode.source_file')]), (bold_bold_trans_wf, bold_confounds_wf, [ - ('outputnode.bold', 'inputnode.bold'), - ('outputnode.bold_mask', 'inputnode.bold_mask')]), + ('outputnode.bold', 'inputnode.bold')], + (bold_bold_trans_wf, final_boldref_wf, [ + ('outputnode.bold', 'inputnode.bold')]), (bold_split, bold_t1_trans_wf, [ ('out_files', 'inputnode.bold_split')]), (bold_hmc_wf, bold_t1_trans_wf, [ @@ -514,22 +528,22 @@ def init_func_preproc_wf(bold_file): # update name source for optimal combination (inputnode, func_derivatives_wf, [ (('bold_file', combine_meepi_source), 'inputnode.source_file')]), + (bold_bold_trans_wf, join_echos, [ + ('outputnode.bold', 'bold_files')]), + (join_echos, final_boldref_wf, [ + ('bold_files', 'inputnode.bold')]), (bold_bold_trans_wf, skullstrip_bold_wf, [ ('outputnode.bold', 'inputnode.in_file')]), (skullstrip_bold_wf, join_echos, [ - ('outputnode.skull_stripped_file', 'bold_files')]), + ('outputnode.skull_stripped_file', 'skullstripped_bold_files')]), (join_echos, bold_t2s_wf, [ - ('bold_files', 'inputnode.bold_file')]), + ('skullstripped_bold_files', 'inputnode.bold_file')]), (bold_t2s_wf, bold_confounds_wf, [ ('outputnode.bold', 'inputnode.bold')]), (bold_t2s_wf, split_opt_comb, [ ('outputnode.bold', 'in_file')]), (split_opt_comb, bold_t1_trans_wf, [ - ('out_files', 'inputnode.bold_split')]), - (bold_bold_trans_wf, join_echos, [ - ('outputnode.bold_mask', 'bold_masks')]), - (join_echos, bold_confounds_wf, [ - (('bold_masks', pop_file), 'inputnode.bold_mask')]) + ('out_files', 'inputnode.bold_split')]) ]) # Already applied in bold_bold_trans_wf, which inputs to bold_t2s_wf @@ -543,7 +557,7 @@ def init_func_preproc_wf(bold_file): workflow.connect([ (inputnode, fmap_unwarp_report_wf, [ ('t1w_dseg', 'inputnode.in_seg')]), - (bold_reference_wf, fmap_unwarp_report_wf, [ + (initial_boldref_wf, fmap_unwarp_report_wf, [ ('outputnode.ref_image', 'inputnode.in_pre')]), (bold_reg_wf, fmap_unwarp_report_wf, [ ('outputnode.itk_t1_to_bold', 'inputnode.in_xfm')]), @@ -580,7 +594,7 @@ def init_func_preproc_wf(bold_file): workflow.connect([ (inputnode, syn_unwarp_report_wf, [ ('t1w_dseg', 'inputnode.in_seg')]), - (bold_reference_wf, syn_unwarp_report_wf, [ + (initial_boldref_wf, syn_unwarp_report_wf, [ ('outputnode.ref_image', 'inputnode.in_pre')]), (bold_reg_wf, syn_unwarp_report_wf, [ ('outputnode.itk_t1_to_bold', 'inputnode.in_xfm')]), @@ -611,36 +625,18 @@ def init_func_preproc_wf(bold_file): ('outputnode.bold_mask_t1', 'reference_image')]), (boldmask_to_t1w, outputnode, [ ('output_image', 'bold_mask_t1')]), + (final_boldref_wf, boldmask_to_t1w, [ + ('outputnode.bold_mask', 'input_image')]) ]) - if not multiecho: - workflow.connect([ - (bold_bold_trans_wf, boldmask_to_t1w, [ - ('outputnode.bold_mask', 'input_image')]), - ]) - else: - workflow.connect([ - (join_echos, boldmask_to_t1w, [ - (('bold_masks', pop_file), 'input_image')]), - ]) if nonstd_spaces.intersection(('func', 'run', 'bold', 'boldref', 'sbref')): workflow.connect([ - (bold_bold_trans_wf, outputnode, [ - ('outputnode.bold', 'bold_native')]), - (bold_bold_trans_wf, func_derivatives_wf, [ + (final_boldref_wf, func_derivatives_wf, [ ('outputnode.bold_ref', 'inputnode.bold_native_ref'), - ]), + ('outputnode.bold_mask', 'inputnode.bold_mask_native')]), + (bold_bold_trans_wf if not multiecho else bold_t2s_wf, outputnode, [ + ('outputnode.bold', 'bold_native')]) ]) - if not multiecho: - workflow.connect([ - (bold_bold_trans_wf, func_derivatives_wf, [ - ('outputnode.bold_mask', 'inputnode.bold_mask_native')]), - ]) - else: - workflow.connect([ - (join_echos, func_derivatives_wf, [ - (('bold_masks', pop_file), 'inputnode.bold_mask_native')]), - ]) if spaces.get_spaces(nonstandard=False, dim=(3,)): # Apply transforms in 1 shot @@ -660,6 +656,8 @@ def init_func_preproc_wf(bold_file): ('bold_file', 'inputnode.name_source'), ('t1w_aseg', 'inputnode.bold_aseg'), ('t1w_aparc', 'inputnode.bold_aparc')]), + (final_boldref_wf, bold_std_trans_wf, [ + ('outputnode.bold_mask', 'inputnode.bold_mask')]), (bold_reg_wf, bold_std_trans_wf, [ ('outputnode.itk_bold_to_t1', 'inputnode.itk_bold_to_t1')]), (bold_std_trans_wf, outputnode, [('outputnode.bold_std', 'bold_std'), @@ -669,8 +667,6 @@ def init_func_preproc_wf(bold_file): if not multiecho: workflow.connect([ - (bold_bold_trans_wf, bold_std_trans_wf, [ - ('outputnode.bold_mask', 'inputnode.bold_mask')]), (bold_split, bold_std_trans_wf, [ ('out_files', 'inputnode.bold_split')]), (bold_sdc_wf, bold_std_trans_wf, [ @@ -680,8 +676,6 @@ def init_func_preproc_wf(bold_file): ]) else: workflow.connect([ - (join_echos, bold_std_trans_wf, [ - (('bold_masks', pop_file), 'inputnode.bold_mask')]), (split_opt_comb, bold_std_trans_wf, [ ('out_files', 'inputnode.bold_split')]), ]) @@ -743,7 +737,7 @@ def init_func_preproc_wf(bold_file): ('bold_file', 'inputnode.name_source')]), (bold_hmc_wf, ica_aroma_wf, [ ('outputnode.movpar_file', 'inputnode.movpar_file')]), - (bold_reference_wf, ica_aroma_wf, [ + (initial_boldref_wf, ica_aroma_wf, [ ('outputnode.skip_vols', 'inputnode.skip_vols')]), (bold_confounds_wf, join, [ ('outputnode.confounds_file', 'in_file')]), @@ -839,17 +833,9 @@ def init_func_preproc_wf(bold_file): ('outputnode.bold', 'inputnode.bold')]), (bold_reg_wf, carpetplot_wf, [ ('outputnode.itk_t1_to_bold', 'inputnode.t1_bold_xform')]), + (final_boldref_wf, carpetplot_wf, [ + ('outputnode.bold_mask', 'inputnode.bold_mask')]), ]) - if not multiecho: - workflow.connect([ - (bold_bold_trans_wf, carpetplot_wf, [ - ('outputnode.bold_mask', 'inputnode.bold_mask')]), - ]) - else: - workflow.connect([ - (join_echos, carpetplot_wf, [ - (('bold_masks', pop_file), 'inputnode.bold_mask')]), - ]) workflow.connect([ (bold_confounds_wf, carpetplot_wf, [ @@ -871,7 +857,7 @@ def init_func_preproc_wf(bold_file): workflow.connect([ (summary, ds_report_summary, [('out_report', 'in_file')]), - (bold_reference_wf, ds_report_validation, [ + (initial_boldref_wf, ds_report_validation, [ ('outputnode.validation_report', 'in_file')]), ]) diff --git a/fmriprep/workflows/bold/resampling.py b/fmriprep/workflows/bold/resampling.py index afa6fb1e5..3a81bbd94 100644 --- a/fmriprep/workflows/bold/resampling.py +++ b/fmriprep/workflows/bold/resampling.py @@ -472,16 +472,9 @@ def init_bold_preproc_trans_wf(mem_gb, omp_nthreads, ------- bold BOLD series, resampled in native space, including all preprocessing - bold_mask - BOLD series mask calculated with the new time-series - bold_ref - BOLD reference image: an average-like 3D image of the time-series - bold_ref_brain - Same as ``bold_ref``, but once the brain mask has been applied """ from niworkflows.engine.workflows import LiterateWorkflow as Workflow - from niworkflows.func.util import init_bold_reference_wf from niworkflows.interfaces.itk import MultiApplyTransforms from niworkflows.interfaces.nilearn import Merge @@ -515,10 +508,6 @@ def init_bold_preproc_trans_wf(mem_gb, omp_nthreads, merge = pe.Node(Merge(compress=use_compression), name='merge', mem_gb=mem_gb * 3) - # Generate a new BOLD reference - bold_reference_wf = init_bold_reference_wf(omp_nthreads=omp_nthreads) - bold_reference_wf.__desc__ = None # Unset description to avoid second appearance - workflow.connect([ (inputnode, merge_xforms, [('fieldwarp', 'in1'), ('hmc_xforms', 'in2')]), @@ -527,12 +516,7 @@ def init_bold_preproc_trans_wf(mem_gb, omp_nthreads, (inputnode, merge, [('name_source', 'header_source')]), (merge_xforms, bold_transform, [('out', 'transforms')]), (bold_transform, merge, [('out_files', 'in_files')]), - (merge, bold_reference_wf, [('out_file', 'inputnode.bold_file')]), (merge, outputnode, [('out_file', 'bold')]), - (bold_reference_wf, outputnode, [ - ('outputnode.ref_image', 'bold_ref'), - ('outputnode.ref_image_brain', 'bold_ref_brain'), - ('outputnode.bold_mask', 'bold_mask')]), ]) return workflow From 80aa3b61beb134f3962a0489282f69ad4bf7ca39 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Mon, 17 Aug 2020 13:39:59 -0400 Subject: [PATCH 08/15] Fix the bugs. --- fmriprep/workflows/bold/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 39be2caef..5be397b6a 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -17,7 +17,7 @@ from nipype.pipeline import engine as pe from nipype.interfaces import utility as niu -from niworkflows.utils.connections import listify +from niworkflows.utils.connections import listify, pop_file from ...utils.meepi import combine_meepi_source @@ -513,7 +513,7 @@ def init_func_preproc_wf(bold_file): (inputnode, func_derivatives_wf, [ ('bold_file', 'inputnode.source_file')]), (bold_bold_trans_wf, bold_confounds_wf, [ - ('outputnode.bold', 'inputnode.bold')], + ('outputnode.bold', 'inputnode.bold')]), (bold_bold_trans_wf, final_boldref_wf, [ ('outputnode.bold', 'inputnode.bold')]), (bold_split, bold_t1_trans_wf, [ From 0f8936ad04c8c925df399c93da3ca8cf6ab3d41b Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Mon, 17 Aug 2020 14:14:44 -0400 Subject: [PATCH 09/15] Fix links. --- fmriprep/workflows/bold/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 5be397b6a..966bcbac7 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -515,7 +515,7 @@ def init_func_preproc_wf(bold_file): (bold_bold_trans_wf, bold_confounds_wf, [ ('outputnode.bold', 'inputnode.bold')]), (bold_bold_trans_wf, final_boldref_wf, [ - ('outputnode.bold', 'inputnode.bold')]), + ('outputnode.bold', 'inputnode.bold_file')]), (bold_split, bold_t1_trans_wf, [ ('out_files', 'inputnode.bold_split')]), (bold_hmc_wf, bold_t1_trans_wf, [ @@ -531,7 +531,7 @@ def init_func_preproc_wf(bold_file): (bold_bold_trans_wf, join_echos, [ ('outputnode.bold', 'bold_files')]), (join_echos, final_boldref_wf, [ - ('bold_files', 'inputnode.bold')]), + ('bold_files', 'inputnode.bold_file')]), (bold_bold_trans_wf, skullstrip_bold_wf, [ ('outputnode.bold', 'inputnode.in_file')]), (skullstrip_bold_wf, join_echos, [ From 9e5a68903be84852385ec01dfbbf939e9e571968 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Mon, 17 Aug 2020 15:44:09 -0400 Subject: [PATCH 10/15] Fix reference image link. --- fmriprep/workflows/bold/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 966bcbac7..d5cd8b068 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -632,7 +632,7 @@ def init_func_preproc_wf(bold_file): if nonstd_spaces.intersection(('func', 'run', 'bold', 'boldref', 'sbref')): workflow.connect([ (final_boldref_wf, func_derivatives_wf, [ - ('outputnode.bold_ref', 'inputnode.bold_native_ref'), + ('outputnode.ref_image', 'inputnode.bold_native_ref'), ('outputnode.bold_mask', 'inputnode.bold_mask_native')]), (bold_bold_trans_wf if not multiecho else bold_t2s_wf, outputnode, [ ('outputnode.bold', 'bold_native')]) From 71226b99d332ca92803b563823d99e3cc87098b9 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Mon, 17 Aug 2020 21:25:23 -0400 Subject: [PATCH 11/15] Update fmriprep/workflows/bold/base.py Co-authored-by: Chris Markiewicz --- fmriprep/workflows/bold/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index d5cd8b068..74ff3db14 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -416,7 +416,7 @@ def init_func_preproc_wf(bold_file): join_echos = pe.JoinNode( niu.IdentityInterface(fields=['bold_files', 'skullstripped_bold_files']), joinsource=('meepi_echos' if run_stc is True else 'boldbuffer'), - joinfield=['bold_files'], + joinfield=['bold_files', 'skullstripped_bold_files'], name='join_echos' ) From 9d530eaae8d2999d16f49247da681a41b1942d25 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Mon, 17 Aug 2020 21:53:59 -0400 Subject: [PATCH 12/15] Update fmriprep/workflows/bold/base.py Co-authored-by: Chris Markiewicz --- fmriprep/workflows/bold/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 74ff3db14..33445bf3a 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -370,7 +370,8 @@ def init_func_preproc_wf(bold_file): # This BOLD references *does not use* single-band reference images. final_boldref_wf = init_bold_reference_wf( name='final_boldref_wf', - omp_nthreads=omp_nthreads + omp_nthreads=omp_nthreads, + multiecho=multiecho, ) final_boldref_wf.__desc__ = None # Unset description to avoid second appearance From 3703963dd347493a6691694e8f4f4099b84abb66 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 18 Aug 2020 09:22:51 -0400 Subject: [PATCH 13/15] Apply suggestions from code review Thanks @effigies. Co-authored-by: Chris Markiewicz --- fmriprep/workflows/bold/base.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 33445bf3a..1b90ad530 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -17,7 +17,7 @@ from nipype.pipeline import engine as pe from nipype.interfaces import utility as niu -from niworkflows.utils.connections import listify, pop_file +from niworkflows.utils.connections import pop_file, listify from ...utils.meepi import combine_meepi_source @@ -491,6 +491,8 @@ def init_func_preproc_wf(bold_file): ('outputnode.itk_t1_to_bold', 'inputnode.t1_bold_xform')]), (initial_boldref_wf, bold_confounds_wf, [ ('outputnode.skip_vols', 'inputnode.skip_vols')]), + (final_boldref_wf, bold_confounds_wf, [ + ('outputnode.bold_mask', 'inputnode.bold_mask')]), (bold_confounds_wf, outputnode, [ ('outputnode.confounds_file', 'confounds'), ]), @@ -502,8 +504,6 @@ def init_func_preproc_wf(bold_file): ('out_files', 'inputnode.bold_file')]), (bold_hmc_wf, bold_bold_trans_wf, [ ('outputnode.xforms', 'inputnode.hmc_xforms')]), - (final_boldref_wf, bold_confounds_wf, [ - ('outputnode.bold_mask', 'inputnode.bold_mask')]), # Summary (outputnode, summary, [('confounds', 'confounds_file')]), ]) @@ -624,10 +624,10 @@ def init_func_preproc_wf(bold_file): ('outputnode.itk_bold_to_t1', 'transforms')]), (bold_t1_trans_wf, boldmask_to_t1w, [ ('outputnode.bold_mask_t1', 'reference_image')]), - (boldmask_to_t1w, outputnode, [ - ('output_image', 'bold_mask_t1')]), (final_boldref_wf, boldmask_to_t1w, [ ('outputnode.bold_mask', 'input_image')]) + (boldmask_to_t1w, outputnode, [ + ('output_image', 'bold_mask_t1')]), ]) if nonstd_spaces.intersection(('func', 'run', 'bold', 'boldref', 'sbref')): @@ -832,10 +832,10 @@ def init_func_preproc_wf(bold_file): ('std2anat_xfm', 'inputnode.std2anat_xfm')]), (bold_bold_trans_wf if not multiecho else bold_t2s_wf, carpetplot_wf, [ ('outputnode.bold', 'inputnode.bold')]), - (bold_reg_wf, carpetplot_wf, [ - ('outputnode.itk_t1_to_bold', 'inputnode.t1_bold_xform')]), (final_boldref_wf, carpetplot_wf, [ ('outputnode.bold_mask', 'inputnode.bold_mask')]), + (bold_reg_wf, carpetplot_wf, [ + ('outputnode.itk_t1_to_bold', 'inputnode.t1_bold_xform')]), ]) workflow.connect([ From 3e9d2cb4796b70055877152aafa8b9d17a9e9cb9 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 18 Aug 2020 09:34:53 -0400 Subject: [PATCH 14/15] Update fmriprep/workflows/bold/base.py --- fmriprep/workflows/bold/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 1b90ad530..b34116a31 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -625,7 +625,7 @@ def init_func_preproc_wf(bold_file): (bold_t1_trans_wf, boldmask_to_t1w, [ ('outputnode.bold_mask_t1', 'reference_image')]), (final_boldref_wf, boldmask_to_t1w, [ - ('outputnode.bold_mask', 'input_image')]) + ('outputnode.bold_mask', 'input_image')]), (boldmask_to_t1w, outputnode, [ ('output_image', 'bold_mask_t1')]), ]) From 7415cbbb5911a2b2ebf0565b7f2b6ab21b1cc9e6 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 18 Aug 2020 09:39:45 -0400 Subject: [PATCH 15/15] Cleanup to minimize diff. --- fmriprep/workflows/bold/base.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index b34116a31..a8494ff74 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -544,7 +544,7 @@ def init_func_preproc_wf(bold_file): (bold_t2s_wf, split_opt_comb, [ ('outputnode.bold', 'in_file')]), (split_opt_comb, bold_t1_trans_wf, [ - ('out_files', 'inputnode.bold_split')]) + ('out_files', 'inputnode.bold_split')]), ]) # Already applied in bold_bold_trans_wf, which inputs to bold_t2s_wf @@ -666,6 +666,17 @@ def init_func_preproc_wf(bold_file): ('outputnode.bold_mask_std', 'bold_mask_std')]), ]) + if freesurfer: + workflow.connect([ + (bold_std_trans_wf, func_derivatives_wf, [ + ('outputnode.bold_aseg_std', 'inputnode.bold_aseg_std'), + ('outputnode.bold_aparc_std', 'inputnode.bold_aparc_std'), + ]), + (bold_std_trans_wf, outputnode, [ + ('outputnode.bold_aseg_std', 'bold_aseg_std'), + ('outputnode.bold_aparc_std', 'bold_aparc_std')]), + ]) + if not multiecho: workflow.connect([ (bold_split, bold_std_trans_wf, [ @@ -678,24 +689,13 @@ def init_func_preproc_wf(bold_file): else: workflow.connect([ (split_opt_comb, bold_std_trans_wf, [ - ('out_files', 'inputnode.bold_split')]), + ('out_files', 'inputnode.bold_split')]) ]) # Already applied in bold_bold_trans_wf, which inputs to bold_t2s_wf bold_std_trans_wf.inputs.inputnode.fieldwarp = 'identity' bold_std_trans_wf.inputs.inputnode.hmc_xforms = 'identity' - if freesurfer: - workflow.connect([ - (bold_std_trans_wf, func_derivatives_wf, [ - ('outputnode.bold_aseg_std', 'inputnode.bold_aseg_std'), - ('outputnode.bold_aparc_std', 'inputnode.bold_aparc_std'), - ]), - (bold_std_trans_wf, outputnode, [ - ('outputnode.bold_aseg_std', 'bold_aseg_std'), - ('outputnode.bold_aparc_std', 'bold_aparc_std')]), - ]) - # func_derivatives_wf internally parametrizes over snapshotted spaces. workflow.connect([ (bold_std_trans_wf, func_derivatives_wf, [