예제 #1
0
파일: anat_preproc.py 프로젝트: gkiar/C-PAC
def anatomical_init(wf, cfg, strat_pool, pipe_num, opt=None):
    '''
    {"name": "anatomical_init",
     "config": "None",
     "switch": "None",
     "option_key": "None",
     "option_val": "None",
     "inputs": ["T1w"],
     "outputs": ["desc-preproc_T1w",
                 "desc-reorient_T1w"]}
    '''

    anat_deoblique = pe.Node(interface=afni.Refit(),
                             name=f'anat_deoblique_{pipe_num}')
    anat_deoblique.inputs.deoblique = True

    node, out = strat_pool.get_data('T1w')
    wf.connect(node, out, anat_deoblique, 'in_file')

    anat_reorient = pe.Node(interface=afni.Resample(),
                            name=f'anat_reorient_{pipe_num}')
    anat_reorient.inputs.orientation = 'RPI'
    anat_reorient.inputs.outputtype = 'NIFTI_GZ'

    wf.connect(anat_deoblique, 'out_file', anat_reorient, 'in_file')

    outputs = {
        'desc-preproc_T1w': (anat_reorient, 'out_file'),
        'desc-reorient_T1w': (anat_reorient, 'out_file')
    }

    return (wf, outputs)
예제 #2
0
def create_workflow(config: AttrDict, resource_pool: ResourcePool,
                    context: Context):
    for _, rp in resource_pool[['T1w']]:
        anat_image = rp[R('T1w')]
        anat_deoblique = NipypeJob(interface=afni.Refit(deoblique=True),
                                   reference='anat_deoblique')
        anat_deoblique.in_file = anat_image
        output_node = anat_deoblique.out_file

        if config.non_local_means_filtering:
            denoise = NipypeJob(interface=ants.DenoiseImage(),
                                reference='anat_denoise')
            denoise.input_image = output_node
            output_node = denoise.output_image

        if config.n4_bias_field_correction:
            n4 = NipypeJob(interface=ants.N4BiasFieldCorrection(
                dimension=3, shrink_factor=2, copy_header=True),
                           reference='anat_n4')
            n4.input_image = output_node
            output_node = n4.output_image

        anat_reorient = NipypeJob(interface=afni.Resample(
            orientation='RPI', outputtype='NIFTI_GZ'),
                                  reference='anat_reorient')
        anat_reorient.in_file = output_node
        rp[R('T1w', label='reorient')] = anat_reorient.out_file
예제 #3
0
 def test_mock_nipype(self):
     with mock_nipype():
         from radiome.core.jobs import NipypeJob
         job = NipypeJob(interface=afni.Refit(deoblique=True),
                         reference='deoblique')
         in_file = data_path(__file__, 'mocks/sub-0050682_T1w.nii.gz')
         res = job(in_file=in_file)
         self.assertEqual(str(res['out_file']), in_file)
예제 #4
0
def _reset_affines(in_file, out_file, overwrite=False, axes_to_permute=None,
                   axes_to_flip=None, xyzscale=None, center_mass=None,
                   verbose=1):
    """Sets the qform equal to the sform in the header, with optionally
       rescaling, setting the image center to 0, permuting or/and flipping axes
    """
    if not os.path.isfile(out_file) or overwrite:
        shutil.copy(in_file, out_file)
    else:
        raise ValueError('{} already existed'.format(out_file))

    if verbose:
        terminal_output = 'stream'
    else:
        terminal_output = 'none'

    in_file = out_file
    if xyzscale is not None:
        refit = afni.Refit()
        refit.inputs.in_file = in_file
        refit.inputs.xyzscale = xyzscale
        refit.set_default_terminal_output(terminal_output)
        result = refit.run()
        in_file = result.outputs.out_file

    if center_mass is not None:
        set_center_mass = afni.CenterMass()
        set_center_mass.inputs.in_file = in_file
        set_center_mass.inputs.cm_file = fname_presuffix(out_file,
                                                         suffix='.txt',
                                                         use_ext=False)
        set_center_mass.inputs.set_cm = center_mass
#        set_center_mass.set_default_terminal_output(terminal_output) # XXX BUG
        result = set_center_mass.run()
        in_file = result.outputs.out_file

    img = nibabel.load(in_file)
    header = img.header.copy()
    sform, code = header.get_sform(coded=True)

    if axes_to_flip:
        for axis in axes_to_flip:
            sform[axis] *= -1

    if axes_to_permute:
        for (axis1, axis2) in axes_to_permute:
            sform[[axis1, axis2]] = sform[[axis2, axis1]]

    header.set_sform(sform)
    header.set_qform(sform, int(code))
    nibabel.Nifti1Image(img.get_data(), sform, header).to_filename(out_file)
    def refit(self, in_file, out_file=None, deoblique=False, args=""):

        myfit = afni.Refit(in_file=in_file)
        #https://nipype.readthedocs.io/en/latest/interfaces/generated/interfaces.afni/utils.html#refit

        myfit.inputs.deoblique = deoblique
        myfit.inputs.args = args
        myfit.run()

        #remove temp files
        if type(in_file) == models.BIDSImageFile:
            in_file = os.path.join(self._output_dir, in_file.filename)
        if "_desc-temp" in in_file:
            os.remove(in_file)
예제 #6
0
def lesion_preproc(lesion_mask: str):
    lesion_deoblique = NipypeJob(interface=afni.Refit(deoblique=True),
                                 reference='lesion_deoblique')
    lesion_inverted = PythonJob(function=inverse_lesion,
                                reference='inverse_lesion')
    lesion_reorient = NipypeJob(interface=afni.Resample(orientation='RPI',
                                                        outputtype='NIFTI_GZ'),
                                reference='lesion_reorient')

    lesion_inverted.lesion_path = S3Resource(lesion_mask) if lesion_mask.lower(
    ).startswith('s3://') else lesion_mask
    lesion_deoblique.in_file = lesion_inverted.lesion_out
    lesion_reorient.in_file = lesion_deoblique.out_file
    return lesion_reorient.out_file
예제 #7
0
def _reorient_wf(name='ReorientWorkflow'):
    """A workflow to reorient images to 'RPI' orientation."""
    workflow = Workflow(name=name)
    workflow.__desc__ = "Inner workflow. "
    inputnode = Node(niu.IdentityInterface(fields=['in_file']),
                     name='inputnode')
    outputnode = Node(niu.IdentityInterface(fields=['out_file']),
                      name='outputnode')
    deoblique = Node(afni.Refit(deoblique=True), name='deoblique')
    reorient = Node(afni.Resample(orientation='RPI', outputtype='NIFTI_GZ'),
                    name='reorient')
    workflow.connect([(inputnode, deoblique, [('in_file', 'in_file')]),
                      (deoblique, reorient, [('out_file', 'in_file')]),
                      (reorient, outputnode, [('out_file', 'out_file')])])
    return workflow
예제 #8
0
def create_workflow(config: AttrDict, resource_pool: ResourcePool, context: Context):
    for _, rp in resource_pool[['T1w']]:
        anat_image = rp[R('T1w')]
        anat_deoblique = NipypeJob(
            interface=afni.Refit(deoblique=True),
            reference='deoblique'
        )
        anat_deoblique.in_file = anat_image
        output_node = anat_deoblique.out_file

        anat_reorient = NipypeJob(
            interface=afni.Resample(orientation='RPI', outputtype='NIFTI_GZ'),
            reference='reorient'
        )
        anat_reorient.in_file = output_node
        rp[R('T1w', label='reorient')] = anat_reorient.out_file
예제 #9
0
def _reorient_wf(name="ReorientWorkflow"):
    """A workflow to reorient images to 'RPI' orientation."""
    workflow = Workflow(name=name)
    workflow.__desc__ = "Inner workflow. "
    inputnode = Node(niu.IdentityInterface(fields=["in_file"]),
                     name="inputnode")
    outputnode = Node(niu.IdentityInterface(fields=["out_file"]),
                      name="outputnode")
    deoblique = Node(afni.Refit(deoblique=True), name="deoblique")
    reorient = Node(afni.Resample(orientation="RPI", outputtype="NIFTI_GZ"),
                    name="reorient")
    workflow.connect([
        (inputnode, deoblique, [("in_file", "in_file")]),
        (deoblique, reorient, [("out_file", "in_file")]),
        (reorient, outputnode, [("out_file", "out_file")]),
    ])
    return workflow
예제 #10
0
def test_refit():
    input_map = dict(
        args=dict(argstr='%s', ),
        deoblique=dict(argstr='-deoblique', ),
        environ=dict(usedefault=True, ),
        ignore_exception=dict(usedefault=True, ),
        in_file=dict(
            copyfile=True,
            mandatory=True,
            argstr='%s',
        ),
        outputtype=dict(),
        xorigin=dict(argstr='-xorigin %s', ),
        yorigin=dict(argstr='-yorigin %s', ),
        zorigin=dict(argstr='-zorigin %s', ),
    )
    instance = afni.Refit()
    for key, metadata in input_map.items():
        for metakey, value in metadata.items():
            yield assert_equal, getattr(instance.inputs.traits()[key],
                                        metakey), value
예제 #11
0
def _delete_orientation(in_file,
                        write_dir=None,
                        min_zoom=.1,
                        caching=False,
                        verbose=True):
    if write_dir is None:
        write_dir = os.path.dirname(in_file)

    if verbose:
        terminal_output = 'stream'
    else:
        terminal_output = 'none'

    if caching:
        memory = Memory(write_dir)
        copy = memory.cache(afni.Copy)
        refit = memory.cache(afni.Refit)
        center_mass = memory.cache(afni.CenterMass)
        for step in [copy, refit]:
            step.interface().set_default_terminal_output(terminal_output)
    else:
        copy = afni.Copy(terminal_output=terminal_output).run
        refit = afni.Refit(terminal_output=terminal_output).run
        center_mass = afni.CenterMass().run

    out_copy = copy(in_file=in_file,
                    out_file=fname_presuffix(in_file, newpath=write_dir))

    zooms = nibabel.load(in_file).header.get_zooms()[:3]
    out_refit = refit(in_file=out_copy.outputs.out_file,
                      xyzscale=min_zoom / min(zooms))
    out_center_mass = center_mass(in_file=out_refit.outputs.out_file,
                                  cm_file=fname_presuffix(in_file,
                                                          suffix='.txt',
                                                          use_ext=False,
                                                          newpath=write_dir),
                                  set_cm=(0, 0, 0))
    return out_center_mass.outputs.out_file
