Beispiel #1
0
def anatomical_preprocessing():
    '''
    Inputs:
        MP2RAGE Skull stripped image using Spectre-2010

    Workflow:
        1. reorient to RPI
        2. create a brain mask

    Returns:
        brain
        brain_mask

    '''
    # define workflow
    flow = Workflow('anat_preprocess')
    inputnode = Node(util.IdentityInterface(
        fields=['anat', 'anat_gm', 'anat_wm', 'anat_csf', 'anat_first']),
                     name='inputnode')
    outputnode = Node(util.IdentityInterface(fields=[
        'brain',
        'brain_gm',
        'brain_wm',
        'brain_csf',
        'brain_first',
        'brain_mask',
    ]),
                      name='outputnode')

    reorient = Node(interface=preprocess.Resample(), name='anat_reorient')
    reorient.inputs.orientation = 'RPI'
    reorient.inputs.outputtype = 'NIFTI'

    erode = Node(interface=fsl.ErodeImage(), name='anat_preproc')

    reorient_gm = reorient.clone('anat_preproc_gm')
    reorient_wm = reorient.clone('anat_preproc_wm')
    reorient_cm = reorient.clone('anat_preproc_csf')
    reorient_first = reorient.clone('anat_preproc_first')

    make_mask = Node(interface=fsl.UnaryMaths(), name='anat_preproc_mask')
    make_mask.inputs.operation = 'bin'

    # connect workflow nodes
    flow.connect(inputnode, 'anat', reorient, 'in_file')
    flow.connect(inputnode, 'anat_gm', reorient_gm, 'in_file')
    flow.connect(inputnode, 'anat_wm', reorient_wm, 'in_file')
    flow.connect(inputnode, 'anat_csf', reorient_cm, 'in_file')
    flow.connect(inputnode, 'anat_first', reorient_first, 'in_file')
    flow.connect(reorient, 'out_file', erode, 'in_file')
    flow.connect(erode, 'out_file', make_mask, 'in_file')
    flow.connect(make_mask, 'out_file', outputnode, 'brain_mask')

    flow.connect(erode, 'out_file', outputnode, 'brain')
    flow.connect(reorient_gm, 'out_file', outputnode, 'brain_gm')
    flow.connect(reorient_wm, 'out_file', outputnode, 'brain_wm')
    flow.connect(reorient_cm, 'out_file', outputnode, 'brain_csf')
    flow.connect(reorient_first, 'out_file', outputnode, 'brain_first')

    return flow
    def __init__(self, name, base_dir=None):

        super(BrainExtractionWorkflow, self).__init__(name, base_dir)

        # Segmentation
        # ============
        seg_node = npe.MapNode(name="Segmentation",
                               iterfield="data",
                               interface=spm.Segment())
        seg_node.inputs.gm_output_type = [False, False, True]
        seg_node.inputs.wm_output_type = [False, False, True]
        seg_node.inputs.csf_output_type = [False, False, True]
        add1_node = npe.MapNode(name="AddGMWM",
                                iterfield=["in_file", "operand_file"],
                                interface=fsl.BinaryMaths())
        add1_node.inputs.operation = 'add'
        add2_node = npe.MapNode(name="AddGMWMCSF",
                                iterfield=["in_file", "operand_file"],
                                interface=fsl.BinaryMaths())
        add2_node.inputs.operation = 'add'
        dil_node = npe.MapNode(name="Dilate",
                               iterfield="in_file",
                               interface=fsl.DilateImage())
        dil_node.inputs.operation = 'mean'
        ero_node = npe.MapNode(name="Erode",
                               iterfield="in_file",
                               interface=fsl.ErodeImage())
        thre_node = npe.MapNode(name="Threshold",
                                iterfield="in_file",
                                interface=fsl.Threshold())
        thre_node.inputs.thresh = 0.5
        fill_node = npe.MapNode(name="Fill",
                                iterfield="in_file",
                                interface=fsl.UnaryMaths())
        fill_node.inputs.operation = 'fillh'
        mask_node = npe.MapNode(name="ApplyMask",
                                iterfield=["in_file", "mask_file"],
                                interface=fsl.ApplyMask())

        mask_node.inputs.output_type = str("NIFTI")

        self.connect([
            (seg_node, add1_node, [('native_gm_image', 'in_file')]),
            (seg_node, add1_node, [('native_wm_image', 'operand_file')]),
            (seg_node, add2_node, [('native_csf_image', 'in_file')]),
            (add1_node, add2_node, [('out_file', 'operand_file')]),
            (add2_node, dil_node, [('out_file', 'in_file')]),
            (dil_node, ero_node, [('out_file', 'in_file')]),
            (ero_node, thre_node, [('out_file', 'in_file')]),
            (thre_node, fill_node, [('out_file', 'in_file')]),
            (fill_node, mask_node, [('out_file', 'mask_file')]),
        ])
Beispiel #3
0
def create_anat_noise_roi_workflow(SinkTag="func_preproc",
                                   wf_name="create_noise_roi"):
    """
    Creates an anatomical noise ROI for use with compcor

    inputs are awaited from the (BBR-based) func2anat registration
    and are already transformed to functional space

    Tamas Spisak
    2018


    """
    import os
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import nipype.interfaces.fsl as fsl
    import PUMI.utils.globals as globals

    # Basic interface class generates identity mappings
    inputspec = pe.Node(
        utility.IdentityInterface(fields=['wm_mask', 'ventricle_mask']),
        name='inputspec')

    # Basic interface class generates identity mappings
    outputspec = pe.Node(utility.IdentityInterface(fields=['noise_roi']),
                         name='outputspec')

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)
    wf = nipype.Workflow(wf_name)

    # erode WM mask in functional space
    erode_mask = pe.MapNode(fsl.ErodeImage(),
                            iterfield=['in_file'],
                            name="erode_wm_mask")
    wf.connect(inputspec, 'wm_mask', erode_mask, 'in_file')

    # add ventricle and eroded WM masks
    add_masks = pe.MapNode(fsl.ImageMaths(op_string=' -add'),
                           iterfield=['in_file', 'in_file2'],
                           name="addimgs")

    wf.connect(inputspec, 'ventricle_mask', add_masks, 'in_file')
    wf.connect(erode_mask, 'out_file', add_masks, 'in_file2')

    wf.connect(add_masks, 'out_file', outputspec, 'noise_roi')

    return wf
Beispiel #4
0
def fmri_bmsk_workflow(name='fMRIBrainMask', use_bet=False):
    """
    Computes a brain mask for the input :abbr:`fMRI (functional MRI)`
    dataset

    .. workflow::

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


    """

    workflow = pe.Workflow(name=name)
    inputnode = pe.Node(niu.IdentityInterface(fields=['in_file']),
                        name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(fields=['out_file']),
                         name='outputnode')

    if not use_bet:
        afni_msk = pe.Node(afni.Automask(
            outputtype='NIFTI_GZ'), name='afni_msk')

        # Connect brain mask extraction
        workflow.connect([
            (inputnode, afni_msk, [('in_file', 'in_file')]),
            (afni_msk, outputnode, [('out_file', 'out_file')])
        ])

    else:
        bet_msk = pe.Node(fsl.BET(mask=True, functional=True), name='bet_msk')
        erode = pe.Node(fsl.ErodeImage(), name='erode')

        # Connect brain mask extraction
        workflow.connect([
            (inputnode, bet_msk, [('in_file', 'in_file')]),
            (bet_msk, erode, [('mask_file', 'in_file')]),
            (erode, outputnode, [('out_file', 'out_file')])
        ])

    return workflow
