def init_func_derivatives_wf( bids_root, cifti_output, freesurfer, metadata, output_dir, output_spaces, standard_spaces, use_aroma, name='func_derivatives_wf', ): """ Set up a battery of datasinks to store derivatives in the right location **Parameters** bids_root : str cifti_output : bool freesurfer : bool metadata : dict output_dir : str output_spaces : OrderedDict use_aroma : bool name : str """ from smriprep.workflows.outputs import _bids_relative workflow = Workflow(name=name) inputnode = pe.Node( niu.IdentityInterface(fields=[ 'bold_mag_files_source', 'bold_mag_files_preproc', 'bold_mag_files_metadata', 'bold_phase_files_source', 'bold_phase_files_preproc', 'bold_phase_files_metadata', 'sbref_mag_files_source', 'sbref_mag_files_preproc', 'sbref_mag_files_metadata', 'sbref_phase_files_source', 'sbref_phase_files_preproc', 'sbref_phase_files_metadata', 'motion_parameters_file', ]), name='inputnode', ) raw_sources = pe.Node(niu.Function(function=_bids_relative), name='raw_sources') raw_sources.inputs.bids_root = bids_root ds_preproc_bold = pe.MapNode( DerivativesDataSink(base_directory=output_dir, desc='preproc', suffix='bold'), name='ds_preproc_bold', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, iterfield=['source_file', 'in_file', 'meta_dict'], ) workflow.connect([ ( inputnode, raw_sources, [(('bold_mag_files_source', pick_first), 'in_files')], ), ( inputnode, ds_preproc_bold, [ ('bold_mag_files_source', 'source_file'), ('bold_mag_files_preproc', 'in_file'), ('bold_mag_files_metadata', 'meta_dict'), ], ), ]) if set(['func', 'run', 'bold', 'boldref', 'sbref']).intersection(output_spaces): ds_bold_native = pe.Node( DerivativesDataSink( base_directory=output_dir, desc='preproc', keep_dtype=True, compress=True, SkullStripped=False, RepetitionTime=metadata.get('RepetitionTime'), TaskName=metadata.get('TaskName'), ), name='ds_bold_native', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) ds_bold_native_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, suffix='boldref', compress=True), name='ds_bold_native_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) ds_bold_mask_native = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='brain', suffix='mask', compress=True), name='ds_bold_mask_native', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) workflow.connect([ ( inputnode, ds_bold_native, [('source_file', 'source_file'), ('bold_native', 'in_file')], ), ( inputnode, ds_bold_native_ref, [('source_file', 'source_file'), ('bold_native_ref', 'in_file')], ), ( inputnode, ds_bold_mask_native, [('source_file', 'source_file'), ('bold_mask_native', 'in_file')], ), (raw_sources, ds_bold_mask_native, [('out', 'RawSources')]), ]) # Resample to T1w space if 'T1w' in output_spaces or 'anat' in output_spaces: ds_bold_t1 = pe.Node( DerivativesDataSink( base_directory=output_dir, space='T1w', desc='preproc', keep_dtype=True, compress=True, SkullStripped=False, RepetitionTime=metadata.get('RepetitionTime'), TaskName=metadata.get('TaskName'), ), name='ds_bold_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) ds_bold_t1_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', suffix='boldref', compress=True), name='ds_bold_t1_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) ds_bold_mask_t1 = pe.Node( DerivativesDataSink( base_directory=output_dir, space='T1w', desc='brain', suffix='mask', compress=True, ), name='ds_bold_mask_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) workflow.connect([ ( inputnode, ds_bold_t1, [('source_file', 'source_file'), ('bold_t1', 'in_file')], ), ( inputnode, ds_bold_t1_ref, [('source_file', 'source_file'), ('bold_t1_ref', 'in_file')], ), ( inputnode, ds_bold_mask_t1, [('source_file', 'source_file'), ('bold_mask_t1', 'in_file')], ), (raw_sources, ds_bold_mask_t1, [('out', 'RawSources')]), ]) if freesurfer: ds_bold_aseg_t1 = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', desc='aseg', suffix='dseg'), name='ds_bold_aseg_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) ds_bold_aparc_t1 = pe.Node( DerivativesDataSink( base_directory=output_dir, space='T1w', desc='aparcaseg', suffix='dseg', ), name='ds_bold_aparc_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) workflow.connect([ ( inputnode, ds_bold_aseg_t1, [('source_file', 'source_file'), ('bold_aseg_t1', 'in_file')], ), ( inputnode, ds_bold_aparc_t1, [('source_file', 'source_file'), ('bold_aparc_t1', 'in_file')], ), ]) # Resample to template (default: MNI) if standard_spaces: ds_bold_std = pe.Node( DerivativesDataSink( base_directory=output_dir, desc='preproc', keep_dtype=True, compress=True, SkullStripped=False, RepetitionTime=metadata.get('RepetitionTime'), TaskName=metadata.get('TaskName'), ), name='ds_bold_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) ds_bold_std_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, suffix='boldref'), name='ds_bold_std_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) ds_bold_mask_std = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='brain', suffix='mask'), name='ds_bold_mask_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) workflow.connect([ ( inputnode, ds_bold_std, [ ('source_file', 'source_file'), ('bold_std', 'in_file'), ('template', 'space'), ], ), ( inputnode, ds_bold_std_ref, [ ('source_file', 'source_file'), ('bold_std_ref', 'in_file'), ('template', 'space'), ], ), ( inputnode, ds_bold_mask_std, [ ('source_file', 'source_file'), ('bold_mask_std', 'in_file'), ('template', 'space'), ], ), (raw_sources, ds_bold_mask_std, [('out', 'RawSources')]), ]) if freesurfer: ds_bold_aseg_std = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='aseg', suffix='dseg'), name='ds_bold_aseg_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) ds_bold_aparc_std = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='aparcaseg', suffix='dseg'), name='ds_bold_aparc_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) workflow.connect([ ( inputnode, ds_bold_aseg_std, [ ('source_file', 'source_file'), ('bold_aseg_std', 'in_file'), ('template', 'space'), ], ), ( inputnode, ds_bold_aparc_std, [ ('source_file', 'source_file'), ('bold_aparc_std', 'in_file'), ('template', 'space'), ], ), ]) # fsaverage space if freesurfer and any( space.startswith('fs') for space in output_spaces.keys()): name_surfs = pe.MapNode( GiftiNameSource( pattern=r'(?P<LR>[lr])h.(?P<space>\w+).gii', template='space-{space}_hemi-{LR}.func', ), iterfield='in_file', name='name_surfs', mem_gb=DEFAULT_MEMORY_MIN_GB, run_without_submitting=True, ) ds_bold_surfs = pe.MapNode( DerivativesDataSink(base_directory=output_dir), iterfield=['in_file', 'suffix'], name='ds_bold_surfs', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) workflow.connect([ (inputnode, name_surfs, [('surfaces', 'in_file')]), ( inputnode, ds_bold_surfs, [('source_file', 'source_file'), ('surfaces', 'in_file')], ), (name_surfs, ds_bold_surfs, [('out_name', 'suffix')]), ]) # CIFTI output if cifti_output and 'MNI152NLin2009cAsym' in output_spaces: name_cifti = pe.MapNode( CiftiNameSource(), iterfield=['variant'], name='name_cifti', mem_gb=DEFAULT_MEMORY_MIN_GB, run_without_submitting=True, ) cifti_bolds = pe.MapNode( DerivativesDataSink(base_directory=output_dir, compress=False), iterfield=['in_file', 'suffix'], name='cifti_bolds', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) cifti_key = pe.MapNode( DerivativesDataSink(base_directory=output_dir), iterfield=['in_file', 'suffix'], name='cifti_key', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB, ) workflow.connect([ (inputnode, name_cifti, [('cifti_variant', 'variant')]), ( inputnode, cifti_bolds, [('bold_cifti', 'in_file'), ('source_file', 'source_file')], ), (name_cifti, cifti_bolds, [('out_name', 'suffix')]), (name_cifti, cifti_key, [('out_name', 'suffix')]), ( inputnode, cifti_key, [ ('source_file', 'source_file'), ('cifti_variant_key', 'in_file'), ], ), ]) return workflow
def init_anat_derivatives_wf(bids_root, freesurfer, num_t1w, output_dir, name='anat_derivatives_wf'): """Set up a battery of datasinks to store derivatives in the right location.""" workflow = Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'template', 'source_files', 't1w_ref_xfms', 't1w_preproc', 't1w_mask', 't1w_dseg', 't1w_tpms', 'anat2std_xfm', 'std2anat_xfm', 'std_t1w', 'std_mask', 'std_dseg', 'std_tpms', 't1w2fsnative_xfm', 'fsnative2t1w_xfm', 'surfaces', 't1w_fs_aseg', 't1w_fs_aparc' ]), name='inputnode') t1w_name = pe.Node(niu.Function(function=fix_multi_T1w_source_name), name='t1w_name') raw_sources = pe.Node(niu.Function(function=_bids_relative), name='raw_sources') raw_sources.inputs.bids_root = bids_root ds_t1w_preproc = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='preproc', keep_dtype=True, compress=True), name='ds_t1w_preproc', run_without_submitting=True) ds_t1w_preproc.inputs.SkullStripped = False ds_t1w_mask = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='brain', suffix='mask', compress=True), name='ds_t1w_mask', run_without_submitting=True) ds_t1w_mask.inputs.Type = 'Brain' lut_t1w_dseg = pe.Node(niu.Function(function=_apply_default_bids_lut), name='lut_t1w_dseg') ds_t1w_dseg = pe.Node(DerivativesDataSink(base_directory=output_dir, suffix='dseg', compress=True), name='ds_t1w_dseg', run_without_submitting=True) ds_t1w_tpms = pe.Node(DerivativesDataSink(base_directory=output_dir, suffix='probseg', compress=True), name='ds_t1w_tpms', run_without_submitting=True) ds_t1w_tpms.inputs.extra_values = ['label-CSF', 'label-GM', 'label-WM'] ds_t1w_tpl = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='preproc', keep_dtype=True, compress=True), name='ds_t1w_tpl', run_without_submitting=True) ds_t1w_tpl.inputs.SkullStripped = True ds_std_mask = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='brain', suffix='mask', compress=True), name='ds_std_mask', run_without_submitting=True) ds_std_mask.inputs.Type = 'Brain' lut_std_dseg = pe.Node(niu.Function(function=_apply_default_bids_lut), name='lut_std_dseg') ds_std_dseg = pe.Node(DerivativesDataSink(base_directory=output_dir, suffix='dseg', compress=True), name='ds_std_dseg', run_without_submitting=True) ds_std_tpms = pe.Node(DerivativesDataSink(base_directory=output_dir, suffix='probseg', compress=True), name='ds_std_tpms', run_without_submitting=True) ds_std_tpms.inputs.extra_values = ['label-CSF', 'label-GM', 'label-WM'] # Transforms ds_t1w_tpl_inv_warp = pe.Node(DerivativesDataSink( base_directory=output_dir, allowed_entities=['from', 'to', 'mode'], to='T1w', mode='image', suffix='xfm'), name='ds_t1w_tpl_inv_warp', run_without_submitting=True) ds_t1w_tpl_warp = pe.Node(DerivativesDataSink( base_directory=output_dir, allowed_entities=['from', 'to', 'mode'], mode='image', suffix='xfm', **{'from': 'T1w'}), name='ds_t1w_tpl_warp', run_without_submitting=True) workflow.connect([ (inputnode, t1w_name, [('source_files', 'in_files')]), (inputnode, raw_sources, [('source_files', 'in_files')]), (inputnode, ds_t1w_preproc, [('t1w_preproc', 'in_file')]), (inputnode, ds_t1w_mask, [('t1w_mask', 'in_file')]), (inputnode, lut_t1w_dseg, [('t1w_dseg', 'in_file')]), (inputnode, ds_t1w_tpms, [('t1w_tpms', 'in_file')]), (lut_t1w_dseg, ds_t1w_dseg, [('out', 'in_file')]), (t1w_name, ds_t1w_preproc, [('out', 'source_file')]), (t1w_name, ds_t1w_mask, [('out', 'source_file')]), (t1w_name, ds_t1w_dseg, [('out', 'source_file')]), (t1w_name, ds_t1w_tpms, [('out', 'source_file')]), (raw_sources, ds_t1w_mask, [('out', 'RawSources')]), # Template (inputnode, ds_t1w_tpl_warp, [('anat2std_xfm', 'in_file'), ('template', 'to')]), (inputnode, ds_t1w_tpl_inv_warp, [('std2anat_xfm', 'in_file'), ('template', 'from')]), (inputnode, ds_t1w_tpl, [('std_t1w', 'in_file'), ('template', 'space')]), (inputnode, ds_std_mask, [('std_mask', 'in_file'), ('template', 'space'), (('template', _rawsources), 'RawSources')]), (inputnode, ds_std_dseg, [('template', 'space')]), (inputnode, lut_std_dseg, [('std_dseg', 'in_file')]), (lut_std_dseg, ds_std_dseg, [('out', 'in_file')]), (inputnode, ds_std_tpms, [('std_tpms', 'in_file'), ('template', 'space')]), (t1w_name, ds_t1w_tpl_warp, [('out', 'source_file')]), (t1w_name, ds_t1w_tpl_inv_warp, [('out', 'source_file')]), (t1w_name, ds_t1w_tpl, [('out', 'source_file')]), (t1w_name, ds_std_mask, [('out', 'source_file')]), (t1w_name, ds_std_dseg, [('out', 'source_file')]), (t1w_name, ds_std_tpms, [('out', 'source_file')]), ]) if num_t1w > 1: # Please note the dictionary unpacking to provide the from argument. # It is necessary because from is a protected keyword (not allowed as argument name). ds_t1w_ref_xfms = pe.MapNode(DerivativesDataSink( base_directory=output_dir, allowed_entities=['from', 'to', 'mode'], to='T1w', mode='image', suffix='xfm', **{'from': 'orig'}), iterfield=['source_file', 'in_file'], name='ds_t1w_ref_xfms', run_without_submitting=True) workflow.connect([ (inputnode, ds_t1w_ref_xfms, [('source_files', 'source_file'), ('t1w_ref_xfms', 'in_file')]), ]) if not freesurfer: return workflow # FS native space transforms lta2itk_fwd = pe.Node(LTAConvert(out_itk=True), name='lta2itk_fwd') lta2itk_inv = pe.Node(LTAConvert(out_itk=True), name='lta2itk_inv') ds_t1w_fsnative = pe.Node(DerivativesDataSink( base_directory=output_dir, allowed_entities=['from', 'to', 'mode'], mode='image', to='fsnative', suffix='xfm', **{'from': 'T1w'}), name='ds_t1w_fsnative', run_without_submitting=True) ds_fsnative_t1w = pe.Node(DerivativesDataSink( base_directory=output_dir, allowed_entities=['from', 'to', 'mode'], mode='image', to='T1w', suffix='xfm', **{'from': 'fsnative'}), name='ds_fsnative_t1w', run_without_submitting=True) # Surfaces name_surfs = pe.MapNode(GiftiNameSource( pattern=r'(?P<LR>[lr])h.(?P<surf>.+)_converted.gii', template='hemi-{LR}_{surf}.surf'), iterfield='in_file', name='name_surfs', run_without_submitting=True) ds_surfs = pe.MapNode(DerivativesDataSink(base_directory=output_dir), iterfield=['in_file', 'suffix'], name='ds_surfs', run_without_submitting=True) # Parcellations ds_t1w_fsaseg = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='aseg', suffix='dseg', compress=True), name='ds_t1w_fsaseg', run_without_submitting=True) ds_t1w_fsparc = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='aparcaseg', suffix='dseg', compress=True), name='ds_t1w_fsparc', run_without_submitting=True) workflow.connect([ (inputnode, lta2itk_fwd, [('t1w2fsnative_xfm', 'in_lta')]), (inputnode, lta2itk_inv, [('fsnative2t1w_xfm', 'in_lta')]), (t1w_name, ds_t1w_fsnative, [('out', 'source_file')]), (lta2itk_fwd, ds_t1w_fsnative, [('out_itk', 'in_file')]), (t1w_name, ds_fsnative_t1w, [('out', 'source_file')]), (lta2itk_inv, ds_fsnative_t1w, [('out_itk', 'in_file')]), (inputnode, name_surfs, [('surfaces', 'in_file')]), (inputnode, ds_surfs, [('surfaces', 'in_file')]), (t1w_name, ds_surfs, [('out', 'source_file')]), (name_surfs, ds_surfs, [('out_name', 'suffix')]), (inputnode, ds_t1w_fsaseg, [('t1w_fs_aseg', 'in_file')]), (inputnode, ds_t1w_fsparc, [('t1w_fs_aparc', 'in_file')]), (t1w_name, ds_t1w_fsaseg, [('out', 'source_file')]), (t1w_name, ds_t1w_fsparc, [('out', 'source_file')]), ]) return workflow
def init_func_derivatives_wf(output_dir, output_spaces, template, freesurfer, use_aroma, cifti_output, name='func_derivatives_wf'): """ Set up a battery of datasinks to store derivatives in the right location """ workflow = Workflow(name=name) inputnode = pe.Node( niu.IdentityInterface( fields=['source_file', 'bold_t1', 'bold_t1_ref', 'bold_mask_t1', 'bold_mni', 'bold_mni_ref', 'bold_mask_mni', 'bold_aseg_t1', 'bold_aparc_t1', 'bold_aseg_mni', 'bold_aparc_mni', 'cifti_variant_key', 'confounds', 'surfaces', 'aroma_noise_ics', 'melodic_mix', 'nonaggr_denoised_file', 'bold_cifti', 'cifti_variant']), name='inputnode') ds_confounds = pe.Node(DerivativesDataSink( base_directory=output_dir, desc='confounds', suffix='regressors'), name="ds_confounds", run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_confounds, [('source_file', 'source_file'), ('confounds', 'in_file')]), ]) # Resample to T1w space if 'T1w' in output_spaces: ds_bold_t1 = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', desc='preproc', keep_dtype=True, compress=True), name='ds_bold_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_t1_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', suffix='boldref'), name='ds_bold_t1_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_mask_t1 = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', desc='brain', suffix='mask'), name='ds_bold_mask_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_t1, [('source_file', 'source_file'), ('bold_t1', 'in_file')]), (inputnode, ds_bold_t1_ref, [('source_file', 'source_file'), ('bold_t1_ref', 'in_file')]), (inputnode, ds_bold_mask_t1, [('source_file', 'source_file'), ('bold_mask_t1', 'in_file')]), ]) if freesurfer: ds_bold_aseg_t1 = pe.Node(DerivativesDataSink( base_directory=output_dir, space='T1w', desc='aseg', suffix='dseg'), name='ds_bold_aseg_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_aparc_t1 = pe.Node(DerivativesDataSink( base_directory=output_dir, space='T1w', desc='aparcaseg', suffix='dseg'), name='ds_bold_aparc_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_aseg_t1, [('source_file', 'source_file'), ('bold_aseg_t1', 'in_file')]), (inputnode, ds_bold_aparc_t1, [('source_file', 'source_file'), ('bold_aparc_t1', 'in_file')]), ]) # Resample to template (default: MNI) if 'template' in output_spaces: ds_bold_mni = pe.Node( DerivativesDataSink(base_directory=output_dir, space=template, desc='preproc', keep_dtype=True, compress=True), name='ds_bold_mni', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_mni_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, space=template, suffix='boldref'), name='ds_bold_mni_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_mask_mni = pe.Node( DerivativesDataSink(base_directory=output_dir, space=template, desc='brain', suffix='mask'), name='ds_bold_mask_mni', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_mni, [('source_file', 'source_file'), ('bold_mni', 'in_file')]), (inputnode, ds_bold_mni_ref, [('source_file', 'source_file'), ('bold_mni_ref', 'in_file')]), (inputnode, ds_bold_mask_mni, [('source_file', 'source_file'), ('bold_mask_mni', 'in_file')]), ]) if freesurfer: ds_bold_aseg_mni = pe.Node(DerivativesDataSink( base_directory=output_dir, space=template, desc='aseg', suffix='dseg'), name='ds_bold_aseg_mni', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_aparc_mni = pe.Node(DerivativesDataSink( base_directory=output_dir, space=template, desc='aparcaseg', suffix='dseg'), name='ds_bold_aparc_mni', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_aseg_mni, [('source_file', 'source_file'), ('bold_aseg_mni', 'in_file')]), (inputnode, ds_bold_aparc_mni, [('source_file', 'source_file'), ('bold_aparc_mni', 'in_file')]), ]) # fsaverage space if freesurfer and any(space.startswith('fs') for space in output_spaces): name_surfs = pe.MapNode(GiftiNameSource( pattern=r'(?P<LR>[lr])h.(?P<space>\w+).gii', template='space-{space}_hemi-{LR}.func'), iterfield='in_file', name='name_surfs', mem_gb=DEFAULT_MEMORY_MIN_GB, run_without_submitting=True) ds_bold_surfs = pe.MapNode(DerivativesDataSink(base_directory=output_dir), iterfield=['in_file', 'suffix'], name='ds_bold_surfs', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, name_surfs, [('surfaces', 'in_file')]), (inputnode, ds_bold_surfs, [('source_file', 'source_file'), ('surfaces', 'in_file')]), (name_surfs, ds_bold_surfs, [('out_name', 'suffix')]), ]) # CIFTI output if cifti_output and 'template' in output_spaces: name_cifti = pe.MapNode( CiftiNameSource(), iterfield=['variant'], name='name_cifti', mem_gb=DEFAULT_MEMORY_MIN_GB, run_without_submitting=True) cifti_bolds = pe.MapNode( DerivativesDataSink(base_directory=output_dir, compress=False), iterfield=['in_file', 'suffix'], name='cifti_bolds', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) cifti_key = pe.MapNode(DerivativesDataSink( base_directory=output_dir), iterfield=['in_file', 'suffix'], name='cifti_key', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, name_cifti, [('cifti_variant', 'variant')]), (inputnode, cifti_bolds, [('bold_cifti', 'in_file'), ('source_file', 'source_file')]), (name_cifti, cifti_bolds, [('out_name', 'suffix')]), (name_cifti, cifti_key, [('out_name', 'suffix')]), (inputnode, cifti_key, [('source_file', 'source_file'), ('cifti_variant_key', 'in_file')]), ]) if use_aroma: ds_aroma_noise_ics = pe.Node(DerivativesDataSink( base_directory=output_dir, suffix='AROMAnoiseICs'), name="ds_aroma_noise_ics", run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_melodic_mix = pe.Node(DerivativesDataSink( base_directory=output_dir, desc='MELODIC', suffix='mixing'), name="ds_melodic_mix", run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_aroma_mni = pe.Node( DerivativesDataSink(base_directory=output_dir, space=template, desc='smoothAROMAnonaggr', keep_dtype=True), name='ds_aroma_mni', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_aroma_noise_ics, [('source_file', 'source_file'), ('aroma_noise_ics', 'in_file')]), (inputnode, ds_melodic_mix, [('source_file', 'source_file'), ('melodic_mix', 'in_file')]), (inputnode, ds_aroma_mni, [('source_file', 'source_file'), ('nonaggr_denoised_file', 'in_file')]), ]) return workflow
def init_func_derivatives_wf( bids_root, cifti_output, freesurfer, metadata, output_dir, output_spaces, standard_spaces, use_aroma, name='func_derivatives_wf', ): """ Set up a battery of datasinks to store derivatives in the right location. Parameters ---------- bids_root : str Original BIDS dataset path. cifti_output : bool Whether the ``--cifti-output`` flag was set. freesurfer : bool Whether FreeSurfer anatomical processing was run. metadata : dict Metadata dictionary associated to the BOLD run. output_dir : str Where derivatives should be written out to. output_spaces : OrderedDict List of selected ``--output-spaces``. use_aroma : bool Whether ``--use-aroma`` flag was set. name : str This workflow's identifier (default: ``func_derivatives_wf``). """ from smriprep.workflows.outputs import _bids_relative workflow = Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'aroma_noise_ics', 'bold_aparc_std', 'bold_aparc_t1', 'bold_aseg_std', 'bold_aseg_t1', 'bold_cifti', 'bold_mask_std', 'bold_mask_t1', 'bold_std', 'bold_std_ref', 'bold_t1', 'bold_t1_ref', 'bold_native', 'bold_native_ref', 'bold_mask_native', 'cifti_variant', 'cifti_variant_key', 'confounds', 'confounds_metadata', 'melodic_mix', 'nonaggr_denoised_file', 'source_file', 'surfaces', 'template']), name='inputnode') raw_sources = pe.Node(niu.Function(function=_bids_relative), name='raw_sources') raw_sources.inputs.bids_root = bids_root ds_confounds = pe.Node(DerivativesDataSink( base_directory=output_dir, desc='confounds', suffix='regressors'), name="ds_confounds", run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, raw_sources, [('source_file', 'in_files')]), (inputnode, ds_confounds, [('source_file', 'source_file'), ('confounds', 'in_file'), ('confounds_metadata', 'meta_dict')]), ]) if set(['func', 'run', 'bold', 'boldref', 'sbref']).intersection(output_spaces): ds_bold_native = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='preproc', keep_dtype=True, compress=True, SkullStripped=False, RepetitionTime=metadata.get('RepetitionTime'), TaskName=metadata.get('TaskName')), name='ds_bold_native', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_native_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, suffix='boldref', compress=True), name='ds_bold_native_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_mask_native = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='brain', suffix='mask', compress=True), name='ds_bold_mask_native', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_native, [('source_file', 'source_file'), ('bold_native', 'in_file')]), (inputnode, ds_bold_native_ref, [('source_file', 'source_file'), ('bold_native_ref', 'in_file')]), (inputnode, ds_bold_mask_native, [('source_file', 'source_file'), ('bold_mask_native', 'in_file')]), (raw_sources, ds_bold_mask_native, [('out', 'RawSources')]), ]) # Resample to T1w space if 'T1w' in output_spaces or 'anat' in output_spaces: ds_bold_t1 = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', desc='preproc', keep_dtype=True, compress=True, SkullStripped=False, RepetitionTime=metadata.get('RepetitionTime'), TaskName=metadata.get('TaskName')), name='ds_bold_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_t1_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', suffix='boldref', compress=True), name='ds_bold_t1_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_mask_t1 = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', desc='brain', suffix='mask', compress=True), name='ds_bold_mask_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_t1, [('source_file', 'source_file'), ('bold_t1', 'in_file')]), (inputnode, ds_bold_t1_ref, [('source_file', 'source_file'), ('bold_t1_ref', 'in_file')]), (inputnode, ds_bold_mask_t1, [('source_file', 'source_file'), ('bold_mask_t1', 'in_file')]), (raw_sources, ds_bold_mask_t1, [('out', 'RawSources')]), ]) if freesurfer: ds_bold_aseg_t1 = pe.Node(DerivativesDataSink( base_directory=output_dir, space='T1w', desc='aseg', suffix='dseg'), name='ds_bold_aseg_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_aparc_t1 = pe.Node(DerivativesDataSink( base_directory=output_dir, space='T1w', desc='aparcaseg', suffix='dseg'), name='ds_bold_aparc_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_aseg_t1, [('source_file', 'source_file'), ('bold_aseg_t1', 'in_file')]), (inputnode, ds_bold_aparc_t1, [('source_file', 'source_file'), ('bold_aparc_t1', 'in_file')]), ]) # Resample to template (default: MNI) if standard_spaces: ds_bold_std = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='preproc', keep_dtype=True, compress=True, SkullStripped=False, RepetitionTime=metadata.get('RepetitionTime'), TaskName=metadata.get('TaskName')), name='ds_bold_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_std_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, suffix='boldref'), name='ds_bold_std_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_mask_std = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='brain', suffix='mask'), name='ds_bold_mask_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_std, [('source_file', 'source_file'), ('bold_std', 'in_file'), ('template', 'space')]), (inputnode, ds_bold_std_ref, [('source_file', 'source_file'), ('bold_std_ref', 'in_file'), ('template', 'space')]), (inputnode, ds_bold_mask_std, [('source_file', 'source_file'), ('bold_mask_std', 'in_file'), ('template', 'space')]), (raw_sources, ds_bold_mask_std, [('out', 'RawSources')]), ]) if freesurfer: ds_bold_aseg_std = pe.Node(DerivativesDataSink( base_directory=output_dir, desc='aseg', suffix='dseg'), name='ds_bold_aseg_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_aparc_std = pe.Node(DerivativesDataSink( base_directory=output_dir, desc='aparcaseg', suffix='dseg'), name='ds_bold_aparc_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_aseg_std, [('source_file', 'source_file'), ('bold_aseg_std', 'in_file'), ('template', 'space')]), (inputnode, ds_bold_aparc_std, [('source_file', 'source_file'), ('bold_aparc_std', 'in_file'), ('template', 'space')]), ]) # fsaverage space if freesurfer and any(space.startswith('fs') for space in output_spaces.keys()): name_surfs = pe.MapNode(GiftiNameSource( pattern=r'(?P<LR>[lr])h.(?P<space>\w+).gii', template='space-{space}_hemi-{LR}.func'), iterfield='in_file', name='name_surfs', mem_gb=DEFAULT_MEMORY_MIN_GB, run_without_submitting=True) ds_bold_surfs = pe.MapNode(DerivativesDataSink(base_directory=output_dir), iterfield=['in_file', 'suffix'], name='ds_bold_surfs', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, name_surfs, [('surfaces', 'in_file')]), (inputnode, ds_bold_surfs, [('source_file', 'source_file'), ('surfaces', 'in_file')]), (name_surfs, ds_bold_surfs, [('out_name', 'suffix')]), ]) # CIFTI output if cifti_output and 'MNI152NLin2009cAsym' in output_spaces: name_cifti = pe.MapNode( CiftiNameSource(), iterfield=['variant'], name='name_cifti', mem_gb=DEFAULT_MEMORY_MIN_GB, run_without_submitting=True) cifti_bolds = pe.MapNode( DerivativesDataSink(base_directory=output_dir, compress=False), iterfield=['in_file', 'suffix'], name='cifti_bolds', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) cifti_key = pe.MapNode(DerivativesDataSink( base_directory=output_dir), iterfield=['in_file', 'suffix'], name='cifti_key', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, name_cifti, [('cifti_variant', 'variant')]), (inputnode, cifti_bolds, [('bold_cifti', 'in_file'), ('source_file', 'source_file')]), (name_cifti, cifti_bolds, [('out_name', 'suffix')]), (name_cifti, cifti_key, [('out_name', 'suffix')]), (inputnode, cifti_key, [('source_file', 'source_file'), ('cifti_variant_key', 'in_file')]), ]) if use_aroma: ds_aroma_noise_ics = pe.Node(DerivativesDataSink( base_directory=output_dir, suffix='AROMAnoiseICs'), name="ds_aroma_noise_ics", run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_melodic_mix = pe.Node(DerivativesDataSink( base_directory=output_dir, desc='MELODIC', suffix='mixing'), name="ds_melodic_mix", run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_aroma_std = pe.Node( DerivativesDataSink(base_directory=output_dir, space='MNI152NLin6Asym', desc='smoothAROMAnonaggr', keep_dtype=True), name='ds_aroma_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_aroma_noise_ics, [('source_file', 'source_file'), ('aroma_noise_ics', 'in_file')]), (inputnode, ds_melodic_mix, [('source_file', 'source_file'), ('melodic_mix', 'in_file')]), (inputnode, ds_aroma_std, [('source_file', 'source_file'), ('nonaggr_denoised_file', 'in_file')]), ]) return workflow
def init_func_derivatives_wf( bids_root, cifti_output, freesurfer, metadata, output_dir, spaces, use_aroma, name='func_derivatives_wf', ): """ Set up a battery of datasinks to store derivatives in the right location. Parameters ---------- bids_root : :obj:`str` Original BIDS dataset path. cifti_output : :obj:`bool` Whether the ``--cifti-output`` flag was set. freesurfer : :obj:`bool` Whether FreeSurfer anatomical processing was run. metadata : :obj:`dict` Metadata dictionary associated to the BOLD run. output_dir : :obj:`str` Where derivatives should be written out to. spaces : :py:class:`~niworkflows.utils.spaces.SpatialReferences` A container for storing, organizing, and parsing spatial normalizations. Composed of :py:class:`~niworkflows.utils.spaces.Reference` objects representing spatial references. Each ``Reference`` contains a space, which is a string of either TemplateFlow template IDs (e.g., ``MNI152Lin``, ``MNI152NLin6Asym``, ``MNIPediatricAsym``), nonstandard references (e.g., ``T1w`` or ``anat``, ``sbref``, ``run``, etc.), or a custom template located in the TemplateFlow root directory. Each ``Reference`` may also contain a spec, which is a dictionary with template specifications (e.g., a specification of ``{'resolution': 2}`` would lead to resampling on a 2mm resolution of the space). use_aroma : :obj:`bool` Whether ``--use-aroma`` flag was set. name : :obj:`str` This workflow's identifier (default: ``func_derivatives_wf``). """ from smriprep.workflows.outputs import _bids_relative nonstd_spaces = set(spaces.get_nonstandard()) workflow = Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'aroma_noise_ics', 'bold_aparc_std', 'bold_aparc_t1', 'bold_aseg_std', 'bold_aseg_t1', 'bold_cifti', 'bold_mask_std', 'bold_mask_t1', 'bold_std', 'bold_std_ref', 'bold_t1', 'bold_t1_ref', 'bold_native', 'bold_native_ref', 'bold_mask_native', 'cifti_variant', 'cifti_metadata', 'cifti_density', 'confounds', 'confounds_metadata', 'melodic_mix', 'nonaggr_denoised_file', 'source_file', 'surf_files', 'surf_refs', 'template', 'spatial_reference']), name='inputnode') raw_sources = pe.Node(niu.Function(function=_bids_relative), name='raw_sources') raw_sources.inputs.bids_root = bids_root ds_confounds = pe.Node(DerivativesDataSink( base_directory=output_dir, desc='confounds', suffix='regressors'), name="ds_confounds", run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, raw_sources, [('source_file', 'in_files')]), (inputnode, ds_confounds, [('source_file', 'source_file'), ('confounds', 'in_file'), ('confounds_metadata', 'meta_dict')]), ]) if nonstd_spaces.intersection(('func', 'run', 'bold', 'boldref', 'sbref')): ds_bold_native = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='preproc', keep_dtype=True, compress=True, SkullStripped=False, RepetitionTime=metadata.get('RepetitionTime'), TaskName=metadata.get('TaskName')), name='ds_bold_native', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_native_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, suffix='boldref', compress=True), name='ds_bold_native_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_mask_native = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='brain', suffix='mask', compress=True), name='ds_bold_mask_native', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_native, [('source_file', 'source_file'), ('bold_native', 'in_file')]), (inputnode, ds_bold_native_ref, [('source_file', 'source_file'), ('bold_native_ref', 'in_file')]), (inputnode, ds_bold_mask_native, [('source_file', 'source_file'), ('bold_mask_native', 'in_file')]), (raw_sources, ds_bold_mask_native, [('out', 'RawSources')]), ]) # Resample to T1w space if nonstd_spaces.intersection(('T1w', 'anat')): ds_bold_t1 = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', desc='preproc', keep_dtype=True, compress=True, SkullStripped=False, RepetitionTime=metadata.get('RepetitionTime'), TaskName=metadata.get('TaskName')), name='ds_bold_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_t1_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', suffix='boldref', compress=True), name='ds_bold_t1_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_mask_t1 = pe.Node( DerivativesDataSink(base_directory=output_dir, space='T1w', desc='brain', suffix='mask', compress=True), name='ds_bold_mask_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_t1, [('source_file', 'source_file'), ('bold_t1', 'in_file')]), (inputnode, ds_bold_t1_ref, [('source_file', 'source_file'), ('bold_t1_ref', 'in_file')]), (inputnode, ds_bold_mask_t1, [('source_file', 'source_file'), ('bold_mask_t1', 'in_file')]), (raw_sources, ds_bold_mask_t1, [('out', 'RawSources')]), ]) if freesurfer: ds_bold_aseg_t1 = pe.Node(DerivativesDataSink( base_directory=output_dir, space='T1w', desc='aseg', suffix='dseg'), name='ds_bold_aseg_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_aparc_t1 = pe.Node(DerivativesDataSink( base_directory=output_dir, space='T1w', desc='aparcaseg', suffix='dseg'), name='ds_bold_aparc_t1', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_aseg_t1, [('source_file', 'source_file'), ('bold_aseg_t1', 'in_file')]), (inputnode, ds_bold_aparc_t1, [('source_file', 'source_file'), ('bold_aparc_t1', 'in_file')]), ]) if use_aroma: ds_aroma_noise_ics = pe.Node(DerivativesDataSink( base_directory=output_dir, suffix='AROMAnoiseICs'), name="ds_aroma_noise_ics", run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_melodic_mix = pe.Node(DerivativesDataSink( base_directory=output_dir, desc='MELODIC', suffix='mixing'), name="ds_melodic_mix", run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_aroma_std = pe.Node( DerivativesDataSink(base_directory=output_dir, space='MNI152NLin6Asym', desc='smoothAROMAnonaggr', keep_dtype=True), name='ds_aroma_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_aroma_noise_ics, [('source_file', 'source_file'), ('aroma_noise_ics', 'in_file')]), (inputnode, ds_melodic_mix, [('source_file', 'source_file'), ('melodic_mix', 'in_file')]), (inputnode, ds_aroma_std, [('source_file', 'source_file'), ('nonaggr_denoised_file', 'in_file')]), ]) if getattr(spaces, '_cached') is None: return workflow # Store resamplings in standard spaces when listed in --output-spaces if spaces.cached.references: itersource = pe.Node(niu.IdentityInterface(fields=['space_definition']), name='itersource') itersource.iterables = ( 'space_definition', [(s.fullname, s.spec) for s in spaces.cached.get_standard(dim=(3,))] ) select_std = pe.Node(KeySelect( fields=['template', 'bold_std', 'bold_std_ref', 'bold_mask_std']), name='select_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_std = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='preproc', keep_dtype=True, compress=True, SkullStripped=False, RepetitionTime=metadata.get('RepetitionTime'), TaskName=metadata.get('TaskName')), name='ds_bold_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_std_ref = pe.Node( DerivativesDataSink(base_directory=output_dir, suffix='boldref'), name='ds_bold_std_ref', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_mask_std = pe.Node( DerivativesDataSink(base_directory=output_dir, desc='brain', suffix='mask'), name='ds_bold_mask_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, ds_bold_std, [('source_file', 'source_file')]), (inputnode, ds_bold_std_ref, [('source_file', 'source_file')]), (inputnode, ds_bold_mask_std, [('source_file', 'source_file')]), (inputnode, select_std, [('bold_std', 'bold_std'), ('bold_std_ref', 'bold_std_ref'), ('bold_mask_std', 'bold_mask_std'), ('template', 'template'), ('spatial_reference', 'keys')]), (itersource, select_std, [(('space_definition', _fmt_space), 'key')]), (select_std, ds_bold_std, [('bold_std', 'in_file'), ('key', 'space')]), (select_std, ds_bold_std_ref, [('bold_std_ref', 'in_file'), ('key', 'space')]), (select_std, ds_bold_mask_std, [('bold_mask_std', 'in_file'), ('key', 'space')]), (raw_sources, ds_bold_mask_std, [('out', 'RawSources')]), ]) if freesurfer: select_fs_std = pe.Node(KeySelect( fields=['bold_aseg_std', 'bold_aparc_std', 'template']), name='select_fs_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_aseg_std = pe.Node(DerivativesDataSink( base_directory=output_dir, desc='aseg', suffix='dseg'), name='ds_bold_aseg_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) ds_bold_aparc_std = pe.Node(DerivativesDataSink( base_directory=output_dir, desc='aparcaseg', suffix='dseg'), name='ds_bold_aparc_std', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (itersource, select_fs_std, [ (('space_definition', _fmt_space), 'key')]), (inputnode, select_fs_std, [('bold_aseg_std', 'bold_aseg_std'), ('bold_aparc_std', 'bold_aparc_std'), ('template', 'template'), ('spatial_reference', 'keys')]), (select_fs_std, ds_bold_aseg_std, [('bold_aseg_std', 'in_file'), ('key', 'space')]), (select_fs_std, ds_bold_aparc_std, [('bold_aparc_std', 'in_file'), ('key', 'space')]), (inputnode, ds_bold_aseg_std, [('source_file', 'source_file')]), (inputnode, ds_bold_aparc_std, [('source_file', 'source_file')]) ]) fs_outputs = spaces.cached.get_fs_spaces() if freesurfer and fs_outputs: select_fs_surf = pe.Node(KeySelect( fields=['surfaces', 'surf_kwargs']), name='select_fs_surf', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) select_fs_surf.iterables = [('key', fs_outputs)] select_fs_surf.inputs.surf_kwargs = [{'space': s} for s in fs_outputs] name_surfs = pe.MapNode(GiftiNameSource( pattern=r'(?P<LR>[lr])h.\w+', template='space-{space}_hemi-{LR}.func'), iterfield=['in_file'], name='name_surfs', mem_gb=DEFAULT_MEMORY_MIN_GB, run_without_submitting=True) ds_bold_surfs = pe.MapNode(DerivativesDataSink(base_directory=output_dir), iterfield=['in_file', 'suffix'], name='ds_bold_surfs', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, select_fs_surf, [ ('surf_files', 'surfaces'), ('surf_refs', 'keys')]), (select_fs_surf, name_surfs, [('surfaces', 'in_file'), ('surf_kwargs', 'template_kwargs')]), (inputnode, ds_bold_surfs, [('source_file', 'source_file')]), (select_fs_surf, ds_bold_surfs, [('surfaces', 'in_file')]), (name_surfs, ds_bold_surfs, [('out_name', 'suffix')]), ]) # CIFTI output if cifti_output: name_cifti = pe.MapNode( CiftiNameSource(), iterfield=['variant', 'density'], name='name_cifti', mem_gb=DEFAULT_MEMORY_MIN_GB, run_without_submitting=True) cifti_bolds = pe.MapNode( DerivativesDataSink(base_directory=output_dir, compress=False), iterfield=['in_file', 'suffix'], name='cifti_bolds', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) cifti_key = pe.MapNode(DerivativesDataSink( base_directory=output_dir), iterfield=['in_file', 'suffix'], name='cifti_key', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, name_cifti, [('cifti_variant', 'variant'), ('cifti_density', 'density')]), (inputnode, cifti_bolds, [('bold_cifti', 'in_file'), ('source_file', 'source_file')]), (name_cifti, cifti_bolds, [('out_name', 'suffix')]), (name_cifti, cifti_key, [('out_name', 'suffix')]), (inputnode, cifti_key, [('source_file', 'source_file'), ('cifti_metadata', 'in_file')]), ]) return workflow
def init_anat_derivatives_wf(bids_root, freesurfer, output_dir, template, name='anat_derivatives_wf'): """ Set up a battery of datasinks to store derivatives in the right location """ workflow = Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'source_files', 't1_template_transforms', 't1_preproc', 't1_mask', 't1_seg', 't1_tpms', 't1_2_mni_forward_transform', 't1_2_mni_reverse_transform', 't1_2_mni', 'mni_mask', 'mni_seg', 'mni_tpms', 't1_2_fsnative_forward_transform', 'surfaces', 't1_fs_aseg', 't1_fs_aparc' ]), name='inputnode') t1_name = pe.Node(niu.Function(function=fix_multi_T1w_source_name), name='t1_name') raw_sources = pe.Node(niu.Function(function=_bids_relative), name='raw_sources') raw_sources.inputs.bids_root = bids_root ds_t1_preproc = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='preproc', keep_dtype=True), name='ds_t1_preproc', run_without_submitting=True) ds_t1_preproc.inputs.SkullStripped = False ds_t1_mask = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='brain', suffix='mask'), name='ds_t1_mask', run_without_submitting=True) ds_t1_mask.inputs.Type = 'Brain' lut_t1_seg = pe.Node(niu.Function(function=_apply_default_bids_lut), name='lut_t1_seg') ds_t1_seg = pe.Node(DerivativesDataSink(base_directory=output_dir, suffix='dseg'), name='ds_t1_seg', run_without_submitting=True) ds_t1_tpms = pe.Node(DerivativesDataSink(base_directory=output_dir, suffix='probseg'), name='ds_t1_tpms', run_without_submitting=True) ds_t1_tpms.inputs.extra_values = ['label-CSF', 'label-GM', 'label-WM'] ds_t1_mni = pe.Node(DerivativesDataSink(base_directory=output_dir, space=template, desc='preproc', keep_dtype=True), name='ds_t1_mni', run_without_submitting=True) ds_t1_mni.inputs.SkullStripped = True ds_mni_mask = pe.Node(DerivativesDataSink(base_directory=output_dir, space=template, desc='brain', suffix='mask'), name='ds_mni_mask', run_without_submitting=True) ds_mni_mask.inputs.Type = 'Brain' ds_mni_mask.inputs.RawSources = 'tpl-{0}/tpl-{0}_res-01_desc-brain_mask.nii.gz'.format( template) lut_mni_seg = pe.Node(niu.Function(function=_apply_default_bids_lut), name='lut_mni_seg') ds_mni_seg = pe.Node(DerivativesDataSink(base_directory=output_dir, space=template, suffix='dseg'), name='ds_mni_seg', run_without_submitting=True) ds_mni_tpms = pe.Node(DerivativesDataSink(base_directory=output_dir, space=template, suffix='probseg'), name='ds_mni_tpms', run_without_submitting=True) ds_mni_tpms.inputs.extra_values = ['label-CSF', 'label-GM', 'label-WM'] # Transforms suffix_fmt = 'from-{}_to-{}_mode-image_xfm'.format ds_t1_mni_inv_warp = pe.Node(DerivativesDataSink(base_directory=output_dir, suffix=suffix_fmt( template, 'T1w')), name='ds_t1_mni_inv_warp', run_without_submitting=True) ds_t1_template_transforms = pe.MapNode( DerivativesDataSink(base_directory=output_dir, suffix=suffix_fmt('orig', 'T1w')), iterfield=['source_file', 'in_file'], name='ds_t1_template_transforms', run_without_submitting=True) ds_t1_mni_warp = pe.Node(DerivativesDataSink(base_directory=output_dir, suffix=suffix_fmt( 'T1w', template)), name='ds_t1_mni_warp', run_without_submitting=True) lta_2_itk = pe.Node(LTAConvert(out_itk=True), name='lta_2_itk') ds_t1_fsnative = pe.Node(DerivativesDataSink(base_directory=output_dir, suffix=suffix_fmt( 'T1w', 'fsnative')), name='ds_t1_fsnative', run_without_submitting=True) name_surfs = pe.MapNode(GiftiNameSource( pattern=r'(?P<LR>[lr])h.(?P<surf>.+)_converted.gii', template='hemi-{LR}_{surf}.surf'), iterfield='in_file', name='name_surfs', run_without_submitting=True) ds_surfs = pe.MapNode(DerivativesDataSink(base_directory=output_dir), iterfield=['in_file', 'suffix'], name='ds_surfs', run_without_submitting=True) workflow.connect([ (inputnode, t1_name, [('source_files', 'in_files')]), (inputnode, raw_sources, [('source_files', 'in_files')]), (inputnode, ds_t1_template_transforms, [('source_files', 'source_file'), ('t1_template_transforms', 'in_file')]), (inputnode, ds_t1_preproc, [('t1_preproc', 'in_file')]), (inputnode, ds_t1_mask, [('t1_mask', 'in_file')]), (inputnode, lut_t1_seg, [('t1_seg', 'in_file')]), (inputnode, ds_t1_tpms, [('t1_tpms', 'in_file')]), (lut_t1_seg, ds_t1_seg, [('out', 'in_file')]), (t1_name, ds_t1_preproc, [('out', 'source_file')]), (t1_name, ds_t1_mask, [('out', 'source_file')]), (t1_name, ds_t1_seg, [('out', 'source_file')]), (t1_name, ds_t1_tpms, [('out', 'source_file')]), (raw_sources, ds_t1_mask, [('out', 'RawSources')]), # Template (inputnode, ds_t1_mni_warp, [('t1_2_mni_forward_transform', 'in_file')] ), (inputnode, ds_t1_mni_inv_warp, [('t1_2_mni_reverse_transform', 'in_file')]), (inputnode, ds_t1_mni, [('t1_2_mni', 'in_file')]), (inputnode, ds_mni_mask, [('mni_mask', 'in_file')]), (inputnode, lut_mni_seg, [('mni_seg', 'in_file')]), (lut_mni_seg, ds_mni_seg, [('out', 'in_file')]), (inputnode, ds_mni_tpms, [('mni_tpms', 'in_file')]), (t1_name, ds_t1_mni_warp, [('out', 'source_file')]), (t1_name, ds_t1_mni_inv_warp, [('out', 'source_file')]), (t1_name, ds_t1_mni, [('out', 'source_file')]), (t1_name, ds_mni_mask, [('out', 'source_file')]), (t1_name, ds_mni_seg, [('out', 'source_file')]), (t1_name, ds_mni_tpms, [('out', 'source_file')]), ]) if freesurfer: ds_t1_fsaseg = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='aseg', suffix='dseg'), name='ds_t1_fsaseg', run_without_submitting=True) ds_t1_fsparc = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='aparcaseg', suffix='dseg'), name='ds_t1_fsparc', run_without_submitting=True) ds_t1_fsparc = pe.Node(DerivativesDataSink(base_directory=output_dir, desc='aparcaseg', suffix='dseg'), name='ds_t1_fsparc', run_without_submitting=True) workflow.connect([ (inputnode, lta_2_itk, [('t1_2_fsnative_forward_transform', 'in_lta')]), (t1_name, ds_t1_fsnative, [('out', 'source_file')]), (lta_2_itk, ds_t1_fsnative, [('out_itk', 'in_file')]), (inputnode, name_surfs, [('surfaces', 'in_file')]), (inputnode, ds_surfs, [('surfaces', 'in_file')]), (t1_name, ds_surfs, [('out', 'source_file')]), (name_surfs, ds_surfs, [('out_name', 'suffix')]), (inputnode, ds_t1_fsaseg, [('t1_fs_aseg', 'in_file')]), (inputnode, ds_t1_fsparc, [('t1_fs_aparc', 'in_file')]), (t1_name, ds_t1_fsaseg, [('out', 'source_file')]), (t1_name, ds_t1_fsparc, [('out', 'source_file')]), ]) return workflow