예제 #12
0
def create_anat_preproc(template_path=None,
                        mask_path=None,
                        regmask_path=None,
                        method='afni',
                        already_skullstripped=False,
                        non_local_means_filtering=True,
                        n4_correction=True,
                        wf_name='anat_preproc'):
    """ 
    The main purpose of this workflow is to process T1 scans. Raw mprage file is deobliqued, reoriented
    into RPI and skullstripped. Also, a whole brain only mask is generated from the skull stripped image
    for later use in registration.

    Returns
    -------
    anat_preproc : workflow
        Anatomical Preprocessing Workflow

    Notes
    -----
    `Source <https://github.com/FCP-INDI/C-PAC/blob/master/CPAC/anat_preproc/anat_preproc.py>`_
    
    Workflow Inputs::
        inputspec.anat : string
            User input anatomical (T1) Image, in any of the 8 orientations
    
    Workflow Outputs::

        outputspec.refit : string
            Path to deobliqued anatomical image
    
        outputspec.reorient : string
            Path to RPI oriented anatomical image
    
        outputspec.skullstrip : string
            Path to skull stripped RPI oriented mprage file with normalized intensities.
    
        outputspec.brain : string
            Path to skull stripped RPI brain image with original intensity values and not normalized or scaled.
    
    Order of commands:
    - Deobliqing the scans. ::
        3drefit -deoblique mprage.nii.gz

    - Re-orienting the Image into Right-to-Left Posterior-to-Anterior Inferior-to-Superior  (RPI) orientation ::
        3dresample -orient RPI
                   -prefix mprage_RPI.nii.gz
                   -inset mprage.nii.gz
                   
    - Skull-Stripping the image ::
        Using AFNI ::
            3dSkullStrip -input mprage_RPI.nii.gz
                         -o_ply mprage_RPI_3dT.nii.gz
        or using BET ::
            bet mprage_RPI.nii.gz

    - The skull-stripping step modifies the intensity values. To get back the original intensity values, we do an element wise product of RPI data with step function of skull-stripped data ::
        3dcalc -a mprage_RPI.nii.gz
               -b mprage_RPI_3dT.nii.gz
               -expr 'a*step(b)'
               -prefix mprage_RPI_3dc.nii.gz
    
    High Level Workflow Graph:
    .. image:: ../images/anatpreproc_graph.dot.png
       :width: 500
    
    Detailed Workflow Graph:
    .. image:: ../images/anatpreproc_graph_detailed.dot.png
       :width: 500

    Examples
    --------
    >>> from CPAC.anat_preproc import create_anat_preproc
    >>> preproc = create_anat_preproc()
    >>> preproc.inputs.inputspec.anat = 'sub1/anat/mprage.nii.gz'
    >>> preproc.run() #doctest: +SKIP
    """

    preproc = pe.Workflow(name=wf_name)

    inputnode = pe.Node(util.IdentityInterface(fields=['anat', 'brain_mask']),
                        name='inputspec')

    outputnode = pe.Node(util.IdentityInterface(
        fields=['refit', 'reorient', 'skullstrip', 'brain', 'brain_mask']),
                         name='outputspec')

    anat_deoblique = pe.Node(interface=afni.Refit(), name='anat_deoblique')

    anat_deoblique.inputs.deoblique = True
    preproc.connect(inputnode, 'anat', anat_deoblique, 'in_file')
    preproc.connect(anat_deoblique, 'out_file', outputnode, 'refit')
    # Disable non_local_means_filtering and n4_correction when run niworkflows-ants
    if method == 'niworkflows-ants':
        non_local_means_filtering = False
        n4_correction = False

    if non_local_means_filtering and n4_correction:
        denoise = pe.Node(interface=ants.DenoiseImage(), name='anat_denoise')
        preproc.connect(anat_deoblique, 'out_file', denoise, 'input_image')
        n4 = pe.Node(interface=ants.N4BiasFieldCorrection(dimension=3,
                                                          shrink_factor=2,
                                                          copy_header=True),
                     name='anat_n4')
        preproc.connect(denoise, 'output_image', n4, 'input_image')
    elif non_local_means_filtering and not n4_correction:
        denoise = pe.Node(interface=ants.DenoiseImage(), name='anat_denoise')
        preproc.connect(anat_deoblique, 'out_file', denoise, 'input_image')
    elif not non_local_means_filtering and n4_correction:
        n4 = pe.Node(interface=ants.N4BiasFieldCorrection(dimension=3,
                                                          shrink_factor=2,
                                                          copy_header=True),
                     name='anat_n4')
        preproc.connect(anat_deoblique, 'out_file', n4, 'input_image')

    # Anatomical reorientation
    anat_reorient = pe.Node(interface=afni.Resample(), name='anat_reorient')

    anat_reorient.inputs.orientation = 'RPI'
    anat_reorient.inputs.outputtype = 'NIFTI_GZ'

    if n4_correction:
        preproc.connect(n4, 'output_image', anat_reorient, 'in_file')
    elif non_local_means_filtering and not n4_correction:
        preproc.connect(denoise, 'output_image', anat_reorient, 'in_file')
    else:
        preproc.connect(anat_deoblique, 'out_file', anat_reorient, 'in_file')

    preproc.connect(anat_reorient, 'out_file', outputnode, 'reorient')

    if already_skullstripped:

        anat_skullstrip = pe.Node(
            interface=util.IdentityInterface(fields=['out_file']),
            name='anat_skullstrip')

        preproc.connect(anat_reorient, 'out_file', anat_skullstrip, 'out_file')

        preproc.connect(anat_skullstrip, 'out_file', outputnode, 'skullstrip')

        preproc.connect(anat_skullstrip, 'out_file', outputnode, 'brain')

    else:

        if method == 'afni':
            # Skull-stripping using AFNI 3dSkullStrip
            inputnode_afni = pe.Node(util.IdentityInterface(fields=[
                'shrink_factor', 'var_shrink_fac', 'shrink_fac_bot_lim',
                'avoid_vent', 'niter', 'pushout', 'touchup', 'fill_hole',
                'avoid_eyes', 'use_edge', 'exp_frac', 'smooth_final',
                'push_to_edge', 'use_skull', 'perc_int', 'max_inter_iter',
                'blur_fwhm', 'fac', 'monkey'
            ]),
                                     name='AFNI_options')

            skullstrip_args = pe.Node(util.Function(
                input_names=[
                    'spat_norm', 'spat_norm_dxyz', 'shrink_fac',
                    'var_shrink_fac', 'shrink_fac_bot_lim', 'avoid_vent',
                    'niter', 'pushout', 'touchup', 'fill_hole', 'avoid_eyes',
                    'use_edge', 'exp_frac', 'smooth_final', 'push_to_edge',
                    'use_skull', 'perc_int', 'max_inter_iter', 'blur_fwhm',
                    'fac', 'monkey'
                ],
                output_names=['expr'],
                function=create_3dskullstrip_arg_string),
                                      name='anat_skullstrip_args')

            preproc.connect([(inputnode_afni, skullstrip_args,
                              [('shrink_factor', 'shrink_fac'),
                               ('var_shrink_fac', 'var_shrink_fac'),
                               ('shrink_fac_bot_lim', 'shrink_fac_bot_lim'),
                               ('avoid_vent', 'avoid_vent'),
                               ('niter', 'niter'), ('pushout', 'pushout'),
                               ('touchup', 'touchup'),
                               ('fill_hole', 'fill_hole'),
                               ('avoid_eyes', 'avoid_eyes'),
                               ('use_edge', 'use_edge'),
                               ('exp_frac', 'exp_frac'),
                               ('smooth_final', 'smooth_final'),
                               ('push_to_edge', 'push_to_edge'),
                               ('use_skull', 'use_skull'),
                               ('perc_int', 'perc_int'),
                               ('max_inter_iter', 'max_inter_iter'),
                               ('blur_fwhm', 'blur_fwhm'), ('fac', 'fac'),
                               ('monkey', 'monkey')])])

            anat_skullstrip = pe.Node(interface=afni.SkullStrip(),
                                      name='anat_skullstrip')

            anat_skullstrip.inputs.outputtype = 'NIFTI_GZ'

            preproc.connect(anat_reorient, 'out_file', anat_skullstrip,
                            'in_file')
            preproc.connect(skullstrip_args, 'expr', anat_skullstrip, 'args')

            preproc.connect(anat_skullstrip, 'out_file', outputnode,
                            'skullstrip')
            # Apply skull-stripping step mask to original volume
            anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(),
                                               name='anat_skullstrip_orig_vol')

            anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
            anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

            preproc.connect(anat_reorient, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_a')

            anat_brain_mask = pe.Node(interface=afni.Calc(),
                                      name='anat_brain_mask')

            anat_brain_mask.inputs.expr = 'step(a)'
            anat_brain_mask.inputs.outputtype = 'NIFTI_GZ'

            preproc.connect(anat_skullstrip, 'out_file', anat_brain_mask,
                            'in_file_a')

            preproc.connect(anat_skullstrip, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_b')

            preproc.connect(anat_brain_mask, 'out_file', outputnode,
                            'brain_mask')

            preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode,
                            'brain')

        elif method == 'fsl':
            # Skull-stripping using FSL BET
            inputnode_bet = pe.Node(util.IdentityInterface(fields=[
                'frac', 'mask_boolean', 'mesh_boolean', 'outline', 'padding',
                'radius', 'reduce_bias', 'remove_eyes', 'robust', 'skull',
                'surfaces', 'threshold', 'vertical_gradient'
            ]),
                                    name='BET_options')

            anat_skullstrip = pe.Node(interface=fsl.BET(),
                                      name='anat_skullstrip')

            preproc.connect(anat_reorient, 'out_file', anat_skullstrip,
                            'in_file')

            preproc.connect([(inputnode_bet, anat_skullstrip, [
                ('frac', 'frac'),
                ('mask_boolean', 'mask'),
                ('mesh_boolean', 'mesh'),
                ('outline', 'outline'),
                ('padding', 'padding'),
                ('radius', 'radius'),
                ('reduce_bias', 'reduce_bias'),
                ('remove_eyes', 'remove_eyes'),
                ('robust', 'robust'),
                ('skull', 'skull'),
                ('surfaces', 'surfaces'),
                ('threshold', 'threshold'),
                ('vertical_gradient', 'vertical_gradient'),
            ])])

            preproc.connect(anat_skullstrip, 'out_file', outputnode,
                            'skullstrip')

            # Apply skull-stripping step mask to original volume
            anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(),
                                               name='anat_skullstrip_orig_vol')

            anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
            anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

            preproc.connect(anat_reorient, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_a')

            preproc.connect(anat_skullstrip, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_b')

            preproc.connect(anat_skullstrip, 'mask_file', outputnode,
                            'brain_mask')

            preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode,
                            'brain')

        elif method == 'niworkflows-ants':
            # Skull-stripping using niworkflows-ants
            anat_skullstrip_ants = init_brain_extraction_wf(
                tpl_target_path=template_path,
                tpl_mask_path=mask_path,
                tpl_regmask_path=regmask_path,
                name='anat_skullstrip_ants')

            preproc.connect(anat_reorient, 'out_file', anat_skullstrip_ants,
                            'inputnode.in_files')

            preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file',
                            outputnode, 'skullstrip')

            preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file',
                            outputnode, 'brain')

            preproc.connect(anat_skullstrip_ants,
                            'atropos_wf.copy_xform.out_mask', outputnode,
                            'brain_mask')

        elif method == 'mask':

            anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(),
                                               name='anat_skullstrip_orig_vol')

            anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
            anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

            preproc.connect(anat_reorient, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_a')

            preproc.connect(inputnode, 'brain_mask', anat_skullstrip_orig_vol,
                            'in_file_b')

            preproc.connect(inputnode, 'brain_mask', outputnode, 'brain_mask')

            preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode,
                            'brain')

    return preproc
def create_lesion_preproc(wf_name='lesion_preproc'):
    """
    The main purpose of this workflow is to process lesions masks.
    Lesion mask file is deobliqued and reoriented in the same way as the T1 in
    the anat_preproc function.

    Returns
    -------
    lesion_preproc : workflow
        Lesion preprocessing Workflow

    Workflow Inputs::
        inputspec.lesion : string
            User input lesion mask, in any of the 8 orientations

    Workflow Outputs::

        outputspec.refit : string
            Path to deobliqued anatomical image

        outputspec.reorient : string
            Path to RPI oriented anatomical image

    Order of commands:
    - Deobliqing the scans. ::
        3drefit -deoblique mprage.nii.gz

    - Re-orienting the Image into Right-to-Left Posterior-to-Anterior
    Inferior-to-Superior  (RPI) orientation ::
        3dresample -orient RPI
                   -prefix mprage_RPI.nii.gz
                   -inset mprage.nii.gz

    Examples
    --------
    >>> from CPAC.anat_preproc.lesion_preproc import create_lesion_preproc
    >>> preproc = create_lesion_preproc()
    >>> preproc.inputs.inputspec.lesion = 'sub1/anat/lesion-mask.nii.gz'
    >>> preproc.run() #doctest: +SKIP
    """

    preproc = pe.Workflow(name=wf_name)

    inputnode = pe.Node(util.IdentityInterface(fields=['lesion']),
                        name='inputspec')

    outputnode = pe.Node(util.IdentityInterface(fields=['refit', 'reorient']),
                         name='outputspec')

    lesion_deoblique = pe.Node(interface=afni.Refit(), name='lesion_deoblique')

    lesion_deoblique.inputs.deoblique = True

    lesion_inverted = pe.Node(interface=util.Function(
        input_names=['lesion_path'],
        output_names=['lesion_out'],
        function=inverse_lesion),
                              name='inverse_lesion')
    # We first check and invert the lesion if needed to be used by ANTs
    preproc.connect(inputnode, 'lesion', lesion_inverted, 'lesion_path')

    preproc.connect(lesion_inverted, 'lesion_out', lesion_deoblique, 'in_file')

    preproc.connect(lesion_deoblique, 'out_file', outputnode, 'refit')

    # Anatomical reorientation
    lesion_reorient = pe.Node(interface=afni.Resample(),
                              name='lesion_reorient')

    lesion_reorient.inputs.orientation = 'RPI'
    lesion_reorient.inputs.outputtype = 'NIFTI_GZ'

    preproc.connect(lesion_deoblique, 'out_file', lesion_reorient, 'in_file')
    preproc.connect(lesion_reorient, 'out_file', outputnode, 'reorient')

    return preproc
