Exemplo n.º 1
0
def create_func_preproc(use_bet=False, wf_name='func_preproc'):
    """

    The main purpose of this workflow is to process functional data. Raw rest file is deobliqued and reoriented
    into RPI. Then take the mean intensity values over all time points for each voxel and use this image
    to calculate motion parameters. The image is then skullstripped, normalized and a processed mask is
    obtained to use it further in Image analysis.

    Parameters
    ----------

    wf_name : string
        Workflow name

    Returns
    -------
    func_preproc : workflow object
        Functional Preprocessing workflow object

    Notes
    -----

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

    Workflow Inputs::

        inputspec.rest : func/rest file or a list of func/rest nifti file
            User input functional(T2) Image, in any of the 8 orientations

        scan_params.tr : string
            Subject TR

        scan_params.acquistion : string
            Acquisition pattern (interleaved/sequential, ascending/descending)

        scan_params.ref_slice : integer
            Reference slice for slice timing correction

    Workflow Outputs::

        outputspec.refit : string (nifti file)
            Path to deobliqued anatomical data

        outputspec.reorient : string (nifti file)
            Path to RPI oriented anatomical data

        outputspec.motion_correct_ref : string (nifti file)
             Path to Mean intensity Motion corrected image
             (base reference image for the second motion correction run)

        outputspec.motion_correct : string (nifti file)
            Path to motion corrected output file

        outputspec.max_displacement : string (Mat file)
            Path to maximum displacement (in mm) for brain voxels in each volume

        outputspec.movement_parameters : string (Mat file)
            Path to 1D file containing six movement/motion parameters(3 Translation, 3 Rotations)
            in different columns (roll pitch yaw dS  dL  dP)

        outputspec.skullstrip : string (nifti file)
            Path to skull stripped Motion Corrected Image

        outputspec.mask : string (nifti file)
            Path to brain-only mask

        outputspec.example_func : string (nifti file)
            Mean, Skull Stripped, Motion Corrected output T2 Image path
            (Image with mean intensity values across voxels)

        outputpsec.preprocessed : string (nifti file)
            output skull stripped, motion corrected T2 image
            with normalized intensity values

        outputspec.preprocessed_mask : string (nifti file)
           Mask obtained from normalized preprocessed image

    Order of commands:

    - Deobliqing the scans.  For details see `3drefit <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3drefit.html>`_::

        3drefit -deoblique rest_3dc.nii.gz

    - Re-orienting the Image into Right-to-Left Posterior-to-Anterior Inferior-to-Superior (RPI) orientation. For details see `3dresample <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dresample.html>`_::

        3dresample -orient RPI
                   -prefix rest_3dc_RPI.nii.gz
                   -inset rest_3dc.nii.gz

    - Calculate voxel wise statistics. Get the RPI Image with mean intensity values over all timepoints for each voxel. For details see `3dTstat <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dTstat.html>`_::

        3dTstat -mean
                -prefix rest_3dc_RPI_3dT.nii.gz
                rest_3dc_RPI.nii.gz

    - Motion Correction. For details see `3dvolreg <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dvolreg.html>`_::

        3dvolreg -Fourier
                 -twopass
                 -base rest_3dc_RPI_3dT.nii.gz/
                 -zpad 4
                 -maxdisp1D rest_3dc_RPI_3dvmd1D.1D
                 -1Dfile rest_3dc_RPI_3dv1D.1D
                 -prefix rest_3dc_RPI_3dv.nii.gz
                 rest_3dc_RPI.nii.gz

      The base image or the reference image is the mean intensity RPI image obtained in the above the step.For each volume
      in RPI-oriented T2 image, the command, aligns the image with the base mean image and calculates the motion, displacement
      and movement parameters. It also outputs the aligned 4D volume and movement and displacement parameters for each volume.

    - Calculate voxel wise statistics. Get the motion corrected output Image from the above step, with mean intensity values over all timepoints for each voxel.
      For details see `3dTstat <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dTstat.html>`_::

        3dTstat -mean
                -prefix rest_3dc_RPI_3dv_3dT.nii.gz
                rest_3dc_RPI_3dv.nii.gz

    - Motion Correction and get motion, movement and displacement parameters. For details see `3dvolreg <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dvolreg.html>`_::

        3dvolreg -Fourier
                 -twopass
                 -base rest_3dc_RPI_3dv_3dT.nii.gz
                 -zpad 4
                 -maxdisp1D rest_3dc_RPI_3dvmd1D.1D
                 -1Dfile rest_3dc_RPI_3dv1D.1D
                 -prefix rest_3dc_RPI_3dv.nii.gz
                 rest_3dc_RPI.nii.gz

      The base image or the reference image is the mean intensity motion corrected image obtained from the above the step (first 3dvolreg run).
      For each volume in RPI-oriented T2 image, the command, aligns the image with the base mean image and calculates the motion, displacement
      and movement parameters. It also outputs the aligned 4D volume and movement and displacement parameters for each volume.

    - Create a brain-only mask. For details see `3dautomask <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dAutomask.html>`_::

        3dAutomask
                   -prefix rest_3dc_RPI_3dv_automask.nii.gz
                   rest_3dc_RPI_3dv.nii.gz

    - Edge Detect(remove skull) and get the brain only. For details see `3dcalc <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dcalc.html>`_::

        3dcalc -a rest_3dc_RPI_3dv.nii.gz
               -b rest_3dc_RPI_3dv_automask.nii.gz
               -expr 'a*b'
               -prefix rest_3dc_RPI_3dv_3dc.nii.gz

    - Normalizing the image intensity values. For details see `fslmaths <http://www.fmrib.ox.ac.uk/fsl/avwutils/index.html>`_::

        fslmaths rest_3dc_RPI_3dv_3dc.nii.gz
                 -ing 10000 rest_3dc_RPI_3dv_3dc_maths.nii.gz
                 -odt float

      Normalized intensity = (TrueValue*10000)/global4Dmean

    - Calculate mean of skull stripped image. For details see `3dTstat <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dTstat.html>`_::

        3dTstat -mean -prefix rest_3dc_RPI_3dv_3dc_3dT.nii.gz rest_3dc_RPI_3dv_3dc.nii.gz

    - Create Mask (Generate mask from Normalized data). For details see `fslmaths <http://www.fmrib.ox.ac.uk/fsl/avwutils/index.html>`_::

        fslmaths rest_3dc_RPI_3dv_3dc_maths.nii.gz
               -Tmin -bin rest_3dc_RPI_3dv_3dc_maths_maths.nii.gz
               -odt char

    High Level Workflow Graph:

    .. image:: ../images/func_preproc.dot.png
       :width: 1000


    Detailed Workflow Graph:

    .. image:: ../images/func_preproc_detailed.dot.png
       :width: 1000

    Examples
    --------

    >>> import func_preproc
    >>> preproc = create_func_preproc(bet=True)
    >>> preproc.inputs.inputspec.func='sub1/func/rest.nii.gz'
    >>> preproc.run() #doctest: +SKIP


    >>> import func_preproc
    >>> preproc = create_func_preproc(bet=False)
    >>> preproc.inputs.inputspec.func='sub1/func/rest.nii.gz'
    >>> preproc.run() #doctest: +SKIP

    """

    preproc = pe.Workflow(name=wf_name)
    inputNode = pe.Node(util.IdentityInterface(fields=['func']),
                        name='inputspec')

    outputNode = pe.Node(
        util.IdentityInterface(fields=[
            'refit',
            'reorient',
            'reorient_mean',
            'motion_correct',
            'motion_correct_ref',
            'movement_parameters',
            'max_displacement',
            # 'xform_matrix',
            'mask',
            'skullstrip',
            'example_func',
            'preprocessed',
            'preprocessed_mask',
            'slice_time_corrected',
            'oned_matrix_save'
        ]),
        name='outputspec')

    try:
        from nipype.interfaces.afni import utils as afni_utils
        func_deoblique = pe.Node(interface=afni_utils.Refit(),
                                 name='func_deoblique')
    except ImportError:
        func_deoblique = pe.Node(interface=preprocess.Refit(),
                                 name='func_deoblique')
    func_deoblique.inputs.deoblique = True

    preproc.connect(inputNode, 'func', func_deoblique, 'in_file')

    try:
        func_reorient = pe.Node(interface=afni_utils.Resample(),
                                name='func_reorient')
    except UnboundLocalError:
        func_reorient = pe.Node(interface=preprocess.Resample(),
                                name='func_reorient')

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

    preproc.connect(func_deoblique, 'out_file', func_reorient, 'in_file')

    preproc.connect(func_reorient, 'out_file', outputNode, 'reorient')

    try:
        func_get_mean_RPI = pe.Node(interface=afni_utils.TStat(),
                                    name='func_get_mean_RPI')
    except UnboundLocalError:
        func_get_mean_RPI = pe.Node(interface=preprocess.TStat(),
                                    name='func_get_mean_RPI')

    func_get_mean_RPI.inputs.options = '-mean'
    func_get_mean_RPI.inputs.outputtype = 'NIFTI_GZ'

    preproc.connect(func_reorient, 'out_file', func_get_mean_RPI, 'in_file')

    # calculate motion parameters
    func_motion_correct = pe.Node(interface=preprocess.Volreg(),
                                  name='func_motion_correct')
    func_motion_correct.inputs.args = '-Fourier -twopass'
    func_motion_correct.inputs.zpad = 4
    func_motion_correct.inputs.outputtype = 'NIFTI_GZ'

    preproc.connect(func_reorient, 'out_file', func_motion_correct, 'in_file')
    preproc.connect(func_get_mean_RPI, 'out_file', func_motion_correct,
                    'basefile')

    func_get_mean_motion = func_get_mean_RPI.clone('func_get_mean_motion')
    preproc.connect(func_motion_correct, 'out_file', func_get_mean_motion,
                    'in_file')

    preproc.connect(func_get_mean_motion, 'out_file', outputNode,
                    'motion_correct_ref')

    func_motion_correct_A = func_motion_correct.clone('func_motion_correct_A')
    func_motion_correct_A.inputs.md1d_file = 'max_displacement.1D'

    preproc.connect(func_reorient, 'out_file', func_motion_correct_A,
                    'in_file')
    preproc.connect(func_get_mean_motion, 'out_file', func_motion_correct_A,
                    'basefile')

    preproc.connect(func_motion_correct_A, 'out_file', outputNode,
                    'motion_correct')
    preproc.connect(func_motion_correct_A, 'md1d_file', outputNode,
                    'max_displacement')
    preproc.connect(func_motion_correct_A, 'oned_file', outputNode,
                    'movement_parameters')
    preproc.connect(func_motion_correct_A, 'oned_matrix_save', outputNode,
                    'oned_matrix_save')

    if not use_bet:

        func_get_brain_mask = pe.Node(interface=preprocess.Automask(),
                                      name='func_get_brain_mask')

        func_get_brain_mask.inputs.outputtype = 'NIFTI_GZ'

        preproc.connect(func_motion_correct_A, 'out_file', func_get_brain_mask,
                        'in_file')

        preproc.connect(func_get_brain_mask, 'out_file', outputNode, 'mask')

    else:

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

        func_get_brain_mask.inputs.mask = True
        func_get_brain_mask.inputs.functional = True

        erode_one_voxel = pe.Node(interface=fsl.ErodeImage(),
                                  name='erode_one_voxel')

        erode_one_voxel.inputs.kernel_shape = 'box'
        erode_one_voxel.inputs.kernel_size = 1.0

        preproc.connect(func_motion_correct_A, 'out_file', func_get_brain_mask,
                        'in_file')

        preproc.connect(func_get_brain_mask, 'mask_file', erode_one_voxel,
                        'in_file')

        preproc.connect(erode_one_voxel, 'out_file', outputNode, 'mask')

    try:
        func_edge_detect = pe.Node(interface=afni_utils.Calc(),
                                   name='func_edge_detect')
    except UnboundLocalError:
        func_edge_detect = pe.Node(interface=preprocess.Calc(),
                                   name='func_edge_detect')

    func_edge_detect.inputs.expr = 'a*b'
    func_edge_detect.inputs.outputtype = 'NIFTI_GZ'

    preproc.connect(func_motion_correct_A, 'out_file', func_edge_detect,
                    'in_file_a')

    if not use_bet:
        preproc.connect(func_get_brain_mask, 'out_file', func_edge_detect,
                        'in_file_b')
    else:
        preproc.connect(erode_one_voxel, 'out_file', func_edge_detect,
                        'in_file_b')

    preproc.connect(func_edge_detect, 'out_file', outputNode, 'skullstrip')

    try:
        func_mean_skullstrip = pe.Node(interface=afni_utils.TStat(),
                                       name='func_mean_skullstrip')
    except UnboundLocalError:
        func_mean_skullstrip = pe.Node(interface=preprocess.TStat(),
                                       name='func_mean_skullstrip')

    func_mean_skullstrip.inputs.options = '-mean'
    func_mean_skullstrip.inputs.outputtype = 'NIFTI_GZ'

    preproc.connect(func_edge_detect, 'out_file', func_mean_skullstrip,
                    'in_file')

    preproc.connect(func_mean_skullstrip, 'out_file', outputNode,
                    'example_func')

    func_normalize = pe.Node(interface=fsl.ImageMaths(), name='func_normalize')
    func_normalize.inputs.op_string = '-ing 10000'
    func_normalize.inputs.out_data_type = 'float'

    preproc.connect(func_edge_detect, 'out_file', func_normalize, 'in_file')

    preproc.connect(func_normalize, 'out_file', outputNode, 'preprocessed')

    func_mask_normalize = pe.Node(interface=fsl.ImageMaths(),
                                  name='func_mask_normalize')
    func_mask_normalize.inputs.op_string = '-Tmin -bin'
    func_mask_normalize.inputs.out_data_type = 'char'

    preproc.connect(func_normalize, 'out_file', func_mask_normalize, 'in_file')

    preproc.connect(func_mask_normalize, 'out_file', outputNode,
                    'preprocessed_mask')

    return preproc
