Пример #1
0
def create_vmhc(use_ants, name='vmhc_workflow', ants_threads=1):
    """
    Compute the map of brain functional homotopy, the high degree of synchrony in spontaneous activity between geometrically corresponding interhemispheric (i.e., homotopic) regions.



    Parameters
    ----------

    None

    Returns
    -------

    vmhc_workflow : workflow

        Voxel Mirrored Homotopic Connectivity Analysis Workflow



    Notes
    -----

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

    Workflow Inputs::

        inputspec.brain : string (existing nifti file)
            Anatomical image(without skull)

        inputspec.symmetric_brain : string (existing nifti file)
            MNI152_T1_2mm_symmetric_brain.nii.gz
 
        inputspec.rest_res_filt : string (existing nifti file)
            Band passed Image with nuisance signal regressed out(and optionally scrubbed). Recommended bandpass filter (0.001,0.1) )

        inputspec.reorient : string (existing nifti file)
            RPI oriented anatomical data

        inputspec.example_func2highres_mat : string (existing affine transformation .mat file)
            Specifies an affine transform that should be applied to the example_func before non linear warping

        inputspec.standard_for_func: string (existing nifti file)
            MNI152_T1_standard_resolution_brain.nii.gz

        inputspec.symmetric_skull : string (existing nifti file)
            MNI152_T1_2mm_symmetric.nii.gz

        inputspec.twomm_brain_mask_dil : string (existing nifti file)
            MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz

        inputspec.config_file_twomm_symmetric : string (existing .cnf file)
            T1_2_MNI152_2mm_symmetric.cnf

        inputspec.rest_mask : string (existing nifti file)
            A mask functional volume(derived by dilation from motion corrected functional volume)

        fwhm_input.fwhm : list (float) 
            For spatial smoothing the Z-transformed correlations in MNI space.
            Generally the value of this parameter is 1.5 or 2 times the voxel size of the input Image.

        inputspec.mean_functional : string (existing nifti file)
            The mean functional image for use in the func-to-anat registration matrix conversion
            to ITK (ANTS) format, if the user selects to use ANTS.

        
    Workflow Outputs::

        outputspec.highres2symmstandard : string (nifti file)
            Linear registration of T1 image to symmetric standard image

        outputspec.highres2symmstandard_mat : string (affine transformation .mat file)
            An affine transformation .mat file from linear registration and used in non linear registration

        outputspec.highres2symmstandard_warp : string (nifti file)
            warp file from Non Linear registration of T1 to symmetrical standard brain

        outputspec.fnirt_highres2symmstandard : string (nifti file)
            Non Linear registration of T1 to symmetrical standard brain

        outputspec.highres2symmstandard_jac : string (nifti file)
            jacobian determinant image from Non Linear registration of T1 to symmetrical standard brain

        outputspec.rest_res_2symmstandard : string (nifti file)
            nonlinear registration (func to standard) image

        outputspec.VMHC_FWHM_img : string (nifti file)
            pearson correlation between res2standard and flipped res2standard

        outputspec.VMHC_Z_FWHM_img : string (nifti file)
            Fisher Z transform map

        outputspec.VMHC_Z_stat_FWHM_img : string (nifti file)
            Z statistic map

    Order of commands:

    - Perform linear registration of Anatomical brain in T1 space to symmetric standard space. For details see `flirt <http://www.fmrib.ox.ac.uk/fsl/flirt/index.html>`_::

        flirt
        -ref MNI152_T1_2mm_symmetric_brain.nii.gz
        -in mprage_brain.nii.gz
        -out highres2symmstandard.nii.gz
        -omat highres2symmstandard.mat
        -cost corratio
        -searchcost corratio
        -dof 12
        -interp trilinear    
        
    - Perform nonlinear registration (higres to standard) to symmetric standard brain. For details see `fnirt <http://fsl.fmrib.ox.ac.uk/fsl/fnirt/>`_::
    
        fnirt
        --in=head.nii.gz
        --aff=highres2symmstandard.mat
        --cout=highres2symmstandard_warp.nii.gz
        --iout=fnirt_highres2symmstandard.nii.gz
        --jout=highres2symmstandard_jac.nii.gz
        --config=T1_2_MNI152_2mm_symmetric.cnf
        --ref=MNI152_T1_2mm_symmetric.nii.gz
        --refmask=MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz
        --warpres=10,10,10 

    - Perform spatial smoothing on the input functional image(inputspec.rest_res_filt).  For details see `PrinciplesSmoothing <http://imaging.mrc-cbu.cam.ac.uk/imaging/PrinciplesSmoothing>`_ `fslmaths <http://www.fmrib.ox.ac.uk/fslcourse/lectures/practicals/intro/index.htm>`_::

        fslmaths rest_res_filt.nii.gz
        -kernel gauss FWHM/ sqrt(8-ln(2))
        -fmean -mas rest_mask.nii.gz
        rest_res_filt_FWHM.nii.gz
        
    - Apply nonlinear registration (func to standard). For details see  `applywarp <http://www.fmrib.ox.ac.uk/fsl/fnirt/warp_utils.html#applywarp>`_::
        
        applywarp
        --ref=MNI152_T1_2mm_symmetric.nii.gz
        --in=rest_res_filt_FWHM.nii.gz
        --out=rest_res_2symmstandard.nii.gz
        --warp=highres2symmstandard_warp.nii.gz
        --premat=example_func2highres.mat
        
        
    - Copy and L/R swap the output of applywarp command (rest_res_2symmstandard.nii.gz). For details see  `fslswapdim <http://fsl.fmrib.ox.ac.uk/fsl/fsl4.0/avwutils/index.html>`_::

        fslswapdim
        rest_res_2symmstandard.nii.gz
        -x y z
        tmp_LRflipped.nii.gz


    - Calculate pearson correlation between rest_res_2symmstandard.nii.gz and flipped rest_res_2symmstandard.nii.gz(tmp_LRflipped.nii.gz). For details see  `3dTcorrelate <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dTcorrelate.html>`_::
        
        3dTcorrelate
        -pearson
        -polort -1
        -prefix VMHC_FWHM.nii.gz
        rest_res_2symmstandard.nii.gz
        tmp_LRflipped.nii.gz
    
    
    - Fisher Z Transform the correlation. For details see `3dcalc <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dcalc.html>`_::
        
        3dcalc
        -a VMHC_FWHM.nii.gz
        -expr 'log((a+1)/(1-a))/2'
        -prefix VMHC_FWHM_Z.nii.gz
    
        
    - Calculate the number of volumes(nvols) in flipped rest_res_2symmstandard.nii.gz(tmp_LRflipped.nii.gz) ::
        
        -Use Nibabel to do this
        
        
    - Compute the Z statistic map ::
        
        3dcalc
        -a VMHC_FWHM_Z.nii.gz
        -expr 'a*sqrt('${nvols}'-3)'
        -prefix VMHC_FWHM_Z_stat.nii.gz
    
    
    Workflow:
    
    .. image:: ../images/vmhc_graph.dot.png
        :width: 500 
    
    Workflow Detailed:
    
    .. image:: ../images/vmhc_detailed_graph.dot.png
        :width: 500 
    

    References
    ----------
    
    .. [1] Zuo, X.-N., Kelly, C., Di Martino, A., Mennes, M., Margulies, D. S., Bangaru, S., Grzadzinski, R., et al. (2010). Growing together and growing apart: regional and sex differences in the lifespan developmental trajectories of functional homotopy. The Journal of neuroscience : the official journal of the Society for Neuroscience, 30(45), 15034-43. doi:10.1523/JNEUROSCI.2612-10.2010


    Examples
    --------
    
    >>> vmhc_w = create_vmhc()
    >>> vmhc_w.inputs.inputspec.symmetric_brain = 'MNI152_T1_2mm_symmetric_brain.nii.gz'
    >>> vmhc_w.inputs.inputspec.symmetric_skull = 'MNI152_T1_2mm_symmetric.nii.gz'
    >>> vmhc_w.inputs.inputspec.twomm_brain_mask_dil = 'MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz'
    >>> vmhc_w.inputs.inputspec.config_file_twomm = 'T1_2_MNI152_2mm_symmetric.cnf'
    >>> vmhc_w.inputs.inputspec.standard_for_func= 'MNI152_T1_2mm.nii.gz'
    >>> vmhc_w.inputs.fwhm_input.fwhm = [4.5, 6]
    >>> vmhc_w.get_node('fwhm_input').iterables = ('fwhm', [4.5, 6])
    >>> vmhc_w.inputs.inputspec.rest_res = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/func/original/rest_res_filt.nii.gz')
    >>> vmhc_w.inputs.inputspec.reorient = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/anat/mprage_RPI.nii.gz')
    >>> vmhc_w.inputs.inputspec.brain = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/anat/mprage_brain.nii.gz')
    >>> vmhc_w.inputs.inputspec.example_func2highres_mat = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/func/original/reg/example_func2highres.mat')
    >>> vmhc_w.inputs.inputspec.rest_mask = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/func/original/rest_mask.nii.gz')
    >>> vmhc_w.run() # doctest: +SKIP

    """

    vmhc = pe.Workflow(name=name)

    inputNode = pe.Node(util.IdentityInterface(fields=[
        'rest_res', 'example_func2highres_mat', 'rest_mask',
        'standard_for_func', 'mean_functional', 'brain',
        'fnirt_nonlinear_warp', 'ants_symm_initial_xfm', 'ants_symm_rigid_xfm',
        'ants_symm_affine_xfm', 'ants_symm_warp_field'
    ]),
                        name='inputspec')

    outputNode = pe.Node(util.IdentityInterface(fields=[
        'rest_res_2symmstandard', 'VMHC_FWHM_img', 'VMHC_Z_FWHM_img',
        'VMHC_Z_stat_FWHM_img'
    ]),
                         name='outputspec')

    inputnode_fwhm = pe.Node(util.IdentityInterface(fields=['fwhm']),
                             name='fwhm_input')

    if use_ants == False:
        # Apply nonlinear registration (func to standard)
        nonlinear_func_to_standard = pe.Node(interface=fsl.ApplyWarp(),
                                             name='nonlinear_func_to_standard')

    elif use_ants == True:
        # ANTS warp image etc.
        fsl_to_itk_vmhc = create_wf_c3d_fsl_to_itk(0, name='fsl_to_itk_vmhc')

        collect_transforms_vmhc = create_wf_collect_transforms(
            0, name='collect_transforms_vmhc')

        apply_ants_xfm_vmhc = create_wf_apply_ants_warp(
            0, name='apply_ants_xfm_vmhc', ants_threads=ants_threads)

        # this has to be 3 instead of default 0 because it is a 4D file
        apply_ants_xfm_vmhc.inputs.inputspec.input_image_type = 3

    # copy and L/R swap file
    copy_and_L_R_swap = pe.Node(interface=fsl.SwapDimensions(),
                                name='copy_and_L_R_swap')
    copy_and_L_R_swap.inputs.new_dims = ('-x', 'y', 'z')

    # calculate vmhc
    pearson_correlation = pe.Node(interface=preprocess.TCorrelate(),
                                  name='pearson_correlation')
    pearson_correlation.inputs.pearson = True
    pearson_correlation.inputs.polort = -1
    pearson_correlation.inputs.outputtype = 'NIFTI_GZ'

    try:
        z_trans = pe.Node(interface=preprocess.Calc(), name='z_trans')
        z_stat = pe.Node(interface=preprocess.Calc(), name='z_stat')
    except AttributeError:
        from nipype.interfaces.afni import utils as afni_utils
        z_trans = pe.Node(interface=afni_utils.Calc(), name='z_trans')
        z_stat = pe.Node(interface=afni_utils.Calc(), name='z_stat')

    z_trans.inputs.expr = 'log((1+a)/(1-a))/2'
    z_trans.inputs.outputtype = 'NIFTI_GZ'
    z_stat.inputs.outputtype = 'NIFTI_GZ'

    NVOLS = pe.Node(util.Function(input_names=['in_files'],
                                  output_names=['nvols'],
                                  function=get_img_nvols),
                    name='NVOLS')

    generateEXP = pe.Node(util.Function(input_names=['nvols'],
                                        output_names=['expr'],
                                        function=get_operand_expression),
                          name='generateEXP')

    smooth = pe.Node(interface=fsl.MultiImageMaths(), name='smooth')

    if use_ants == False:
        vmhc.connect(inputNode, 'rest_res', smooth, 'in_file')
        vmhc.connect(inputnode_fwhm, ('fwhm', set_gauss), smooth, 'op_string')
        vmhc.connect(inputNode, 'rest_mask', smooth, 'operand_files')
        vmhc.connect(smooth, 'out_file', nonlinear_func_to_standard, 'in_file')
        vmhc.connect(inputNode, 'standard_for_func',
                     nonlinear_func_to_standard, 'ref_file')
        vmhc.connect(inputNode, 'fnirt_nonlinear_warp',
                     nonlinear_func_to_standard, 'field_file')
        ## func->anat matrix (bbreg)
        vmhc.connect(inputNode, 'example_func2highres_mat',
                     nonlinear_func_to_standard, 'premat')
        vmhc.connect(nonlinear_func_to_standard, 'out_file', copy_and_L_R_swap,
                     'in_file')
        vmhc.connect(nonlinear_func_to_standard, 'out_file',
                     pearson_correlation, 'xset')

    elif use_ants == True:
        # connections for ANTS stuff

        # functional apply warp stuff
        vmhc.connect(inputNode, 'rest_res', smooth, 'in_file')
        vmhc.connect(inputnode_fwhm, ('fwhm', set_gauss), smooth, 'op_string')
        vmhc.connect(inputNode, 'rest_mask', smooth, 'operand_files')

        vmhc.connect(smooth, 'out_file', apply_ants_xfm_vmhc,
                     'inputspec.input_image')

        vmhc.connect(inputNode, 'ants_symm_initial_xfm',
                     collect_transforms_vmhc, 'inputspec.linear_initial')

        vmhc.connect(inputNode, 'ants_symm_rigid_xfm', collect_transforms_vmhc,
                     'inputspec.linear_rigid')

        vmhc.connect(inputNode, 'ants_symm_affine_xfm',
                     collect_transforms_vmhc, 'inputspec.linear_affine')

        vmhc.connect(inputNode, 'ants_symm_warp_field',
                     collect_transforms_vmhc, 'inputspec.warp_file')

        # func->anat matrix (bbreg)
        vmhc.connect(inputNode, 'example_func2highres_mat', fsl_to_itk_vmhc,
                     'inputspec.affine_file')

        vmhc.connect(inputNode, 'brain', fsl_to_itk_vmhc,
                     'inputspec.reference_file')

        vmhc.connect(inputNode, 'mean_functional', fsl_to_itk_vmhc,
                     'inputspec.source_file')

        vmhc.connect(fsl_to_itk_vmhc, 'outputspec.itk_transform',
                     collect_transforms_vmhc, 'inputspec.fsl_to_itk_affine')

        vmhc.connect(inputNode, 'standard_for_func', apply_ants_xfm_vmhc,
                     'inputspec.reference_image')

        vmhc.connect(collect_transforms_vmhc,
                     'outputspec.transformation_series', apply_ants_xfm_vmhc,
                     'inputspec.transforms')

        vmhc.connect(apply_ants_xfm_vmhc, 'outputspec.output_image',
                     copy_and_L_R_swap, 'in_file')

        vmhc.connect(apply_ants_xfm_vmhc, 'outputspec.output_image',
                     pearson_correlation, 'xset')

    vmhc.connect(copy_and_L_R_swap, 'out_file', pearson_correlation, 'yset')
    vmhc.connect(pearson_correlation, 'out_file', z_trans, 'in_file_a')
    vmhc.connect(copy_and_L_R_swap, 'out_file', NVOLS, 'in_files')
    vmhc.connect(NVOLS, 'nvols', generateEXP, 'nvols')
    vmhc.connect(z_trans, 'out_file', z_stat, 'in_file_a')
    vmhc.connect(generateEXP, 'expr', z_stat, 'expr')

    if use_ants == False:
        vmhc.connect(nonlinear_func_to_standard, 'out_file', outputNode,
                     'rest_res_2symmstandard')

    elif use_ants == True:
        # ANTS warp outputs to outputnode
        vmhc.connect(apply_ants_xfm_vmhc, 'outputspec.output_image',
                     outputNode, 'rest_res_2symmstandard')

    vmhc.connect(pearson_correlation, 'out_file', outputNode, 'VMHC_FWHM_img')
    vmhc.connect(z_trans, 'out_file', outputNode, 'VMHC_Z_FWHM_img')
    vmhc.connect(z_stat, 'out_file', outputNode, 'VMHC_Z_stat_FWHM_img')

    return vmhc