예제 #14
0
def create_anat_preproc(method='afni',
                        already_skullstripped=False,
                        c=None,
                        wf_name='anat_preproc'):
    """The main purpose of this workflow is to process T1 scans. Raw mprage file is deobliqued, reoriented
    into RPI and skullstripped. Also, a whole brain only mask is generated from the skull stripped image
    for later use in registration.

    Returns
    -------
    anat_preproc : workflow
        Anatomical Preprocessing Workflow

    Notes
    -----
    `Source <https://github.com/FCP-INDI/C-PAC/blob/master/CPAC/anat_preproc/anat_preproc.py>`_

    Workflow Inputs::
        inputspec.anat : string
            User input anatomical (T1) Image, in any of the 8 orientations

    Workflow Outputs::

        outputspec.refit : string
            Path to deobliqued anatomical image

        outputspec.reorient : string
            Path to RPI oriented anatomical image

        outputspec.skullstrip : string
            Path to skull stripped RPI oriented mprage file with normalized intensities.

        outputspec.brain : string
            Path to skull stripped RPI brain image with original intensity values and not normalized or scaled.

    Order of commands:
    - Deobliqing the scans. ::
        3drefit -deoblique mprage.nii.gz

    - Re-orienting the Image into Right-to-Left Posterior-to-Anterior Inferior-to-Superior  (RPI) orientation ::
        3dresample -orient RPI
                   -prefix mprage_RPI.nii.gz
                   -inset mprage.nii.gz

    - Skull-Stripping the image ::
        Using AFNI ::
            3dSkullStrip -input mprage_RPI.nii.gz
                         -o_ply mprage_RPI_3dT.nii.gz
        or using BET ::
            bet mprage_RPI.nii.gz

    - The skull-stripping step modifies the intensity values. To get back the original intensity values, we do an element wise product of RPI data with step function of skull-stripped data ::
        3dcalc -a mprage_RPI.nii.gz
               -b mprage_RPI_3dT.nii.gz
               -expr 'a*step(b)'
               -prefix mprage_RPI_3dc.nii.gz

    High Level Workflow Graph:
    .. image:: ../images/anatpreproc_graph.dot.png
       :width: 500

    Detailed Workflow Graph:
    .. image:: ../images/anatpreproc_graph_detailed.dot.png
       :width: 500

    Examples
    --------
    >>> from CPAC.anat_preproc import create_anat_preproc
    >>> preproc = create_anat_preproc()
    >>> preproc.inputs.inputspec.anat = 'sub1/anat/mprage.nii.gz'
    >>> preproc.run() #doctest: +SKIP
    """

    preproc = pe.Workflow(name=wf_name)

    inputnode = pe.Node(util.IdentityInterface(fields=['anat', 'brain_mask']),
                        name='inputspec')

    outputnode = pe.Node(util.IdentityInterface(
        fields=['refit', 'reorient', 'skullstrip', 'brain', 'brain_mask']),
                         name='outputspec')

    anat_deoblique = pe.Node(interface=afni.Refit(), name='anat_deoblique')
    anat_deoblique.inputs.deoblique = True
    preproc.connect(inputnode, 'anat', anat_deoblique, 'in_file')

    preproc.connect(anat_deoblique, 'out_file', outputnode, 'refit')
    # Disable non_local_means_filtering and n4_bias_field_correction when run niworkflows-ants
    if method == 'niworkflows-ants':
        c.non_local_means_filtering = False
        c.n4_bias_field_correction = False

    if c.non_local_means_filtering and c.n4_bias_field_correction:
        denoise = pe.Node(interface=ants.DenoiseImage(), name='anat_denoise')
        preproc.connect(anat_deoblique, 'out_file', denoise, 'input_image')
        n4 = pe.Node(interface=ants.N4BiasFieldCorrection(dimension=3,
                                                          shrink_factor=2,
                                                          copy_header=True),
                     name='anat_n4')
        preproc.connect(denoise, 'output_image', n4, 'input_image')
    elif c.non_local_means_filtering and not c.n4_bias_field_correction:
        denoise = pe.Node(interface=ants.DenoiseImage(), name='anat_denoise')
        preproc.connect(anat_deoblique, 'out_file', denoise, 'input_image')
    elif not c.non_local_means_filtering and c.n4_bias_field_correction:
        n4 = pe.Node(interface=ants.N4BiasFieldCorrection(dimension=3,
                                                          shrink_factor=2,
                                                          copy_header=True),
                     name='anat_n4')
        preproc.connect(anat_deoblique, 'out_file', n4, 'input_image')

    # Anatomical reorientation
    anat_reorient = pe.Node(interface=afni.Resample(), name='anat_reorient')
    anat_reorient.inputs.orientation = 'RPI'
    anat_reorient.inputs.outputtype = 'NIFTI_GZ'

    if c.n4_bias_field_correction:
        preproc.connect(n4, 'output_image', anat_reorient, 'in_file')
    elif c.non_local_means_filtering and not c.n4_bias_field_correction:
        preproc.connect(denoise, 'output_image', anat_reorient, 'in_file')
    else:
        preproc.connect(anat_deoblique, 'out_file', anat_reorient, 'in_file')

    preproc.connect(anat_reorient, 'out_file', outputnode, 'reorient')

    if already_skullstripped:

        anat_skullstrip = pe.Node(
            interface=util.IdentityInterface(fields=['out_file']),
            name='anat_skullstrip')

        preproc.connect(anat_reorient, 'out_file', anat_skullstrip, 'out_file')

        preproc.connect(anat_skullstrip, 'out_file', outputnode, 'skullstrip')

        preproc.connect(anat_skullstrip, 'out_file', outputnode, 'brain')

    else:

        if method == 'afni':
            # Skull-stripping using AFNI 3dSkullStrip
            inputnode_afni = pe.Node(util.IdentityInterface(fields=[
                'mask_vol', 'shrink_factor', 'var_shrink_fac',
                'shrink_fac_bot_lim', 'avoid_vent', 'niter', 'pushout',
                'touchup', 'fill_hole', 'avoid_eyes', 'use_edge', 'exp_frac',
                'smooth_final', 'push_to_edge', 'use_skull', 'perc_int',
                'max_inter_iter', 'blur_fwhm', 'fac', 'monkey'
            ]),
                                     name='AFNI_options')

            skullstrip_args = pe.Node(util.Function(
                input_names=[
                    'spat_norm', 'spat_norm_dxyz', 'mask_vol', 'shrink_fac',
                    'var_shrink_fac', 'shrink_fac_bot_lim', 'avoid_vent',
                    'niter', 'pushout', 'touchup', 'fill_hole', 'avoid_eyes',
                    'use_edge', 'exp_frac', 'smooth_final', 'push_to_edge',
                    'use_skull', 'perc_int', 'max_inter_iter', 'blur_fwhm',
                    'fac', 'monkey'
                ],
                output_names=['expr'],
                function=create_3dskullstrip_arg_string),
                                      name='anat_skullstrip_args')

            preproc.connect([(inputnode_afni, skullstrip_args,
                              [('mask_vol', 'mask_vol'),
                               ('shrink_factor', 'shrink_fac'),
                               ('var_shrink_fac', 'var_shrink_fac'),
                               ('shrink_fac_bot_lim', 'shrink_fac_bot_lim'),
                               ('avoid_vent', 'avoid_vent'),
                               ('niter', 'niter'), ('pushout', 'pushout'),
                               ('touchup', 'touchup'),
                               ('fill_hole', 'fill_hole'),
                               ('avoid_eyes', 'avoid_eyes'),
                               ('use_edge', 'use_edge'),
                               ('exp_frac', 'exp_frac'),
                               ('smooth_final', 'smooth_final'),
                               ('push_to_edge', 'push_to_edge'),
                               ('use_skull', 'use_skull'),
                               ('perc_int', 'perc_int'),
                               ('max_inter_iter', 'max_inter_iter'),
                               ('blur_fwhm', 'blur_fwhm'), ('fac', 'fac'),
                               ('monkey', 'monkey')])])

            anat_skullstrip = pe.Node(interface=afni.SkullStrip(),
                                      name='anat_skullstrip')

            anat_skullstrip.inputs.outputtype = 'NIFTI_GZ'

            preproc.connect(anat_reorient, 'out_file', anat_skullstrip,
                            'in_file')
            preproc.connect(skullstrip_args, 'expr', anat_skullstrip, 'args')

            # Generate anatomical brain mask

            anat_brain_mask = pe.Node(interface=afni.Calc(),
                                      name='anat_brain_mask')

            anat_brain_mask.inputs.expr = 'step(a)'
            anat_brain_mask.inputs.outputtype = 'NIFTI_GZ'

            preproc.connect(anat_skullstrip, 'out_file', anat_brain_mask,
                            'in_file_a')

            # Apply skull-stripping step mask to original volume
            anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(),
                                               name='anat_skullstrip_orig_vol')

            anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
            anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

            preproc.connect(anat_reorient, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_a')

            preproc.connect(anat_brain_mask, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_b')

            preproc.connect(anat_brain_mask, 'out_file', outputnode,
                            'brain_mask')

            preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode,
                            'brain')

        elif method == 'fsl':
            # Skull-stripping using FSL BET
            inputnode_bet = pe.Node(util.IdentityInterface(fields=[
                'frac', 'mask_boolean', 'mesh_boolean', 'outline', 'padding',
                'radius', 'reduce_bias', 'remove_eyes', 'robust', 'skull',
                'surfaces', 'threshold', 'vertical_gradient'
            ]),
                                    name='BET_options')

            anat_skullstrip = pe.Node(interface=fsl.BET(),
                                      name='anat_skullstrip')
            anat_skullstrip.inputs.output_type = 'NIFTI_GZ'

            preproc.connect(anat_reorient, 'out_file', anat_skullstrip,
                            'in_file')

            preproc.connect([(inputnode_bet, anat_skullstrip, [
                ('frac', 'frac'),
                ('mask_boolean', 'mask'),
                ('mesh_boolean', 'mesh'),
                ('outline', 'outline'),
                ('padding', 'padding'),
                ('radius', 'radius'),
                ('reduce_bias', 'reduce_bias'),
                ('remove_eyes', 'remove_eyes'),
                ('robust', 'robust'),
                ('skull', 'skull'),
                ('surfaces', 'surfaces'),
                ('threshold', 'threshold'),
                ('vertical_gradient', 'vertical_gradient'),
            ])])

            preproc.connect(anat_skullstrip, 'out_file', outputnode,
                            'skullstrip')

            # Apply skull-stripping step mask to original volume
            anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(),
                                               name='anat_skullstrip_orig_vol')

            anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
            anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

            preproc.connect(anat_reorient, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_a')

            preproc.connect(anat_skullstrip, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_b')

            preproc.connect(anat_skullstrip, 'mask_file', outputnode,
                            'brain_mask')

            preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode,
                            'brain')

        elif method == 'niworkflows-ants':
            # Skull-stripping using niworkflows-ants
            anat_skullstrip_ants = init_brain_extraction_wf(
                tpl_target_path=c.niworkflows_ants_template_path,
                tpl_mask_path=c.niworkflows_ants_mask_path,
                tpl_regmask_path=c.niworkflows_ants_regmask_path,
                name='anat_skullstrip_ants')

            preproc.connect(anat_reorient, 'out_file', anat_skullstrip_ants,
                            'inputnode.in_files')

            preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file',
                            outputnode, 'skullstrip')

            preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file',
                            outputnode, 'brain')

            preproc.connect(anat_skullstrip_ants,
                            'atropos_wf.copy_xform.out_mask', outputnode,
                            'brain_mask')

        elif method == 'mask':

            brain_mask_deoblique = pe.Node(interface=afni.Refit(),
                                           name='brain_mask_deoblique')
            brain_mask_deoblique.inputs.deoblique = True
            preproc.connect(inputnode, 'brain_mask', brain_mask_deoblique,
                            'in_file')

            brain_mask_reorient = pe.Node(interface=afni.Resample(),
                                          name='brain_mask_reorient')
            brain_mask_reorient.inputs.orientation = 'RPI'
            brain_mask_reorient.inputs.outputtype = 'NIFTI_GZ'
            preproc.connect(brain_mask_deoblique, 'out_file',
                            brain_mask_reorient, 'in_file')

            anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(),
                                               name='anat_skullstrip_orig_vol')
            anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
            anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

            preproc.connect(anat_reorient, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_a')

            preproc.connect(brain_mask_reorient, 'out_file',
                            anat_skullstrip_orig_vol, 'in_file_b')

            preproc.connect(brain_mask_reorient, 'out_file', outputnode,
                            'brain_mask')

            preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputnode,
                            'brain')

        elif method == 'unet':
            """
            UNet
            options (following numbers are default):
            input_slice: 3
            conv_block: 5
            kernel_root: 16
            rescale_dim: 256
            """
            # TODO: add options to pipeline_config
            train_model = UNet2d(dim_in=3, num_conv_block=5, kernel_root=16)
            unet_path = check_for_s3(c.unet_model)
            checkpoint = torch.load(unet_path, map_location={'cuda:0': 'cpu'})
            train_model.load_state_dict(checkpoint['state_dict'])
            model = nn.Sequential(train_model, nn.Softmax2d())

            # create a node called unet_mask
            unet_mask = pe.Node(util.Function(input_names=['model', 'cimg_in'],
                                              output_names=['out_path'],
                                              function=predict_volumes),
                                name='unet_mask')

            unet_mask.inputs.model = model
            preproc.connect(anat_reorient, 'out_file', unet_mask, 'cimg_in')
            """
            Revised mask with ANTs
            """
            # fslmaths <whole head> -mul <mask> brain.nii.gz
            unet_masked_brain = pe.Node(interface=fsl.MultiImageMaths(),
                                        name='unet_masked_brain')
            unet_masked_brain.inputs.op_string = "-mul %s"
            preproc.connect(anat_reorient, 'out_file', unet_masked_brain,
                            'in_file')
            preproc.connect(unet_mask, 'out_path', unet_masked_brain,
                            'operand_files')

            # flirt -v -dof 6 -in brain.nii.gz -ref NMT_SS_0.5mm.nii.gz -o brain_rot2atl -omat brain_rot2atl.mat -interp sinc
            # TODO change it to ANTs linear transform
            native_brain_to_template_brain = pe.Node(
                interface=fsl.FLIRT(), name='native_brain_to_template_brain')
            native_brain_to_template_brain.inputs.reference = c.template_brain_only_for_anat
            native_brain_to_template_brain.inputs.dof = 6
            native_brain_to_template_brain.inputs.interp = 'sinc'
            preproc.connect(unet_masked_brain, 'out_file',
                            native_brain_to_template_brain, 'in_file')

            # flirt -in head.nii.gz -ref NMT_0.5mm.nii.gz -o head_rot2atl -applyxfm -init brain_rot2atl.mat
            # TODO change it to ANTs linear transform
            native_head_to_template_head = pe.Node(
                interface=fsl.FLIRT(), name='native_head_to_template_head')
            native_head_to_template_head.inputs.reference = c.template_skull_for_anat
            native_head_to_template_head.inputs.apply_xfm = True
            preproc.connect(anat_reorient, 'out_file',
                            native_head_to_template_head, 'in_file')
            preproc.connect(native_brain_to_template_brain, 'out_matrix_file',
                            native_head_to_template_head, 'in_matrix_file')

            # fslmaths NMT_SS_0.5mm.nii.gz -bin templateMask.nii.gz
            template_brain_mask = pe.Node(interface=fsl.maths.MathsCommand(),
                                          name='template_brain_mask')
            template_brain_mask.inputs.in_file = c.template_brain_only_for_anat
            template_brain_mask.inputs.args = '-bin'

            # ANTS 3 -m  CC[head_rot2atl.nii.gz,NMT_0.5mm.nii.gz,1,5] -t SyN[0.25] -r Gauss[3,0] -o atl2T1rot -i 60x50x20 --use-Histogram-Matching  --number-of-affine-iterations 10000x10000x10000x10000x10000 --MI-option 32x16000
            ants_template_head_to_template = pe.Node(
                interface=ants.Registration(),
                name='template_head_to_template')
            ants_template_head_to_template.inputs.metric = ['CC']
            ants_template_head_to_template.inputs.metric_weight = [1, 5]
            ants_template_head_to_template.inputs.moving_image = c.template_skull_for_anat
            ants_template_head_to_template.inputs.transforms = ['SyN']
            ants_template_head_to_template.inputs.transform_parameters = [
                (0.25, )
            ]
            ants_template_head_to_template.inputs.interpolation = 'NearestNeighbor'
            ants_template_head_to_template.inputs.number_of_iterations = [[
                60, 50, 20
            ]]
            ants_template_head_to_template.inputs.smoothing_sigmas = [[
                0.6, 0.2, 0.0
            ]]
            ants_template_head_to_template.inputs.shrink_factors = [[4, 2, 1]]
            ants_template_head_to_template.inputs.convergence_threshold = [
                1.e-8
            ]
            preproc.connect(native_head_to_template_head, 'out_file',
                            ants_template_head_to_template, 'fixed_image')

            # antsApplyTransforms -d 3 -i templateMask.nii.gz -t atl2T1rotWarp.nii.gz atl2T1rotAffine.txt -r brain_rot2atl.nii.gz -o brain_rot2atl_mask.nii.gz
            template_head_transform_to_template = pe.Node(
                interface=ants.ApplyTransforms(),
                name='template_head_transform_to_template')
            template_head_transform_to_template.inputs.dimension = 3
            preproc.connect(template_brain_mask, 'out_file',
                            template_head_transform_to_template, 'input_image')
            preproc.connect(native_brain_to_template_brain, 'out_file',
                            template_head_transform_to_template,
                            'reference_image')
            preproc.connect(ants_template_head_to_template,
                            'forward_transforms',
                            template_head_transform_to_template, 'transforms')

            # convert_xfm -omat brain_rot2native.mat -inverse brain_rot2atl.mat
            invt = pe.Node(interface=fsl.ConvertXFM(), name='convert_xfm')
            invt.inputs.invert_xfm = True
            preproc.connect(native_brain_to_template_brain, 'out_matrix_file',
                            invt, 'in_file')

            # flirt -in brain_rot2atl_mask.nii.gz -ref brain.nii.gz -o brain_mask.nii.gz -applyxfm -init brain_rot2native.mat
            template_brain_to_native_brain = pe.Node(
                interface=fsl.FLIRT(), name='template_brain_to_native_brain')
            template_brain_to_native_brain.inputs.apply_xfm = True
            preproc.connect(template_head_transform_to_template,
                            'output_image', template_brain_to_native_brain,
                            'in_file')
            preproc.connect(unet_masked_brain, 'out_file',
                            template_brain_to_native_brain, 'reference')
            preproc.connect(invt, 'out_file', template_brain_to_native_brain,
                            'in_matrix_file')

            # fslmaths brain_mask.nii.gz -thr .5 -bin brain_mask_thr.nii.gz
            refined_mask = pe.Node(interface=fsl.Threshold(),
                                   name='refined_mask')
            refined_mask.inputs.thresh = 0.5
            preproc.connect(template_brain_to_native_brain, 'out_file',
                            refined_mask, 'in_file')

            # get a new brain with mask
            refined_brain = pe.Node(interface=fsl.MultiImageMaths(),
                                    name='refined_brain')
            refined_brain.inputs.op_string = "-mul %s"
            preproc.connect(anat_reorient, 'out_file', refined_brain,
                            'in_file')
            preproc.connect(refined_mask, 'out_file', refined_brain,
                            'operand_files')

            preproc.connect(refined_mask, 'out_file', outputnode, 'brain_mask')
            preproc.connect(refined_brain, 'out_file', outputnode, 'brain')

    return preproc