Exemplo n.º 2
0
def create_asl_preproc(c, strat, wf_name='asl_preproc'):
    # resource_pool = strat?
    # print('resource pool asl preproc: ', str(strat.get_resource_pool()))

    # allocate a workflow object
    asl_workflow = pe.Workflow(name=wf_name)
    asl_workflow.base_dir = c.workingDirectory

    # configure the workflow's input spec
    inputNode = pe.Node(util.IdentityInterface(fields=[
        'asl_file', 'anatomical_skull', 'anatomical_brain', 'seg_wm_pve'
    ]),
                        name='inputspec')

    # configure the workflow's output spec
    outputNode = pe.Node(util.IdentityInterface(
        fields=['meanasl', 'perfusion_image', 'diffdata', 'diffdata_mean']),
                         name='outputspec')

    # get segmentation output dir and file stub

    # create nodes for de-obliquing and reorienting
    try:
        from nipype.interfaces.afni import utils as afni_utils
        func_deoblique = pe.Node(interface=afni_utils.Refit(),
                                 name='func_deoblique')
    except ImportError:
        func_deoblique = pe.Node(interface=preprocess.Refit(),
                                 name='func_deoblique')
    func_deoblique.inputs.deoblique = True

    asl_workflow.connect(inputNode, 'asl_file', func_deoblique, 'in_file')

    try:
        func_reorient = pe.Node(interface=afni_utils.Resample(),
                                name='func_reorient')
    except UnboundLocalError:
        func_reorient = pe.Node(interface=preprocess.Resample(),
                                name='func_reorient')

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

    # connect deoblique to reorient
    asl_workflow.connect(func_deoblique, 'out_file', func_reorient, 'in_file')

    # create node for splitting control and label pairs (unused currently)
    split_pairs_imports = ['import os', 'import subprocess']
    split_ASL_pairs = pe.Node(interface=util.Function(
        input_names=['asl_file'],
        output_names=['control_image', 'label_image'],
        function=split_pairs,
        imports=split_pairs_imports),
                              name='split_pairs')

    # create node for calculating subtracted images
    diffdata_imports = ['import os', 'import subprocess']
    run_diffdata = pe.Node(interface=util.Function(
        input_names=['asl_file'],
        output_names=['diffdata_image', 'diffdata_mean'],
        function=diffdata,
        imports=diffdata_imports),
                           name='diffdata')

    asl_workflow.connect(func_reorient, 'out_file', run_diffdata, 'asl_file')

    asl_workflow.connect(run_diffdata, 'diffdata_image', outputNode,
                         'diffdata')

    asl_workflow.connect(run_diffdata, 'diffdata_mean', outputNode,
                         'diffdata_mean')

    # create node for oxford_asl (perfusion image)

    asl_imports = ['import os', 'import subprocess']
    run_oxford_asl = pe.Node(interface=util.Function(
        input_names=[
            'asl_file', 'anatomical_skull', 'anatomical_brain', 'seg'
        ],
        output_names=['perfusion_image', 'asl2anat_linear_xfm', 'asl2anat'],
        function=oxford_asl,
        imports=asl_imports),
                             name='run_oxford_asl')

    # wire inputs from resource pool to ASL preprocessing FSL script

    # connect output of reorient to run_oxford_asl
    asl_workflow.connect(func_reorient, 'out_file', run_oxford_asl, 'asl_file')

    asl_workflow.connect(inputNode, 'seg_wm_pve', run_oxford_asl, 'seg')

    # pass the anatomical to the workflow
    asl_workflow.connect(inputNode, 'anatomical_skull', run_oxford_asl,
                         'anatomical_skull')

    # pass the anatomical to the workflow
    asl_workflow.connect(inputNode, 'anatomical_brain', run_oxford_asl,
                         'anatomical_brain')

    # connect oxford_asl outputs to outputNode

    asl_workflow.connect(run_oxford_asl, 'asl2anat_linear_xfm', outputNode,
                         'asl2anat_linear_xfm')

    asl_workflow.connect(run_oxford_asl, 'asl2anat', outputNode, 'asl2anat')

    asl_workflow.connect(run_oxford_asl, 'perfusion_image', outputNode,
                         'perfusion_image')

    strat.update_resource_pool({
        'mean_asl_in_anat': (run_oxford_asl, 'anat_asl'),
        'asl_to_anat_linear_xfm': (run_oxford_asl, 'asl2anat_linear_xfm')
    })

    # Take mean of the asl data for registration

    try:
        get_mean_asl = pe.Node(interface=afni_utils.TStat(),
                               name='get_mean_asl')
    except UnboundLocalError:
        get_mean_asl = pe.Node(interface=preprocess.TStat(),
                               name='get_mean_asl')

    get_mean_asl.inputs.options = '-mean'
    get_mean_asl.inputs.outputtype = 'NIFTI_GZ'

    asl_workflow.connect(func_reorient, 'out_file', get_mean_asl, 'in_file')

    asl_workflow.connect(get_mean_asl, 'out_file', outputNode, 'meanasl')

    return asl_workflow
