Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
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
Example #6
0
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