예제 #15
0
def create_pipeline_graph(pipeline_name, graph_file,
                          graph_kind='hierarchical'):
    """Creates pipeline graph for a given piepline.

    Parameters
    ----------
    pipeline_name : one of {'anat_to_common_rigid', 'anat_to_common_affine',
        'anat_to_common_nonlinear'}
        Pipeline name.

    graph_file : str.
        Path to save the graph image to.

    graph_kind : one of {'orig', 'hierarchical', 'flat', 'exec', 'colored'}, optional.
        The kind of the graph, passed to
        nipype.pipeline.workflows.Workflow().write_graph
    """
    pipeline_names = ['anats_to_common_rigid', 'anats_to_common_affine',
                      'anats_to_common_nonlinear']
    if pipeline_name not in pipeline_names:
        raise NotImplementedError(
            'Pipeline name must be one of {0}, you entered {1}'.format(
                pipeline_names, pipeline_name))
    graph_kinds = ['orig', 'hierarchical', 'flat', 'exec', 'colored']
    if graph_kind not in graph_kinds:
        raise ValueError(
            'Graph kind must be one of {0}, you entered {1}'.format(
                graph_kinds, graph_kind))

    workflow = pe.Workflow(name=pipeline_name)

    #######################################################################
    # Specify rigid body registration pipeline steps
    unifize = pe.Node(interface=afni.Unifize(), name='bias_correct')
    clip_level = pe.Node(interface=afni.ClipLevel(),
                         name='compute_mask_threshold')
    compute_mask = pe.Node(interface=interfaces.MathMorphoMask(),
                           name='compute_brain_mask')
    apply_mask = pe.Node(interface=afni.Calc(), name='apply_brain_mask')
    center_mass = pe.Node(interface=afni.CenterMass(),
                          name='compute_and_set_cm_in_header')
    refit_copy = pe.Node(afni.Refit(), name='copy_cm_in_header')
    tcat1 = pe.Node(afni.TCat(), name='concatenate_across_individuals1')
    tstat1 = pe.Node(afni.TStat(), name='compute_average1')
    undump = pe.Node(afni.Undump(), name='create_empty_template')
    refit_set = pe.Node(afni.Refit(), name='set_cm_in_header')
    resample1 = pe.Node(afni.Resample(), name='resample1')
    resample2 = pe.Node(afni.Resample(), name='resample2')
    shift_rotate = pe.Node(afni.Allineate(), name='shift_rotate')
    apply_allineate1 = pe.Node(afni.Allineate(), name='apply_transform1')
    tcat2 = pe.Node(afni.TCat(), name='concatenate_across_individuals2')
    tstat2 = pe.Node(afni.TStat(), name='compute_average2')
    tcat3 = pe.Node(afni.TCat(), name='concatenate_across_individuals3')
    tstat3 = pe.Node(afni.TStat(), name='compute_average3')

    workflow.add_nodes([unifize, clip_level, compute_mask, apply_mask,
                        center_mass,
                        refit_copy, tcat1, tstat1, undump, refit_set,
                        resample1, resample2, shift_rotate, apply_allineate1,
                        tcat2, tstat2, tcat3, tstat3])

    #######################################################################
    # and connections
    workflow.connect(unifize, 'out_file', clip_level, 'in_file')
    workflow.connect(clip_level, 'clip_val',
                     compute_mask, 'intensity_threshold')
    workflow.connect(unifize, 'out_file', compute_mask, 'in_file')
    workflow.connect(compute_mask, 'out_file', apply_mask, 'in_file_a')
    workflow.connect(unifize, 'out_file', apply_mask, 'in_file_b')
    workflow.connect(apply_mask, 'out_file',
                     center_mass, 'in_file')
    workflow.connect(unifize, 'out_file', refit_copy, 'in_file')
    workflow.connect(center_mass, 'out_file',
                     refit_copy, 'duporigin_file')
    workflow.connect(center_mass, 'out_file', tcat1, 'in_files')
    workflow.connect(tcat1, 'out_file', tstat1, 'in_file')
    workflow.connect(tstat1, 'out_file', undump, 'in_file')
    workflow.connect(undump, 'out_file', refit_set, 'in_file')
    workflow.connect(refit_set, 'out_file', resample1, 'master')
    workflow.connect(refit_copy, 'out_file', resample1, 'in_file')
    workflow.connect(refit_set, 'out_file', resample2, 'master')
    workflow.connect(center_mass, 'out_file', resample2, 'in_file')
    workflow.connect(resample2, 'out_file', tcat2, 'in_files')
    workflow.connect(tcat2, 'out_file', tstat2, 'in_file')
    workflow.connect(tstat2, 'out_file', shift_rotate, 'reference')
    workflow.connect(resample2, 'out_file', shift_rotate, 'in_file')
    workflow.connect(tstat2, 'out_file', apply_allineate1, 'master')
    workflow.connect(resample1, 'out_file',
                     apply_allineate1, 'in_file')
    workflow.connect(shift_rotate, 'out_matrix',
                     apply_allineate1, 'in_matrix')
    workflow.connect(apply_allineate1, 'out_file', tcat3, 'in_files')
    workflow.connect(tcat3, 'out_file', tstat3, 'in_file')
    if pipeline_name in ['anats_to_common_affine',
                         'anat_to_common_nonlinear']:
        mask = pe.Node(afni.MaskTool(), name='generate_count_mask')
        allineate = pe.Node(afni.Allineate(), name='allineate')
        catmatvec = pe.Node(afni.CatMatvec(), name='concatenate_transforms')
        apply_allineate2 = pe.Node(afni.Allineate(), name='apply_transform2')
        tcat3 = pe.Node(
            afni.TCat(), name='concatenate_across_individuals4')
        tstat3 = pe.Node(afni.TStat(), name='compute_average4')

        workflow.add_nodes([mask, allineate, catmatvec, apply_allineate2,
                            tcat3, tstat3])

        workflow.connect(tcat2, 'out_file', mask, 'in_file')
        workflow.connect(mask, 'out_file', allineate, 'weight')
        workflow.connect(apply_allineate1, 'out_file',
                         allineate, 'in_file')
        workflow.connect(allineate, 'out_matrix',
                         catmatvec, 'in_file')
        #XXX how can we enter multiple files ? 
        workflow.connect(catmatvec, 'out_file',
                         apply_allineate2, 'in_matrix')
        workflow.connect(resample1, 'out_file',
                         apply_allineate2, 'in_file')
        workflow.connect(apply_allineate2, 'out_file', tcat3, 'in_files')
        workflow.connect(tcat3, 'out_file', tstat3, 'in_file')

    if pipeline_name == 'anats_to_common_nonlinear':
        pass

    graph_file_root, graph_file_ext = os.path.splitext(graph_file)
    if graph_file_ext:
        _ = workflow.write_graph(graph2use=graph_kind,
                                 format=graph_file_ext[1:],
                                 dotfilename=graph_file_root)
    else:
        _ = workflow.write_graph(graph2use=graph_kind,
                                 dotfilename=graph_file_root)
예제 #16
0
def fix_obliquity(to_fix_filename, reference_filename, caching=False,
                  caching_dir=None, overwrite=False,
                  verbose=True, environ=None):
    if caching_dir is None:
        caching_dir = os.getcwd()
    if caching:
        memory = Memory(caching_dir)

    if verbose:
        terminal_output = 'allatonce'
    else:
        terminal_output = 'none'

    if environ is None:
        if caching:
            environ = {}
        else:
            environ = {'AFNI_DECONFLICT': 'OVERWRITE'}

    if caching:
        copy = memory.cache(afni.Copy)
        refit = memory.cache(afni.Refit)
        copy.interface().set_default_terminal_output(terminal_output)
        refit.interface().set_default_terminal_output(terminal_output)
    else:
        copy = afni.Copy(terminal_output=terminal_output).run
        refit = afni.Refit(terminal_output=terminal_output).run

    tmp_folder = os.path.join(caching_dir, 'tmp')
    if not os.path.isdir(tmp_folder):
        os.makedirs(tmp_folder)

    reference_basename = os.path.basename(reference_filename)
    orig_reference_filename = fname_presuffix(os.path.join(
        tmp_folder, reference_basename), suffix='+orig.BRIK',
        use_ext=False)
    out_copy_oblique = copy(in_file=reference_filename,
                            out_file=orig_reference_filename,
                            environ=environ)
    orig_reference_filename = out_copy_oblique.outputs.out_file

    to_fix_basename = os.path.basename(to_fix_filename)
    orig_to_fix_filename = fname_presuffix(os.path.join(
        tmp_folder, to_fix_basename), suffix='+orig.BRIK',
        use_ext=False)
    out_copy = copy(in_file=to_fix_filename,
                    out_file=orig_to_fix_filename,
                    environ=environ)
    orig_to_fix_filename = out_copy.outputs.out_file

    out_refit = refit(in_file=orig_to_fix_filename,
                      atrcopy=(orig_reference_filename,
                               'IJK_TO_DICOM_REAL'))

    out_copy = copy(in_file=out_refit.outputs.out_file,
                    out_file=fname_presuffix(to_fix_filename,
                                             suffix='_oblique'),
                    environ=environ)

    if not caching:
        shutil.rmtree(tmp_folder)

    return out_copy.outputs.out_file
예제 #17
0
def create_register_NMT_pipe(params_template,
                             params={},
                             name="register_NMT_pipe"):
    """
    Description: Register template to anat with the script NMT_subject_align,
        and then apply it to tissues list_priors

    Inputs:

        inputnode:
            T1: T1 file name
            indiv_params: dict with individuals parameters for some nodes

        arguments:
            params_template: dictionary of info about template

            params: dictionary of node sub-parameters (from a json file)

            name: pipeline name (default = "register_NMT_pipe")

    Outputs:

        norm_intensity.output_image:
            filled mask after erode
        align_seg_csf.out_file:
            csf template tissue in subject space
        align_seg_gm.out_file:
            grey matter template tissue in subject space
        align_seg_wm.out_file:
            white matter template tissue in subject space
    """

    register_NMT_pipe = pe.Workflow(name=name)

    # creating inputnode
    inputnode = pe.Node(niu.IdentityInterface(fields=['T1', 'indiv_params']),
                        name='inputnode')

    # N4 intensity normalization over brain
    norm_intensity = NodeParams(ants.N4BiasFieldCorrection(),
                                params=parse_key(params, "norm_intensity"),
                                name='norm_intensity')

    register_NMT_pipe.connect(inputnode, 'T1', norm_intensity, "input_image")

    register_NMT_pipe.connect(inputnode,
                              ('indiv_params', parse_key, "norm_intensity"),
                              norm_intensity, "indiv_params")

    deoblique = pe.Node(afni.Refit(deoblique=True), name="deoblique")
    register_NMT_pipe.connect(norm_intensity, 'output_image', deoblique,
                              "in_file")

    # align subj to nmt (with NMT_subject_align, wrapped version with nodes)
    NMT_subject_align = pe.Node(NMTSubjectAlign(), name='NMT_subject_align')

    register_NMT_pipe.connect(deoblique, 'out_file', NMT_subject_align,
                              "T1_file")

    NMT_subject_align.inputs.NMT_SS_file = params_template["template_brain"]

    # align_masks
    # "overwrap" of NwarpApply, with specifying the outputs as wished
    list_priors = [
        params_template["template_head"], params_template["template_csf"],
        params_template["template_gm"], params_template["template_wm"]
    ]

    align_masks = pe.Node(NwarpApplyPriors(), name='align_masks')
    align_masks.inputs.in_file = list_priors
    align_masks.inputs.out_file = list_priors
    align_masks.inputs.interp = "NN"
    align_masks.inputs.args = "-overwrite"

    register_NMT_pipe.connect(NMT_subject_align, 'shft_aff_file', align_masks,
                              'master')
    register_NMT_pipe.connect(NMT_subject_align, 'warpinv_file', align_masks,
                              "warp")

    # align_NMT
    align_NMT = pe.Node(afni.Allineate(),
                        name="align_NMT",
                        iterfield=['in_file'])
    align_NMT.inputs.final_interpolation = "nearestneighbour"
    align_NMT.inputs.overwrite = True
    align_NMT.inputs.outputtype = "NIFTI_GZ"

    register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 0),
                              align_NMT, "in_file")  # -source
    register_NMT_pipe.connect(norm_intensity, 'output_image', align_NMT,
                              "reference")  # -base
    register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file', align_NMT,
                              "in_matrix")  # -1Dmatrix_apply

    # seg_csf
    align_seg_csf = pe.Node(afni.Allineate(),
                            name="align_seg_csf",
                            iterfield=['in_file'])
    align_seg_csf.inputs.final_interpolation = "nearestneighbour"
    align_seg_csf.inputs.overwrite = True
    align_seg_csf.inputs.outputtype = "NIFTI_GZ"

    register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 1),
                              align_seg_csf, "in_file")  # -source
    register_NMT_pipe.connect(norm_intensity, 'output_image', align_seg_csf,
                              "reference")  # -base
    register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                              align_seg_csf, "in_matrix")  # -1Dmatrix_apply

    # seg_gm
    align_seg_gm = pe.Node(afni.Allineate(),
                           name="align_seg_gm",
                           iterfield=['in_file'])
    align_seg_gm.inputs.final_interpolation = "nearestneighbour"
    align_seg_gm.inputs.overwrite = True
    align_seg_gm.inputs.outputtype = "NIFTI_GZ"

    register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 2),
                              align_seg_gm, "in_file")  # -source
    register_NMT_pipe.connect(norm_intensity, 'output_image', align_seg_gm,
                              "reference")  # -base
    register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                              align_seg_gm, "in_matrix")  # -1Dmatrix_apply

    # seg_wm
    align_seg_wm = pe.Node(afni.Allineate(),
                           name="align_seg_wm",
                           iterfield=['in_file'])
    align_seg_wm.inputs.final_interpolation = "nearestneighbour"
    align_seg_wm.inputs.overwrite = True
    align_seg_wm.inputs.outputtype = "NIFTI_GZ"

    register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 3),
                              align_seg_wm, "in_file")  # -source
    register_NMT_pipe.connect(norm_intensity, 'output_image', align_seg_wm,
                              "reference")  # -base
    register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                              align_seg_wm, "in_matrix")  # -1Dmatrix_apply

    return register_NMT_pipe