Exemplo n.º 3
0
def create_anat_preproc(already_skullstripped=False):
    """ 

    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 : mprage file or a list of mprage nifti file
            User input anatomical(T1) Image, in any of the 8 orientations

    Workflow Outputs::

        outputspec.refit : nifti file
            Deobliqued anatomical data
        outputspec.reorient : nifti file
            RPI oriented anatomical data
        outputspec.skullstrip : nifti file
            Skull Stripped RPI oriented mprage file with normalized intensities.
        outputspec.brain : nifti file
            Skull Stripped RPI Brain Image with original intensity values and not normalized or scaled.

    Order of commands:

    - Deobliqing the scans.  For details see `3drefit <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3drefit.html>`_::

        3drefit -deoblique mprage.nii.gz

    - Re-orienting the Image into Right-to-Left Posterior-to-Anterior Inferior-to-Superior  (RPI) orientation.  For details see `3dresample <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dresample.html>`_::

        3dresample -orient RPI -prefix mprage_RPI.nii.gz -inset mprage.nii.gz

    - SkullStripping the image.  For details see `3dSkullStrip <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dSkullStrip.html>`_::

        3dSkullStrip -input mprage_RPI.nii.gz -o_ply mprage_RPI_3dT.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.  For details see `3dcalc <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dcalc.html>`_::

        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
    --------

    >>> import anat
    >>> preproc = create_anat_preproc()
    >>> preproc.inputs.inputspec.anat='sub1/anat/mprage.nii.gz'
    >>> preproc.run() #doctest: +SKIP

    """

    preproc = pe.Workflow(name='anat_preproc')
    inputNode = pe.Node(util.IdentityInterface(fields=['anat']),
                        name='inputspec')
    outputNode = pe.Node(util.IdentityInterface(
        fields=['refit', 'reorient', 'skullstrip', 'brain']),
                         name='outputspec')

    try:
        from nipype.interfaces.afni import utils as afni_utils
        anat_deoblique = pe.Node(interface=afni_utils.Refit(),
                                 name='anat_deoblique')
    except ImportError:
        anat_deoblique = pe.Node(interface=preprocess.Refit(),
                                 name='anat_deoblique')

    anat_deoblique.inputs.deoblique = True

    try:
        anat_reorient = pe.Node(interface=afni_utils.Resample(),
                                name='anat_reorient')
    except UnboundLocalError:
        anat_reorient = pe.Node(interface=preprocess.Resample(),
                                name='anat_reorient')

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

    if not already_skullstripped:
        anat_skullstrip = pe.Node(interface=preprocess.SkullStrip(),
                                  name='anat_skullstrip')
        anat_skullstrip.inputs.outputtype = 'NIFTI_GZ'

    try:
        anat_skullstrip_orig_vol = pe.Node(interface=afni_utils.Calc(),
                                           name='anat_skullstrip_orig_vol')
    except UnboundLocalError:
        anat_skullstrip_orig_vol = pe.Node(interface=preprocess.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', anat_deoblique, 'in_file')
    preproc.connect(anat_deoblique, 'out_file', anat_reorient, 'in_file')
    if not already_skullstripped:
        preproc.connect(anat_reorient, 'out_file', anat_skullstrip, 'in_file')
        preproc.connect(anat_skullstrip, 'out_file', anat_skullstrip_orig_vol,
                        'in_file_b')
    else:
        preproc.connect(anat_reorient, 'out_file', anat_skullstrip_orig_vol,
                        'in_file_b')
    preproc.connect(anat_reorient, 'out_file', anat_skullstrip_orig_vol,
                    'in_file_a')

    preproc.connect(anat_deoblique, 'out_file', outputNode, 'refit')
    preproc.connect(anat_reorient, 'out_file', outputNode, 'reorient')
    if not already_skullstripped:
        preproc.connect(anat_skullstrip, 'out_file', outputNode, 'skullstrip')
    preproc.connect(anat_skullstrip_orig_vol, 'out_file', outputNode, 'brain')

    return preproc
Exemplo n.º 4
0
def create_func_preproc(skullstrip_tool,
                        n4_correction,
                        anatomical_mask_dilation=False,
                        wf_name='func_preproc'):
    """

    The main purpose of this workflow is to process functional data. Raw rest file is deobliqued and reoriented
    into RPI. Then take the mean intensity values over all time points for each voxel and use this image
    to calculate motion parameters. The image is then skullstripped, normalized and a processed mask is
    obtained to use it further in Image analysis.

    Parameters
    ----------

    wf_name : string
        Workflow name

    Returns
    -------
    func_preproc : workflow object
        Functional Preprocessing workflow object

    Notes
    -----

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

    Workflow Inputs::

        inputspec.func : func nifti file
            User input functional(T2) Image, in any of the 8 orientations

        inputspec.twopass : boolean
            Perform two-pass on volume registration

    Workflow Outputs::

        outputspec.refit : string (nifti file)
            Path to deobliqued anatomical data

        outputspec.reorient : string (nifti file)
            Path to RPI oriented anatomical data

        outputspec.motion_correct_ref : string (nifti file)
             Path to Mean intensity Motion corrected image
             (base reference image for the second motion correction run)

        outputspec.motion_correct : string (nifti file)
            Path to motion corrected output file

        outputspec.max_displacement : string (Mat file)
            Path to maximum displacement (in mm) for brain voxels in each volume

        outputspec.movement_parameters : string (Mat file)
            Path to 1D file containing six movement/motion parameters(3 Translation, 3 Rotations)
            in different columns (roll pitch yaw dS  dL  dP)

        outputspec.skullstrip : string (nifti file)
            Path to skull stripped Motion Corrected Image

        outputspec.mask : string (nifti file)
            Path to brain-only mask

        outputspec.func_mean : string (nifti file)
            Mean, Skull Stripped, Motion Corrected output T2 Image path
            (Image with mean intensity values across voxels)

        outputpsec.preprocessed : string (nifti file)
            output skull stripped, motion corrected T2 image
            with normalized intensity values

        outputspec.preprocessed_mask : string (nifti file)
           Mask obtained from normalized preprocessed image

    Order of commands:

    - Deobliqing the scans.  For details see `3drefit <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3drefit.html>`_::

        3drefit -deoblique rest_3dc.nii.gz

    - Re-orienting the Image into Right-to-Left Posterior-to-Anterior Inferior-to-Superior (RPI) orientation. For details see `3dresample <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dresample.html>`_::

        3dresample -orient RPI
                   -prefix rest_3dc_RPI.nii.gz
                   -inset rest_3dc.nii.gz

    - Calculate voxel wise statistics. Get the RPI Image with mean intensity values over all timepoints for each voxel. For details see `3dTstat <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dTstat.html>`_::

        3dTstat -mean
                -prefix rest_3dc_RPI_3dT.nii.gz
                rest_3dc_RPI.nii.gz

    - Motion Correction. For details see `3dvolreg <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dvolreg.html>`_::

        3dvolreg -Fourier
                 -twopass
                 -base rest_3dc_RPI_3dT.nii.gz/
                 -zpad 4
                 -maxdisp1D rest_3dc_RPI_3dvmd1D.1D
                 -1Dfile rest_3dc_RPI_3dv1D.1D
                 -prefix rest_3dc_RPI_3dv.nii.gz
                 rest_3dc_RPI.nii.gz

      The base image or the reference image is the mean intensity RPI image obtained in the above the step.For each volume
      in RPI-oriented T2 image, the command, aligns the image with the base mean image and calculates the motion, displacement
      and movement parameters. It also outputs the aligned 4D volume and movement and displacement parameters for each volume.

    - Calculate voxel wise statistics. Get the motion corrected output Image from the above step, with mean intensity values over all timepoints for each voxel.
      For details see `3dTstat <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dTstat.html>`_::

        3dTstat -mean
                -prefix rest_3dc_RPI_3dv_3dT.nii.gz
                rest_3dc_RPI_3dv.nii.gz

    - Motion Correction and get motion, movement and displacement parameters. For details see `3dvolreg <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dvolreg.html>`_::

        3dvolreg -Fourier
                 -twopass
                 -base rest_3dc_RPI_3dv_3dT.nii.gz
                 -zpad 4
                 -maxdisp1D rest_3dc_RPI_3dvmd1D.1D
                 -1Dfile rest_3dc_RPI_3dv1D.1D
                 -prefix rest_3dc_RPI_3dv.nii.gz
                 rest_3dc_RPI.nii.gz

      The base image or the reference image is the mean intensity motion corrected image obtained from the above the step (first 3dvolreg run).
      For each volume in RPI-oriented T2 image, the command, aligns the image with the base mean image and calculates the motion, displacement
      and movement parameters. It also outputs the aligned 4D volume and movement and displacement parameters for each volume.

    - Create a brain-only mask. For details see `3dautomask <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dAutomask.html>`_::

        3dAutomask
                   -prefix rest_3dc_RPI_3dv_automask.nii.gz
                   rest_3dc_RPI_3dv.nii.gz

    - Edge Detect(remove skull) and get the brain only. For details see `3dcalc <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dcalc.html>`_::

        3dcalc -a rest_3dc_RPI_3dv.nii.gz
               -b rest_3dc_RPI_3dv_automask.nii.gz
               -expr 'a*b'
               -prefix rest_3dc_RPI_3dv_3dc.nii.gz

    - Normalizing the image intensity values. For details see `fslmaths <http://www.fmrib.ox.ac.uk/fsl/avwutils/index.html>`_::

        fslmaths rest_3dc_RPI_3dv_3dc.nii.gz
                 -ing 10000 rest_3dc_RPI_3dv_3dc_maths.nii.gz
                 -odt float

      Normalized intensity = (TrueValue*10000)/global4Dmean

    - Calculate mean of skull stripped image. For details see `3dTstat <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dTstat.html>`_::

        3dTstat -mean -prefix rest_3dc_RPI_3dv_3dc_3dT.nii.gz rest_3dc_RPI_3dv_3dc.nii.gz

    - Create Mask (Generate mask from Normalized data). For details see `fslmaths <http://www.fmrib.ox.ac.uk/fsl/avwutils/index.html>`_::

        fslmaths rest_3dc_RPI_3dv_3dc_maths.nii.gz
               -Tmin -bin rest_3dc_RPI_3dv_3dc_maths_maths.nii.gz
               -odt char

    .. exec::
        from CPAC.func_preproc import create_func_preproc
        wf = create_func_preproc()
        wf.write_graph(
            graph2use='orig',
            dotfilename='./images/generated/func_preproc.dot'
        )

    High Level Workflow Graph:

    .. image:: ../images/generated/func_preproc.png
       :width: 1000

    Detailed Workflow Graph:

    .. image:: ../images/generated/func_preproc_detailed.png
       :width: 1000

    Examples
    --------

    >>> import func_preproc
    >>> preproc = create_func_preproc(bet=True)
    >>> preproc.inputs.inputspec.func='sub1/func/rest.nii.gz'
    >>> preproc.run() #doctest: +SKIP


    >>> import func_preproc
    >>> preproc = create_func_preproc(bet=False)
    >>> preproc.inputs.inputspec.func='sub1/func/rest.nii.gz'
    >>> preproc.run() #doctest: +SKIP

    """

    preproc = pe.Workflow(name=wf_name)
    input_node = pe.Node(util.IdentityInterface(
        fields=['func', 'twopass', 'anatomical_brain_mask', 'anat_skull']),
                         name='inputspec')

    output_node = pe.Node(util.IdentityInterface(fields=[
        'refit', 'reorient', 'reorient_mean', 'motion_correct',
        'motion_correct_ref', 'movement_parameters', 'max_displacement',
        'mask', 'skullstrip', 'func_mean', 'preprocessed', 'preprocessed_mask',
        'slice_time_corrected', 'transform_matrices'
    ]),
                          name='outputspec')

    func_deoblique = pe.Node(interface=afni_utils.Refit(),
                             name='func_deoblique')
    func_deoblique.inputs.deoblique = True

    preproc.connect(input_node, 'func', func_deoblique, 'in_file')

    func_reorient = pe.Node(interface=afni_utils.Resample(),
                            name='func_reorient')

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

    preproc.connect(func_deoblique, 'out_file', func_reorient, 'in_file')

    preproc.connect(func_reorient, 'out_file', output_node, 'reorient')

    func_get_mean_RPI = pe.Node(interface=afni_utils.TStat(),
                                name='func_get_mean_RPI')

    func_get_mean_RPI.inputs.options = '-mean'
    func_get_mean_RPI.inputs.outputtype = 'NIFTI_GZ'

    preproc.connect(func_reorient, 'out_file', func_get_mean_RPI, 'in_file')

    # calculate motion parameters
    func_motion_correct = pe.Node(interface=preprocess.Volreg(),
                                  name='func_motion_correct_3dvolreg')
    func_motion_correct.inputs.zpad = 4
    func_motion_correct.inputs.outputtype = 'NIFTI_GZ'

    preproc.connect([
        (input_node, func_motion_correct,
         [(('twopass', collect_arguments, '-twopass', '-Fourier'), 'args')]),
    ])
    preproc.connect(func_get_mean_RPI, 'out_file', func_motion_correct,
                    'basefile')

    preproc.connect(func_reorient, 'out_file', func_motion_correct, 'in_file')

    func_get_mean_motion = func_get_mean_RPI.clone('func_get_mean_motion')
    preproc.connect(func_motion_correct, 'out_file', func_get_mean_motion,
                    'in_file')

    preproc.connect(func_get_mean_motion, 'out_file', output_node,
                    'motion_correct_ref')

    func_motion_correct_A = func_motion_correct.clone('func_motion_correct_A')
    func_motion_correct_A.inputs.md1d_file = 'max_displacement.1D'

    preproc.connect([
        (input_node, func_motion_correct_A,
         [(('twopass', collect_arguments, '-twopass', '-Fourier'), 'args')]),
    ])

    preproc.connect(func_reorient, 'out_file', func_motion_correct_A,
                    'in_file')
    preproc.connect(func_get_mean_motion, 'out_file', func_motion_correct_A,
                    'basefile')

    preproc.connect(func_motion_correct_A, 'out_file', output_node,
                    'motion_correct')
    preproc.connect(func_motion_correct_A, 'md1d_file', output_node,
                    'max_displacement')
    preproc.connect(func_motion_correct_A, 'oned_file', output_node,
                    'movement_parameters')
    preproc.connect(func_motion_correct_A, 'oned_matrix_save', output_node,
                    'transform_matrices')

    skullstrip_func = skullstrip_functional(skullstrip_tool,
                                            anatomical_mask_dilation,
                                            "{0}_skullstrip".format(wf_name))

    preproc.connect(func_motion_correct_A, 'out_file', skullstrip_func,
                    'inputspec.func')

    preproc.connect(input_node, 'anatomical_brain_mask', skullstrip_func,
                    'inputspec.anatomical_brain_mask')

    preproc.connect(input_node, 'anat_skull', skullstrip_func,
                    'inputspec.anat_skull')

    preproc.connect(skullstrip_func, 'outputspec.func_brain', output_node,
                    'skullstrip')

    preproc.connect(skullstrip_func, 'outputspec.func_brain_mask', output_node,
                    'mask')

    func_mean = pe.Node(interface=afni_utils.TStat(), name='func_mean')

    func_mean.inputs.options = '-mean'
    func_mean.inputs.outputtype = 'NIFTI_GZ'

    preproc.connect(skullstrip_func, 'outputspec.func_brain', func_mean,
                    'in_file')

    if n4_correction:
        func_mean_n4_corrected = pe.Node(interface=ants.N4BiasFieldCorrection(
            dimension=3, copy_header=True, bspline_fitting_distance=200),
                                         shrink_factor=2,
                                         name='func_mean_n4_corrected')
        func_mean_n4_corrected.inputs.args = '-r True'
        # func_mean_n4_corrected.inputs.rescale_intensities = True
        preproc.connect(func_mean, 'out_file', func_mean_n4_corrected,
                        'input_image')
        preproc.connect(func_mean_n4_corrected, 'output_image', output_node,
                        'func_mean')

    else:
        preproc.connect(func_mean, 'out_file', output_node, 'func_mean')

    func_normalize = pe.Node(interface=fsl.ImageMaths(), name='func_normalize')
    func_normalize.inputs.op_string = '-ing 10000'
    func_normalize.inputs.out_data_type = 'float'

    preproc.connect(skullstrip_func, 'outputspec.func_brain', func_normalize,
                    'in_file')

    preproc.connect(func_normalize, 'out_file', output_node, 'preprocessed')

    func_mask_normalize = pe.Node(interface=fsl.ImageMaths(),
                                  name='func_mask_normalize')
    func_mask_normalize.inputs.op_string = '-Tmin -bin'
    func_mask_normalize.inputs.out_data_type = 'char'

    preproc.connect(func_normalize, 'out_file', func_mask_normalize, 'in_file')

    preproc.connect(func_mask_normalize, 'out_file', output_node,
                    'preprocessed_mask')

    return preproc