Beispiel #5
0
    def qsm_pipeline(self, **name_maps):
        """
        Process dual echo data for QSM (TE=[7.38, 22.14])

        NB: Default values come from the STI-Suite
        """
        pipeline = self.new_pipeline(
            name='qsm_pipeline',
            name_maps=name_maps,
            desc="Resolve QSM from t2star coils",
            citations=[sti_cites, fsl_cite, matlab_cite])

        erosion = pipeline.add(
            'mask_erosion',
            fsl.ErodeImage(kernel_shape='sphere',
                           kernel_size=self.parameter('qsm_erosion_size'),
                           output_type='NIFTI'),
            inputs={'in_file': ('brain_mask', nifti_gz_format)},
            requirements=[fsl_req.v('5.0.8')],
            wall_time=15,
            mem_gb=12)

        # If we have multiple echoes we can combine the phase images from
        # each channel into a single image. Otherwise for single echo sequences
        # we need to perform QSM on each coil separately and then combine
        # afterwards.
        if self.branch('qsm_dual_echo'):
            # Combine channels to produce phase and magnitude images
            channel_combine = pipeline.add(
                'channel_combine',
                HIPCombineChannels(),
                inputs={
                    'magnitudes_dir': ('mag_channels', multi_nifti_gz_format),
                    'phases_dir': ('phase_channels', multi_nifti_gz_format)
                })

            # Unwrap phase using Laplacian unwrapping
            unwrap = pipeline.add(
                'unwrap',
                UnwrapPhase(padsize=self.parameter('qsm_padding')),
                inputs={
                    'voxelsize': ('voxel_sizes', float),
                    'in_file': (channel_combine, 'phase')
                },
                requirements=[matlab_req.v('r2017a'),
                              sti_req.v(2.2)])

            # Remove background noise
            vsharp = pipeline.add(
                "vsharp",
                VSharp(mask_manip="imerode({}>0, ball(5))"),
                inputs={
                    'voxelsize': ('voxel_sizes', float),
                    'in_file': (unwrap, 'out_file'),
                    'mask': (erosion, 'out_file')
                },
                requirements=[matlab_req.v('r2017a'),
                              sti_req.v(2.2)])

            # Run QSM iLSQR
            pipeline.add('qsmrecon',
                         QSMiLSQR(mask_manip="{}>0",
                                  padsize=self.parameter('qsm_padding')),
                         inputs={
                             'voxelsize': ('voxel_sizes', float),
                             'te': ('echo_times', float),
                             'B0': ('main_field_strength', float),
                             'H': ('main_field_orient', float),
                             'in_file': (vsharp, 'out_file'),
                             'mask': (vsharp, 'new_mask')
                         },
                         outputs={'qsm': ('qsm', nifti_format)},
                         requirements=[matlab_req.v('r2017a'),
                                       sti_req.v(2.2)])

        else:
            # Dialate eroded mask
            dialate = pipeline.add(
                'dialate',
                DialateMask(dialation=self.parameter('qsm_mask_dialation')),
                inputs={'in_file': (erosion, 'out_file')},
                requirements=[matlab_req.v('r2017a')])

            # List files for the phases of separate channel
            list_phases = pipeline.add(
                'list_phases',
                ListDir(sort_key=coil_sort_key,
                        filter=CoilEchoFilter(self.parameter('qsm_echo'))),
                inputs={
                    'directory': ('phase_channels', multi_nifti_gz_format)
                })

            # List files for the phases of separate channel
            list_mags = pipeline.add(
                'list_mags',
                ListDir(sort_key=coil_sort_key,
                        filter=CoilEchoFilter(self.parameter('qsm_echo'))),
                inputs={'directory': ('mag_channels', multi_nifti_gz_format)})

            # Generate coil specific masks
            mask_coils = pipeline.add(
                'mask_coils',
                MaskCoils(dialation=self.parameter('qsm_mask_dialation')),
                inputs={
                    'masks': (list_mags, 'files'),
                    'whole_brain_mask': (dialate, 'out_file')
                },
                requirements=[matlab_req.v('r2017a')])

            # Unwrap phase
            unwrap = pipeline.add(
                'unwrap',
                BatchUnwrapPhase(padsize=self.parameter('qsm_padding')),
                inputs={
                    'voxelsize': ('voxel_sizes', float),
                    'in_file': (list_phases, 'files')
                },
                requirements=[matlab_req.v('r2017a'),
                              sti_req.v(2.2)])

            # Background phase removal
            vsharp = pipeline.add(
                "vsharp",
                BatchVSharp(mask_manip='{}>0'),
                inputs={
                    'voxelsize': ('voxel_sizes', float),
                    'mask': (mask_coils, 'out_files'),
                    'in_file': (unwrap, 'out_file')
                },
                requirements=[matlab_req.v('r2017a'),
                              sti_req.v(2.2)])

            first_echo_time = pipeline.add(
                'first_echo',
                Select(index=0),
                inputs={'inlist': ('echo_times', float)})

            # Perform channel-wise QSM
            coil_qsm = pipeline.add(
                'coil_qsmrecon',
                BatchQSMiLSQR(mask_manip="{}>0",
                              padsize=self.parameter('qsm_padding')),
                inputs={
                    'voxelsize': ('voxel_sizes', float),
                    'B0': ('main_field_strength', float),
                    'H': ('main_field_orient', float),
                    'in_file': (vsharp, 'out_file'),
                    'mask': (vsharp, 'new_mask'),
                    'te': (first_echo_time, 'out')
                },
                requirements=[matlab_req.v('r2017a'),
                              sti_req.v(2.2)],
                wall_time=45)  # FIXME: Should be dependent on number of coils

            # Combine channel QSM by taking the median coil value
            pipeline.add('combine_qsm',
                         MedianInMasks(),
                         inputs={
                             'channels': (coil_qsm, 'out_file'),
                             'channel_masks': (vsharp, 'new_mask'),
                             'whole_brain_mask': (dialate, 'out_file')
                         },
                         outputs={'qsm': ('out_file', nifti_format)},
                         requirements=[matlab_req.v('r2017a')])
        return pipeline
Beispiel #6
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
Beispiel #7
0
                           name="reorient_func")

myanatproc = anatproc.AnatProc(stdreg=_regtype_)
myanatproc.inputs.inputspec.bet_fract_int_thr = 0.3  # feel free to adjust, a nice bet is important!
myanatproc.inputs.inputspec.bet_vertical_gradient = -0.3  # feel free to adjust, a nice bet is important!
# try scripts/opt_bet.py to optimise these parameters

mybbr = bbr.bbr_workflow()
# Add arbitrary number of nii images wthin the same space. The default is to add csf and wm masks for anatcompcor calculation.
#myadding=adding.addimgs_workflow(numimgs=2)
add_masks = pe.MapNode(fsl.ImageMaths(op_string=' -add'),
                       iterfield=['in_file', 'in_file2'],
                       name="addimgs")

# TODO_ready: erode compcor noise mask!!!!
erode_mask = pe.MapNode(fsl.ErodeImage(),
                        iterfield=['in_file'],
                        name="erode_compcor_mask")


def pickindex(vec, i):
    return [x[i] for x in vec]


myfuncproc = funcproc.FuncProc()