예제 #18
0
def skullstrip_anatomical(method='afni', config=None, wf_name='skullstrip_anatomical'):

    method = method.lower()

    preproc = pe.Workflow(name=wf_name)

    inputnode = pe.Node(util.IdentityInterface(fields=['anat_data', 
                                                       'brain_mask',
                                                       'template_brain_only_for_anat',
                                                       'template_skull_for_anat']), 
                         name='inputspec')
    outputnode = pe.Node(util.IdentityInterface(fields=['skullstrip',
                                                        'brain',
                                                        'brain_mask']),
                        name='outputspec')

    if method == 'afni':
        # Skull-stripping using AFNI 3dSkullStrip
        inputnode_afni = pe.Node(
            util.IdentityInterface(fields=['mask_vol',
                                            'shrink_factor',
                                            'var_shrink_fac',
                                            'shrink_fac_bot_lim',
                                            'avoid_vent',
                                            'niter',
                                            'pushout',
                                            'touchup',
                                            'fill_hole',
                                            'avoid_eyes',
                                            'use_edge',
                                            'exp_frac',
                                            'smooth_final',
                                            'push_to_edge',
                                            'use_skull',
                                            'perc_int',
                                            'max_inter_iter',
                                            'blur_fwhm',
                                            'fac',
                                            'monkey']),
            name='AFNI_options')

        skullstrip_args = pe.Node(util.Function(input_names=['spat_norm',
                                                                'spat_norm_dxyz',
                                                                'mask_vol',
                                                                'shrink_fac',
                                                                'var_shrink_fac',
                                                                'shrink_fac_bot_lim',
                                                                'avoid_vent',
                                                                'niter',
                                                                'pushout',
                                                                'touchup',
                                                                'fill_hole',
                                                                'avoid_eyes',
                                                                'use_edge',
                                                                'exp_frac',
                                                                'smooth_final',
                                                                'push_to_edge',
                                                                'use_skull',
                                                                'perc_int',
                                                                'max_inter_iter',
                                                                'blur_fwhm',
                                                                'fac',
                                                                'monkey'],
                                                output_names=['expr'],
                                                function=create_3dskullstrip_arg_string),
                                    name='anat_skullstrip_args')
        
        inputnode_afni.inputs.set(
                mask_vol=config.skullstrip_mask_vol,
                shrink_factor=config.skullstrip_shrink_factor,
                var_shrink_fac=config.skullstrip_var_shrink_fac,
                shrink_fac_bot_lim=config.skullstrip_shrink_factor_bot_lim,
                avoid_vent=config.skullstrip_avoid_vent,
                niter=config.skullstrip_n_iterations,
                pushout=config.skullstrip_pushout,
                touchup=config.skullstrip_touchup,
                fill_hole=config.skullstrip_fill_hole,
                avoid_eyes=config.skullstrip_avoid_eyes,
                use_edge=config.skullstrip_use_edge,
                exp_frac=config.skullstrip_exp_frac,
                smooth_final=config.skullstrip_smooth_final,
                push_to_edge=config.skullstrip_push_to_edge,
                use_skull=config.skullstrip_use_skull,
                perc_int=config.skullstrip_perc_int,
                max_inter_iter=config.skullstrip_max_inter_iter,
                blur_fwhm=config.skullstrip_blur_fwhm,
                fac=config.skullstrip_fac,
                monkey=config.skullstrip_monkey,
            )

        preproc.connect([
            (inputnode_afni, skullstrip_args, [
                ('mask_vol', 'mask_vol'),
                ('shrink_factor', 'shrink_fac'),
                ('var_shrink_fac', 'var_shrink_fac'),
                ('shrink_fac_bot_lim', 'shrink_fac_bot_lim'),
                ('avoid_vent', 'avoid_vent'),
                ('niter', 'niter'),
                ('pushout', 'pushout'),
                ('touchup', 'touchup'),
                ('fill_hole', 'fill_hole'),
                ('avoid_eyes', 'avoid_eyes'),
                ('use_edge', 'use_edge'),
                ('exp_frac', 'exp_frac'),
                ('smooth_final', 'smooth_final'),
                ('push_to_edge', 'push_to_edge'),
                ('use_skull', 'use_skull'),
                ('perc_int', 'perc_int'),
                ('max_inter_iter', 'max_inter_iter'),
                ('blur_fwhm', 'blur_fwhm'),
                ('fac', 'fac'),
                ('monkey','monkey')
            ])
        ])

        anat_skullstrip = pe.Node(interface=afni.SkullStrip(),
                                    name='anat_skullstrip')

        anat_skullstrip.inputs.outputtype = 'NIFTI_GZ'

        preproc.connect(inputnode, 'anat_data',
                        anat_skullstrip, 'in_file')

        preproc.connect(skullstrip_args, 'expr',
                        anat_skullstrip, 'args')

        # Generate anatomical brain mask
        anat_brain_mask = pe.Node(interface=afni.Calc(),
                                        name='anat_brain_mask')

        anat_brain_mask.inputs.expr = 'step(a)'
        anat_brain_mask.inputs.outputtype = 'NIFTI_GZ'

        preproc.connect(anat_skullstrip, 'out_file',
                        anat_brain_mask, 'in_file_a')

        # Apply skull-stripping step mask to original volume
        anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(),
                                        name='anat_skullstrip_orig_vol')

        anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
        anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

        preproc.connect(inputnode, 'anat_data',
                        anat_skullstrip_orig_vol, 'in_file_a')

        preproc.connect(anat_brain_mask, 'out_file',
                        anat_skullstrip_orig_vol, 'in_file_b')

        preproc.connect(anat_brain_mask, 'out_file',
                        outputnode, 'brain_mask')

        preproc.connect(anat_skullstrip_orig_vol, 'out_file',
                        outputnode, 'brain')

    elif method == 'fsl':
        # Skull-stripping using FSL BET
        inputnode_bet = pe.Node(
            util.IdentityInterface(fields=['frac',
                                            'mask_boolean',
                                            'mesh_boolean',
                                            'outline',
                                            'padding',
                                            'radius',
                                            'reduce_bias',
                                            'remove_eyes',
                                            'robust',
                                            'skull',
                                            'surfaces',
                                            'threshold',
                                            'vertical_gradient']),
            name='BET_options')

        anat_skullstrip = pe.Node(
            interface=fsl.BET(), name='anat_skullstrip')
        anat_skullstrip.inputs.output_type = 'NIFTI_GZ'
        
        inputnode_bet.inputs.set(
                frac=config.bet_frac,
                mask_boolean=config.bet_mask_boolean,
                mesh_boolean=config.bet_mesh_boolean,
                outline=config.bet_outline,
                padding=config.bet_padding,
                radius=config.bet_radius,
                reduce_bias=config.bet_reduce_bias,
                remove_eyes=config.bet_remove_eyes,
                robust=config.bet_robust,
                skull=config.bet_skull,
                surfaces=config.bet_surfaces,
                threshold=config.bet_threshold,
                vertical_gradient=config.bet_vertical_gradient,
            )

        preproc.connect(inputnode, 'anat_data',
                        anat_skullstrip, 'in_file')

        preproc.connect([
            (inputnode_bet, anat_skullstrip, [
                ('frac', 'frac'),
                ('mask_boolean', 'mask'),
                ('mesh_boolean', 'mesh'),
                ('outline', 'outline'),
                ('padding', 'padding'),
                ('radius', 'radius'),
                ('reduce_bias', 'reduce_bias'),
                ('remove_eyes', 'remove_eyes'),
                ('robust', 'robust'),
                ('skull', 'skull'),
                ('surfaces', 'surfaces'),
                ('threshold', 'threshold'),
                ('vertical_gradient', 'vertical_gradient'),
            ])
        ])

        preproc.connect(anat_skullstrip, 'out_file',
                        outputnode, 'skullstrip')

        # Apply skull-stripping step mask to original volume
        anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(),
                                        name='anat_skullstrip_orig_vol')

        anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
        anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

        preproc.connect(inputnode, 'anat_data',
                        anat_skullstrip_orig_vol, 'in_file_a')

        preproc.connect(anat_skullstrip, 'out_file',
                        anat_skullstrip_orig_vol, 'in_file_b')

        preproc.connect(anat_skullstrip, 'mask_file',
                        outputnode, 'brain_mask')

        preproc.connect(anat_skullstrip_orig_vol, 'out_file',
                        outputnode, 'brain')

    elif method == 'niworkflows-ants': 
        # Skull-stripping using niworkflows-ants  
        anat_skullstrip_ants = init_brain_extraction_wf(tpl_target_path=config.niworkflows_ants_template_path,
                                                        tpl_mask_path=config.niworkflows_ants_mask_path,
                                                        tpl_regmask_path=config.niworkflows_ants_regmask_path,
                                                        name='anat_skullstrip_ants')

        preproc.connect(inputnode, 'anat_data',
                        anat_skullstrip_ants, 'inputnode.in_files')

        preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file',
                        outputnode, 'skullstrip')

        preproc.connect(anat_skullstrip_ants, 'copy_xform.out_file',
                        outputnode, 'brain')

        preproc.connect(anat_skullstrip_ants, 'atropos_wf.copy_xform.out_mask',
                        outputnode, 'brain_mask')

    elif method == 'mask':

        brain_mask_deoblique = pe.Node(interface=afni.Refit(),
                                name='brain_mask_deoblique')
        brain_mask_deoblique.inputs.deoblique = True
        preproc.connect(inputnode, 'brain_mask',
                        brain_mask_deoblique, 'in_file')

        brain_mask_reorient = pe.Node(interface=afni.Resample(),
                                name='brain_mask_reorient')
        brain_mask_reorient.inputs.orientation = 'RPI'
        brain_mask_reorient.inputs.outputtype = 'NIFTI_GZ'
        preproc.connect(brain_mask_deoblique, 'out_file',
                        brain_mask_reorient, 'in_file')


        anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(),
                                        name='anat_skullstrip_orig_vol')
        anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)'
        anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ'

        preproc.connect(inputnode, 'anat_data',
                        anat_skullstrip_orig_vol, 'in_file_a')

        preproc.connect(brain_mask_reorient, 'out_file',
                        anat_skullstrip_orig_vol, 'in_file_b')

        preproc.connect(brain_mask_reorient, 'out_file',
                        outputnode, 'brain_mask')

        preproc.connect(anat_skullstrip_orig_vol, 'out_file',
                        outputnode, 'brain')

    elif method == 'unet':
        """
        UNet
        options (following numbers are default):
        input_slice: 3
        conv_block: 5
        kernel_root: 16
        rescale_dim: 256
        """
        # TODO: add options to pipeline_config
        unet_check_for_s3 = create_check_for_s3_node('unet', config.unet_model)
        unet_mask = pe.Node(util.Function(input_names=['model_path', 'cimg_in'], 
                                            output_names=['out_path'],
                                            function=predict_volumes),                        
                            name='unet_mask')
        
        preproc.connect(unet_check_for_s3, 'local_path', unet_mask, 'model_path')
        preproc.connect(inputnode, 'anat_data', unet_mask, 'cimg_in')

        """
        Revised mask with ANTs
        """
        # fslmaths <whole head> -mul <mask> brain.nii.gz
        unet_masked_brain = pe.Node(interface=fsl.MultiImageMaths(), name='unet_masked_brain')
        unet_masked_brain.inputs.op_string = "-mul %s"
        preproc.connect(inputnode, 'anat_data', unet_masked_brain, 'in_file')
        preproc.connect(unet_mask, 'out_path', unet_masked_brain, 'operand_files')

        # flirt -v -dof 6 -in brain.nii.gz -ref NMT_SS_0.5mm.nii.gz -o brain_rot2atl -omat brain_rot2atl.mat -interp sinc
        # TODO: antsRegistration -z 0 -d 3 -r [NMT_SS_0.5mm.nii.gz,brain.nii.gz,0] -o [transform,brain_rot2atl.nii.gz,brain_inv_rot2atl.nii.gz] -t Rigid[0.1] -m MI[NMT_SS_0.5mm.nii.gz,brain.nii.gz,1,32,Regular,0.25] -c [1000x500x250x100,1e-08,10] -s 3.0x2.0x1.0x0.0 -f 8x4x2x1 -u 1 -t Affine[0.1] -m MI[NMT_SS_0.5mm.nii.gz,brain.nii.gz,1,32,Regular,0.25] -c [1000x500x250x100,1e-08,10] -s 3.0x2.0x1.0x0.0 -f 8x4x2x1 -u 1
        native_brain_to_template_brain = pe.Node(interface=fsl.FLIRT(), name='native_brain_to_template_brain')
        native_brain_to_template_brain.inputs.dof = 6
        native_brain_to_template_brain.inputs.interp = 'sinc'
        preproc.connect(unet_masked_brain, 'out_file', native_brain_to_template_brain, 'in_file')
        preproc.connect(inputnode, 'template_brain_only_for_anat', native_brain_to_template_brain, 'reference')
        
        # flirt -in head.nii.gz -ref NMT_0.5mm.nii.gz -o head_rot2atl -applyxfm -init brain_rot2atl.mat
        # TODO: antsApplyTransforms -d 3 -i head.nii.gz -r NMT_0.5mm.nii.gz -n Linear -o head_rot2atl.nii.gz -v -t transform1Rigid.mat -t transform2Affine.mat -t transform0DerivedInitialMovingTranslation.mat 
        native_head_to_template_head = pe.Node(interface=fsl.FLIRT(), name='native_head_to_template_head')
        native_head_to_template_head.inputs.apply_xfm = True
        preproc.connect(inputnode, 'anat_data', native_head_to_template_head, 'in_file')
        preproc.connect(native_brain_to_template_brain, 'out_matrix_file', native_head_to_template_head, 'in_matrix_file')
        preproc.connect(inputnode, 'template_skull_for_anat', native_head_to_template_head, 'reference')

        # fslmaths NMT_SS_0.5mm.nii.gz -bin templateMask.nii.gz
        template_brain_mask = pe.Node(interface=fsl.maths.MathsCommand(), name='template_brain_mask')
        template_brain_mask.inputs.args = '-bin'
        preproc.connect(inputnode, 'template_brain_only_for_anat', template_brain_mask, 'in_file')

        # ANTS 3 -m  CC[head_rot2atl.nii.gz,NMT_0.5mm.nii.gz,1,5] -t SyN[0.25] -r Gauss[3,0] -o atl2T1rot -i 60x50x20 --use-Histogram-Matching  --number-of-affine-iterations 10000x10000x10000x10000x10000 --MI-option 32x16000
        ants_template_head_to_template = pe.Node(interface=ants.Registration(), name='template_head_to_template')
        ants_template_head_to_template.inputs.metric = ['CC']
        ants_template_head_to_template.inputs.metric_weight = [1,5]
        ants_template_head_to_template.inputs.transforms = ['SyN']
        ants_template_head_to_template.inputs.transform_parameters = [(0.25,)]
        ants_template_head_to_template.inputs.interpolation = 'NearestNeighbor'
        ants_template_head_to_template.inputs.number_of_iterations = [[60,50,20]] 
        ants_template_head_to_template.inputs.smoothing_sigmas = [[0.6,0.2,0.0]]
        ants_template_head_to_template.inputs.shrink_factors = [[4,2,1]] 
        ants_template_head_to_template.inputs.convergence_threshold = [1.e-8]
        preproc.connect(native_head_to_template_head, 'out_file', ants_template_head_to_template, 'fixed_image')
        preproc.connect(inputnode, 'template_skull_for_anat', ants_template_head_to_template, 'moving_image')
        # antsApplyTransforms -d 3 -i templateMask.nii.gz -t atl2T1rotWarp.nii.gz atl2T1rotAffine.txt -r brain_rot2atl.nii.gz -o brain_rot2atl_mask.nii.gz
        template_head_transform_to_template = pe.Node(interface=ants.ApplyTransforms(), name='template_head_transform_to_template')
        template_head_transform_to_template.inputs.dimension = 3
        preproc.connect(template_brain_mask, 'out_file', template_head_transform_to_template, 'input_image')
        preproc.connect(native_brain_to_template_brain, 'out_file', template_head_transform_to_template, 'reference_image')
        preproc.connect(ants_template_head_to_template, 'forward_transforms', template_head_transform_to_template, 'transforms')

        # TODO: replace convert_xfm and flirt with: 
        # antsApplyTransforms -d 3 -i brain_rot2atl_mask.nii.gz -r brain.nii.gz -n linear -o brain_mask.nii.gz -t [transform0DerivedInitialMovingTranslation.mat,1] -t [transform2Affine.mat,1] -t [transform1Rigid.mat,1] 
        # convert_xfm -omat brain_rot2native.mat -inverse brain_rot2atl.mat 
        invt = pe.Node(interface=fsl.ConvertXFM(), name='convert_xfm')
        invt.inputs.invert_xfm = True
        preproc.connect(native_brain_to_template_brain, 'out_matrix_file', invt, 'in_file')

        # flirt -in brain_rot2atl_mask.nii.gz -ref brain.nii.gz -o brain_mask.nii.gz -applyxfm -init brain_rot2native.mat
        template_brain_to_native_brain = pe.Node(interface=fsl.FLIRT(), name='template_brain_to_native_brain')
        template_brain_to_native_brain.inputs.apply_xfm = True
        preproc.connect(template_head_transform_to_template, 'output_image', template_brain_to_native_brain, 'in_file')
        preproc.connect(unet_masked_brain, 'out_file', template_brain_to_native_brain, 'reference')
        preproc.connect(invt, 'out_file', template_brain_to_native_brain, 'in_matrix_file')

        # fslmaths brain_mask.nii.gz -thr .5 -bin brain_mask_thr.nii.gz
        refined_mask = pe.Node(interface=fsl.Threshold(), name='refined_mask')
        refined_mask.inputs.thresh = 0.5
        refined_mask.inputs.args = '-bin'
        preproc.connect(template_brain_to_native_brain, 'out_file', refined_mask, 'in_file')

        # get a new brain with mask
        refined_brain = pe.Node(interface=fsl.MultiImageMaths(), name='refined_brain')
        refined_brain.inputs.op_string = "-mul %s"
        preproc.connect(inputnode, 'anat_data', refined_brain, 'in_file')
        preproc.connect(refined_mask, 'out_file', refined_brain, 'operand_files')
        
        preproc.connect(refined_mask, 'out_file', outputnode, 'brain_mask')
        preproc.connect(refined_brain, 'out_file', outputnode, 'brain')

    return preproc
