Example #1
0
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'])

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

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

#Very simple frontend for storing values into a JSON file.
Example #2
0
def fieldmap_correction(name='fieldmap_correction', nocheck=False):
    """

    .. deprecated:: 0.9.3
      Use :func:`nipype.workflows.dmri.preprocess.epi.sdc_fmb` instead.


    Fieldmap-based retrospective correction of EPI images for the susceptibility distortion
    artifact (Jezzard et al., 1995). Fieldmap images are assumed to be already registered
    to EPI data, and a brain mask is required.

    Replaces the former workflow, still available as create_epidewarp_pipeline().  The difference
    with respect the epidewarp pipeline is that now the workflow uses the new fsl_prepare_fieldmap
    available as of FSL 5.0.


    Example
    -------

    >>> nipype_epicorrect = fieldmap_correction('nipype_epidewarp')
    >>> nipype_epicorrect.inputs.inputnode.in_file = 'diffusion.nii'
    >>> nipype_epicorrect.inputs.inputnode.in_mask = 'brainmask.nii'
    >>> nipype_epicorrect.inputs.inputnode.fieldmap_pha = 'phase.nii'
    >>> nipype_epicorrect.inputs.inputnode.fieldmap_mag = 'magnitude.nii'
    >>> nipype_epicorrect.inputs.inputnode.te_diff = 2.46
    >>> nipype_epicorrect.inputs.inputnode.epi_echospacing = 0.77
    >>> nipype_epicorrect.inputs.inputnode.encoding_direction = 'y'
    >>> nipype_epicorrect.run() # doctest: +SKIP

    Inputs::

        inputnode.in_file - The volume acquired with EPI sequence
        inputnode.in_mask - A brain mask
        inputnode.fieldmap_pha - The phase difference map from the fieldmapping, registered to in_file
        inputnode.fieldmap_mag - The magnitud maps (usually 4D, one magnitude per GRE scan)
                                 from the fieldmapping, registered to in_file
        inputnode.te_diff - Time difference in msec. between TE in ms of the fieldmapping (usually a GRE sequence).
        inputnode.epi_echospacing - The effective echo spacing (aka dwell time) in msec. of the EPI sequence. If
                                    EPI was acquired with parallel imaging, then the effective echo spacing is
                                    eff_es = es / acc_factor.
        inputnode.encoding_direction - The phase encoding direction in EPI acquisition (default y)
        inputnode.vsm_sigma - Sigma value of the gaussian smoothing filter applied to the vsm (voxel shift map)


    Outputs::

        outputnode.epi_corrected
        outputnode.out_vsm

    """

    warnings.warn(('This workflow is deprecated from v.1.0.0, use '
                   'nipype.workflows.dmri.preprocess.epi.sdc_fmb instead'),
                  DeprecationWarning)

    inputnode = pe.Node(niu.IdentityInterface(fields=[
        'in_file', 'in_mask', 'fieldmap_pha', 'fieldmap_mag', 'te_diff',
        'epi_echospacing', 'vsm_sigma', 'encoding_direction'
    ]),
                        name='inputnode')

    pipeline = pe.Workflow(name=name)

    # Keep first frame from magnitude
    select_mag = pe.Node(fsl.utils.ExtractROI(t_size=1, t_min=0),
                         name='select_magnitude')

    # Mask magnitude (it is required by PreparedFieldMap)
    mask_mag = pe.Node(fsl.maths.ApplyMask(), name='mask_magnitude')

    # Run fsl_prepare_fieldmap
    fslprep = pe.Node(fsl.PrepareFieldmap(), name='prepare_fieldmap')

    if nocheck:
        fslprep.inputs.nocheck = True

    # Use FUGUE to generate the voxel shift map (vsm)
    vsm = pe.Node(fsl.FUGUE(save_shift=True), name='generate_vsm')

    # VSM demean is not anymore present in the epi_reg script
    # vsm_mean = pe.Node(niu.Function(input_names=['in_file', 'mask_file', 'in_unwarped'], output_names=[
    #                   'out_file'], function=_vsm_remove_mean), name='vsm_mean_shift')

    # fugue_epi
    dwi_split = pe.Node(niu.Function(input_names=['in_file'],
                                     output_names=['out_files'],
                                     function=_split_dwi),
                        name='dwi_split')

    # 'fugue -i %s -u %s --loadshift=%s --mask=%s' % ( vol_name, out_vol_name, vsm_name, mask_name )
    dwi_applyxfm = pe.MapNode(fsl.FUGUE(icorr=True, save_shift=False),
                              iterfield=['in_file'],
                              name='dwi_fugue')
    # Merge back all volumes
    dwi_merge = pe.Node(fsl.utils.Merge(dimension='t'), name='dwi_merge')

    outputnode = pe.Node(
        niu.IdentityInterface(fields=['epi_corrected', 'out_vsm']),
        name='outputnode')

    pipeline.connect([
        (inputnode, select_mag, [('fieldmap_mag', 'in_file')]),
        (inputnode, fslprep, [('fieldmap_pha', 'in_phase'),
                              ('te_diff', 'delta_TE')]),
        (inputnode, mask_mag, [('in_mask', 'mask_file')]),
        (select_mag, mask_mag, [('roi_file', 'in_file')]),
        (mask_mag, fslprep, [('out_file', 'in_magnitude')]),
        (fslprep, vsm, [('out_fieldmap', 'phasemap_in_file')]),
        (inputnode, vsm, [('fieldmap_mag', 'in_file'),
                          ('encoding_direction', 'unwarp_direction'),
                          (('te_diff', _ms2sec), 'asym_se_time'),
                          ('vsm_sigma', 'smooth2d'),
                          (('epi_echospacing', _ms2sec), 'dwell_time')]),
        (mask_mag, vsm, [('out_file', 'mask_file')]),
        (inputnode, dwi_split, [('in_file', 'in_file')]),
        (dwi_split, dwi_applyxfm, [('out_files', 'in_file')]),
        (mask_mag, dwi_applyxfm, [('out_file', 'mask_file')]),
        (vsm, dwi_applyxfm, [('shift_out_file', 'shift_in_file')]),
        (inputnode, dwi_applyxfm, [('encoding_direction', 'unwarp_direction')
                                   ]),
        (dwi_applyxfm, dwi_merge, [('unwarped_file', 'in_files')]),
        (dwi_merge, outputnode, [('merged_file', 'epi_corrected')]),
        (vsm, outputnode, [('shift_out_file', 'out_vsm')])
    ])

    return pipeline