Пример #2
0
def create_wf_edit_func(wf_name="edit_func"):
    """
    Workflow Inputs::

        inputspec.func : func file or a list of func/rest nifti file
            User input functional(T2*) Image

        inputspec.start_idx : string
            Starting volume/slice of the functional image (optional)

        inputspec.stop_idx : string
            Last volume/slice of the functional image (optional)

    Workflow Outputs::

        outputspec.edited_func : string (nifti file)
            Path to Output image with the initial few slices dropped


    Order of commands:

    - Get the start and the end volume index of the functional run. If not defined by the user, return the first and last volume.

        get_idx(in_files, stop_idx, start_idx)

    - Dropping the initial TRs. For details see `3dcalc <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dcalc.html>`_::

        3dcalc -a rest.nii.gz[4..299]
               -expr 'a'
               -prefix rest_3dc.nii.gz

    """

    # allocate a workflow object
    try:
        preproc = pe.Workflow(name=wf_name)
    except:
        logger.info("Error allocating workflow %s." + \
                    " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    # configure the workflow's input spec
    try:
        inputNode = pe.Node(
            util.IdentityInterface(fields=['func', 'start_idx', 'stop_idx']),
            name='inputspec')
    except:
        logger.info("Error allocating inputspec (wflow %s)." + \
                    " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    # configure the workflow's output spec
    try:
        outputNode = pe.Node(util.IdentityInterface(fields=['edited_func']),
                             name='outputspec')
    except:
        logger.info("Error allocating output spec (wflow %s)." + \
                    " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    # allocate a node to check that the requested edits are
    # reasonable given the data
    try:
        func_get_idx = pe.Node(util.Function(
            input_names=['in_files', 'stop_idx', 'start_idx'],
            output_names=['stopidx', 'startidx'],
            function=get_idx),
                               name='func_get_idx')
    except:
        logger.info("Error allocating get_idx function node (wflow %s)." + \
                    " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    # wire in the func_get_idx node
    try:
        preproc.connect(inputNode, 'func', func_get_idx, 'in_files')
    except:
        logger.info(
            "Error connecting 'in_files' input to get_idx function node (wflow %s)." + \
            " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    try:
        preproc.connect(inputNode, 'start_idx', func_get_idx, 'start_idx')
    except:
        logger.info(
            "Error connecting 'start_idx' input to get_idx function node (wflow %s)." + \
            " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    try:
        preproc.connect(inputNode, 'stop_idx', func_get_idx, 'stop_idx')
    except:
        logger.info(
            "Error connecting 'stop_idx' input to get_idx function node (wflow %s)." + \
            " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    # allocate a node to edit the functional file
    try:
        from nipype.interfaces.afni import utils as afni_utils
        func_drop_trs = pe.Node(interface=afni_utils.Calc(),
                                name='func_drop_trs')
    except ImportError:
        func_drop_trs = pe.Node(interface=preprocess.Calc(),
                                name='func_drop_trs')
    except:
        logger.info("Error allocating afni Calc node (wflow %s)." + \
                    " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    func_drop_trs.inputs.expr = 'a'
    func_drop_trs.inputs.outputtype = 'NIFTI_GZ'

    # wire in the inputs
    try:
        preproc.connect(inputNode, 'func', func_drop_trs, 'in_file_a')
    except:
        logger.info(
            "Error connecting 'in_file_a' input to afni Calc node (wflow %s)." + \
            " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    try:
        preproc.connect(func_get_idx, 'startidx', func_drop_trs, 'start_idx')
    except:
        logger.info(
            "Error connecting 'start_idx' input to afni Calc node (wflow %s)." + \
            " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    try:
        preproc.connect(func_get_idx, 'stopidx', func_drop_trs, 'stop_idx')
    except:
        logger.info(
            "Error connecting 'stop_idx' input to afni Calc node (wflow %s)." + \
            " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    try:
        # wire the output
        preproc.connect(func_drop_trs, 'out_file', outputNode, 'edited_func')
    except:
        logger.info("Error connecting output (wflow %s)." + \
                    " (%s:%d)" % (wf_name, dbg_file_lineno()[1]))
        raise

    return preproc
Пример #3
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
Пример #4
0
def create_alff(wf_name='alff_workflow'):
    """
    Calculate Amplitude of low frequency oscillations (ALFF) and fractional ALFF maps

    Parameters
    ----------
    wf_name : string
        Workflow name

    Returns
    -------
    alff_workflow : workflow object
        ALFF workflow

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

    Workflow Inputs::

        hp_input.hp : list of float
            high pass frequencies

        lp_input.lp : list of float
            low pass frequencies

        inputspec.rest_res : string
            Path to existing Nifti file. Nuisance signal regressed functional image.

        inputspec.rest_mask : string
            Path to existing Nifti file. A mask volume(derived by dilating the motion corrected functional volume) in native space


    Workflow Outputs::

        outputspec.alff_img : string
            Path to Nifti file. Image containing the sum of the amplitudes in the low frequency band

        outputspec.falff_img : string
            Path to Nifti file. Image containing the sum of the amplitudes in the low frequency band divided by the amplitude of the total frequency

        outputspec.alff_Z_img : string
            Path to Nifti file. Image containing Normalized ALFF Z scores across full brain in native space

        outputspec.falff_Z_img : string
            Path to Nifti file. Image containing Normalized fALFF Z scores across full brain in native space


    Order of Commands:

    - Filter the input file rest file( slice-time, motion corrected and nuisance regressed) ::
        3dBandpass -prefix residual_filtered.nii.gz
                    0.009 0.08 residual.nii.gz

    - Calculate ALFF by taking the standard deviation of the filtered file ::
        3dTstat -stdev
                -mask rest_mask.nii.gz
                -prefix residual_filtered_3dT.nii.gz
                residual_filtered.nii.gz

    - Calculate the standard deviation of the unfiltered file ::
        3dTstat -stdev
                -mask rest_mask.nii.gz
                -prefix residual_3dT.nii.gz
                residual.nii.gz

    - Calculate fALFF ::
        3dcalc -a rest_mask.nii.gz
               -b residual_filtered_3dT.nii.gz
               -c residual_3dT.nii.gz
               -expr '(1.0*bool(a))*((1.0*b)/(1.0*c))' -float

    - Normalize ALFF/fALFF to Z-score across full brain ::

        fslstats
        ALFF.nii.gz
        -k rest_mask.nii.gz
        -m > mean_ALFF.txt ; mean=$( cat mean_ALFF.txt )

        fslstats
        ALFF.nii.gz
        -k rest_mask.nii.gz
        -s > std_ALFF.txt ; std=$( cat std_ALFF.txt )

        fslmaths
        ALFF.nii.gz
        -sub ${mean}
        -div ${std}
        -mas rest_mask.nii.gz ALFF_Z.nii.gz

        fslstats
        fALFF.nii.gz
        -k rest_mask.nii.gz
        -m > mean_fALFF.txt ; mean=$( cat mean_fALFF.txt )

        fslstats
        fALFF.nii.gz
        -k rest_mask.nii.gz
        -s > std_fALFF.txt
        std=$( cat std_fALFF.txt )

        fslmaths
        fALFF.nii.gz
        -sub ${mean}
        -div ${std}
        -mas rest_mask.nii.gz
        fALFF_Z.nii.gz

    High Level Workflow Graph:

    .. image:: ../images/alff.dot.png
        :width: 500

    Detailed Workflow Graph:

    .. image:: ../images/alff_detailed.dot.png
        :width: 500


    References
    ----------

    .. [1] Zou, Q.-H., Zhu, C.-Z., Yang, Y., Zuo, X.-N., Long, X.-Y., Cao, Q.-J., Wang, Y.-F., et al. (2008). An improved approach to detection of amplitude of low-frequency fluctuation (ALFF) for resting-state fMRI: fractional ALFF. Journal of neuroscience methods, 172(1), 137-41. doi:10.10

    Examples
    --------

    >>> alff_w = create_alff()
    >>> alff_w.inputs.hp_input.hp = [0.01]
    >>> alff_w.inputs.lp_input.lp = [0.1]
    >>> alff_w.get_node('hp_input').iterables = ('hp', [0.01])
    >>> alff_w.get_node('lp_input').iterables = ('lp', [0.1])
    >>> alff_w.inputs.inputspec.rest_res = '/home/data/subject/func/rest_bandpassed.nii.gz'
    >>> alff_w.inputs.inputspec.rest_mask= '/home/data/subject/func/rest_mask.nii.gz'
    >>> alff_w.run() # doctest: +SKIP
    """

    wf = pe.Workflow(name=wf_name)
    input_node = pe.Node(
        util.IdentityInterface(fields=['rest_res', 'rest_mask']),
        name='inputspec')

    input_node_hp = pe.Node(util.IdentityInterface(fields=['hp']),
                            name='hp_input')

    input_node_lp = pe.Node(util.IdentityInterface(fields=['lp']),
                            name='lp_input')

    output_node = pe.Node(
        util.IdentityInterface(fields=['alff_img', 'falff_img']),
        name='outputspec')

    # filtering
    bandpass = pe.Node(interface=preprocess.Bandpass(),
                       name='bandpass_filtering')
    bandpass.inputs.outputtype = 'NIFTI_GZ'
    bandpass.inputs.out_file = os.path.join(os.path.curdir,
                                            'residual_filtered.nii.gz')

    wf.connect(input_node_hp, 'hp', bandpass, 'highpass')
    wf.connect(input_node_lp, 'lp', bandpass, 'lowpass')
    wf.connect(input_node, 'rest_res', bandpass, 'in_file')

    get_option_string = pe.Node(util.Function(input_names=['mask'],
                                              output_names=['option_string'],
                                              function=get_opt_string),
                                name='get_option_string')

    wf.connect(input_node, 'rest_mask', get_option_string, 'mask')

    # standard deviation over frequency
    try:
        from nipype.interfaces.afni import utils as afni_utils
        stddev_filtered = pe.Node(interface=afni_utils.TStat(),
                                  name='stddev_filtered')
    except ImportError:
        stddev_filtered = pe.Node(interface=preprocess.TStat(),
                                  name='stddev_filtered')

    stddev_filtered.inputs.outputtype = 'NIFTI_GZ'
    stddev_filtered.inputs.out_file = os.path.join(os.path.curdir,
                                                   'alff.nii.gz')

    wf.connect(bandpass, 'out_file', stddev_filtered, 'in_file')
    wf.connect(get_option_string, 'option_string', stddev_filtered, 'options')

    wf.connect(stddev_filtered, 'out_file', output_node, 'alff_img')

    # standard deviation of the unfiltered nuisance corrected image
    try:
        stddev_unfiltered = pe.Node(interface=afni_utils.TStat(),
                                    name='stddev_unfiltered')
    except UnboundLocalError:
        stddev_unfiltered = pe.Node(interface=preprocess.TStat(),
                                    name='stddev_unfiltered')

    stddev_unfiltered.inputs.outputtype = 'NIFTI_GZ'
    stddev_unfiltered.inputs.out_file = os.path.join(os.path.curdir,
                                                     'residual_3dT.nii.gz')

    wf.connect(input_node, 'rest_res', stddev_unfiltered, 'in_file')
    wf.connect(get_option_string, 'option_string', stddev_unfiltered,
               'options')

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

    falff.inputs.args = '-float'
    falff.inputs.expr = '(1.0*bool(a))*((1.0*b)/(1.0*c))'
    falff.inputs.outputtype = 'NIFTI_GZ'
    falff.inputs.out_file = os.path.join(os.path.curdir, 'falff.nii.gz')

    wf.connect(input_node, 'rest_mask', falff, 'in_file_a')
    wf.connect(stddev_filtered, 'out_file', falff, 'in_file_b')
    wf.connect(stddev_unfiltered, 'out_file', falff, 'in_file_c')

    wf.connect(falff, 'out_file', output_node, 'falff_img')

    return wf
Пример #5
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
Пример #6
0
def create_wf_edit_func(wf_name="edit_func"):
    """Workflow to edit the scan to the proscribed TRs.
    
    Workflow Inputs::

        inputspec.func : func file or a list of func/rest nifti file
            User input functional(T2*) Image

        inputspec.start_idx : string
            Starting volume/slice of the functional image (optional)

        inputspec.stop_idx : string
            Last volume/slice of the functional image (optional)

    Workflow Outputs::

        outputspec.edited_func : string (nifti file)
            Path to Output image with the initial few slices dropped


    Order of commands:

    - Get the start and the end volume index of the functional run. If not defined by the user, return the first and last volume.

        get_idx(in_files, stop_idx, start_idx)

    - Dropping the initial TRs. For details see `3dcalc <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dcalc.html>`_::

        3dcalc -a rest.nii.gz[4..299]
               -expr 'a'
               -prefix rest_3dc.nii.gz

    """

    # allocate a workflow object
    preproc = pe.Workflow(name=wf_name)

    # configure the workflow's input spec
    inputNode = pe.Node(
        util.IdentityInterface(fields=['func', 'start_idx', 'stop_idx']),
        name='inputspec')

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

    # allocate a node to check that the requested edits are
    # reasonable given the data
    func_get_idx = pe.Node(util.Function(
        input_names=['in_files', 'stop_idx', 'start_idx'],
        output_names=['stopidx', 'startidx'],
        function=get_idx),
                           name='func_get_idx')

    # wire in the func_get_idx node
    preproc.connect(inputNode, 'func', func_get_idx, 'in_files')
    preproc.connect(inputNode, 'start_idx', func_get_idx, 'start_idx')
    preproc.connect(inputNode, 'stop_idx', func_get_idx, 'stop_idx')

    # allocate a node to edit the functional file
    func_drop_trs = pe.Node(interface=afni_utils.Calc(), name='func_drop_trs')

    func_drop_trs.inputs.expr = 'a'
    func_drop_trs.inputs.outputtype = 'NIFTI_GZ'

    # wire in the inputs
    preproc.connect(inputNode, 'func', func_drop_trs, 'in_file_a')

    preproc.connect(func_get_idx, 'startidx', func_drop_trs, 'start_idx')

    preproc.connect(func_get_idx, 'stopidx', func_drop_trs, 'stop_idx')

    # wire the output
    preproc.connect(func_drop_trs, 'out_file', outputNode, 'edited_func')

    return preproc
Пример #7
0
def skullstrip_functional(skullstrip_tool='afni',
                          anatomical_mask_dilation=False,
                          wf_name='skullstrip_functional'):

    skullstrip_tool = skullstrip_tool.lower()
    if skullstrip_tool != 'afni' and skullstrip_tool != 'fsl' and skullstrip_tool != 'fsl_afni' and skullstrip_tool != 'anatomical_refined':
        raise Exception(
            "\n\n[!] Error: The 'tool' parameter of the "
            "'skullstrip_functional' workflow must be either "
            "'afni' or 'fsl' or 'fsl_afni' or 'anatomical_refined'.\n\nTool input: "
            "{0}\n\n".format(skullstrip_tool))

    wf = pe.Workflow(name=wf_name)

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

    output_node = pe.Node(
        util.IdentityInterface(fields=['func_brain', 'func_brain_mask']),
        name='outputspec')

    if skullstrip_tool == 'afni':
        func_get_brain_mask = pe.Node(interface=preprocess.Automask(),
                                      name='func_get_brain_mask_AFNI')
        func_get_brain_mask.inputs.outputtype = 'NIFTI_GZ'

        wf.connect(input_node, 'func', func_get_brain_mask, 'in_file')

        wf.connect(func_get_brain_mask, 'out_file', output_node,
                   'func_brain_mask')

    elif skullstrip_tool == 'fsl':
        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

        wf.connect(input_node, 'func', func_get_brain_mask, 'in_file')

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

        wf.connect(erode_one_voxel, 'out_file', output_node, 'func_brain_mask')

    elif skullstrip_tool == 'fsl_afni':
        skullstrip_first_pass = pe.Node(fsl.BET(frac=0.2,
                                                mask=True,
                                                functional=True),
                                        name='skullstrip_first_pass')
        bet_dilate = pe.Node(fsl.DilateImage(operation='max',
                                             kernel_shape='sphere',
                                             kernel_size=6.0,
                                             internal_datatype='char'),
                             name='skullstrip_first_dilate')
        bet_mask = pe.Node(fsl.ApplyMask(), name='skullstrip_first_mask')
        unifize = pe.Node(afni_utils.Unifize(
            t2=True,
            outputtype='NIFTI_GZ',
            args='-clfrac 0.2 -rbt 18.3 65.0 90.0',
            out_file="uni.nii.gz"),
                          name='unifize')
        skullstrip_second_pass = pe.Node(preprocess.Automask(
            dilate=1, outputtype='NIFTI_GZ'),
                                         name='skullstrip_second_pass')
        combine_masks = pe.Node(fsl.BinaryMaths(operation='mul'),
                                name='combine_masks')

        wf.connect([
            (input_node, skullstrip_first_pass, [('func', 'in_file')]),
            (skullstrip_first_pass, bet_dilate, [('mask_file', 'in_file')]),
            (bet_dilate, bet_mask, [('out_file', 'mask_file')]),
            (skullstrip_first_pass, bet_mask, [('out_file', 'in_file')]),
            (bet_mask, unifize, [('out_file', 'in_file')]),
            (unifize, skullstrip_second_pass, [('out_file', 'in_file')]),
            (skullstrip_first_pass, combine_masks, [('mask_file', 'in_file')]),
            (skullstrip_second_pass, combine_masks, [('out_file',
                                                      'operand_file')]),
            (combine_masks, output_node, [('out_file', 'func_brain_mask')])
        ])

    # Refine functional mask by registering anatomical mask to functional space
    elif skullstrip_tool == 'anatomical_refined':

        # Get functional mean to use later as reference, when transform anatomical mask to functional space
        func_skull_mean = pe.Node(interface=afni_utils.TStat(),
                                  name='func_skull_mean')
        func_skull_mean.inputs.options = '-mean'
        func_skull_mean.inputs.outputtype = 'NIFTI_GZ'

        wf.connect(input_node, 'func', func_skull_mean, 'in_file')

        # Register func to anat
        linear_reg_func_to_anat = pe.Node(interface=fsl.FLIRT(),
                                          name='linear_reg_func_to_anat')
        linear_reg_func_to_anat.inputs.cost = 'mutualinfo'
        linear_reg_func_to_anat.inputs.dof = 6

        wf.connect(func_skull_mean, 'out_file', linear_reg_func_to_anat,
                   'in_file')
        wf.connect(input_node, 'anat_skull', linear_reg_func_to_anat,
                   'reference')

        # Inverse func to anat affine
        inv_func_to_anat_affine = pe.Node(interface=fsl.ConvertXFM(),
                                          name='inv_func_to_anat_affine')
        inv_func_to_anat_affine.inputs.invert_xfm = True

        wf.connect(linear_reg_func_to_anat, 'out_matrix_file',
                   inv_func_to_anat_affine, 'in_file')

        # Transform anatomical mask to functional space
        linear_trans_mask_anat_to_func = pe.Node(
            interface=fsl.FLIRT(), name='linear_trans_mask_anat_to_func')
        linear_trans_mask_anat_to_func.inputs.apply_xfm = True
        linear_trans_mask_anat_to_func.inputs.cost = 'mutualinfo'
        linear_trans_mask_anat_to_func.inputs.dof = 6
        linear_trans_mask_anat_to_func.inputs.interp = 'nearestneighbour'

        # Dialate anatomical mask, if 'anatomical_mask_dilation : True' in config file
        if anatomical_mask_dilation:
            anat_mask_dilate = pe.Node(interface=afni.MaskTool(),
                                       name='anat_mask_dilate')
            anat_mask_dilate.inputs.dilate_inputs = '1'
            anat_mask_dilate.inputs.outputtype = 'NIFTI_GZ'

            wf.connect(input_node, 'anatomical_brain_mask', anat_mask_dilate,
                       'in_file')
            wf.connect(anat_mask_dilate, 'out_file',
                       linear_trans_mask_anat_to_func, 'in_file')

        else:
            wf.connect(input_node, 'anatomical_brain_mask',
                       linear_trans_mask_anat_to_func, 'in_file')

        wf.connect(func_skull_mean, 'out_file', linear_trans_mask_anat_to_func,
                   'reference')
        wf.connect(inv_func_to_anat_affine, 'out_file',
                   linear_trans_mask_anat_to_func, 'in_matrix_file')
        wf.connect(linear_trans_mask_anat_to_func, 'out_file', output_node,
                   'func_brain_mask')

    func_edge_detect = pe.Node(interface=afni_utils.Calc(),
                               name='func_extract_brain')

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

    wf.connect(input_node, 'func', func_edge_detect, 'in_file_a')

    if skullstrip_tool == 'afni':
        wf.connect(func_get_brain_mask, 'out_file', func_edge_detect,
                   'in_file_b')
    elif skullstrip_tool == 'fsl':
        wf.connect(erode_one_voxel, 'out_file', func_edge_detect, 'in_file_b')
    elif skullstrip_tool == 'fsl_afni':
        wf.connect(combine_masks, 'out_file', func_edge_detect, 'in_file_b')
    elif skullstrip_tool == 'anatomical_refined':
        wf.connect(linear_trans_mask_anat_to_func, 'out_file',
                   func_edge_detect, 'in_file_b')

    wf.connect(func_edge_detect, 'out_file', output_node, 'func_brain')

    return wf
Пример #8
0
def skullstrip_functional(tool='afni', wf_name='skullstrip_functional'):

    tool = tool.lower()
    if tool != 'afni' and tool != 'fsl' and tool != 'fsl_afni':
        raise Exception("\n\n[!] Error: The 'tool' parameter of the "
                        "'skullstrip_functional' workflow must be either "
                        "'afni' or 'fsl'.\n\nTool input: "
                        "{0}\n\n".format(tool))

    wf = pe.Workflow(name=wf_name)

    input_node = pe.Node(util.IdentityInterface(fields=['func']),
                         name='inputspec')

    output_node = pe.Node(
        util.IdentityInterface(fields=['func_brain', 'func_brain_mask']),
        name='outputspec')

    if tool == 'afni':
        func_get_brain_mask = pe.Node(interface=preprocess.Automask(),
                                      name='func_get_brain_mask_AFNI')
        func_get_brain_mask.inputs.outputtype = 'NIFTI_GZ'

        wf.connect(input_node, 'func', func_get_brain_mask, 'in_file')

        wf.connect(func_get_brain_mask, 'out_file', output_node,
                   'func_brain_mask')

    elif tool == 'fsl':
        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

        wf.connect(input_node, 'func', func_get_brain_mask, 'in_file')

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

        wf.connect(erode_one_voxel, 'out_file', output_node, 'func_brain_mask')

    elif tool == 'fsl_afni':
        skullstrip_first_pass = pe.Node(fsl.BET(frac=0.2,
                                                mask=True,
                                                functional=True),
                                        name='skullstrip_first_pass')
        bet_dilate = pe.Node(fsl.DilateImage(operation='max',
                                             kernel_shape='sphere',
                                             kernel_size=6.0,
                                             internal_datatype='char'),
                             name='skullstrip_first_dilate')
        bet_mask = pe.Node(fsl.ApplyMask(), name='skullstrip_first_mask')
        unifize = pe.Node(afni_utils.Unifize(
            t2=True,
            outputtype='NIFTI_GZ',
            args='-clfrac 0.2 -rbt 18.3 65.0 90.0',
            out_file="uni.nii.gz"),
                          name='unifize')
        skullstrip_second_pass = pe.Node(preprocess.Automask(
            dilate=1, outputtype='NIFTI_GZ'),
                                         name='skullstrip_second_pass')
        combine_masks = pe.Node(fsl.BinaryMaths(operation='mul'),
                                name='combine_masks')

        wf.connect([
            (input_node, skullstrip_first_pass, [('func', 'in_file')]),
            (skullstrip_first_pass, bet_dilate, [('mask_file', 'in_file')]),
            (bet_dilate, bet_mask, [('out_file', 'mask_file')]),
            (skullstrip_first_pass, bet_mask, [('out_file', 'in_file')]),
            (bet_mask, unifize, [('out_file', 'in_file')]),
            (unifize, skullstrip_second_pass, [('out_file', 'in_file')]),
            (skullstrip_first_pass, combine_masks, [('mask_file', 'in_file')]),
            (skullstrip_second_pass, combine_masks, [('out_file',
                                                      'operand_file')]),
            (combine_masks, output_node, [('out_file', 'func_brain_mask')])
        ])

    func_edge_detect = pe.Node(interface=afni_utils.Calc(),
                               name='func_extract_brain')

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

    wf.connect(input_node, 'func', func_edge_detect, 'in_file_a')

    if tool == 'afni':
        wf.connect(func_get_brain_mask, 'out_file', func_edge_detect,
                   'in_file_b')
    elif tool == 'fsl':
        wf.connect(erode_one_voxel, 'out_file', func_edge_detect, 'in_file_b')
    elif tool == 'fsl_afni':
        wf.connect(combine_masks, 'out_file', func_edge_detect, 'in_file_b')

    wf.connect(func_edge_detect, 'out_file', output_node, 'func_brain')

    return wf