예제 #19
0
파일: functional.py 프로젝트: xwolfs/mriqc
def hmc_afni(name='fMRI_HMC_afni', st_correct=False, despike=False, deoblique=False):
    """A head motion correction (HMC) workflow for functional scans"""

    workflow = pe.Workflow(name=name)

    inputnode = pe.Node(niu.IdentityInterface(
        fields=['in_file', 'fd_radius', 'start_idx', 'stop_idx']), name='inputnode')

    outputnode = pe.Node(niu.IdentityInterface(
        fields=['out_file', 'out_fd']), name='outputnode')

    drop_trs = pe.Node(afni.Calc(expr='a', outputtype='NIFTI_GZ'),
                       name='drop_trs')

    reorient = pe.Node(afni.Resample(
        orientation='RPI', outputtype='NIFTI_GZ'), name='reorient')

    get_mean_RPI = pe.Node(afni.TStat(
        options='-mean', outputtype='NIFTI_GZ'), name='get_mean_RPI')

    # calculate hmc parameters
    hmc = pe.Node(
        afni.Volreg(args='-Fourier -twopass', zpad=4, outputtype='NIFTI_GZ'),
        name='motion_correct')

    get_mean_motion = get_mean_RPI.clone('get_mean_motion')
    hmc_A = hmc.clone('motion_correct_A')
    hmc_A.inputs.md1d_file = 'max_displacement.1D'

    # Compute the frame-wise displacement
    calc_fd = pe.Node(niu.Function(
        function=fd_jenkinson, input_names=['in_file', 'rmax'],
        output_names=['out_fd']), name='calc_fd')

    workflow.connect([
        (inputnode, drop_trs, [('in_file', 'in_file_a'),
                               ('start_idx', 'start_idx'),
                               ('stop_idx', 'stop_idx')]),
        (inputnode, calc_fd, [('fd_radius', 'rmax')]),
        (reorient, get_mean_RPI, [('out_file', 'in_file')]),
        (reorient, hmc, [('out_file', 'in_file')]),
        (get_mean_RPI, hmc, [('out_file', 'basefile')]),
        (hmc, get_mean_motion, [('out_file', 'in_file')]),
        (reorient, hmc_A, [('out_file', 'in_file')]),
        (get_mean_motion, hmc_A, [('out_file', 'basefile')]),
        (hmc_A, outputnode, [('out_file', 'out_file')]),
        (hmc_A, calc_fd, [('oned_matrix_save', 'in_file')]),
        (calc_fd, outputnode, [('out_fd', 'out_fd')]),
    ])

    # Slice timing correction, despiking, and deoblique

    st_corr = pe.Node(afni.TShift(outputtype='NIFTI_GZ'), name='TimeShifts')

    deoblique_node = pe.Node(afni.Refit(deoblique=True), name='deoblique')

    despike_node = pe.Node(afni.Despike(outputtype='NIFTI_GZ'), name='despike')

    if st_correct and despike and deoblique:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, despike_node, [('out_file', 'in_file')]),
            (despike_node, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, reorient, [('out_file', 'in_file')])
        ])

    elif st_correct and despike:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, despike_node, [('out_file', 'in_file')]),
            (despike_node, reorient, [('out_file', 'in_file')]),
        ])

    elif st_correct and deoblique:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, reorient, [('out_file', 'in_file')])
        ])

    elif st_correct:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, reorient, [('out_file', 'in_file')])
        ])

    elif despike and deoblique:

        workflow.connect([
            (drop_trs, despike_node, [('out_file', 'in_file')]),
            (despike_node, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, reorient, [('out_file', 'in_file')])
        ])

    elif despike:

        workflow.connect([
            (drop_trs, despike_node, [('out_file', 'in_file')]),
            (despike_node, reorient, [('out_file', 'in_file')]),
        ])

    elif deoblique:

        workflow.connect([
            (drop_trs, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, reorient, [('out_file', 'in_file')])
        ])

    else:

        workflow.connect([
            (drop_trs, reorient, [('out_file', 'in_file')]),
        ])

    return workflow
예제 #20
0
def create_nii_to_mesh_fs_pipe(params, name="nii_to_mesh_fs_pipe"):
    """
    Description: surface generation using freesurfer tools

    Params:

    - fill_wm (see `MRIFill <https://nipype.readthedocs.io/en/0.12.1/\
    interfaces/generated/nipype.interfaces.freesurfer.utils.html#mrifill>`_) \
    - also available as :ref:`indiv_params <indiv_params>`


    Inputs:

        inputnode:

            wm_mask_file:
                segmented white matter mask (binary) in template space

            reg_brain_file:
                preprocessd T1, registered to template

            indiv_params (opt):
                dict with individuals parameters for some nodes

        arguments:

            params:
                dictionary of node sub-parameters (from a json file)

            name:
                pipeline name (default = "nii_to_mesh_fs_pipe")

    Outputs:

    """
    # creating pipeline
    nii_to_mesh_fs_pipe = pe.Workflow(name=name)

    # creating inputnode
    inputnode = pe.Node(niu.IdentityInterface(
        fields=['wm_mask_file', 'reg_brain_file', 'indiv_params']),
                        name='inputnode')

    # bin_wm
    bin_wm = pe.Node(interface=fsl.UnaryMaths(), name="bin_wm")
    bin_wm.inputs.operation = "fillh"

    nii_to_mesh_fs_pipe.connect(inputnode, 'wm_mask_file', bin_wm, 'in_file')

    # resample everything
    refit_wm = pe.Node(interface=afni.Refit(), name="refit_wm")
    refit_wm.inputs.args = "-xdel 1.0 -ydel 1.0 -zdel 1.0 -keepcen"

    nii_to_mesh_fs_pipe.connect(bin_wm, 'out_file', refit_wm, 'in_file')

    # resample everything
    refit_reg = pe.Node(interface=afni.Refit(), name="refit_reg")
    refit_reg.inputs.args = "-xdel 1.0 -ydel 1.0 -zdel 1.0 -keepcen"

    nii_to_mesh_fs_pipe.connect(inputnode, 'reg_brain_file', refit_reg,
                                'in_file')

    # mri_convert wm to freesurfer mgz
    convert_wm = pe.Node(interface=fs.MRIConvert(), name="convert_wm")
    convert_wm.inputs.out_type = "mgz"
    convert_wm.inputs.conform = True

    nii_to_mesh_fs_pipe.connect(refit_wm, 'out_file', convert_wm, 'in_file')

    # mri_convert reg to freesurfer mgz
    convert_reg = pe.Node(interface=fs.MRIConvert(), name="convert_reg")
    convert_reg.inputs.out_type = "mgz"
    convert_reg.inputs.conform = True

    nii_to_mesh_fs_pipe.connect(refit_reg, 'out_file', convert_reg, 'in_file')

    # mri_fill
    fill_wm = NodeParams(interface=fs.MRIFill(),
                         params=parse_key(params, "fill_wm"),
                         name="fill_wm")

    fill_wm.inputs.out_file = "filled.mgz"

    nii_to_mesh_fs_pipe.connect(convert_wm, 'out_file', fill_wm, 'in_file')

    nii_to_mesh_fs_pipe.connect(inputnode,
                                ("indiv_params", parse_key, "fill_wm"),
                                fill_wm, 'indiv_params')

    # pretesselate wm
    pretess_wm = pe.Node(interface=fs.MRIPretess(), name="pretess_wm")
    pretess_wm.inputs.label = 255

    nii_to_mesh_fs_pipe.connect(fill_wm, 'out_file', pretess_wm, 'in_filled')

    nii_to_mesh_fs_pipe.connect(convert_reg, 'out_file', pretess_wm, 'in_norm')

    # tesselate wm lh
    tess_wm_lh = pe.Node(interface=fs.MRITessellate(), name="tess_wm_lh")
    tess_wm_lh.inputs.label_value = 255
    tess_wm_lh.inputs.out_file = "lh_tess"

    nii_to_mesh_fs_pipe.connect(pretess_wm, 'out_file', tess_wm_lh, 'in_file')

    # tesselate wm rh
    tess_wm_rh = pe.Node(interface=fs.MRITessellate(), name="tess_wm_rh")
    tess_wm_rh.inputs.label_value = 127
    tess_wm_rh.inputs.out_file = "rh_tess"

    nii_to_mesh_fs_pipe.connect(pretess_wm, 'out_file', tess_wm_rh, 'in_file')

    # ExtractMainComponent lh
    extract_mc_lh = pe.Node(interface=fs.ExtractMainComponent(),
                            name="extract_mc_lh")

    nii_to_mesh_fs_pipe.connect(tess_wm_lh, 'surface', extract_mc_lh,
                                'in_file')

    extract_mc_lh.inputs.out_file = "lh.lh_tess.maincmp"

    # ExtractMainComponent rh
    extract_mc_rh = pe.Node(interface=fs.ExtractMainComponent(),
                            name="extract_mc_rh")

    nii_to_mesh_fs_pipe.connect(tess_wm_rh, 'surface', extract_mc_rh,
                                'in_file')

    extract_mc_rh.inputs.out_file = "rh.rh_tess.maincmp"

    # SmoothTessellation lh
    smooth_tess_lh = pe.Node(interface=fs.SmoothTessellation(),
                             name="smooth_tess_lh")
    smooth_tess_lh.inputs.disable_estimates = True

    nii_to_mesh_fs_pipe.connect(extract_mc_lh, 'out_file', smooth_tess_lh,
                                'in_file')

    # SmoothTessellation rh
    smooth_tess_rh = pe.Node(interface=fs.SmoothTessellation(),
                             name="smooth_tess_rh")
    smooth_tess_rh.inputs.disable_estimates = True

    nii_to_mesh_fs_pipe.connect(extract_mc_rh, 'out_file', smooth_tess_rh,
                                'in_file')

    return nii_to_mesh_fs_pipe
예제 #21
0
def create_anat_preproc(method='afni', already_skullstripped=False,
                        config=None, acpc_target='whole-head', wf_name='anat_preproc'):
    """The main purpose of this workflow is to process T1 scans. Raw mprage
    file is deobliqued, reoriented into RPI and skullstripped. Also, a whole
    brain only mask is generated from the skull stripped image for later use
    in registration.

    Returns
    -------
    anat_preproc : workflow
        Anatomical Preprocessing Workflow

    Notes
    -----
    `Source <https://github.com/FCP-INDI/C-PAC/blob/master/CPAC/anat_preproc/anat_preproc.py>`_

    Workflow Inputs::
        inputspec.anat : string
            User input anatomical (T1) Image, in any of the 8 orientations

    Workflow Outputs::

        outputspec.refit : string
            Path to deobliqued anatomical image

        outputspec.reorient : string
            Path to RPI oriented anatomical image

        outputspec.skullstrip : string
            Path to skull stripped RPI oriented mprage file with normalized
            intensities.

        outputspec.brain : string
            Path to skull stripped RPI brain image with original intensity
            values and not normalized or scaled.

    Order of commands:
    - Deobliqing the scans. ::
        3drefit -deoblique mprage.nii.gz

    - Re-orienting the Image into Right-to-Left Posterior-to-Anterior
      Inferior-to-Superior  (RPI) orientation ::
        3dresample -orient RPI
                   -prefix mprage_RPI.nii.gz
                   -inset mprage.nii.gz

    - Skull-Stripping the image ::
        Using AFNI ::
            3dSkullStrip -input mprage_RPI.nii.gz
                         -o_ply mprage_RPI_3dT.nii.gz
        or using BET ::
            bet mprage_RPI.nii.gz

    - The skull-stripping step modifies the intensity values. To get back the
      original intensity values, we do an element wise product of RPI data
      with step function of skull-stripped data ::
        3dcalc -a mprage_RPI.nii.gz
               -b mprage_RPI_3dT.nii.gz
               -expr 'a*step(b)'
               -prefix mprage_RPI_3dc.nii.gz

    High Level Workflow Graph:
    .. image:: ../images/anatpreproc_graph.dot.png
       :width: 500

    Detailed Workflow Graph:
    .. image:: ../images/anatpreproc_graph_detailed.dot.png
       :width: 500

    Examples
    --------
    >>> from CPAC.anat_preproc import create_anat_preproc
    >>> preproc = create_anat_preproc()
    >>> preproc.inputs.inputspec.anat = 'sub1/anat/mprage.nii.gz'
    >>> preproc.run() #doctest: +SKIP
    """

    preproc = pe.Workflow(name=wf_name)

    inputnode = pe.Node(util.IdentityInterface(fields=['anat', 
                                                       'brain_mask',
                                                       'template_brain_only_for_anat',
                                                       'template_skull_for_anat',
                                                       'template_brain_only_for_acpc',
                                                       'template_skull_for_acpc',
                                                       'template_cmass']), 
                        name='inputspec')

    outputnode = pe.Node(util.IdentityInterface(fields=['refit',
                                                        'reorient',
                                                        'skullstrip',
                                                        'brain',
                                                        'brain_mask',
                                                        'anat_skull_leaf',
                                                        'center_of_mass']),
                        name='outputspec')

    anat_deoblique = pe.Node(interface=afni.Refit(),
                             name='anat_deoblique')
    anat_deoblique.inputs.deoblique = True

    preproc.connect(inputnode, 'anat', anat_deoblique, 'in_file')
    preproc.connect(anat_deoblique, 'out_file', outputnode, 'refit')

    # Anatomical reorientation
    anat_reorient = pe.Node(interface=afni.Resample(),
                            name='anat_reorient')
    anat_reorient.inputs.orientation = 'RPI'
    anat_reorient.inputs.outputtype = 'NIFTI_GZ'

    preproc.connect(anat_deoblique, 'out_file', anat_reorient, 'in_file')
    preproc.connect(anat_reorient, 'out_file', outputnode, 'reorient')

    anat_leaf = pe.Node(util.IdentityInterface(fields=['anat_data']),
                        name='anat_leaf')

    if not config.acpc_align:
        preproc.connect(anat_reorient, 'out_file', anat_leaf, 'anat_data')

    # ACPC alignment     
    if config.acpc_align:
        acpc_align = acpc_alignment(skullstrip_tool=method, config=config, acpc_target=acpc_target, wf_name='acpc_align')

        preproc.connect(anat_reorient, 'out_file', acpc_align, 'inputspec.anat_leaf')
        preproc.connect(inputnode, 'brain_mask', acpc_align, 'inputspec.brain_mask')
        preproc.connect(inputnode, 'template_brain_only_for_acpc', acpc_align, 'inputspec.template_brain_for_acpc')
        preproc.connect(inputnode, 'template_skull_for_acpc', acpc_align, 'inputspec.template_head_for_acpc')
        preproc.connect(acpc_align, 'outputspec.acpc_aligned_head', anat_leaf, 'anat_data')
        if method == 'unet':
            preproc.connect(inputnode, 'template_brain_only_for_anat', acpc_align, 'inputspec.template_brain_only_for_anat')
            preproc.connect(inputnode, 'template_skull_for_anat', acpc_align, 'inputspec.template_skull_for_anat')
    # Disable non_local_means_filtering and n4_bias_field_correction when run niworkflows-ants
    if method == 'niworkflows-ants':
        config.non_local_means_filtering = False
        config.n4_bias_field_correction = False
        
    if config.non_local_means_filtering and config.n4_bias_field_correction:
        denoise = pe.Node(interface = ants.DenoiseImage(), name = 'anat_denoise')
        preproc.connect(anat_leaf, 'anat_data', denoise, 'input_image')

        n4 = pe.Node(interface = ants.N4BiasFieldCorrection(dimension=3, shrink_factor=2, copy_header=True),
            name='anat_n4')
        preproc.connect(denoise, 'output_image', n4, 'input_image')

    elif config.non_local_means_filtering and not config.n4_bias_field_correction:
        denoise = pe.Node(interface = ants.DenoiseImage(), name = 'anat_denoise')
        preproc.connect(anat_leaf, 'anat_data', denoise, 'input_image')

    elif not config.non_local_means_filtering and config.n4_bias_field_correction:
        n4 = pe.Node(interface = ants.N4BiasFieldCorrection(dimension=3, shrink_factor=2, copy_header=True),
            name='anat_n4')
        preproc.connect(anat_leaf, 'anat_data', n4, 'input_image')

    anat_leaf2 = pe.Node(util.IdentityInterface(fields=['anat_data']),
                         name='anat_leaf2')
    
    if config.n4_bias_field_correction:
        preproc.connect(n4, 'output_image', anat_leaf2, 'anat_data')
    elif config.non_local_means_filtering and not config.n4_bias_field_correction:
        preproc.connect(denoise, 'output_image', anat_leaf2, 'anat_data')
    else:
        preproc.connect(anat_leaf, 'anat_data', anat_leaf2, 'anat_data')

    if already_skullstripped:
        anat_skullstrip = pe.Node(interface=util.IdentityInterface(fields=['out_file']),
                                    name='anat_skullstrip')

        preproc.connect(anat_leaf2, 'anat_data',
                        anat_skullstrip, 'out_file')

        preproc.connect(anat_skullstrip, 'out_file',
                        outputnode, 'skullstrip')
        
        # binarize skullstripped brain to get brain mask
        brain_mask = pe.Node(interface=fsl.maths.MathsCommand(), name='brain_mask')
        brain_mask.inputs.args = '-bin'

        preproc.connect(anat_skullstrip, 'out_file',
                        brain_mask, 'in_file')

        preproc.connect(brain_mask, 'out_file',
                        outputnode, 'brain_mask')

        preproc.connect(anat_skullstrip, 'out_file',
                        outputnode, 'brain')

    else:

        anat_skullstrip = skullstrip_anatomical(method=method, config=config, 
                                                wf_name="{0}_skullstrip".format(wf_name))
        preproc.connect(anat_leaf2, 'anat_data',
                        anat_skullstrip, 'inputspec.anat_data')
        preproc.connect(inputnode, 'template_brain_only_for_anat',
                        anat_skullstrip, 'inputspec.template_brain_only_for_anat') 
        preproc.connect(inputnode, 'template_skull_for_anat', 
                        anat_skullstrip, 'inputspec.template_skull_for_anat')
            
        if method == 'mask' and config.acpc_align:
            preproc.connect(acpc_align, 'outputspec.acpc_brain_mask', 
                            anat_skullstrip, 'inputspec.brain_mask') 
        else:             
            preproc.connect(inputnode, 'brain_mask',
                            anat_skullstrip, 'inputspec.brain_mask') 
        preproc.connect(anat_skullstrip, 'outputspec.brain_mask',
                        outputnode, 'brain_mask')
        preproc.connect(anat_skullstrip, 'outputspec.brain', 
                        outputnode, 'brain')
    
    preproc.connect(anat_leaf2, 'anat_data', outputnode, 'anat_skull_leaf')

    return preproc