Example #3
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
Example #4
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))
                     name='magVolTrim')

magBiasCorrect = pe.Node(ants.N4BiasFieldCorrection(
    dimension=3,
    n_iterations=[50, 50, 30, 20],
    convergence_threshold=0.0,
    shrink_factor=3,
    bspline_fitting_distance=300),
                         name='magBiasCorrect')

magExtract = pe.Node(fsl.BET(robust=True, frac=0.6, vertical_gradient=0.18),
                     name='magExtract')

erode = pe.Node(fsl.maths.ErodeImage(output_type='NIFTI_GZ'), name='erode')

prepareFmap = pe.Node(fsl.PrepareFieldmap(delta_TE=deltaTE, scanner='SIEMENS'),
                      name='prepareFmap')

filterFmap = pe.Node(fsl.preprocess.FUGUE(median_2dfilter=True,
                                          save_fmap=True),
                     name='filterFmap')

# Warp fieldmap before registration
magWarp = pe.Node(fsl.preprocess.FUGUE(dwell_time=effectEcho,
                                       unwarp_direction=unwarpDir,
                                       forward_warping=True,
                                       nokspace=True),
                  name='magWarp')

epiMean = pe.Node(fsl.maths.MeanImage(dimension='T', output_type='NIFTI_GZ'),
                  name='epiMean')