#create atlas matching this space
resample_atlas = pe.Node(
    interface=afni.Resample(
        outputtype='NIFTI_GZ',
        in_file="/Users/tspisak/data/atlases/MIST/Parcellations/MIST_7.nii.gz",
Beispiel #8
0
def fieldmapper(TE1=4.9,
                TE2=7.3,
                dwell_time=0.00035,
                unwarp_direction="y-",
                SinkTag="func_fieldmapcorr",
                wf_name="fieldmap_correction"):
    import os
    import PUMI.utils.globals as globals

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)
    ###########################################
    # HERE INSERT PORCUPINE GENERATED CODE
    # MUST DEFINE
    # OutJSON: file path to JSON file contaioning the output strings to be returned
    # variables can (should) use variable SinkDir (defined here as function argument)
    ###########################################
    # To do
    ###########################################
    # adjust number of cores with psutil.cpu_count()
    ###########################################
    # also subtract:
    # analysisflow = nipype.Workflow('FieldMapper')
    # analysisflow.base_dir = '.'
    ###########################################
    # Here comes the generated code
    ###########################################

    # This is a Nipype generator. Warning, here be dragons.
    # !/usr/bin/env python
    import sys
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import nipype.interfaces.fsl as fsl
    import PUMI.utils.utils_math as utils_math
    import nipype.interfaces.io as io
    import PUMI.utils.QC as qc
    import PUMI.utils.utils_convert as utils_convert

    OutJSON = SinkDir + "/outputs.JSON"

    # Basic interface class generates identity mappings
    inputspec = pe.Node(utility.IdentityInterface(fields=[
        'in_file', 'magnitude', 'phase', 'TE1', 'TE2', 'dwell_time',
        'unwarp_direction'
    ]),
                        name='inputspec')
    #defaults:
    #inputspec.inputs.func = func
    #inputspec.inputs.magnitude = magnitude
    #inputspec.inputs.phase = phase
    inputspec.inputs.TE1 = TE1
    inputspec.inputs.TE2 = TE2
    inputspec.inputs.dwell_time = dwell_time
    inputspec.inputs.unwarp_direction = unwarp_direction

    # Wraps command **bet**
    bet = pe.MapNode(interface=fsl.BET(), name='bet', iterfield=['in_file'])
    bet.inputs.mask = True

    # Wraps command **fslmaths**
    erode = pe.MapNode(interface=fsl.ErodeImage(),
                       name='erode',
                       iterfield=['in_file'])

    # Wraps command **fslmaths**
    erode2 = pe.MapNode(interface=fsl.ErodeImage(),
                        name='erode2',
                        iterfield=['in_file'])

    # Custom interface wrapping function SubTwo
    subtract = pe.Node(interface=utils_math.SubTwo, name='subtract')

    # Custom interface wrapping function Abs
    abs = pe.Node(interface=utils_math.Abs, name='abs')

    # Wraps command **fsl_prepare_fieldmap**
    preparefm = pe.MapNode(interface=fsl.PrepareFieldmap(),
                           name='preparefm',
                           iterfield=['in_phase', 'in_magnitude'])

    # Wraps command **fugue**
    fugue = pe.MapNode(interface=fsl.FUGUE(),
                       name='fugue',
                       iterfield=['in_file', 'fmap_in_file', 'mask_file'])

    # Generic datasink module to store structured outputs
    outputspec = pe.Node(interface=io.DataSink(), name='outputspec')
    outputspec.inputs.base_directory = SinkDir
    outputspec.inputs.regexp_substitutions = [
        ("func_fieldmapcorr/_NodeName_.{13}", "")
    ]

    # Generic datasink module to store structured outputs
    outputspec2 = pe.Node(interface=io.DataSink(), name='outputspec2')
    outputspec2.inputs.base_directory = SinkDir
    outputspec2.inputs.regexp_substitutions = [("_NodeName_.{13}", "")]

    myqc_orig = qc.vol2png("fielmap_correction", tag="original")
    myqc_unwarp = qc.vol2png("fielmap_correction", tag="unwarped")

    # Create a workflow to connect all those nodes
    analysisflow = nipype.Workflow(wf_name)
    analysisflow.base_dir = '.'
    analysisflow.connect(preparefm, 'out_fieldmap', outputspec2, 'fieldmap')
    analysisflow.connect(abs, 'abs', preparefm, 'delta_TE')
    analysisflow.connect(subtract, 'dif', abs, 'x')
    analysisflow.connect(inputspec, 'unwarp_direction', fugue,
                         'unwarp_direction')
    analysisflow.connect(fugue, 'unwarped_file', outputspec,
                         'func_fieldmapcorr')
    analysisflow.connect(preparefm, 'out_fieldmap', fugue, 'fmap_in_file')
    analysisflow.connect(erode2, 'out_file', fugue, 'mask_file')
    analysisflow.connect(bet, 'mask_file', erode2, 'in_file')
    analysisflow.connect(inputspec, 'dwell_time', fugue, 'dwell_time')
    analysisflow.connect(inputspec, 'in_file', fugue, 'in_file')
    analysisflow.connect(bet, 'out_file', erode, 'in_file')
    analysisflow.connect(inputspec, 'TE2', subtract, 'b')
    analysisflow.connect(inputspec, 'TE1', subtract, 'a')
    analysisflow.connect(inputspec, 'phase', preparefm, 'in_phase')
    analysisflow.connect(erode, 'out_file', preparefm, 'in_magnitude')
    analysisflow.connect(inputspec, 'magnitude', bet, 'in_file')

    analysisflow.connect(inputspec, 'magnitude', myqc_orig,
                         'inputspec.bg_image')
    analysisflow.connect(inputspec, 'in_file', myqc_orig,
                         'inputspec.overlay_image')
    analysisflow.connect(inputspec, 'magnitude', myqc_unwarp,
                         'inputspec.bg_image')
    analysisflow.connect(fugue, 'unwarped_file', myqc_unwarp,
                         'inputspec.overlay_image')

    # Run the workflow
    #plugin = 'MultiProc'  # adjust your desired plugin here
    #plugin_args = {'n_procs': psutil.cpu_count()}  # adjust to your number of cores
    #analysisflow.write_graph(graph2use='flat', format='png', simple_form=False)
    #analysisflow.run(plugin=plugin, plugin_args=plugin_args)

    ####################################################################################################
    # Porcupine generated code ends here
    ####################################################################################################

    #load and return json
    # you have to be aware the keys of the json map here

    #ret = json.load(open(OutJSON))
    #return ret['func_fieldmapcorr'], ret['fieldmap']
    return analysisflow
Beispiel #9
0
def create_mask_from_seg_pipe(params={}, name="mask_from_seg_pipe"):
    """
    Description:  mask from segmentation tissues

    #TODO To be added if required (was in old_segment before)

    Function:

        - Compute union of those 3 tissues;
        - Apply morphological opening on the union mask
        - Fill holes

    Inputs:

        mask_gm, mask_wm:
            binary mask for grey matter and white matter
    Outputs:

        fill_holes.out_file:
            filled mask after erode

        fill_holes_dil.out_file
            filled mask after dilate
    """

    # creating pipeline
    seg_pipe = pe.Workflow(name=name)

    # Creating inputnode
    inputnode = pe.Node(niu.IdentityInterface(
        fields=['mask_gm', 'mask_wm', 'mask_csf', 'indiv_params']),
                        name='inputnode')

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

    seg_pipe.connect(inputnode, 'mask_gm', bin_gm, 'in_file')

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

    seg_pipe.connect(inputnode, 'mask_csf', bin_csf, 'in_file')

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

    seg_pipe.connect(inputnode, 'mask_wm', bin_wm, 'in_file')

    # Compute union of the 3 tissues
    # Done with 2 fslmaths as it seems to hard to do it
    wmgm_union = pe.Node(fsl.BinaryMaths(), name="wmgm_union")
    wmgm_union.inputs.operation = "add"
    seg_pipe.connect(bin_gm, 'out_file', wmgm_union, 'in_file')
    seg_pipe.connect(bin_wm, 'out_file', wmgm_union, 'operand_file')

    tissues_union = pe.Node(fsl.BinaryMaths(), name="tissues_union")
    tissues_union.inputs.operation = "add"
    seg_pipe.connect(wmgm_union, 'out_file', tissues_union, 'in_file')
    seg_pipe.connect(bin_csf, 'out_file', tissues_union, 'operand_file')

    # Opening (dilating) mask
    dilate_mask = NodeParams(fsl.DilateImage(),
                             params=parse_key(params, "dilate_mask"),
                             name="dilate_mask")

    dilate_mask.inputs.operation = "mean"  # Arbitrary operation
    seg_pipe.connect(tissues_union, 'out_file', dilate_mask, 'in_file')

    # fill holes of dilate_mask
    fill_holes_dil = pe.Node(BinaryFillHoles(), name="fill_holes_dil")
    seg_pipe.connect(dilate_mask, 'out_file', fill_holes_dil, 'in_file')

    # Eroding mask
    erode_mask = NodeParams(fsl.ErodeImage(),
                            params=parse_key(params, "erode_mask"),
                            name="erode_mask")

    seg_pipe.connect(tissues_union, 'out_file', erode_mask, 'in_file')

    # fill holes of erode_mask
    fill_holes = pe.Node(BinaryFillHoles(), name="fill_holes")
    seg_pipe.connect(erode_mask, 'out_file', fill_holes, 'in_file')

    # merge to index
    merge_indexed_mask = NodeParams(
        interface=niu.Function(input_names=[
            "mask_csf_file", "mask_wm_file", "mask_gm_file", "index_csf",
            "index_gm", "index_wm"
        ],
                               output_names=['indexed_mask'],
                               function=merge_masks),
        params=parse_key(params, "merge_indexed_mask"),
        name="merge_indexed_mask")

    seg_pipe.connect(bin_gm, 'out_file', merge_indexed_mask, "mask_gm_file")
    seg_pipe.connect(bin_wm, 'out_file', merge_indexed_mask, "mask_wm_file")
    seg_pipe.connect(bin_csf, 'out_file', merge_indexed_mask, "mask_csf_file")

    return seg_pipe
Beispiel #10
0
def apply_fieldmap(file_fmap_magn, file_fmap_phase, file_epi, file_epi_moco, file_surf,
                   delta_te=1.02, smooth=2.5, udir="y-", bw=16.304, nerode=1, cleanup=True):
    """
    This function computes a deformation field from a fieldmap acquisition and applies the inverse
    transformation to the undistorted surface. The following steps are performed:
        1. get median time series
        2. skullstrip epi
        3. register fieldmap to epi
        4. mask fieldmap
        5. prepare field
        6. get deforamtion field
        7. apply inverse deformation to surfaces.
        8. remove intermediate files (optional).
        
    To run the script, FSL and Freesurfer have to be in the PATH environment. The basenames of the 
    surface files should be in freesurfer convention with the hemisphere indicated as prefix.
    Inputs:
        *fiele_fmap_magn: fieldmap magnitude image.
        *file_fmap_phase: fieldmap phase difference image.
        *file_epi: filename of raw time series.
        *file_epi_moco: filname of motion corrected time series.
        *file_surf: list of surface filnames.
        *delta_te: echo time difference of fieldmap in ms.
        *smooth: smoothing kernel for fieldmap unmasking.
        *udir: direction for fieldmap unmasking.
        *bw: BandwidthPerPixelPhaseEncode in Hz/px.
        *nerode: number of skullstrip mask eroding iterations.
        *cleanup: removes temporary files at the end of the script (boolean).
    
    created by Daniel Haenelt
    Date created: 31-01-2020
    Last modified: 20-06-2020
    """
    import os
    import numpy as np
    import nibabel as nb
    from nipype.interfaces import fsl
    from lib.skullstrip.skullstrip_epi import skullstrip_epi
    from lib.io.get_filename import get_filename
    from lib.cmap.generate_coordinate_mapping import generate_coordinate_mapping
    from lib.surface.deform_surface import deform_surface
    
    # prepare path and filename
    path_fmap0, name_fmap0, ext_fmap0 = get_filename(file_fmap_magn)
    path_fmap1, name_fmap1, ext_fmap1 = get_filename(file_fmap_phase)
    path_data, name_data, ext_data = get_filename(file_epi)
    path_udata, name_udata, ext_udata = get_filename(file_epi_moco)
    
    # filename with file extension
    name_fmap0 += ext_fmap0
    name_fmap1 += ext_fmap1
    name_data += ext_data
    name_udata += ext_udata
    
    # change directory to fieldmap directory
    os.chdir(path_fmap0)
    
    # get matrix size in phase encoding direction from uncorrected epi
    data = nb.load(file_epi)
    phase_encode = data.header.get_dim_info()[1]
    ImageMatrixPhaseEncode = data.header["dim"][phase_encode+1]
    
    # calculate median epi
    udata = nb.load(file_epi_moco)
    arr_udata = udata.get_fdata()
    arr_udata_median = np.median(arr_udata, axis=3)
    udata_median = nb.Nifti1Image(arr_udata_median, udata.affine, udata.header)
    udata_median.header["dim"][0] = 3
    udata_median.header["dim"][4] = 1
    nb.save(udata_median, os.path.join(path_udata, "median_"+name_udata))
    
    # calculate skullstrip mask of that image
    skullstrip_epi(os.path.join(path_udata, "median_"+name_udata),
                   roi_size=10, 
                   scale=0.75, 
                   nerode=1, 
                   ndilate=2, 
                   savemask=True, 
                   cleanup=True)
    
    # erode skullstrip mask
    for j in range(nerode):
        erode = fsl.ErodeImage()
        erode.inputs.in_file = os.path.join(path_udata, "mask_median_"+name_udata)
        erode.inputs.output_type = "NIFTI"
        erode.inputs.out_file = os.path.join(path_udata, "mask_median_"+name_udata)
        erode.run()
    
    # register fmap1 to median epi (fsl.FLIRT)
    flirt = fsl.FLIRT()
    flirt.inputs.cost_func = "mutualinfo"
    flirt.inputs.dof = 6
    flirt.inputs.interp = "trilinear" # trlinear, nearestneighbour, sinc or spline
    flirt.inputs.in_file = file_fmap_magn
    flirt.inputs.reference = os.path.join(path_udata, "median_"+name_udata)
    flirt.inputs.output_type = "NIFTI"
    flirt.inputs.out_file = os.path.join(path_fmap0, "r"+name_fmap0)
    flirt.inputs.out_matrix_file = os.path.join(path_fmap0, "fmap2epi.txt")
    flirt.run() 
    
    # apply registration to fmap2
    applyxfm = fsl.preprocess.ApplyXFM()
    applyxfm.inputs.in_file = file_fmap_phase
    applyxfm.inputs.reference = os.path.join(path_udata, "median_"+name_udata)
    applyxfm.inputs.in_matrix_file = os.path.join(path_fmap0, "fmap2epi.txt")
    applyxfm.inputs.interp = "trilinear"
    applyxfm.inputs.output_type = "NIFTI"
    applyxfm.inputs.out_file = os.path.join(path_fmap1, "r"+name_fmap1)
    applyxfm.inputs.apply_xfm = True
    applyxfm.run() 
    
    # apply skullstrip mask to fmap1 and fmap2 and save with same header information
    fmap1_img = nb.load(os.path.join(path_fmap0, "r"+name_fmap0))
    arr_fmap1 = fmap1_img.get_fdata()
    fmap2_img = nb.load(os.path.join(path_fmap1, "r"+name_fmap1))
    arr_fmap2 = fmap2_img.get_fdata()
    mask_img = nb.load(os.path.join(path_udata, "mask_median_"+name_udata))
    arr_mask = mask_img.get_fdata()
    
    arr_fmap1 = arr_fmap1 * arr_mask
    arr_fmap2 = (arr_fmap2 * arr_mask) 
    arr_fmap2 = arr_fmap2 + np.abs(np.min(arr_fmap2))
    arr_fmap2 = arr_fmap2 / np.max(arr_fmap2) * 4095 # rescale phase image to be within 0-4095
    
    fmap1_img = nb.Nifti1Image(arr_fmap1, fmap1_img.affine, fmap1_img.header)
    nb.save(fmap1_img, os.path.join(path_fmap0, "pr"+name_fmap0))
    fmap2_img = nb.Nifti1Image(arr_fmap2, fmap1_img.affine, fmap1_img.header)
    nb.save(fmap2_img, os.path.join(path_fmap1, "pr"+name_fmap1))
    
    # prepare fieldmap (saves fieldmap in rad/s)
    prepare = fsl.PrepareFieldmap()
    prepare.inputs.in_magnitude = os.path.join(path_fmap0, "pr"+name_fmap0)
    prepare.inputs.in_phase = os.path.join(path_fmap1, "pr"+name_fmap1)
    prepare.inputs.out_fieldmap = os.path.join(path_fmap0, "fieldmap.nii")
    prepare.inputs.delta_TE = delta_te
    prepare.inputs.scanner = "SIEMENS"
    prepare.inputs.output_type = "NIFTI" 
    prepare.run() 
    
    # effective echo spacing in s
    dwell_time = 1/(bw * ImageMatrixPhaseEncode)
    
    # unmask fieldmap (fsl.FUGUE)
    fugue = fsl.preprocess.FUGUE()
    fugue.inputs.in_file = os.path.join(path_udata, name_udata)
    fugue.inputs.dwell_time = dwell_time
    fugue.inputs.fmap_in_file = os.path.join(path_fmap0, "fieldmap.nii")
    fugue.inputs.smooth3d = smooth
    fugue.inputs.unwarp_direction = udir
    fugue.inputs.save_shift = True
    fugue.inputs.shift_out_file = os.path.join(path_fmap0, "vdm.nii")
    fugue.inputs.output_type = "NIFTI"
    fugue.run() 
    
    # warp coordinate mapping
    generate_coordinate_mapping(file_epi, 
                                0, 
                                path_fmap0, 
                                suffix="fmap", 
                                time=False, 
                                write_output=True)
    
    # apply inverse fieldmap to coordinate mapping
    fugue = fsl.preprocess.FUGUE()
    fugue.inputs.in_file = os.path.join(path_fmap0, "cmap_fmap.nii")
    fugue.inputs.shift_in_file = os.path.join(path_fmap0, "vdm.nii")
    fugue.inputs.forward_warping = False
    fugue.inputs.unwarp_direction = udir
    fugue.inputs.output_type = "NIFTI"
    fugue.run()
    
    # apply cmap to surface
    for i in range(len(file_surf)): 
        path_surf, hemi, name_surf = get_filename(file_surf[i])
        deform_surface(input_surf=file_surf[i], 
                       input_orig=os.path.join(path_udata, "median_"+name_udata), 
                       input_deform=os.path.join(path_fmap0, "cmap_fmap_unwarped.nii"), 
                       input_target=os.path.join(path_udata, "median_"+name_udata), 
                       hemi=hemi, 
                       path_output=path_surf, 
                       input_mask=None,
                       interp_method="trilinear",
                       smooth_iter=0,
                       flip_faces=False, 
                       cleanup=True)
    
    # delete created files
    if cleanup:
        os.remove(os.path.join(path_fmap0, "cmap_fmap.nii"))
        os.remove(os.path.join(path_fmap0, "cmap_fmap_unwarped.nii"))
        os.remove(os.path.join(path_fmap0, "fieldmap.nii"))
        os.remove(os.path.join(path_fmap0, "fmap2epi.txt"))
        os.remove(os.path.join(path_fmap1, os.path.splitext(name_fmap1)[0]+"_flirt.mat"))
        os.remove(os.path.join(path_fmap0, "r"+name_fmap0))
        os.remove(os.path.join(path_fmap0, "pr"+name_fmap0))
        os.remove(os.path.join(path_fmap1, "r"+name_fmap1))
        os.remove(os.path.join(path_fmap1, "pr"+name_fmap1))
        os.remove(os.path.join(path_fmap0, os.path.splitext(name_udata)[0])+"_unwarped.nii")
        os.remove(os.path.join(path_fmap0, "vdm.nii"))
        os.remove(os.path.join(path_udata, "mask_median_"+name_udata))
        os.remove(os.path.join(path_udata, "median_"+name_udata))
        os.remove(os.path.join(path_udata, "pmedian_"+name_udata))
Beispiel #11
0
def create_old_segment_pipe(params_template, params={},
                            name="old_segment_pipe"):
    """
    Description: Extract brain using tissues masks output by SPM's old_segment
        function:

        - Segment the T1 using given priors;
        - Threshold GM, WM and CSF maps;
        - Compute union of those 3 tissues;
        - Apply morphological opening on the union mask
        - Fill holes

    Inputs:

        inputnode:
            T1: T1 file name

        arguments:
            priors: list of file names

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

            name: pipeline name (default = "old_segment_pipe")

    Outputs:

        fill_holes.out_file:
            filled mask after erode

        fill_holes_dil.out_file
            filled mask after dilate

        threshold_gm, threshold_wm, threshold_csf.out_file:
            resp grey matter, white matter, and csf after thresholding

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

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

    # Segment in to 6 tissues
    segment = NodeParams(spm.Segment(),
                         params=parse_key(params, "segment"),
                         name="old_segment")

    segment.inputs.tissue_prob_maps = [params_template["template_gm"],
                                       params_template["template_wm"],
                                       params_template["template_csf"]]

    be_pipe.connect(inputnode, 'T1', segment, 'data')

    # Threshold GM, WM and CSF
    thd_nodes = {}
    for tissue in ['gm', 'wm', 'csf']:

        tmp_node = NodeParams(fsl.Threshold(),
                              params=parse_key(params, "threshold_" + tissue),
                              name="threshold_" + tissue)

        be_pipe.connect(segment, 'native_' + tissue + '_image',
                        tmp_node, 'in_file')

        be_pipe.connect(
            inputnode, ('indiv_params', parse_key, "threshold_" + tissue),
            tmp_node, "indiv_params")

        thd_nodes[tissue] = tmp_node

    # Compute union of the 3 tissues
    # Done with 2 fslmaths as it seems to hard to do it
    wmgm_union = pe.Node(fsl.BinaryMaths(), name="wmgm_union")
    wmgm_union.inputs.operation = "add"
    be_pipe.connect(thd_nodes['gm'], 'out_file', wmgm_union, 'in_file')
    be_pipe.connect(thd_nodes['wm'], 'out_file', wmgm_union, 'operand_file')

    tissues_union = pe.Node(fsl.BinaryMaths(), name="tissues_union")
    tissues_union.inputs.operation = "add"
    be_pipe.connect(wmgm_union, 'out_file', tissues_union, 'in_file')
    be_pipe.connect(thd_nodes['csf'], 'out_file',
                    tissues_union, 'operand_file')

    # Opening
    dilate_mask = NodeParams(fsl.DilateImage(),
                             params=parse_key(params, "dilate_mask"),
                             name="dilate_mask")

    dilate_mask.inputs.operation = "mean"  # Arbitrary operation
    be_pipe.connect(tissues_union, 'out_file', dilate_mask, 'in_file')

    # Eroding mask
    erode_mask = NodeParams(fsl.ErodeImage(),
                            params=parse_key(params, "erode_mask"),
                            name="erode_mask")

    be_pipe.connect(tissues_union, 'out_file', erode_mask, 'in_file')

    # fill holes of erode_mask
    fill_holes = pe.Node(BinaryFillHoles(), name="fill_holes")
    be_pipe.connect(erode_mask, 'out_file', fill_holes, 'in_file')

    # fill holes of dilate_mask
    fill_holes_dil = pe.Node(BinaryFillHoles(), name="fill_holes_dil")
    be_pipe.connect(dilate_mask, 'out_file', fill_holes_dil, 'in_file')

    return be_pipe
Beispiel #12
0
    def __init__(self, settings):
        # call base constructor
        super().__init__(settings)

        # define input/output node
        self.set_input(['func', 'refimg', 'func_aligned'])
        self.set_output(['warp_fmc', 'refimg'])

        # define datasink substitutions
        self.set_subs([('_roi', '_reference'), ('_Warped_mean', '_moco'),
                       ('_Warped', '_realign')])

        # define regex substitutions
        self.set_resubs([(r'_avg_epi\d{1,3}', ''),
                         (r'_applyantsunwarp\d{1,3}', ''),
                         (r'_realign\d{1,3}', '')])

        # get magnitude and phase
        self.get_metadata = MapNode(Function(
            input_names=['epi_file', 'bids_dir'],
            output_names=[
                'magnitude', 'phasediff', 'TE', 'echospacing', 'ped'
            ],
            function=get_metadata),
                                    iterfield=['epi_file'],
                                    name='get_metadata')
        self.get_metadata.inputs.bids_dir = settings['bids_dir']

        # get skullstrip of magnitude image
        self.skullstrip_magnitude = MapNode(fsl.BET(robust=True,
                                                    output_type='NIFTI_GZ'),
                                            iterfield=['in_file'],
                                            name='skullstrip_magnitude')

        # erode skullstripped magnitude image (3x)
        self.erode_magnitude = []
        for n in range(3):
            self.erode_magnitude.append(
                MapNode(fsl.ErodeImage(output_type='NIFTI_GZ', ),
                        iterfield=['in_file'],
                        name='erode_magnitude{}'.format(n)))

        # create mask from eroded magnitude image
        self.create_mask = MapNode(fsl.maths.MathsCommand(
            args='-bin', output_type='NIFTI_GZ'),
                                   iterfield=['in_file'],
                                   name='create_mask')

        # calculate fieldmap image (rad/s)
        self.calculate_fieldmap = MapNode(
            Function(input_names=['phasediff', 'magnitude', 'TE'],
                     output_names=['out_file'],
                     function=fsl_prepare_fieldmap),
            iterfield=['phasediff', 'magnitude', 'TE'],
            name='calculate_fieldmap')

        # apply mask to fieldmap image
        self.apply_mask = MapNode(fsl.ApplyMask(output_type='NIFTI_GZ'),
                                  iterfield=['in_file', 'mask_file'],
                                  name='apply_mask')

        # unmask fieldmap image through interpolation
        self.unmask = MapNode(fsl.FUGUE(save_unmasked_fmap=True,
                                        output_type='NIFTI_GZ'),
                              iterfield=['fmap_in_file', 'mask_file'],
                              name='unmask')

        # average epi image
        self.avg_epi = MapNode(fsl.MeanImage(output_type='NIFTI_GZ'),
                               iterfield=['in_file'],
                               name='avg_epi')

        # skullstrip average epi image
        self.skullstrip_avg_epi = MapNode(fsl.BET(
            robust=True,
            output_type="NIFTI_GZ",
        ),
                                          iterfield=['in_file'],
                                          name='skullstrip_avg_epi')

        # register field map images to the averaged epi image
        self.register_magnitude = MapNode(fsl.FLIRT(output_type='NIFTI_GZ',
                                                    dof=6),
                                          iterfield=['in_file', 'reference'],
                                          name='register_magnitude')
        self.register_fieldmap = MapNode(
            fsl.FLIRT(output_type='NIFTI_GZ', apply_xfm=True),
            iterfield=['in_file', 'reference', 'in_matrix_file'],
            name='register_fieldmap')
        self.register_mask = MapNode(
            fsl.FLIRT(output_type='NIFTI_GZ',
                      apply_xfm=True,
                      interp='nearestneighbour'),
            iterfield=['in_file', 'reference', 'in_matrix_file'],
            name='register_mask')

        # unwarp epis fieldmap
        self.unwarp_epis = MapNode(fsl.FUGUE(save_shift=True,
                                             output_type='NIFTI_GZ'),
                                   iterfield=[
                                       'in_file', 'dwell_time', 'fmap_in_file',
                                       'mask_file', 'unwarp_direction'
                                   ],
                                   name='unwarp_epis')

        # Convert vsm to ANTS warp
        self.convertvsm2antswarp = MapNode(Function(
            input_names=['in_file', 'ped'],
            output_names=['out_file'],
            function=convertvsm2ANTSwarp),
                                           iterfield=['in_file', 'ped'],
                                           name='convertvsm2antswarp')

        # apply fmc ant warp
        self.applyantsunwarp = MapNode(
            ants.ApplyTransforms(out_postfix='_unwarped',
                                 num_threads=settings['num_threads']),
            iterfield=['input_image', 'reference_image', 'transforms'],
            name='applyantsunwarp')
        self.applyantsunwarp.n_procs = settings['num_threads']

        # get refimg transform
        self.get_refimg_transform = Node(Function(
            input_names=['transforms', 'run'],
            output_names=['transform'],
            function=lambda transforms, run: transforms[run]),
                                         name='get_refimg_transform')
        self.get_refimg_transform.inputs.run = settings['func_reference_run']

        # apply fmc ant warp to refimg
        self.applyantsunwarprefimg = Node(ants.ApplyTransforms(
            out_postfix='_unwarped', num_threads=settings['num_threads']),
                                          name='applyantsunwarprefimg')
        self.applyantsunwarprefimg.n_procs = settings['num_threads']

        # create the output name for the realignment
        self.create_prefix = MapNode(Function(input_names=['filename'],
                                              output_names=['basename'],
                                              function=get_prefix),
                                     iterfield=['filename'],
                                     name='create_prefix')

        # realiqn unwarped to refimgs
        self.realign = MapNode(ants.RegistrationSynQuick(
            transform_type='a', num_threads=settings['num_threads']),
                               iterfield=['moving_image', 'output_prefix'],
                               name='realign')
        self.realign.n_procs = settings['num_threads']

        # combine transforms
        self.combine_transforms = MapNode(
            Function(input_names=['avgepi', 'reference', 'unwarp', 'realign'],
                     output_names=['fmc_warp'],
                     function=combinetransforms),
            iterfield=['avgepi', 'reference', 'unwarp', 'realign'],
            name='combine_transforms')
        self.combine_transforms.n_procs = settings['num_threads']
def run_workflow():
    # ------------------ Specify variables
    ds_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))

    data_dir = ds_root
    output_dir = 'skull-stripped-pre-mc'
    working_dir = 'workingdirs/skull-strip-functionals'

    subject_list = ['eddy']
    session_list = ['20170511']

    # ------------------ Input Files
    infosource = Node(IdentityInterface(fields=[
        'subject_id',
        'session_id',
    ]),
                      name="infosource")

    infosource.iterables = [
        ('session_id', session_list),
        ('subject_id', subject_list),
    ]
    # SelectFiles
    templates = {
        'masks':
        'transformed-manual-func-mask/sub-{subject_id}/ses-{session_id}/func/'
        #  'sub-{subject_id}_ses-{session_id}*run-01_bold_res-1x1x1'
        'sub-{subject_id}_ses-{session_id}*_bold_res-1x1x1'
        '_transformedmask.nii.gz',
        'functionals':
        #  'func_unwarp/sub-{subject_id}/ses-{session_id}/func/'
        'resampled-isotropic-1mm/sub-{subject_id}/ses-{session_id}/func/'
        #  'sub-{subject_id}_ses-{session_id}*run-01_bold_res-1x1x1_preproc'
        'sub-{subject_id}_ses-{session_id}*_bold_res-1x1x1_preproc'
        '.nii.gz',
    }
    inputfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                      name="input_files")

    # ------------------ Output Files
    # Datasink
    outputfiles = Node(nio.DataSink(base_directory=ds_root,
                                    container=output_dir,
                                    parameterization=True),
                       name="output_files")

    # Use the following DataSink output substitutions
    outputfiles.inputs.substitutions = [
        ('subject_id_', 'sub-'),
        ('session_id_', 'ses-'),
        ('/funcbrain/', '/'),
        ('_preproc_masked.nii.gz', '_brain.nii.gz'),
    ]
    # Put result into a BIDS-like format
    outputfiles.inputs.regexp_substitutions = [
        (r'_ses-([a-zA-Z0-9]*)_sub-([a-zA-Z0-9]*)', r'sub-\2/ses-\1'),
        (r'_funcbrain[0-9]*/', r'func/'),
    ]

    # -------------------------------------------- Create Pipeline
    workflow = Workflow(name='transform_manual_func_mask',
                        base_dir=os.path.join(ds_root, working_dir))

    workflow.connect([(infosource, inputfiles, [
        ('subject_id', 'subject_id'),
        ('session_id', 'session_id'),
    ])])

    dilmask = MapNode(fsl.DilateImage(
        operation='mean',
        kernel_shape=('boxv'),
        kernel_size=7,
    ),
                      iterfield=['in_file'],
                      name='dilmask')
    workflow.connect(inputfiles, 'masks', dilmask, 'in_file')

    erode = MapNode(fsl.ErodeImage(
        kernel_shape=('boxv'),
        kernel_size=3,
    ),
                    iterfield=['in_file'],
                    name='erode')

    workflow.connect(dilmask, 'out_file', erode, 'in_file')

    funcbrain = MapNode(fsl.ApplyMask(),
                        iterfield=['in_file', 'mask_file'],
                        name='funcbrain')
    workflow.connect(
        erode,
        'out_file',
        funcbrain,
        'mask_file',
    )
    workflow.connect(
        inputfiles,
        'functionals',
        funcbrain,
        'in_file',
    )
    workflow.connect(funcbrain, 'out_file', outputfiles, 'funcbrain')

    workflow.stop_on_first_crash = True
    workflow.keep_inputs = True
    workflow.remove_unnecessary_outputs = False
    workflow.write_graph()
    workflow.run()
Beispiel #14
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
def create_EPI_DistCorr(use_BET, wf_name='epi_distcorr'):
    """
    Fieldmap correction takes in an input magnitude image which is Skull Stripped (Tight).
    The magnitude images are obtained from each echo series. It also requires a phase image
    as an input, the phase image is a subtraction of the two phase images from each echo.

    Created on Thu Nov  9 10:44:47 2017
    @author: nrajamani

    Order of commands and inputs:

    -- SkullStrip:   3d-SkullStrip (or FSL-BET) is used to strip the non-brain (tissue) regions
                     from the fMRI
                     Parameters: -f, default: 0.5
                     in_file: fmap_mag
    -- fslmath_mag:  Magnitude image is eroded using the -ero option in fslmath, in order to remove
                     the non-zero voxels
                     Parameters: -ero
                     in_file:fmap_mag
    -- bet_anat   :  Brain extraction of the anat file to provide as an input for the epi-registration interface
                     Parameters: -f, default: 0.5
                     in_file: anat_file
    -- fast_anat  :  Fast segmentation to provide partial volume files of the anat file, which is further processed
                     to provide the white mater segmentation input for the epi-registration interface.
                     The most important output required from this is the second segment, (e.g.,'T1_brain_pve_2.nii.gz')
                     Parameters: -img_type = 1
                               -bias_iters = 10 (-I)
                               -bias_lowpass = 10 (-l)
                     in_file: brain_extracted anat_file
    -- fslmath_anat: The output of the FAST interface is then analyzed to select all the voxels with more than 50%
                     partial volume into the binary mask
                     Parameters: -thr = 0.5
                     in_file : T1_brain_pve_2
    -- fslmath_wmseg:The selected voxels are now used to create a binary mask which would can then be sent as the
                     white matter segmentation (wm_seg)
                     Parameters: -bin
                     in_file: T1_brain_pve_2
    -- Prepare      :Preparing the fieldmap.
                     Parameters: -deltaTE = default, 2.46 ms
                                 -Scanner = SIEMENS
                     in_files: fmap_phase
                               fmap_magnitude
                     For more details, check:https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FUGUE/Guide
    -- FUGUE        :One of the steps in EPI-DistCorrection toolbox, it unwarps the fieldmaps
                     Parameters: dwell_to_asymm ratio = (0.77e-3 * 3)/(2.46e-3)
                                 dwell time = 0.0005 ms
                                 in_file = field map which is a 4D image (containing 2 unwarpped image)
    """

    preproc = pe.Workflow(name=wf_name)

    inputNode = pe.Node(
        util.IdentityInterface(fields=['anat_file', 'fmap_pha', 'fmap_mag']),
        name='inputspec')

    inputNode_delTE = pe.Node(util.IdentityInterface(fields=['deltaTE']),
                              name='deltaTE_input')

    inputNode_dwellT = pe.Node(util.IdentityInterface(fields=['dwellT']),
                               name='dwellT_input')

    inputNode_dwell_asym_ratio = pe.Node(
        util.IdentityInterface(fields=['dwell_asym_ratio']),
        name='dwell_asym_ratio_input')

    inputNode_bet_frac = pe.Node(util.IdentityInterface(fields=['bet_frac']),
                                 name='bet_frac_input')

    inputNode_afni_threshold = pe.Node(
        util.IdentityInterface(fields=['afni_threshold']),
        name='afni_threshold_input')

    outputNode = pe.Node(util.IdentityInterface(
        fields=['fieldmap', 'fmap_despiked', 'fmapmagbrain', 'fieldmapmask']),
                         name='outputspec')

    # Skull-strip, outputs a masked image file
    if use_BET == False:
        skullstrip_args = pe.Node(util.Function(input_names=['shrink_fac'],
                                                output_names=['expr'],
                                                function=createAFNIiterable),
                                  name='distcorr_skullstrip_arg')

        preproc.connect(inputNode_afni_threshold, 'afni_threshold',
                        skullstrip_args, 'shrink_fac')

        bet = pe.Node(interface=afni.SkullStrip(), name='bet')
        bet.inputs.outputtype = 'NIFTI_GZ'
        preproc.connect(skullstrip_args, 'expr', bet, 'args')
        preproc.connect(inputNode, 'fmap_mag', bet, 'in_file')
        preproc.connect(bet, 'out_file', outputNode, 'magnitude_image')
    else:
        bet = pe.Node(interface=fsl.BET(), name='bet')
        bet.inputs.output_type = 'NIFTI_GZ'
        preproc.connect(inputNode_bet_frac, 'bet_frac', bet, 'frac')
        preproc.connect(inputNode, 'fmap_mag', bet, 'in_file')
        preproc.connect(bet, 'out_file', outputNode, 'magnitude_image')

    # Prepare Fieldmap

    # prepare the field map
    prepare = pe.Node(interface=fsl.epi.PrepareFieldmap(), name='prepare')
    prepare.inputs.output_type = "NIFTI_GZ"
    preproc.connect(inputNode_delTE, 'deltaTE', prepare, 'delta_TE')
    preproc.connect(inputNode, 'fmap_pha', prepare, 'in_phase')
    preproc.connect(bet, 'out_file', prepare, 'in_magnitude')
    preproc.connect(prepare, 'out_fieldmap', outputNode, 'fieldmap')

    # erode the masked magnitude image
    fslmath_mag = pe.Node(interface=fsl.ErodeImage(), name='fslmath_mag')
    preproc.connect(bet, 'out_file', fslmath_mag, 'in_file')
    preproc.connect(fslmath_mag, 'out_file', outputNode, 'fmapmagbrain')

    # calculate the absolute value of the eroded and masked magnitude
    # image
    fslmath_abs = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_abs')
    fslmath_abs.inputs.operation = 'abs'
    preproc.connect(fslmath_mag, 'out_file', fslmath_abs, 'in_file')
    preproc.connect(fslmath_abs, 'out_file', outputNode, 'fmapmag_abs')

    # binarize the absolute value of the eroded and masked magnitude
    # image
    fslmath_bin = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_bin')
    fslmath_bin.inputs.operation = 'bin'
    preproc.connect(fslmath_abs, 'out_file', fslmath_bin, 'in_file')
    preproc.connect(fslmath_bin, 'out_file', outputNode, 'fmapmag_bin')

    # take the absolute value of the fieldmap calculated in the prepare step
    fslmath_mask_1 = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_mask_1')
    fslmath_mask_1.inputs.operation = 'abs'
    preproc.connect(prepare, 'out_fieldmap', fslmath_mask_1, 'in_file')
    preproc.connect(fslmath_mask_1, 'out_file', outputNode, 'fieldmapmask_abs')

    # binarize the absolute value of the fieldmap calculated in the prepare step
    fslmath_mask_2 = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_mask_2')
    fslmath_mask_2.inputs.operation = 'bin'
    preproc.connect(fslmath_mask_1, 'out_file', fslmath_mask_2, 'in_file')
    preproc.connect(fslmath_mask_2, 'out_file', outputNode, 'fieldmapmask_bin')

    # multiply together the binarized magnitude and fieldmap images
    fslmath_mask = pe.Node(interface=fsl.BinaryMaths(), name='fslmath_mask')
    fslmath_mask.inputs.operation = 'mul'
    preproc.connect(fslmath_mask_2, 'out_file', fslmath_mask, 'in_file')
    preproc.connect(fslmath_bin, 'out_file', fslmath_mask, 'operand_file')
    preproc.connect(fslmath_mask, 'out_file', outputNode, 'fieldmapmask')

    # Note for the user. Ensure the phase image is within 0-4096 (upper
    # threshold is 90% of 4096), fsl_prepare_fieldmap will only work in the
    # case of the SIEMENS format. #Maybe we could use deltaTE also as an
    # option in the GUI.

    # fugue
    fugue1 = pe.Node(interface=fsl.FUGUE(), name='fugue1')
    fugue1.inputs.save_fmap = True
    fugue1.outputs.fmap_out_file = 'fmap_rads'
    preproc.connect(fslmath_mask, 'out_file', fugue1, 'mask_file')
    preproc.connect(inputNode_dwellT, 'dwellT', fugue1, 'dwell_time')
    preproc.connect(inputNode_dwell_asym_ratio, 'dwell_asym_ratio', fugue1,
                    'dwell_to_asym_ratio')
    preproc.connect(prepare, 'out_fieldmap', fugue1, 'fmap_in_file')
    preproc.connect(fugue1, 'fmap_out_file', outputNode, 'fmap_despiked')

    return preproc
Beispiel #16
0
moco = pe.Node(fsl.MCFLIRT(cost='normmi'),
                  name="mcflirt")
extractb0 = pe.Node(fsl.ExtractROI(t_size=1, t_min=1),
                       name = "extractb0")
bet = pe.Node(fsl.BET(frac=0.1, mask=True),
                 name="bet_func")
bet2 = pe.Node(fsl.BET(frac=0.1),
                 name="bet_struc")
segment = pe.Node(fsl.FAST(out_basename='fast_'),
                     name="fastSeg")
flirting = pe.Node(fsl.FLIRT(cost_func='normmi', dof=7, searchr_x=[-180, 180],
                             searchr_y=[-180, 180], searchr_z=[-180,180]),
                   name="struc_2_func")
applyxfm = pe.MapNode(fsl.ApplyXfm(apply_xfm = True),
                      name="MaskEPI", iterfield=['in_file'])
erosion = pe.MapNode(fsl.ErodeImage(),
                     name="erode_masks", iterfield=['in_file'])
regcheckoverlay = pe.Node(fsl.Overlay(auto_thresh_bg=True, stat_thresh=(100,500)),
                         name='OverlayCoreg')
regcheck = pe.Node(fsl.Slicer(),
                  name='CheckCoreg')
#filterfeeder = pe.MapNode(fsl.ImageMeants(eig=True, ))

datasink = pe.Node(nio.DataSink(),
                   name='datasink')
datasink.inputs.base_directory = "/Users/Katie/Dropbox/Data/habenula/derivatives/hb_test"

# Connect alllllll the nodes!!
hb_test_wf.connect(subj_iterable, 'subject_id', DataGrabber, 'subject_id')
hb_test_wf.connect(DataGrabber, 'bold', moco, 'in_file')
hb_test_wf.connect(moco, 'out_file', extractb0, 'in_file')
Beispiel #17
0
#Basic interface class generates identity mappings
NodeHash_604000eb5d20 = pe.Node(utility.IdentityInterface(fields=['func','magnitude','phase','TE1','TE2','dwell_time','unwarp_direction']), name = 'NodeName_604000eb5d20')
NodeHash_604000eb5d20.inputs.func = func
NodeHash_604000eb5d20.inputs.magnitude = magnitude
NodeHash_604000eb5d20.inputs.phase = phase
NodeHash_604000eb5d20.inputs.TE1 = TE1
NodeHash_604000eb5d20.inputs.TE2 = TE2
NodeHash_604000eb5d20.inputs.dwell_time = dwell_time
NodeHash_604000eb5d20.inputs.unwarp_direction = unwarp_direction

#Wraps command **bet**
NodeHash_604000cba700 = pe.MapNode(interface = fsl.BET(), name = 'NodeName_604000cba700', iterfield = ['in_file'])
NodeHash_604000cba700.inputs.mask = True

#Wraps command **fslmaths**
NodeHash_600001ab26c0 = pe.MapNode(interface = fsl.ErodeImage(), name = 'NodeName_600001ab26c0', iterfield = ['in_file'])

#Wraps command **fslmaths**
NodeHash_60c0018a6e40 = pe.MapNode(interface = fsl.ErodeImage(), name = 'NodeName_60c0018a6e40', iterfield = ['in_file'])

#Custom interface wrapping function SubTwo
NodeHash_60c0018a4860 = pe.Node(interface = utils_math.SubTwo, name = 'NodeName_60c0018a4860')

#Custom interface wrapping function Abs
NodeHash_600001eab220 = pe.Node(interface = utils_math.Abs, name = 'NodeName_600001eab220')

#Wraps command **fsl_prepare_fieldmap**
NodeHash_6000018b2600 = pe.MapNode(interface = fsl.PrepareFieldmap(), name = 'NodeName_6000018b2600', iterfield = ['in_phase', 'in_magnitude'])

#Wraps command **fugue**
NodeHash_60c0018a5a60 = pe.MapNode(interface = fsl.FUGUE(), name = 'NodeName_60c0018a5a60', iterfield = ['in_file', 'fmap_in_file', 'mask_file'])
Beispiel #18
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