예제 #22
0
def hmc_afni(name='fMRI_HMC_afni',
             st_correct=False,
             despike=False,
             deoblique=False,
             start_idx=None,
             stop_idx=None):
    """
    A :abbr:`HMC (head motion correction)` workflow for
    functional scans

    .. workflow::

      from mriqc.workflows.functional import hmc_afni
      wf = hmc_afni()

    """

    workflow = pe.Workflow(name=name)

    inputnode = pe.Node(niu.IdentityInterface(
        fields=['in_file', 'fd_radius', 'start_idx', 'stop_idx']),
                        name='inputnode')

    outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'out_fd']),
                         name='outputnode')

    if (start_idx is not None) or (stop_idx is not None):
        drop_trs = pe.Node(afni.Calc(expr='a', outputtype='NIFTI_GZ'),
                           name='drop_trs')
        workflow.connect([
            (inputnode, drop_trs, [('in_file', 'in_file_a'),
                                   ('start_idx', 'start_idx'),
                                   ('stop_idx', 'stop_idx')]),
        ])
    else:
        drop_trs = pe.Node(niu.IdentityInterface(fields=['out_file']),
                           name='drop_trs')
        workflow.connect([
            (inputnode, drop_trs, [('in_file', 'out_file')]),
        ])

    get_mean_RPI = pe.Node(afni.TStat(options='-mean', outputtype='NIFTI_GZ'),
                           name='get_mean_RPI')

    # calculate hmc parameters
    hmc = pe.Node(afni.Volreg(args='-Fourier -twopass',
                              zpad=4,
                              outputtype='NIFTI_GZ'),
                  name='motion_correct')

    get_mean_motion = get_mean_RPI.clone('get_mean_motion')
    hmc_A = hmc.clone('motion_correct_A')
    hmc_A.inputs.md1d_file = 'max_displacement.1D'

    # Compute the frame-wise displacement
    fdnode = pe.Node(nac.FramewiseDisplacement(normalize=False,
                                               parameter_source="AFNI"),
                     name='ComputeFD')

    workflow.connect([
        (inputnode, fdnode, [('fd_radius', 'radius')]),
        (get_mean_RPI, hmc, [('out_file', 'basefile')]),
        (hmc, get_mean_motion, [('out_file', 'in_file')]),
        (get_mean_motion, hmc_A, [('out_file', 'basefile')]),
        (hmc_A, outputnode, [('out_file', 'out_file')]),
        (hmc_A, fdnode, [('oned_file', 'in_file')]),
        (fdnode, outputnode, [('out_file', 'out_fd')]),
    ])

    # Slice timing correction, despiking, and deoblique

    st_corr = pe.Node(afni.TShift(outputtype='NIFTI_GZ'), name='TimeShifts')

    deoblique_node = pe.Node(afni.Refit(deoblique=True), name='deoblique')

    despike_node = pe.Node(afni.Despike(outputtype='NIFTI_GZ'), name='despike')

    if st_correct and despike and deoblique:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, despike_node, [('out_file', 'in_file')]),
            (despike_node, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, get_mean_RPI, [('out_file', 'in_file')]),
            (deoblique_node, hmc, [('out_file', 'in_file')]),
            (deoblique_node, hmc_A, [('out_file', 'in_file')]),
        ])

    elif st_correct and despike:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, despike_node, [('out_file', 'in_file')]),
            (despike_node, get_mean_RPI, [('out_file', 'in_file')]),
            (despike_node, hmc, [('out_file', 'in_file')]),
            (despike_node, hmc_A, [('out_file', 'in_file')]),
        ])

    elif st_correct and deoblique:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, get_mean_RPI, [('out_file', 'in_file')]),
            (deoblique_node, hmc, [('out_file', 'in_file')]),
            (deoblique_node, hmc_A, [('out_file', 'in_file')]),
        ])

    elif st_correct:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, get_mean_RPI, [('out_file', 'in_file')]),
            (st_corr, hmc, [('out_file', 'in_file')]),
            (st_corr, hmc_A, [('out_file', 'in_file')]),
        ])

    elif despike and deoblique:

        workflow.connect([
            (drop_trs, despike_node, [('out_file', 'in_file')]),
            (despike_node, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, get_mean_RPI, [('out_file', 'in_file')]),
            (deoblique_node, hmc, [('out_file', 'in_file')]),
            (deoblique_node, hmc_A, [('out_file', 'in_file')]),
        ])

    elif despike:

        workflow.connect([
            (drop_trs, despike_node, [('out_file', 'in_file')]),
            (despike_node, get_mean_RPI, [('out_file', 'in_file')]),
            (despike_node, hmc, [('out_file', 'in_file')]),
            (despike_node, hmc_A, [('out_file', 'in_file')]),
        ])

    elif deoblique:

        workflow.connect([
            (drop_trs, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, get_mean_RPI, [('out_file', 'in_file')]),
            (deoblique_node, hmc, [('out_file', 'in_file')]),
            (deoblique_node, hmc_A, [('out_file', 'in_file')]),
        ])

    else:

        workflow.connect([
            (drop_trs, get_mean_RPI, [('out_file', 'in_file')]),
            (drop_trs, hmc, [('out_file', 'in_file')]),
            (drop_trs, hmc_A, [('out_file', 'in_file')]),
        ])

    return workflow
예제 #23
0
def create_register_NMT_pipe(params_template, params={},
                             name="register_NMT_pipe", NMT_version="v1.3"):
    """Description: Register template to anat with the script NMT_subject_align

    Processing steps:

    - Bias correction (norm_intensity)
    - Deoblique (Refit with deoblique option)
    - NMT_subject_align (see :class:`NMTSubjectAlign \
    <macapype.nodes.register.NMTSubjectAlign>` and :class:`NMTSubjectAlign2 \
    <macapype.nodes.register.NMTSubjectAlign2>` for explanations)
    - apply it to tissues list_priors (NwarpApplyPriors and Allineate)

    Params:
        - norm_intensity (see `N4BiasFieldCorrection <https://\
        nipype.readthedocs.io/en/0.12.1/interfaces/generated/nipype.interfaces\
        .ants.segmentation.html#n4biasfieldcorrection>`_ for arguments)) - \
        also available as :ref:`indiv_params <indiv_params>`
        - NMT_version (default = 1.2; 1.3 is also accepted)

    Inputs:

        inputnode:

            T1:
                T1 file name

            indiv_params:
                dict with individuals parameters for some nodes

        arguments:

            params_template:
                dictionary of info about template

            params:
                dictionary of node sub-parameters (from a json file)

            name:
                pipeline name (default = "register_NMT_pipe")

            NMT_version:
                NMT version (default = 1.2); can be overwritten in params json

    Outputs:

        norm_intensity.output_image:
            filled mask after erode

        align_seg_csf.out_file:
            csf template tissue in subject space

        align_seg_gm.out_file:
            grey matter template tissue in subject space

        align_seg_wm.out_file:
            white matter template tissue in subject space
    """

    register_NMT_pipe = pe.Workflow(name=name)

    # creating inputnode
    inputnode = pe.Node(
        niu.IdentityInterface(fields=['T1', 'indiv_params']),
        name='inputnode')

    if "NMT_version" in params.keys():
        NMT_version = params['NMT_version']

        print("*** Overriding NMT_version with parmas {}".format(
            params['NMT_version']))

    # N4 intensity normalization over brain
    norm_intensity = NodeParams(ants.N4BiasFieldCorrection(),
                                params=parse_key(params, "norm_intensity"),
                                name='norm_intensity')

    register_NMT_pipe.connect(inputnode, 'T1',
                              norm_intensity, "input_image")

    register_NMT_pipe.connect(
        inputnode, ('indiv_params', parse_key, "norm_intensity"),
        norm_intensity, "indiv_params")

    deoblique = pe.Node(afni.Refit(deoblique=True), name="deoblique")
    register_NMT_pipe.connect(norm_intensity, 'output_image',
                              deoblique, "in_file")

    print("*** Found NMT_version {}".format(NMT_version))

    if NMT_version == "v1.2":
        # align subj to nmt
        NMT_subject_align = NodeParams(
            NMTSubjectAlign(), params=parse_key(params, "NMT_subject_align"),
            name='NMT_subject_align')

    elif NMT_version == "v1.3" or NMT_version == "v2.0":
        # align subj to nmt
        NMT_subject_align = NodeParams(
            NMTSubjectAlign2(), params=parse_key(params, "NMT_subject_align"),
            name='NMT_subject_align')

    else:
        print("NMT_version {} is not implemented".format(NMT_version))
        exit()

    NMT_subject_align.inputs.NMT_SS_file = params_template["template_brain"]

    register_NMT_pipe.connect(deoblique, 'out_file',
                              NMT_subject_align, "T1_file")

    if NMT_version.split(".")[0] == "v1":

        # align_masks
        # "overwrap" of NwarpApply, with specifying the outputs as wished
        list_priors = [params_template["template_head"],
                       params_template["template_csf"],
                       params_template["template_gm"],
                       params_template["template_wm"]]

    elif NMT_version.split(".")[0] == "v2":

        # align_masks
        # "overwrap" of NwarpApply, with specifying the outputs as wished
        list_priors = [params_template["template_head"],
                       params_template["template_seg"]]

    align_masks = pe.Node(NwarpApplyPriors(), name='align_masks')
    align_masks.inputs.in_file = list_priors
    align_masks.inputs.out_file = list_priors
    align_masks.inputs.interp = "NN"
    align_masks.inputs.args = "-overwrite"

    register_NMT_pipe.connect(NMT_subject_align, 'aff_file',
                              align_masks, 'master')
    register_NMT_pipe.connect(NMT_subject_align, 'warpinv_file',
                              align_masks, "warp")

    # align_NMT
    align_NMT = pe.Node(
        afni.Allineate(), name="align_NMT", iterfield=['in_file'])
    align_NMT.inputs.final_interpolation = "nearestneighbour"
    align_NMT.inputs.overwrite = True
    align_NMT.inputs.outputtype = "NIFTI_GZ"

    register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 0),
                              align_NMT, "in_file")  # -source
    register_NMT_pipe.connect(norm_intensity, 'output_image',
                              align_NMT, "reference")  # -base
    register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                              align_NMT, "in_matrix")  # -1Dmatrix_apply

    if NMT_version.split(".")[0] == "v1":

        # seg_csf
        align_seg_csf = pe.Node(
            afni.Allineate(), name="align_seg_csf", iterfield=['in_file'])
        align_seg_csf.inputs.final_interpolation = "nearestneighbour"
        align_seg_csf.inputs.overwrite = True
        align_seg_csf.inputs.outputtype = "NIFTI_GZ"

        register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 1),
                                  align_seg_csf, "in_file")  # -source
        register_NMT_pipe.connect(norm_intensity, 'output_image',
                                  align_seg_csf, "reference")  # -base
        register_NMT_pipe.connect(
            NMT_subject_align, 'inv_transfo_file', align_seg_csf,
            "in_matrix")  # -1Dmatrix_apply

        # seg_gm
        align_seg_gm = pe.Node(
            afni.Allineate(), name="align_seg_gm", iterfield=['in_file'])
        align_seg_gm.inputs.final_interpolation = "nearestneighbour"
        align_seg_gm.inputs.overwrite = True
        align_seg_gm.inputs.outputtype = "NIFTI_GZ"

        register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 2),
                                  align_seg_gm, "in_file")  # -source
        register_NMT_pipe.connect(norm_intensity, 'output_image',
                                  align_seg_gm, "reference")  # -base
        register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                                  align_seg_gm, "in_matrix")  # -1Dmatrix_apply

        # seg_wm
        align_seg_wm = pe.Node(afni.Allineate(), name="align_seg_wm",
                               iterfield=['in_file'])
        align_seg_wm.inputs.final_interpolation = "nearestneighbour"
        align_seg_wm.inputs.overwrite = True
        align_seg_wm.inputs.outputtype = "NIFTI_GZ"

        register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 3),
                                  align_seg_wm, "in_file")  # -source
        register_NMT_pipe.connect(norm_intensity, 'output_image',
                                  align_seg_wm, "reference")  # -base
        register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                                  align_seg_wm, "in_matrix")  # -1Dmatrix_apply

    elif NMT_version.split(".")[0] == "v2":

        # seg
        align_seg = pe.Node(
            afni.Allineate(), name="align_seg", iterfield=['in_file'])
        align_seg.inputs.final_interpolation = "nearestneighbour"
        align_seg.inputs.overwrite = True
        align_seg.inputs.outputtype = "NIFTI_GZ"

        register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 1),
                                  align_seg, "in_file")  # -source
        register_NMT_pipe.connect(norm_intensity, 'output_image',
                                  align_seg, "reference")  # -base
        register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                                  align_seg, "in_matrix")  # -1Dmatrix_apply

    return register_NMT_pipe
예제 #24
0
    def __init__(self, experiment_dir, output_dir, func_source, struct_source,
                 datasink):
        self.experiment_dir = experiment_dir
        self.output_dir = output_dir

        # specify input and output nodes
        self.func_source = func_source
        self.struct_source = struct_source
        self.datasink = datasink

        # specify nodes
        # structual process
        self.refit_struct = pe.Node(interface=afni.Refit(),
                                    name='de_oblique_struct')
        self.refit_struct.inputs.deoblique = True

        self.resample_struct = pe.Node(interface=afni.Resample(),
                                       name='re_orientation_struct')
        self.resample_struct.inputs.orientation = 'RPI'
        self.resample_struct.inputs.outputtype = "NIFTI"

        self.bet_struct = pe.Node(interface=fsl.BET(),
                                  name='non_brain_removal_BET_struct')
        self.bet_struct.inputs.output_type = "NIFTI"

        # functional process
        self.refit_func = pe.Node(interface=afni.Refit(),
                                  name='de_oblique_func')
        self.refit_func.inputs.deoblique = True

        self.resample_func = pe.Node(interface=afni.Resample(),
                                     name='re_orientation_func')
        self.resample_func.inputs.orientation = 'RPI'
        self.resample_func.inputs.outputtype = "NIFTI"

        self.slice_timer = pe.Node(interface=fsl.SliceTimer(),
                                   name='time_slice_correction')

        self.mcflirt = pe.Node(interface=fsl.MCFLIRT(),
                               name='motion_correction')
        self.mcflirt.inputs.output_type = "NIFTI"
        self.mcflirt.inputs.mean_vol = True

        self.fslsplit = pe.Node(interface=fsl.Split(), name='fslsplit')
        self.fslsplit.inputs.dimension = 't'
        self.fslsplit.inputs.output_type = "NIFTI"

        self.fslmerge = pe.Node(interface=fsl.Merge(), name='fslmerge')
        self.fslmerge.inputs.dimension = 't'
        self.fslmerge.inputs.output_type = "NIFTI"

        self.bet_mean = pe.Node(interface=fsl.BET(),
                                name='non_brain_removal_BET_mean')
        self.bet_mean.inputs.output_type = "NIFTI"

        # helper function(s)
        def bet_each(in_files):
            '''
            @param in_files: list of image files
            @return out_files: list of image files after applied fsl.BET on it
            '''
            from nipype.interfaces import fsl
            import nipype.pipeline.engine as pe

            out_files = list()
            step_no = 0
            for file_ in in_files:
                bet = pe.Node(interface=fsl.BET(),
                              name='BET_for_step_{}'.format(step_no))
                bet.inputs.in_file = file_
                bet.inputs.out_file = file_[:len(file_) - 4] + '_bet.nii'
                bet.inputs.output_type = "NIFTI"

                bet.run()
                out_files.append(bet.inputs.out_file)

                step_no += 1
            return out_files

        # bet_func return a list of NIFITI files
        self.bet_func = pe.Node(interface=Function(input_names=['in_files'],
                                                   output_names=['out_files'],
                                                   function=bet_each),
                                name='non_brain_removal_BET_func')

        self.coregister = pe.Node(interface=spm.Coregister(),
                                  name="coregister")
        self.coregister.inputs.jobtype = 'estimate'

        self.segment = pe.Node(interface=spm.Segment(), name="segment")
        self.segment.inputs.affine_regularization = 'mni'

        self.normalize = pe.Node(interface=spm.Normalize(), name="normalize")
        self.normalize.inputs.jobtype = "write"

        # self.fourier = pe.Node(interface=afni.Fourier(), name='temporal_filtering')
        # self.fourier.inputs.highpass = 0.01
        # self.fourier.inputs.lowpass = 0.1

        self.smooth = pe.Node(interface=spm.Smooth(), name="smooth")
        self.smooth.inputs.fwhm = [8, 8, 8]

        # specify workflow instance
        self.workflow = pe.Workflow(name='FuNP_workflow')

        # connect nodes
        self.workflow.connect([
            (self.struct_source, self.refit_struct, [('outfiles', 'in_file')]),
            (self.refit_struct, self.resample_struct, [('out_file', 'in_file')
                                                       ]),
            (self.resample_struct, self.bet_struct, [('out_file', 'in_file')]),
            # (self.func_source, self.refit_func, [('outfiles', 'in_file')]),
            # (self.refit_func, self.resample_func, [('out_file', 'in_file')]),
            # (self.resample_func, self.slice_timer, [('out_file', 'in_file')]),
            (self.func_source, self.slice_timer, [('outfiles', 'in_file')]),
            (self.slice_timer, self.mcflirt, [('slice_time_corrected_file',
                                               'in_file')]),
            (self.mcflirt, self.bet_mean, [('mean_img', 'in_file')]),
            (self.mcflirt, self.fslsplit, [('out_file', 'in_file')]),
            (self.fslsplit, self.bet_func, [('out_files', 'in_files')]),
            (self.bet_func, self.fslmerge, [('out_files', 'in_files')
                                            ]),  # intersect
            (self.bet_struct, self.coregister, [('out_file', 'source')]),
            (self.bet_mean, self.coregister, [('out_file', 'target')]),
            (self.coregister, self.segment, [('coregistered_source', 'data')]),
            (self.segment, self.normalize, [('transformation_mat',
                                             'parameter_file')]),
            (self.fslmerge, self.normalize, [('merged_file', 'apply_to_files')
                                             ]),
            (self.normalize, self.smooth, [('normalized_files', 'in_files')]),
            (self.coregister, self.datasink, [('coregistered_source',
                                               'registered_file')]),
            (self.normalize, self.datasink, [('normalized_files',
                                              'before_smooth')]),
            (self.smooth, self.datasink, [('smoothed_files', 'final_out')])
        ])
예제 #25
0
    def __init__(self, settings):
        # call base constructor
        super().__init__(settings)

        # define input/output node
        self.set_input(['T1', 'orig', 'brainmask'])
        self.set_output(['T1_skullstrip', 'allineate_freesurfer2anat'])

        # define datasink substitutions
        self.set_subs([('_maskop40', ''), ('_calc_calc_calc_calc_calc', '')])

        # 3dAllineate (FSorig)
        self.allineate_orig = MapNode(afni.Allineate(
            out_matrix='FSorig2MPR.aff12.1D',
            overwrite=True,
            outputtype='NIFTI_GZ'),
                                      iterfield=['in_file', 'reference'],
                                      name='3dallineate_orig')
        # 3dAllineate (FSbrainmask)
        self.allineate_bm = MapNode(
            afni.Allineate(overwrite=True, no_pad=True, outputtype='NIFTI_GZ'),
            iterfield=['in_file', 'reference', 'in_matrix'],
            name='3dallineate_brainmask')

        # skullstrip mprage (afni)
        self.afni_skullstrip = MapNode(afni.SkullStrip(args="-orig_vol",
                                                       outputtype="NIFTI_GZ"),
                                       iterfield=['in_file'],
                                       name='afni_skullstrip')
        # 3dcalc operations for achieving final mask
        self.maskop1 = MapNode(afni.Calc(expr='step(a)',
                                         overwrite=True,
                                         outputtype='NIFTI_GZ'),
                               iterfield=['in_file_a'],
                               name='maskop1')
        self.maskop2 = []
        for n in range(3):
            self.maskop2.append(
                MapNode(afni.Calc(
                    args='-b a+i -c a-i -d a+j -e a-j -f a+k -g a-k',
                    expr='ispositive(a+b+c+d+e+f+g)',
                    overwrite=True,
                    outputtype='NIFTI_GZ'),
                        iterfield=['in_file_a'],
                        name='maskop2_{}'.format(n)))
        # Inline function for setting up to copy IJK_TO_DICOM_REAL file attribute
        self.refit_setup = MapNode(Function(input_names=['noskull_T1'],
                                            output_names=['refit_input'],
                                            function=lambda noskull_T1:
                                            (noskull_T1, 'IJK_TO_DICOM_REAL')),
                                   iterfield=['noskull_T1'],
                                   name='refitsetup')
        # 3dRefit
        self.refit = MapNode(afni.Refit(),
                             iterfield=['in_file', 'atrcopy'],
                             name='3drefit')
        # 3dcalc for uniform intensity
        self.uniform = MapNode(afni.Calc(expr='a*and(b,b)',
                                         overwrite=True,
                                         outputtype='NIFTI_GZ'),
                               iterfield=['in_file_a', 'in_file_b'],
                               name='uniformintensity')

        # skullstrip mprage (fsl)
        self.fsl_skullstrip = MapNode(fsl.BET(),
                                      iterfield=['in_file'],
                                      name='fsl_skullstrip')
        self.maskop3 = MapNode(
            afni.Calc(expr='or(a,b,c)', overwrite=True, outputtype='NIFTI_GZ'),
            iterfield=['in_file_a', 'in_file_b', 'in_file_c'],
            name='maskop3')
        self.maskop4 = MapNode(
            afni.Calc(expr='c*and(a,b)', overwrite=True,
                      outputtype='NIFTI_GZ'),
            iterfield=['in_file_a', 'in_file_b', 'in_file_c'],
            name='maskop4')

        # Convert from list to string input
        self.select0T1 = Node(Function(input_names=['T1_list'],
                                       output_names=['T1_0'],
                                       function=lambda T1_list: T1_list[0]),
                              name='select0T1')

        # apply bias field correction
        self.biasfieldcorrect = Node(ants.N4BiasFieldCorrection(
            num_threads=settings['num_threads'], copy_header=True),
                                     name='biasfieldcorrect')
예제 #26
0
def hmc_afni(settings, name='fMRI_HMC_afni', st_correct=False, despike=False,
             deoblique=False, start_idx=None, stop_idx=None):
    """
    A :abbr:`HMC (head motion correction)` workflow for
    functional scans

    .. workflow::

      from mriqc.workflows.functional import hmc_afni
      wf = hmc_afni({'biggest_file_size_gb': 1})

    """

    biggest_file_gb = settings.get("biggest_file_size_gb", 1)

    workflow = pe.Workflow(name=name)

    inputnode = pe.Node(niu.IdentityInterface(
        fields=['in_file', 'fd_radius', 'start_idx', 'stop_idx']), name='inputnode')

    outputnode = pe.Node(niu.IdentityInterface(
        fields=['out_file', 'out_fd']), name='outputnode')

    if (start_idx is not None) or (stop_idx is not None):
        drop_trs = pe.Node(afni.Calc(expr='a', outputtype='NIFTI_GZ'),
                           name='drop_trs')
        workflow.connect([
            (inputnode, drop_trs, [('in_file', 'in_file_a'),
                                   ('start_idx', 'start_idx'),
                                   ('stop_idx', 'stop_idx')]),
        ])
    else:
        drop_trs = pe.Node(niu.IdentityInterface(fields=['out_file']),
                           name='drop_trs')
        workflow.connect([
            (inputnode, drop_trs, [('in_file', 'out_file')]),
        ])

    gen_ref = pe.Node(nwr.EstimateReferenceImage(mc_method="AFNI"), name="gen_ref")

    # calculate hmc parameters
    hmc = pe.Node(
        afni.Volreg(args='-Fourier -twopass', zpad=4, outputtype='NIFTI_GZ'),
        name='motion_correct', mem_gb=biggest_file_gb * 2.5)

    # Compute the frame-wise displacement
    fdnode = pe.Node(nac.FramewiseDisplacement(normalize=False,
                                               parameter_source="AFNI"),
                     name='ComputeFD')

    workflow.connect([
        (inputnode, fdnode, [('fd_radius', 'radius')]),
        (gen_ref, hmc, [('ref_image', 'basefile')]),
        (hmc, outputnode, [('out_file', 'out_file')]),
        (hmc, fdnode, [('oned_file', 'in_file')]),
        (fdnode, outputnode, [('out_file', 'out_fd')]),
    ])

    # Slice timing correction, despiking, and deoblique

    st_corr = pe.Node(afni.TShift(outputtype='NIFTI_GZ'), name='TimeShifts')

    deoblique_node = pe.Node(afni.Refit(deoblique=True), name='deoblique')

    despike_node = pe.Node(afni.Despike(outputtype='NIFTI_GZ'), name='despike')

    if st_correct and despike and deoblique:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, despike_node, [('out_file', 'in_file')]),
            (despike_node, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, gen_ref, [('out_file', 'in_file')]),
            (deoblique_node, hmc, [('out_file', 'in_file')]),
        ])

    elif st_correct and despike:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, despike_node, [('out_file', 'in_file')]),
            (despike_node, gen_ref, [('out_file', 'in_file')]),
            (despike_node, hmc, [('out_file', 'in_file')]),
        ])

    elif st_correct and deoblique:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, gen_ref, [('out_file', 'in_file')]),
            (deoblique_node, hmc, [('out_file', 'in_file')]),
        ])

    elif st_correct:

        workflow.connect([
            (drop_trs, st_corr, [('out_file', 'in_file')]),
            (st_corr, gen_ref, [('out_file', 'in_file')]),
            (st_corr, hmc, [('out_file', 'in_file')]),
        ])

    elif despike and deoblique:

        workflow.connect([
            (drop_trs, despike_node, [('out_file', 'in_file')]),
            (despike_node, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, gen_ref, [('out_file', 'in_file')]),
            (deoblique_node, hmc, [('out_file', 'in_file')]),
        ])

    elif despike:

        workflow.connect([
            (drop_trs, despike_node, [('out_file', 'in_file')]),
            (despike_node, gen_ref, [('out_file', 'in_file')]),
            (despike_node, hmc, [('out_file', 'in_file')]),
        ])

    elif deoblique:

        workflow.connect([
            (drop_trs, deoblique_node, [('out_file', 'in_file')]),
            (deoblique_node, gen_ref, [('out_file', 'in_file')]),
            (deoblique_node, hmc, [('out_file', 'in_file')]),
        ])

    else:
        workflow.connect([
            (drop_trs, gen_ref, [('out_file', 'in_file')]),
            (drop_trs, hmc, [('out_file', 'in_file')]),
        ])

    return workflow