def remove_bias(name='bias_correct'):
    """
    This workflow estimates a single multiplicative bias field from the
    averaged *b0* image, as suggested in [Jeurissen2014]_.

    .. admonition:: References

      .. [Jeurissen2014] Jeurissen B. et al., `Multi-tissue constrained
        spherical deconvolution for improved analysis of multi-shell diffusion
        MRI data <https://doi.org/10.1016/j.neuroimage.2014.07.061>`_.
        NeuroImage (2014). doi: 10.1016/j.neuroimage.2014.07.061


    Example
    -------

    >>> from nipype.workflows.dmri.fsl.artifacts import remove_bias
    >>> bias = remove_bias()
    >>> bias.inputs.inputnode.in_file = 'epi.nii'
    >>> bias.inputs.inputnode.in_bval = 'diffusion.bval'
    >>> bias.inputs.inputnode.in_mask = 'mask.nii'
    >>> bias.run() # doctest: +SKIP

    """
    inputnode = pe.Node(
        niu.IdentityInterface(fields=['in_file', 'in_bval', 'in_mask']),
        name='inputnode')

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

    avg_b0 = pe.Node(niu.Function(input_names=['in_dwi', 'in_bval'],
                                  output_names=['out_file'],
                                  function=b0_average),
                     name='b0_avg')
    n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3,
                                            save_bias=True,
                                            bspline_fitting_distance=600),
                 name='Bias_b0')
    split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs')
    mult = pe.MapNode(fsl.MultiImageMaths(op_string='-div %s'),
                      iterfield=['in_file'],
                      name='RemoveBiasOfDWIs')
    thres = pe.MapNode(fsl.Threshold(thresh=0.0),
                       iterfield=['in_file'],
                       name='RemoveNegative')
    merge = pe.Node(fsl.utils.Merge(dimension='t'), name='MergeDWIs')

    wf = pe.Workflow(name=name)
    wf.connect([(inputnode, avg_b0, [('in_file', 'in_dwi'),
                                     ('in_bval', 'in_bval')]),
                (avg_b0, n4, [('out_file', 'input_image')]),
                (inputnode, n4, [('in_mask', 'mask_image')]),
                (inputnode, split, [('in_file', 'in_file')]),
                (n4, mult, [('bias_image', 'operand_files')]),
                (split, mult, [('out_files', 'in_file')]),
                (mult, thres, [('out_file', 'in_file')]),
                (thres, merge, [('out_file', 'in_files')]),
                (merge, outputnode, [('merged_file', 'out_file')])])
    return wf
Exemple #2
0
def epi_sbref_registration(name='EPI_SBrefRegistration'):
    workflow = pe.Workflow(name=name)
    inputnode = pe.Node(
        niu.IdentityInterface(fields=['epi_brain', 'sbref_brain']),
        name='inputnode')
    outputnode = pe.Node(
        niu.IdentityInterface(fields=['epi_registered', 'out_mat']),
        name='outputnode')

    mean = pe.Node(fsl.MeanImage(dimension='T'), name='EPImean')
    inu = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='EPImeanBias')
    epi_sbref = pe.Node(fsl.FLIRT(dof=6, out_matrix_file='init.mat'),
                        name='EPI2SBRefRegistration')

    epi_split = pe.Node(fsl.Split(dimension='t'), name='EPIsplit')
    epi_xfm = pe.MapNode(fsl.ApplyXfm(),
                         name='EPIapplyxfm',
                         iterfield=['in_file'])
    epi_merge = pe.Node(fsl.Merge(dimension='t'), name='EPImergeback')
    workflow.connect([
        (inputnode, epi_split, [('epi_brain', 'in_file')]),
        (inputnode, epi_sbref, [('sbref_brain', 'reference')]),
        (inputnode, epi_xfm, [('sbref_brain', 'reference')]),
        (inputnode, mean, [('epi_brain', 'in_file')]),
        (mean, inu, [('out_file', 'input_image')]),
        (inu, epi_sbref, [('output_image', 'in_file')]),
        (epi_split, epi_xfm, [('out_files', 'in_file')]),
        (epi_sbref, epi_xfm, [('out_matrix_file', 'in_matrix_file')]),
        (epi_xfm, epi_merge, [('out_file', 'in_files')]),
        (epi_sbref, outputnode, [('out_matrix_file', 'out_mat')]),
        (epi_merge, outputnode, [('merged_file', 'epi_registered')])
    ])
    return workflow
Exemple #3
0
def create_eddy_correct_pipeline(name='eddy_correct'):
    """

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


    Creates a pipeline that replaces eddy_correct script in FSL. It takes a
    series of diffusion weighted images and linearly co-registers them to one
    reference image. No rotation of the B-matrix is performed, so this pipeline
    should be executed after the motion correction pipeline.

    Example
    -------

    >>> nipype_eddycorrect = create_eddy_correct_pipeline('nipype_eddycorrect')
    >>> nipype_eddycorrect.inputs.inputnode.in_file = 'diffusion.nii'
    >>> nipype_eddycorrect.inputs.inputnode.ref_num = 0
    >>> nipype_eddycorrect.run() # doctest: +SKIP

    Inputs::

        inputnode.in_file
        inputnode.ref_num

    Outputs::

        outputnode.eddy_corrected
    """

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

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

    pipeline = pe.Workflow(name=name)

    split = pe.Node(fsl.Split(dimension='t'), name='split')
    pick_ref = pe.Node(niu.Select(), name='pick_ref')
    coregistration = pe.MapNode(fsl.FLIRT(no_search=True,
                                          padding_size=1,
                                          interp='trilinear'),
                                name='coregistration',
                                iterfield=['in_file'])
    merge = pe.Node(fsl.Merge(dimension='t'), name='merge')
    outputnode = pe.Node(niu.IdentityInterface(fields=['eddy_corrected']),
                         name='outputnode')

    pipeline.connect([(inputnode, split, [('in_file', 'in_file')]),
                      (split, pick_ref, [('out_files', 'inlist')]),
                      (inputnode, pick_ref, [('ref_num', 'index')]),
                      (split, coregistration, [('out_files', 'in_file')]),
                      (pick_ref, coregistration, [('out', 'reference')]),
                      (coregistration, merge, [('out_file', 'in_files')]),
                      (merge, outputnode, [('merged_file', 'eddy_corrected')])
                      ])
    return pipeline
Exemple #4
0
def fsl_RegrSliceWise(input_file,txtregr_Path,regr_Path):
    # scale Nifti data by factor 10
    dataName = os.path.basename(input_file).split('.')[0]

    # proof  data existence
    regrTextFiles = findRegData(txtregr_Path)
    if len(regrTextFiles) == 0:
        print('No regression with physio data!')
        output_file = os.path.join(regr_Path,
                                   os.path.basename(input_file).split('.')[0]) + '_RGR.nii.gz'
        shutil.copyfile(input_file, output_file)
        return output_file


    fslPath = scaleBy10(input_file, inv=False)
    # split input_file in slices
    mySplit = fsl.Split(in_file=fslPath, dimension='z', out_base_name=dataName)
    print(mySplit.cmdline)
    mySplit.run()
    os.remove(fslPath)

    # sparate ref and src volume in slices
    sliceFiles = findSlicesData(os.getcwd(), dataName)




    if not len(regrTextFiles) == len(sliceFiles):
        sys.exit('Error: Not enough txt.Files in %s' % txtregr_Path)

    print('Start separate slice Regression ... ')

    # start to regression slice by slice
    print('For all Sices ...')
    for i in range(len(sliceFiles)):
        slc = sliceFiles[i]
        regr = regrTextFiles[i]
        # only take the columns [1,2,7,9,11,12,13] of the reg-.txt Files
        output_file = os.path.join(regr_Path, os.path.basename(slc))
        myRegr = fsl.FilterRegressor(in_file=slc,design_file=regr,out_file=output_file,filter_columns=[1,2,7,9,11,12,13])
        print(myRegr.cmdline)
        myRegr.run()
        os.remove(slc)


    # merge slices to a single volume
    mcf_sliceFiles = findSlicesData(regr_Path, dataName)
    output_file = os.path.join(regr_Path,
                               os.path.basename(input_file).split('.')[0]) + '_RGR.nii.gz'
    myMerge = fsl.Merge(in_files=mcf_sliceFiles, dimension='z', merged_file=output_file)
    print(myMerge.cmdline)
    myMerge.run()

    for slc in mcf_sliceFiles: os.remove(slc)

    # unscale result data by factor 10ˆ(-1)
    output_file = scaleBy10(output_file, inv=True)

    return output_file
Exemple #5
0
def apply_all_corrections(name='UnwarpArtifacts'):
    """
    Combines two lists of linear transforms with the deformation field
    map obtained typically after the SDC process.
    Additionally, computes the corresponding bspline coefficients and
    the map of determinants of the jacobian.
    """

    inputnode = pe.Node(niu.IdentityInterface(fields=['in_sdc',
                        'in_hmc', 'in_ecc', 'in_dwi']), name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'out_warp',
                         'out_coeff', 'out_jacobian']), name='outputnode')
    warps = pe.MapNode(fsl.ConvertWarp(relwarp=True),
                       iterfield=['premat', 'postmat'],
                       name='ConvertWarp')

    selref = pe.Node(niu.Select(index=[0]), name='Reference')

    split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs')
    unwarp = pe.MapNode(fsl.ApplyWarp(), iterfield=['in_file', 'field_file'],
                        name='UnwarpDWIs')

    coeffs = pe.MapNode(fsl.WarpUtils(out_format='spline'),
                        iterfield=['in_file'], name='CoeffComp')
    jacobian = pe.MapNode(fsl.WarpUtils(write_jacobian=True),
                          iterfield=['in_file'], name='JacobianComp')
    jacmult = pe.MapNode(fsl.MultiImageMaths(op_string='-mul %s'),
                         iterfield=['in_file', 'operand_files'],
                         name='ModulateDWIs')

    thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'],
                       name='RemoveNegative')
    merge = pe.Node(fsl.Merge(dimension='t'), name='MergeDWIs')

    wf = pe.Workflow(name=name)
    wf.connect([
        (inputnode,   warps,      [('in_sdc', 'warp1'),
                                   ('in_hmc', 'premat'),
                                   ('in_ecc', 'postmat'),
                                   ('in_dwi', 'reference')]),
        (inputnode,   split,      [('in_dwi', 'in_file')]),
        (split,       selref,     [('out_files', 'inlist')]),
        (warps,       unwarp,     [('out_file', 'field_file')]),
        (split,       unwarp,     [('out_files', 'in_file')]),
        (selref,      unwarp,     [('out', 'ref_file')]),
        (selref,      coeffs,     [('out', 'reference')]),
        (warps,       coeffs,     [('out_file', 'in_file')]),
        (selref,      jacobian,   [('out', 'reference')]),
        (coeffs,      jacobian,   [('out_file', 'in_file')]),
        (unwarp,      jacmult,    [('out_file', 'in_file')]),
        (jacobian,    jacmult,    [('out_jacobian', 'operand_files')]),
        (jacmult,     thres,      [('out_file', 'in_file')]),
        (thres,       merge,      [('out_file', 'in_files')]),
        (warps,       outputnode, [('out_file', 'out_warp')]),
        (coeffs,      outputnode, [('out_file', 'out_coeff')]),
        (jacobian,    outputnode, [('out_jacobian', 'out_jacobian')]),
        (merge,       outputnode, [('merged_file', 'out_file')])
    ])
    return wf
Exemple #6
0
def dr_stage2(i, **kwargs):
	subj, mask = i
	regress_moco = True
	desnorm = True
	demean = True
	for i in kwargs.keys():
		if i == 'regress_moco':
			if kwargs[i]:
				regress_moco = True
			else:
				regress_moco = False
		if i == 'desnorm':
			if kwargs[i]:
				desnorm = True
			else:
				desnorm = False
	dr_s1_txt = os.path.join(OUTPUT, 'stage1', 'dr_stage1_idc_' + subj + '.txt')
	moco_txt = os.path.join(os.path.dirname(INPUT), subj, feat_pfix + subj + feat_sfix, 'mc', 'prefiltered_func_data_mcf.par')
	dr_s1 = read_txt_file(dr_s1_txt)
	if regress_moco:
		moco_pars = read_txt_file(moco_txt)
		for i in range(0, len(dr_s1)):
			for j in range(0,6):
				dr_s1[i].append(moco_pars[i][j])
		dr_s1_moco_txt = os.path.join(OUTPUT, 'stage1', 'dr_stage1_moco_idc_' + subj + '.txt')
		write_txt_file(dr_s1, dr_s1_moco_txt)
		designFile = dr_s1_moco_txt
	else:
		designFile = dr_s1_txt
	iFile = os.path.join(os.path.dirname(INPUT), subj, feat_pfix + subj + feat_sfix, ff_data_name)
	oFile = os.path.join(OUTPUT, 'stage2', 'dr_stage2_idc_' + subj + '.nii.gz')
	ozFile = os.path.join(OUTPUT, 'stage2', 'dr_stage2_Z_idc_' + subj + '.nii.gz')
	if os.path.exists(oFile) and os.path.exists(ozFile):
	    return
	mask = os.path.join(OUTPUT, 'stage1', 'mask.nii.gz')
	fsl_glm = fsl.GLM(in_file=iFile, design=designFile, terminal_output='stream', out_file=oFile, out_z_name=ozFile, mask=mask, des_norm=desnorm, demean=demean, output_type='NIFTI_GZ')
	cmd_out = os.path.join(OUTPUT, 'stage2', 'stage2_fslglm_idc_' + subj + '.out')
	write_cmd_out(fsl_glm.cmdline, cmd_out)
	fsl_glm.run()
	obname = os.path.join(OUTPUT, 'stage2', 'dr_stage2_idc_' + subj + '_ic')
	fslsplit = fsl.Split(dimension='t', in_file=oFile, out_base_name=obname, terminal_output='stream', output_type='NIFTI_GZ')
	fslsplit.run()
	obname = os.path.join(OUTPUT, 'stage2', 'dr_stage2_idc_Z' + subj + '_ic')
	fslsplit = fsl.Split(dimension='t', in_file=ozFile, out_base_name=obname, terminal_output='stream', output_type='NIFTI_GZ')
	fslsplit.run()
Exemple #7
0
 def _run_interface(self, runtime):
     splitter = fsl.Split(dimension='t',
                          out_base_name='out_',
                          in_file=self.inputs.in_file)
     split_outputs = splitter.run().outputs.out_files
     if len(split_outputs[0]) == 1:
         split_outputs = [split_outputs]
     self._out_file = self.extract_index(split_outputs, self.inputs.in_id)
     return runtime
Exemple #8
0
def create_nonbrain_meansignal(name='nonbrain_meansignal'):

    nonbrain_meansignal = Workflow(name=name)

    inputspec = Node(utility.IdentityInterface(fields=['func_file']),
                     name='inputspec')

    # Split raw 4D functional image into 3D niftis
    split_image = Node(fsl.Split(dimension='t', output_type='NIFTI'),
                       name='split_image')

    # Create a brain mask for each of the 3D images
    brain_mask = MapNode(fsl.BET(frac=0.3,
                                 mask=True,
                                 no_output=True,
                                 robust=True),
                         iterfield=['in_file'],
                         name='brain_mask')

    # Merge the 3D masks into a 4D nifti (producing a separate mask per volume)
    merge_mask = Node(fsl.Merge(dimension='t'), name='merge_mask')

    # Reverse the 4D brain mask, to produce a 4D non brain mask
    reverse_mask = Node(fsl.ImageMaths(op_string='-sub 1 -mul -1'),
                        name='reverse_mask')

    # Apply the mask on the raw functional data
    apply_mask = Node(fsl.ImageMaths(), name='apply_mask')

    # Highpass filter the non brain image
    highpass = create_highpass_filter(name='highpass')

    # Extract the mean signal from the non brain image
    mean_signal = Node(fsl.ImageMeants(), name='mean_signal')

    outputspec = Node(utility.IdentityInterface(fields=['nonbrain_regressor']),
                      name='outputspec')

    nonbrain_meansignal.connect(inputspec, 'func_file', split_image, 'in_file')
    nonbrain_meansignal.connect(split_image, 'out_files', brain_mask,
                                'in_file')
    nonbrain_meansignal.connect(brain_mask, 'mask_file', merge_mask,
                                'in_files')
    nonbrain_meansignal.connect(merge_mask, 'merged_file', reverse_mask,
                                'in_file')
    nonbrain_meansignal.connect(reverse_mask, 'out_file', apply_mask,
                                'mask_file')
    nonbrain_meansignal.connect(inputspec, 'func_file', apply_mask, 'in_file')
    nonbrain_meansignal.connect(apply_mask, 'out_file', highpass,
                                'inputspec.in_file')
    nonbrain_meansignal.connect(highpass, 'outputspec.filtered_file',
                                mean_signal, 'in_file')
    nonbrain_meansignal.connect(mean_signal, 'out_file', outputspec,
                                'nonbrain_regressor')

    return nonbrain_meansignal
Exemple #9
0
def splitting(launcher, in_file, base_name):
    split = flsi.Split()
    split.inputs.in_file = in_file
    split.inputs.out_base_name = base_name
    split.inputs.dimension = 't'
    split.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI'}

    # 'mcflirt -in functional.nii -cost mutualinfo -out moco.nii'
    # >>> res = mcflt.run()  # doctest: +SKIP
    launcher.run(split.cmdline)
Exemple #10
0
def dwi_flirt(name='DWICoregistration', excl_nodiff=False,
              flirt_param={}):
    """
    Generates a workflow for linear registration of dwi volumes
    """
    inputnode = pe.Node(niu.IdentityInterface(fields=['reference',
                        'in_file', 'ref_mask', 'in_xfms', 'in_bval']),
                        name='inputnode')

    initmat = pe.Node(niu.Function(input_names=['in_bval', 'in_xfms',
                      'excl_nodiff'], output_names=['init_xfms'],
                                   function=_checkinitxfm), name='InitXforms')
    initmat.inputs.excl_nodiff = excl_nodiff
    dilate = pe.Node(fsl.maths.MathsCommand(nan2zeros=True,
                     args='-kernel sphere 5 -dilM'), name='MskDilate')
    split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs')
    pick_ref = pe.Node(niu.Select(), name='Pick_b0')
    n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='Bias')
    enhb0 = pe.Node(niu.Function(input_names=['in_file', 'in_mask',
                    'clip_limit'], output_names=['out_file'],
                                 function=enhance), name='B0Equalize')
    enhb0.inputs.clip_limit = 0.015
    enhdw = pe.MapNode(niu.Function(input_names=['in_file', 'in_mask'],
                       output_names=['out_file'], function=enhance),
                       name='DWEqualize', iterfield=['in_file'])
    flirt = pe.MapNode(fsl.FLIRT(**flirt_param), name='CoRegistration',
                       iterfield=['in_file', 'in_matrix_file'])
    thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'],
                       name='RemoveNegative')
    merge = pe.Node(fsl.Merge(dimension='t'), name='MergeDWIs')
    outputnode = pe.Node(niu.IdentityInterface(fields=['out_file',
                         'out_xfms']), name='outputnode')
    wf = pe.Workflow(name=name)
    wf.connect([
        (inputnode,  split,      [('in_file', 'in_file')]),
        (inputnode,  dilate,     [('ref_mask', 'in_file')]),
        (inputnode,  enhb0,      [('ref_mask', 'in_mask')]),
        (inputnode,  initmat,    [('in_xfms', 'in_xfms'),
                                  ('in_bval', 'in_bval')]),
        (inputnode,  n4,         [('reference', 'input_image'),
                                  ('ref_mask', 'mask_image')]),
        (dilate,     flirt,      [('out_file', 'ref_weight'),
                                  ('out_file', 'in_weight')]),
        (n4,         enhb0,      [('output_image', 'in_file')]),
        (split,      enhdw,      [('out_files', 'in_file')]),
        (dilate,     enhdw,      [('out_file', 'in_mask')]),
        (enhb0,      flirt,      [('out_file', 'reference')]),
        (enhdw,      flirt,      [('out_file', 'in_file')]),
        (initmat,    flirt,      [('init_xfms', 'in_matrix_file')]),
        (flirt,      thres,      [('out_file', 'in_file')]),
        (thres,      merge,      [('out_file', 'in_files')]),
        (merge,      outputnode, [('merged_file', 'out_file')]),
        (flirt,      outputnode, [('out_matrix_file', 'out_xfms')])
    ])
    return wf
def create_realign_flow(name='realign'):
    """Realign a time series to the middle volume using spline interpolation

    Uses MCFLIRT to realign the time series and ApplyWarp to apply the rigid
    body transformations using spline interpolation (unknown order).

    Example
    -------

    >>> wf = create_realign_flow()
    >>> wf.inputs.inputspec.func = 'f3.nii'
    >>> wf.run() # doctest: +SKIP

    """
    realignflow = pe.Workflow(name=name)
    inputnode = pe.Node(interface=util.IdentityInterface(fields=[
        'func',
    ]),
                        name='inputspec')
    outputnode = pe.Node(interface=util.IdentityInterface(
        fields=['realigned_file', 'rms_files', 'par_file']),
                         name='outputspec')
    start_dropper = pe.Node(util.Function(
        input_names=['in_vol_fn', 'n_frames'],
        output_names=['out_fn'],
        function=remove_first_n_frames),
                            name='start_dropper')
    start_dropper.inputs.n_frames = 5

    realigner = pe.Node(fsl.MCFLIRT(save_mats=True,
                                    stats_imgs=True,
                                    save_rms=True,
                                    save_plots=True),
                        name='realigner')

    splitter = pe.Node(fsl.Split(dimension='t'), name='splitter')
    warper = pe.MapNode(fsl.ApplyWarp(interp='spline'),
                        iterfield=['in_file', 'premat'],
                        name='warper')
    joiner = pe.Node(fsl.Merge(dimension='t'), name='joiner')

    realignflow.connect(inputnode, 'func', start_dropper, 'in_vol_fn')
    realignflow.connect(start_dropper, 'out_fn', realigner, 'in_file')
    realignflow.connect(start_dropper, ('out_fn', select_volume, 'middle'),
                        realigner, 'ref_vol')
    realignflow.connect(realigner, 'out_file', splitter, 'in_file')
    realignflow.connect(realigner, 'mat_file', warper, 'premat')
    realignflow.connect(realigner, 'variance_img', warper, 'ref_file')
    realignflow.connect(splitter, 'out_files', warper, 'in_file')
    realignflow.connect(warper, 'out_file', joiner, 'in_files')
    realignflow.connect(joiner, 'merged_file', outputnode, 'realigned_file')
    realignflow.connect(realigner, 'rms_files', outputnode, 'rms_files')
    realignflow.connect(realigner, 'par_file', outputnode, 'par_file')
    return realignflow
Exemple #12
0
def modify_func_fm_run(FILEROOT):
    # Input is like sub-sub_run-01_epi.nii.gz (already in fmap dir)
    NII = FILEROOT + '.nii.gz'
    JSONFILE = FILEROOT + '.json'
    JSON_DAT = read_json(JSONFILE)
    TASKNAME = JSON_DAT['SeriesDescription'].split('_')[1]

    # Splits into AP/PA sets
    # sub-<label>[_ses-<label>][_acq-<label>][_ce-<label>]_dir-<label>[_run-<index>]_epi.json
    LROOT = FILEROOT.split('_')
    APNAME = LROOT[0] + '_dir-AP_' + '_'.join(LROOT[1:])
    PANAME = LROOT[0] + '_dir-PA_' + '_'.join(LROOT[1:])

    # Volumes 1/3 are AP, 2/4 PA
    SPLITTER = fsl.Split(in_file=NII, dimension='t', out_base_name='tmp')
    SPLITTER.run()

    MERGE_AP = fsl.Merge(in_files=['tmp0000.nii.gz', 'tmp0002.nii.gz'],
                         dimension='t',
                         merged_file=APNAME + '.nii.gz')
    MERGE_AP.run()

    MERGE_PA = fsl.Merge(in_files=['tmp0001.nii.gz', 'tmp0003.nii.gz'],
                         dimension='t',
                         merged_file=PANAME + '.nii.gz')
    MERGE_PA.run()

    os.remove(NII)
    os.remove(JSONFILE)
    for FILE in os.listdir('.'):
        if FILE.startswith('tmp0'):
            os.remove(FILE)

    # TODO: should we flip 1st volume and reorient?

    # Find which func data to use it for (right now assumes series description matches, may need to be more open).
    # Kludge: if stub of IntendedFor is there, populate with all runs
    os.chdir('..')

    INTENDEDFOR = []
    if 'IntendedFor' in JSON_DAT:
        STUB_TASKS = JSON_DAT['IntendedFor']
        for STUB in STUB_TASKS:
            INTEND_TASK = glob.glob('func/*task-{}_*bold.nii.gz'.format(STUB))
            INTENDEDFOR += INTEND_TASK
    else:
        INTENDEDFOR = glob.glob('func/*task-{}_*bold.nii.gz'.format(TASKNAME))

    JSON_DAT['IntendedFor'] = sorted(INTENDEDFOR)
    os.chdir('fmap')

    write_json(APNAME + '.json', JSON_DAT)
    write_json(PANAME + '.json', JSON_DAT)
Exemple #13
0
def create_eddy_correct_pipeline(name="eddy_correct"):
    """Creates a pipeline that replaces eddy_correct script in FSL. It takes a
    series of diffusion weighted images and linearly corregisters them to one
    reference image.

    Example
    -------

    >>> nipype_eddycorrect = create_eddy_correct_pipeline("nipype_eddycorrect")
    >>> nipype_eddycorrect.inputs.inputnode.in_file = 'diffusion.nii'
    >>> nipype_eddycorrect.inputs.inputnode.ref_num = 0
    >>> nipype_eddycorrect.run() # doctest: +SKIP

    Inputs::

        inputnode.in_file
        inputnode.ref_num

    Outputs::

        outputnode.eddy_corrected
    """

    inputnode = pe.Node(
        interface=util.IdentityInterface(fields=["in_file", "ref_num"]),
        name="inputnode")

    pipeline = pe.Workflow(name=name)

    split = pe.Node(fsl.Split(dimension='t'), name="split")
    pipeline.connect([(inputnode, split, [("in_file", "in_file")])])

    pick_ref = pe.Node(util.Select(), name="pick_ref")
    pipeline.connect([(split, pick_ref, [("out_files", "inlist")]),
                      (inputnode, pick_ref, [("ref_num", "index")])])

    coregistration = pe.MapNode(fsl.FLIRT(no_search=True, padding_size=1),
                                name="coregistration",
                                iterfield=["in_file"])
    pipeline.connect([(split, coregistration, [("out_files", "in_file")]),
                      (pick_ref, coregistration, [("out", "reference")])])

    merge = pe.Node(fsl.Merge(dimension="t"), name="merge")
    pipeline.connect([(coregistration, merge, [("out_file", "in_files")])])

    outputnode = pe.Node(
        interface=util.IdentityInterface(fields=["eddy_corrected"]),
        name="outputnode")

    pipeline.connect([(merge, outputnode, [("merged_file", "eddy_corrected")])
                      ])

    return pipeline
Exemple #14
0
def test_spm(name='test_spm_3d'):
    """
    A simple workflow to test SPM's installation. By default will split the 4D volume in
    time-steps.
    """
    workflow = pe.Workflow(name=name)

    inputnode = pe.Node(niu.IdentityInterface(fields=['in_data']),
                        name='inputnode')
    dgr = pe.Node(nio.DataGrabber(template="feeds/data/fmri.nii.gz",
                                  outfields=['out_file'],
                                  sort_filelist=False),
                  name='datasource')

    stc = pe.Node(spm.SliceTiming(num_slices=21,
                                  time_repetition=1.0,
                                  time_acquisition=2. - 2. / 32,
                                  slice_order=list(range(21, 0, -1)),
                                  ref_slice=10),
                  name='stc')
    realign_estimate = pe.Node(spm.Realign(jobtype='estimate'),
                               name='realign_estimate')
    realign_write = pe.Node(spm.Realign(jobtype='write'), name='realign_write')
    realign_estwrite = pe.Node(spm.Realign(jobtype='estwrite'),
                               name='realign_estwrite')
    smooth = pe.Node(spm.Smooth(fwhm=[6, 6, 6]), name='smooth')

    if name == 'test_spm_3d':
        split = pe.Node(fsl.Split(dimension="t", output_type="NIFTI"),
                        name="split")
        workflow.connect([(dgr, split, [(('out_file', _get_first), 'in_file')
                                        ]),
                          (split, stc, [("out_files", "in_files")])])
    elif name == 'test_spm_4d':
        gunzip = pe.Node(Gunzip(), name="gunzip")
        workflow.connect([(dgr, gunzip, [(('out_file', _get_first), 'in_file')
                                         ]),
                          (gunzip, stc, [("out_file", "in_files")])])
    else:
        raise NotImplementedError(
            'No implementation of the test workflow \'{}\' was found'.format(
                name))

    workflow.connect([
        (inputnode, dgr, [('in_data', 'base_directory')]),
        (stc, realign_estimate, [('timecorrected_files', 'in_files')]),
        (realign_estimate, realign_write, [('modified_in_files', 'in_files')]),
        (stc, realign_estwrite, [('timecorrected_files', 'in_files')]),
        (realign_write, smooth, [('realigned_files', 'in_files')])
    ])
    return workflow
Exemple #15
0
 def _run_interface(self, runtime):
     from dipy.core import gradients
     splitter = fsl.Split(dimension='t',
                          out_base_name='dwi_',
                          in_file=self.inputs.in_file)
     gtab = gradients.gradient_table(
         bvals=self.inputs.in_bval,
         bvecs=self.inputs.in_bvec,
         b0_threshold=self.inputs.in_bval_threshold)
     masklist = list(gtab.b0s_mask)
     split_outputs = splitter.run().outputs.out_files
     self._b0s, self._dwis, self._all, self._indices = self.extract_sublists(
         split_outputs, masklist)
     return runtime
Exemple #16
0
def fsl_SeparateSliceMoCo(input_file, par_folder):
    # scale Nifti data by factor 10
    dataName = os.path.basename(input_file).split('.')[0]
    fslPath = scaleBy10(input_file, inv=False)
    mySplit = fsl.Split(in_file=fslPath, dimension='z', out_base_name=dataName)
    print(mySplit.cmdline)
    mySplit.run()
    os.remove(fslPath)

    # sparate ref and src volume in slices
    sliceFiles = findSlicesData(os.getcwd(), dataName)
    # refFiles = findSlicesData(os.getcwd(),'ref')
    print('For all slices ... ')

    # start to correct motions slice by slice
    for i in range(len(sliceFiles)):
        slc = sliceFiles[i]
        # ref = refFiles[i]
        # take epi as ref
        output_file = os.path.join(par_folder, os.path.basename(slc))
        myMCFLIRT = fsl.preprocess.MCFLIRT(in_file=slc,
                                           out_file=output_file,
                                           save_plots=True,
                                           terminal_output='none')
        print(myMCFLIRT.cmdline)
        myMCFLIRT.run()
        os.remove(slc)
        # os.remove(ref)

    # merge slices to a single volume

    mcf_sliceFiles = findSlicesData(par_folder, dataName)
    output_file = os.path.join(
        os.path.dirname(input_file),
        os.path.basename(input_file).split('.')[0]) + '_mcf.nii.gz'
    myMerge = fsl.Merge(in_files=mcf_sliceFiles,
                        dimension='z',
                        merged_file=output_file)
    print(myMerge.cmdline)
    myMerge.run()

    for slc in mcf_sliceFiles:
        os.remove(slc)

    # unscale result data by factor 10ˆ(-1)
    output_file = scaleBy10(output_file, inv=True)

    return output_file
Exemple #17
0
    def _run_interface(self, runtime):
        split = fsl.Split(dimension='t', in_file=self.inputs.dwi_file)
        split_dwi_files = split.run().outputs.out_files

        split_bval_files, split_bvec_files = split_bvals_bvecs(
            self.inputs.bval_file, self.inputs.bvec_file, runtime)

        bvalues = np.loadtxt(self.inputs.bval_file)
        b0_indices = np.flatnonzero(bvalues < self.inputs.b0_threshold)
        b0_paths = [split_dwi_files[idx] for idx in b0_indices]
        self._results['dwi_files'] = split_dwi_files
        self._results['bval_files'] = split_bval_files
        self._results['bvec_files'] = split_bvec_files
        self._results['b0_images'] = b0_paths
        self._results['b0_indices'] = b0_indices.tolist()

        return runtime
def create_transform_pipeline(name='transfrom_timeseries'):
    # set fsl output type
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # initiate workflow
    transform_ts = Workflow(name='transform_timeseries')
    # inputnode
    inputnode=Node(util.IdentityInterface(fields=['orig_ts',
    'anat_head',
    'mat_moco',
    'fullwarp',
    'resolution',
    'brain_mask'
    ]),
    name='inputnode')
    # outputnode
    outputnode=Node(util.IdentityInterface(fields=['trans_ts',
    'trans_ts_mean',
    'trans_ts_masked',
    'resamp_brain',
    'brain_mask_resamp',
    'out_dvars'
    ]),
    name='outputnode')
    #resample anatomy
    resample = Node(fsl.FLIRT(datatype='float',
    out_file='T1_resampled.nii.gz'),
    name = 'resample_anat')
    transform_ts.connect([(inputnode, resample, [('anat_head', 'in_file'),
    ('anat_head', 'reference'),
    ('resolution', 'apply_isoxfm')
    ]),
    (resample, outputnode, [('out_file', 'resamp_brain')])
    ])
    # split timeseries in single volumes
    split=Node(fsl.Split(dimension='t',
    out_base_name='timeseries'),
    name='split')
    transform_ts.connect([(inputnode, split, [('orig_ts','in_file')])])
    
    # applymoco premat and fullwarpfield
    applywarp = MapNode(fsl.ApplyWarp(interp='spline',
    relwarp=True,
    out_file='rest2anat.nii.gz',
    datatype='float'),
    iterfield=['in_file', 'premat'],
    name='applywarp')
    transform_ts.connect([(split, applywarp, [('out_files', 'in_file')]),
    (inputnode, applywarp, 
    [('mat_moco', 'premat'),
    ('fullwarp','field_file')]),
    (resample, applywarp, [('out_file', 'ref_file')])
    ])
    # re-concatenate volumes
    merge=Node(fsl.Merge(dimension='t',
    merged_file='rest2anat.nii.gz'),
    name='merge')
    transform_ts.connect([(applywarp,merge,[('out_file','in_files')]),
    (merge, outputnode, [('merged_file', 'trans_ts')])])
    # calculate new mean
    tmean = Node(fsl.maths.MeanImage(dimension='T',
    out_file='rest_mean2anat_lowres.nii.gz'),
    name='tmean')
    transform_ts.connect([(merge, tmean, [('merged_file', 'in_file')]),
    (tmean, outputnode, [('out_file', 'trans_ts_mean')])
    ])
    
    # resample brain mask
    resample_brain = Node(afni.Resample(resample_mode='NN',
    outputtype='NIFTI_GZ',
    out_file='T1_brain_mask_lowres.nii.gz'),
    name = 'resample_brain')
    transform_ts.connect([(inputnode, resample_brain, [('brain_mask', 'in_file')]),
                          (tmean, resample_brain,     [('out_file', 'master')]),
                          (resample_brain, outputnode, [('out_file', 'brain_mask_resamp')])
                          ])
    
    #mask the transformed file
    mask = Node(fsl.ApplyMask(), name="mask")
    transform_ts.connect([(resample_brain,mask, [('out_file', 'mask_file')]),
                          (merge, mask, [('merged_file', 'in_file')]),
                          (mask, outputnode, [('out_file', 'trans_ts_masked')])
		         ])


    #calculate DVARS
    dvars = Node(confounds.ComputeDVARS(save_all=True, save_plot=True), name="dvars")
    transform_ts.connect([(resample_brain, dvars, [('out_file', 'in_mask')]),
                          (merge, dvars, [('merged_file', 'in_file')]),
                          (dvars, outputnode, [('out_all', 'out_dvars')])
                         ])



    
    return transform_ts
Exemple #19
0
    def build_core_nodes(self):
        """Build and connect the core nodes of the pipeline.

        Notes:
            - If `FSLOUTPUTTYPE` environment variable is not set, `nipype` takes
            NIFTI by default.

        Todo:
            - [x] Detect space automatically.
            - [ ] Allow for custom parcellations (See TODOs in utils).

        """
        import nipype.interfaces.utility as niu
        import nipype.pipeline.engine as npe
        import nipype.interfaces.fsl as fsl
        import nipype.interfaces.freesurfer as fs
        import nipype.interfaces.mrtrix3 as mrtrix3
        from clinica.lib.nipype.interfaces.mrtrix.preprocess import MRTransform
        from clinica.lib.nipype.interfaces.mrtrix3.reconst import EstimateFOD
        from clinica.lib.nipype.interfaces.mrtrix3.tracking import Tractography
        from clinica.utils.exceptions import ClinicaException, ClinicaCAPSError
        from clinica.utils.stream import cprint
        import clinica.pipelines.dwi_connectome.dwi_connectome_utils as utils
        from clinica.utils.mri_registration import convert_flirt_transformation_to_mrtrix_transformation

        # cprint('Building the pipeline...')

        # Nodes
        # =====

        # B0 Extraction (only if space=b0)
        # -------------
        split_node = npe.Node(name="Reg-0-DWI-B0Extraction",
                              interface=fsl.Split())
        split_node.inputs.output_type = "NIFTI_GZ"
        split_node.inputs.dimension = 't'
        select_node = npe.Node(name="Reg-0-DWI-B0Selection",
                               interface=niu.Select())
        select_node.inputs.index = 0

        # B0 Brain Extraction (only if space=b0)
        # -------------------
        mask_node = npe.Node(name="Reg-0-DWI-BrainMasking",
                             interface=fsl.ApplyMask())
        mask_node.inputs.output_type = "NIFTI_GZ"

        # T1-to-B0 Registration (only if space=b0)
        # ---------------------
        t12b0_reg_node = npe.Node(name="Reg-1-T12B0Registration",
                                  interface=fsl.FLIRT(
                                      dof=6,
                                      interp='spline',
                                      cost='normmi',
                                      cost_func='normmi',
                                  ))
        t12b0_reg_node.inputs.output_type = "NIFTI_GZ"

        # MGZ File Conversion (only if space=b0)
        # -------------------
        t1_brain_conv_node = npe.Node(name="Reg-0-T1-T1BrainConvertion",
                                      interface=fs.MRIConvert())
        wm_mask_conv_node = npe.Node(name="Reg-0-T1-WMMaskConvertion",
                                     interface=fs.MRIConvert())

        # WM Transformation (only if space=b0)
        # -----------------
        wm_transform_node = npe.Node(name="Reg-2-WMTransformation",
                                     interface=fsl.ApplyXFM())
        wm_transform_node.inputs.apply_xfm = True

        # Nodes Generation
        # ----------------
        label_convert_node = npe.MapNode(
            name="0-LabelsConversion",
            iterfield=['in_file', 'in_config', 'in_lut', 'out_file'],
            interface=mrtrix3.LabelConvert())
        label_convert_node.inputs.in_config = utils.get_conversion_luts()
        label_convert_node.inputs.in_lut = utils.get_luts()

        # FSL flirt matrix to MRtrix matrix Conversion (only if space=b0)
        # --------------------------------------------
        fsl2mrtrix_conv_node = npe.Node(
            name='Reg-2-FSL2MrtrixConversion',
            interface=niu.Function(
                input_names=[
                    'in_source_image', 'in_reference_image', 'in_flirt_matrix',
                    'name_output_matrix'
                ],
                output_names=['out_mrtrix_matrix'],
                function=convert_flirt_transformation_to_mrtrix_transformation)
        )

        # Parc. Transformation (only if space=b0)
        # --------------------
        parc_transform_node = npe.MapNode(
            name="Reg-2-ParcTransformation",
            iterfield=["in_files", "out_filename"],
            interface=MRTransform())

        # Response Estimation
        # -------------------
        resp_estim_node = npe.Node(name="1a-ResponseEstimation",
                                   interface=mrtrix3.ResponseSD())
        resp_estim_node.inputs.algorithm = 'tournier'

        # FOD Estimation
        # --------------
        fod_estim_node = npe.Node(name="1b-FODEstimation",
                                  interface=EstimateFOD())
        fod_estim_node.inputs.algorithm = 'csd'

        # Tracts Generation
        # -----------------
        tck_gen_node = npe.Node(name="2-TractsGeneration",
                                interface=Tractography())
        tck_gen_node.inputs.n_tracks = self.parameters['n_tracks']
        tck_gen_node.inputs.algorithm = 'iFOD2'

        # BUG: Info package does not exist
        # from nipype.interfaces.mrtrix3.base import Info
        # from distutils.version import LooseVersion
        #
        # if Info.looseversion() >= LooseVersion("3.0"):
        #     tck_gen_node.inputs.select = self.parameters['n_tracks']
        # elif Info.looseversion() <= LooseVersion("0.4"):
        #     tck_gen_node.inputs.n_tracks = self.parameters['n_tracks']
        # else:
        #     from clinica.utils.exceptions import ClinicaException
        #     raise ClinicaException("Your MRtrix version is not supported.")

        # Connectome Generation
        # ---------------------
        # only the parcellation and output filename should be iterable, the tck
        # file stays the same.
        conn_gen_node = npe.MapNode(name="3-ConnectomeGeneration",
                                    iterfield=['in_parc', 'out_file'],
                                    interface=mrtrix3.BuildConnectome())

        # Print begin message
        # -------------------
        print_begin_message = npe.MapNode(interface=niu.Function(
            input_names=['in_bids_or_caps_file'],
            function=utils.print_begin_pipeline),
                                          iterfield='in_bids_or_caps_file',
                                          name='WriteBeginMessage')

        # Print end message
        # -----------------
        print_end_message = npe.MapNode(interface=niu.Function(
            input_names=['in_bids_or_caps_file', 'final_file'],
            function=utils.print_end_pipeline),
                                        iterfield=['in_bids_or_caps_file'],
                                        name='WriteEndMessage')

        # CAPS File names Generation
        # --------------------------
        caps_filenames_node = npe.Node(
            name='CAPSFilenamesGeneration',
            interface=niu.Function(input_names='dwi_file',
                                   output_names=self.get_output_fields(),
                                   function=utils.get_caps_filenames))

        # Connections
        # ===========
        # Computation of the diffusion model, tractography & connectome
        # -------------------------------------------------------------
        self.connect([
            (self.input_node, print_begin_message,
             [('dwi_file', 'in_bids_or_caps_file')]),  # noqa
            (self.input_node, caps_filenames_node, [('dwi_file', 'dwi_file')]),
            # Response Estimation
            (self.input_node, resp_estim_node, [('dwi_file', 'in_file')]
             ),  # Preproc. DWI # noqa
            (self.input_node, resp_estim_node,
             [('dwi_brainmask_file', 'in_mask')]),  # B0 brain mask # noqa
            (self.input_node, resp_estim_node, [('grad_fsl', 'grad_fsl')
                                                ]),  # bvecs and bvals # noqa
            (caps_filenames_node, resp_estim_node,
             [('response', 'wm_file')]),  # output response filename # noqa
            # FOD Estimation
            (self.input_node, fod_estim_node, [('dwi_file', 'in_file')]
             ),  # Preproc. DWI # noqa
            (resp_estim_node, fod_estim_node,
             [('wm_file', 'wm_txt')]),  # Response (txt file) # noqa
            (self.input_node, fod_estim_node,
             [('dwi_brainmask_file', 'mask_file')]),  # B0 brain mask # noqa
            (self.input_node, fod_estim_node,
             [('grad_fsl', 'grad_fsl')]),  # T1-to-B0 matrix file # noqa
            (caps_filenames_node, fod_estim_node,
             [('fod', 'wm_odf')]),  # output odf filename # noqa
            # Tracts Generation
            (fod_estim_node, tck_gen_node, [('wm_odf', 'in_file')]
             ),  # ODF file # noqa
            (caps_filenames_node, tck_gen_node,
             [('tracts', 'out_file')]),  # output tck filename # noqa
            # Label Conversion
            (self.input_node, label_convert_node, [('atlas_files', 'in_file')]
             ),  # atlas image files # noqa
            (caps_filenames_node, label_convert_node, [
                ('nodes', 'out_file')
            ]),  # converted atlas image filenames # noqa
            # Connectomes Generation
            (tck_gen_node, conn_gen_node, [('out_file', 'in_file')]),  # noqa
            (caps_filenames_node, conn_gen_node, [('connectomes', 'out_file')
                                                  ]),  # noqa
        ])
        # Registration T1-DWI (only if space=b0)
        # -------------------
        if self.parameters['dwi_space'] == 'b0':
            self.connect([
                # MGZ Files Conversion
                (self.input_node, t1_brain_conv_node, [('t1_brain_file',
                                                        'in_file')]),  # noqa
                (self.input_node, wm_mask_conv_node, [('wm_mask_file',
                                                       'in_file')]),  # noqa
                # B0 Extraction
                (self.input_node, split_node, [('dwi_file', 'in_file')]
                 ),  # noqa
                (split_node, select_node, [('out_files', 'inlist')]),  # noqa
                # Masking
                (select_node, mask_node, [('out', 'in_file')]),  # B0 # noqa
                (self.input_node, mask_node,
                 [('dwi_brainmask_file', 'mask_file')]),  # Brain mask # noqa
                # T1-to-B0 Registration
                (t1_brain_conv_node, t12b0_reg_node, [('out_file', 'in_file')]
                 ),  # Brain # noqa
                (mask_node, t12b0_reg_node, [('out_file', 'reference')
                                             ]),  # B0 brain-masked # noqa
                # WM Transformation
                (wm_mask_conv_node, wm_transform_node,
                 [('out_file', 'in_file')]),  # Brain mask # noqa
                (mask_node, wm_transform_node, [('out_file', 'reference')
                                                ]),  # BO brain-masked # noqa
                (t12b0_reg_node, wm_transform_node, [
                    ('out_matrix_file', 'in_matrix_file')
                ]),  # T1-to-B0 matrix file # noqa
                # FSL flirt matrix to MRtrix matrix Conversion
                (t1_brain_conv_node, fsl2mrtrix_conv_node,
                 [('out_file', 'in_source_image')]),  # noqa
                (mask_node, fsl2mrtrix_conv_node,
                 [('out_file', 'in_reference_image')]),  # noqa
                (t12b0_reg_node, fsl2mrtrix_conv_node,
                 [('out_matrix_file', 'in_flirt_matrix')]),  # noqa
                # Apply registration without resampling on parcellations
                (label_convert_node, parc_transform_node,
                 [('out_file', 'in_files')]),  # noqa
                (fsl2mrtrix_conv_node, parc_transform_node,
                 [('out_mrtrix_matrix', 'linear_transform')]),  # noqa
                (caps_filenames_node, parc_transform_node,
                 [('nodes', 'out_filename')]),  # noqa
            ])
        # Special care for Parcellation & WM mask
        # ---------------------------------------
        if self.parameters['dwi_space'] == 'b0':
            self.connect([
                (wm_transform_node, tck_gen_node, [('out_file', 'seed_image')
                                                   ]),  # noqa
                (parc_transform_node, conn_gen_node, [('out_file', 'in_parc')
                                                      ]),  # noqa
                (parc_transform_node, self.output_node, [('out_file', 'nodes')
                                                         ]),  # noqa
            ])
        elif self.parameters['dwi_space'] == 'T1w':
            self.connect([
                (self.input_node, tck_gen_node, [('wm_mask_file', 'seed_image')
                                                 ]),  # noqa
                (label_convert_node, conn_gen_node, [('out_file', 'in_parc')
                                                     ]),  # noqa
                (label_convert_node, self.output_node, [('out_file', 'nodes')
                                                        ]),  # noqa
            ])
        else:
            raise ClinicaCAPSError(
                'Bad preprocessed DWI space. Please check your CAPS '
                'folder.')
        # Outputs
        # -------
        self.connect([
            (resp_estim_node, self.output_node, [('wm_file', 'response')]),
            (fod_estim_node, self.output_node, [('wm_odf', 'fod')]),
            (tck_gen_node, self.output_node, [('out_file', 'tracts')]),
            (conn_gen_node, self.output_node, [('out_file', 'connectomes')]),
            (self.input_node, print_end_message, [('dwi_file',
                                                   'in_bids_or_caps_file')]),
            (conn_gen_node, print_end_message, [('out_file', 'final_file')]),
        ])
def _b1resize(
    datapath,
    b1name,
    regdir,
    b1FAmap=None,
    outfolder=Path.cwd(),
    inrefname=None,
    outrefname="Ref_CESTres.nii.gz",
    phantom=False,
):
    """B1_RESIZE - Preprocesses B1 Data for Use with FABBER
    Takes the raw B1 data and processes it into a B1 map.  Also flirts it
    into the reference volume space.  Does not apply any actual registration,
    just resamples it so it is in the same resolution as the Reference data.

    Parameters:
    -----------
    datapath : pathlib Path object
        The path to the datafolder
    b1name : str
        The name of the B1+ scan to register.
    regdir : pathlib Path object
        The registration directory being used for all 
        of the registration computations.
    b1FAmap : str
        The name of the B1+ FA map to register. 
        If None, will assume this is in the b1name file.
    outfolder : pathlib Path object
        The output directory of the data being analyzed. 
        If blank, the datapath directory will be used.
    refname : str
        The name of the reference volume to register b1 to. 
        If blank, the file Ref_CESTres.nii.gz will be used.

    Returns:
    --------
        None

    Author:  asmith
    Version: 1.0
    Changelog:

    20181217 - initial creation
    """
    b1dir = sorted(datapath.glob("*{0}*.nii.gz".format(b1name)))

    if len(b1dir) > 1 and b1FAmap is None:
        fslmerge = fsl.Merge()
        fslmerge.inputs.in_files = [str(i) for v, i in enumerate(b1dir)]
        fslmerge.inputs.dimension = "t"
        fslmerge.inputs.merged_file = str(regdir / f"{b1name}_merged.nii.gz")
        fslmerge.run()

        b1dir = regdir / f"{b1name}_merged.nii.gz"

    try:
        b1vol = nib.load(str(b1dir[1]))
    except TypeError:
        b1vol = nib.load(str(b1dir))
    except IndexError:
        b1vol = nib.load(str(b1dir[0]))
    except:
        print(f"Unexpected Error: {sys.exc_info()[0]}")

    if b1FAmap is None and b1vol.ndim < 4:
        if len(b1dir) > 1:
            b1FAmap = Path(b1dir[-1].stem).stem
        else:
            raise NoFAMapError(
                "No FA Map specified for B1 Data!\nProvide a FA map to proceed!"
            )
    if b1FAmap is None and b1vol.shape[3] > 2:
        # Split Data
        fsplt = fsl.Split()
        fsplt.inputs.in_file = str(b1dir)
        fsplt.inputs.out_base_name = str(regdir / "DREAM_s")
        fsplt.inputs.dimension = "t"
        fsplt.run()

        # set variables so anatomical and FA map are defined
        b1dirs = sorted(regdir.glob("*DREAM_s*.nii.gz"))
        b1dir = str(b1dirs[1])
        b1FAmapdir = str(b1dirs[-1])

    elif b1FAmap is None and b1vol.shape[3] == 2:
        # Split Data
        fsplt = fsl.Split()
        fsplt.inputs.in_file = str(b1dir)
        fsplt.inputs.out_base_name = str(regdir / "DREAM_s")
        fsplt.inputs.dimension = "t"
        fsplt.run()

        # Split b1vol into component anatomicals for registration
        b1dirs = sorted(regdir.glob("*DREAM_s*.nii.gz"))
        b1dir = str(b1dirs[1])
        # Define b1FAmap for use in downstream registration
        b1FAmapdir = regdir / "B1map.nii.gz"

        # Build FA map from anatomical maps
        fmaths = fsl.ImageMaths()
        fmaths.inputs.in_file = str(b1dirs[0])
        fmaths.inputs.op_string = "-mul 2 -div"
        fmaths.inputs.in_file2 = str(b1dirs[1])
        fmaths.inputs.out_file = str(regdir / "tmp1.nii.gz")
        fmaths.run()
        fmaths = fsl.ImageMaths()
        fmaths.inputs.in_file = str(regdir / "tmp1.nii.gz")
        fmaths.inputs.op_string = f"-sqrt -atan -div {radians(60)} -mul 600"
        fmaths.inputs.out_file = str(b1FAmapdir)
        fmaths.run()
    else:
        b1FAmapdir = sorted(datapath.glob(f"*{b1FAmap}*.nii.gz"))[0]
        try:
            b1dir = str(b1dir[1])
        except IndexError:
            b1dir = str(b1dir[0])

    b1splt = fsl.ExtractROI()
    b1splt.inputs.in_file = b1dir
    b1splt.inputs.roi_file = str(regdir / "B1_1.nii.gz")
    b1splt.inputs.t_size = 1
    b1splt.inputs.t_min = 0
    b1splt.run()

    # Run FAST on B1 input data to get better registration
    b1FAST = fsl.FAST()
    b1FAST.inputs.in_files = str(regdir / "B1_1.nii.gz")
    b1FAST.inputs.out_basename = str(regdir / "B1_bc")
    b1FAST.inputs.output_biascorrected = True
    b1FAST.inputs.no_pve = True
    b1FAST.inputs.output_type = "NIFTI_GZ"
    b1FAST.run(ignore_exception=True)

    if phantom:
        # _FOVDiff(str(regdir / "B1_bc_restore.nii.gz"), str(inrefdir), "B1resred.txt", regdir=regdir)

        # Flirt B1 Image Data to Original Reference volume
        flt = fsl.FLIRT()
        flt.inputs.in_file = str(regdir / "B1_bc_restore.nii.gz")
        flt.inputs.reference = str(regdir / "Ref_bc_restore.nii.gz")
        flt.inputs.out_file = str(regdir / "B1_to_ref.nii.gz")
        flt.inputs.output_type = "NIFTI_GZ"
        flt.inputs.rigid2D = True
        # flt.inputs.in_matrix_file = str(regdir / "B1resred.txt")

        # flt.inputs.apply_xfm=True
        flt.inputs.out_matrix_file = str(regdir / "B1resred.txt")
        flt.run()
    else:
        # Flirt B1 Image Data to Original Reference volume
        flt = fsl.FLIRT()
        flt.inputs.in_file = str(regdir / "B1_bc_restore.nii.gz")
        flt.inputs.reference = str(regdir / "Ref_bc_restore.nii.gz")
        flt.inputs.out_file = str(regdir / "B1_to_ref.nii.gz")
        flt.inputs.output_type = "NIFTI_GZ"
        flt.inputs.out_matrix_file = str(regdir / "B1resred.txt")
        flt.run()

    if len(_slicenumber2d) > 0:
        # Flirt B1 Map Data to Original Reference volume
        flt = fsl.FLIRT()
        flt.inputs.in_file = str(b1FAmapdir)
        flt.inputs.reference = str(regdir / "Ref_bc_restore.nii.gz")
        flt.inputs.out_file = str(regdir / "B1map_to_ref.nii.gz")
        flt.inputs.output_type = "NIFTI_GZ"
        flt.inputs.in_matrix_file = str(regdir / "B1resred.txt")
        flt.inputs.apply_xfm = True
        flt.inputs.out_matrix_file = str(regdir / "B1resred.txt")
        flt.run()

        if _slicenumber2d[1] > 1:
            # Run for B1 Map
            fsl.ExtractROI(
                in_file=str(regdir / "B1map_to_ref.nii.gz"),
                roi_file=str(regdir / "B1map_sROI.nii.gz"),
                x_min=0,
                x_size=-1,
                y_min=0,
                y_size=-1,
                z_min=_slicenumber2d[0] - 1,
                z_size=_slicenumber2d[1],
            ).run()
        else:
            # Run for B1 Map
            fsl.ExtractROI(
                in_file=str(regdir / "B1map_to_ref.nii.gz"),
                roi_file=str(regdir / "B1map_sROI.nii.gz"),
                x_min=0,
                x_size=-1,
                y_min=0,
                y_size=-1,
                z_min=_slicenumber2d[0],
                z_size=_slicenumber2d[1],
            ).run()

        # Warp 2D B1map to CEST Space
        flt.inputs.in_file = str(regdir / "B1map_sROI.nii.gz")
        flt.inputs.out_file = str(regdir / "B1map_resred.nii.gz")
        flt.inputs.reference = str(regdir / outrefname)
        flt.inputs.in_matrix_file = str(regdir / "Ref_CESTres.txt")
        flt.inputs.apply_xfm = True
        flt.inputs.rigid2D = True
        flt.inputs.out_matrix_file = str(regdir / "B1toCEST.txt")
        flt.run()

    else:
        # Combine B1->Ref matrix with Ref->CEST matrix
        xfmcomb = fsl.ConvertXFM()
        xfmcomb.inputs.in_file = str(regdir / "B1resred.txt")
        xfmcomb.inputs.in_file2 = str(regdir / "Ref_CESTres.txt")
        xfmcomb.inputs.concat_xfm = True
        xfmcomb.inputs.out_file = str(regdir / "B1toCEST.txt")
        xfmcomb.run()

        # Use combine Ref->CEST matrix to register B1 FA map to CEST data
        flt.inputs.in_file = str(b1FAmapdir)
        flt.inputs.out_file = str(regdir / "B1map_resred.nii.gz")
        flt.inputs.reference = str(regdir / outrefname)
        flt.inputs.in_matrix_file = str(regdir / "B1toCEST.txt")
        flt.inputs.apply_xfm = True
        flt.inputs.out_matrix_file = str(regdir / "B1toCEST.txt")
        flt.run()

    # Convert Registered FA Map to Fraction of nominal angle and move to analysis folder
    fmaths = fsl.ImageMaths()
    fmaths.inputs.in_file = str(regdir / "B1map_resred.nii.gz")
    fmaths.inputs.op_string = "-div 600 -mul"
    fmaths.inputs.in_file2 = str(regdir / "Ref_Mask.nii.gz")
    fmaths.inputs.out_file = str(outfolder / "B1map_resize.nii.gz")
    fmaths.run()

    return None
def ecc_pipeline(name='eddy_correct'):
    """
    ECC stands for Eddy currents correction.

    Creates a pipeline that corrects for artifacts induced by Eddy currents in
    dMRI sequences.
    It takes a series of diffusion weighted images and linearly co-registers
    them to one reference image (the average of all b0s in the dataset).

    DWIs are also modulated by the determinant of the Jacobian as indicated by
    [Jones10]_ and [Rohde04]_.

    A list of rigid transformation matrices can be provided, sourcing from a
    :func:`.hmc_pipeline` workflow, to initialize registrations in a *motion
    free* framework.

    A list of affine transformation matrices is available as output, so that
    transforms can be chained (discussion
    `here <https://github.com/nipy/nipype/pull/530#issuecomment-14505042>`_).

    .. admonition:: References

      .. [Jones10] Jones DK, `The signal intensity must be modulated by the
        determinant of the Jacobian when correcting for eddy currents in
        diffusion MRI
        <http://cds.ismrm.org/protected/10MProceedings/files/1644_129.pdf>`_,
        Proc. ISMRM 18th Annual Meeting, (2010).

      .. [Rohde04] Rohde et al., `Comprehensive Approach for Correction of
        Motion and Distortion in Diffusion-Weighted MRI
        <http://stbb.nichd.nih.gov/pdf/com_app_cor_mri04.pdf>`_, MRM
        51:103-114 (2004).

    Example
    -------

    >>> from nipype.workflows.dmri.fsl.artifacts import ecc_pipeline
    >>> ecc = ecc_pipeline()
    >>> ecc.inputs.inputnode.in_file = 'diffusion.nii'
    >>> ecc.inputs.inputnode.in_bval = 'diffusion.bval'
    >>> ecc.inputs.inputnode.in_mask = 'mask.nii'
    >>> ecc.run() # doctest: +SKIP

    Inputs::

        inputnode.in_file - input dwi file
        inputnode.in_mask - weights mask of reference image (a file with data \
range sin [0.0, 1.0], indicating the weight of each voxel when computing the \
metric.
        inputnode.in_bval - b-values table
        inputnode.in_xfms - list of matrices to initialize registration (from \
head-motion correction)

    Outputs::

        outputnode.out_file - corrected dwi file
        outputnode.out_xfms - list of transformation matrices
    """

    from nipype.workflows.data import get_flirt_schedule
    params = dict(dof=12,
                  no_search=True,
                  interp='spline',
                  bgvalue=0,
                  schedule=get_flirt_schedule('ecc'))
    # cost='normmi', cost_func='normmi', bins=64,

    inputnode = pe.Node(niu.IdentityInterface(
        fields=['in_file', 'in_bval', 'in_mask', 'in_xfms']),
                        name='inputnode')
    avg_b0 = pe.Node(niu.Function(input_names=['in_dwi', 'in_bval'],
                                  output_names=['out_file'],
                                  function=b0_average),
                     name='b0_avg')
    pick_dws = pe.Node(niu.Function(input_names=['in_dwi', 'in_bval', 'b'],
                                    output_names=['out_file'],
                                    function=extract_bval),
                       name='ExtractDWI')
    pick_dws.inputs.b = 'diff'

    flirt = dwi_flirt(flirt_param=params, excl_nodiff=True)

    mult = pe.MapNode(fsl.BinaryMaths(operation='mul'),
                      name='ModulateDWIs',
                      iterfield=['in_file', 'operand_value'])
    thres = pe.MapNode(fsl.Threshold(thresh=0.0),
                       iterfield=['in_file'],
                       name='RemoveNegative')

    split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs')
    get_mat = pe.Node(niu.Function(input_names=['in_bval', 'in_xfms'],
                                   output_names=['out_files'],
                                   function=recompose_xfm),
                      name='GatherMatrices')
    merge = pe.Node(niu.Function(
        input_names=['in_dwi', 'in_bval', 'in_corrected'],
        output_names=['out_file'],
        function=recompose_dwi),
                    name='MergeDWIs')

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

    wf = pe.Workflow(name=name)
    wf.connect([(inputnode, avg_b0, [('in_file', 'in_dwi'),
                                     ('in_bval', 'in_bval')]),
                (inputnode, pick_dws, [('in_file', 'in_dwi'),
                                       ('in_bval', 'in_bval')]),
                (inputnode, merge, [('in_file', 'in_dwi'),
                                    ('in_bval', 'in_bval')]),
                (inputnode, flirt, [('in_mask', 'inputnode.ref_mask'),
                                    ('in_xfms', 'inputnode.in_xfms'),
                                    ('in_bval', 'inputnode.in_bval')]),
                (inputnode, get_mat, [('in_bval', 'in_bval')]),
                (avg_b0, flirt, [('out_file', 'inputnode.reference')]),
                (pick_dws, flirt, [('out_file', 'inputnode.in_file')]),
                (flirt, get_mat, [('outputnode.out_xfms', 'in_xfms')]),
                (flirt, mult, [(('outputnode.out_xfms', _xfm_jacobian),
                                'operand_value')]),
                (flirt, split, [('outputnode.out_file', 'in_file')]),
                (split, mult, [('out_files', 'in_file')]),
                (mult, thres, [('out_file', 'in_file')]),
                (thres, merge, [('out_file', 'in_corrected')]),
                (get_mat, outputnode, [('out_files', 'out_xfms')]),
                (merge, outputnode, [('out_file', 'out_file')])])
    return wf
Exemple #22
0
def b0_flirt_pipeline(num_b0s, name="b0_coregistration"):
    """
    Rigid registration of the B0 dataset onto the first volume. Rigid
    registration is achieved using FLIRT and the normalized
    correlation.

    Args:
        num_b0s (int): Number of the B0 volumes in the dataset.
        name (str): Name of the workflow.

    Inputnode:
        in_file(str): B0 dataset.

    Outputnode
        out_b0_reg(str): The set of B0 volumes registered to the first volume.

    Returns:
        The workflow
    """
    import nipype.interfaces.utility as niu
    import nipype.pipeline.engine as pe
    from nipype.interfaces import fsl

    from clinica.utils.dwi import merge_volumes_tdim

    inputnode = pe.Node(niu.IdentityInterface(fields=["in_file"]),
                        name="inputnode")
    fslroi_ref = pe.Node(fsl.ExtractROI(args="0 1"), name="b0_reference")
    tsize = num_b0s - 1
    fslroi_moving = pe.Node(fsl.ExtractROI(args="1 " + str(tsize)),
                            name="b0_moving")
    split_moving = pe.Node(fsl.Split(dimension="t"), name="split_b0_moving")

    bet_ref = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True),
                      name="bet_ref")

    dilate = pe.Node(
        fsl.maths.MathsCommand(nan2zeros=True, args="-kernel sphere 5 -dilM"),
        name="mask_dilate",
    )

    flirt = pe.MapNode(
        fsl.FLIRT(
            interp="spline",
            dof=6,
            bins=50,
            save_log=True,
            cost="corratio",
            cost_func="corratio",
            padding_size=10,
            searchr_x=[-4, 4],
            searchr_y=[-4, 4],
            searchr_z=[-4, 4],
            fine_search=1,
            coarse_search=10,
        ),
        name="b0_co_registration",
        iterfield=["in_file"],
    )

    merge = pe.Node(fsl.Merge(dimension="t"), name="merge_registered_b0s")
    thres = pe.MapNode(fsl.Threshold(thresh=0.0),
                       iterfield=["in_file"],
                       name="remove_negative")
    insert_ref = pe.Node(
        niu.Function(
            input_names=["in_file1", "in_file2"],
            output_names=["out_file"],
            function=merge_volumes_tdim,
        ),
        name="concat_ref_moving",
    )

    outputnode = pe.Node(
        niu.IdentityInterface(fields=["out_file", "out_xfms"]),
        name="outputnode")

    wf = pe.Workflow(name=name)
    wf.connect([
        (inputnode, fslroi_ref, [("in_file", "in_file")]),
        (inputnode, fslroi_moving, [("in_file", "in_file")]),
        (fslroi_moving, split_moving, [("roi_file", "in_file")]),
        (fslroi_ref, bet_ref, [("roi_file", "in_file")]),
        (bet_ref, dilate, [("mask_file", "in_file")]),
        (dilate, flirt, [("out_file", "ref_weight"),
                         ("out_file", "in_weight")]),
        (fslroi_ref, flirt, [("roi_file", "reference")]),
        (split_moving, flirt, [("out_files", "in_file")]),
        (flirt, thres, [("out_file", "in_file")]),
        (thres, merge, [("out_file", "in_files")]),
        (merge, insert_ref, [("merged_file", "in_file2")]),
        (fslroi_ref, insert_ref, [("roi_file", "in_file1")]),
        (insert_ref, outputnode, [("out_file", "out_file")]),
        (flirt, outputnode, [("out_matrix_file", "out_xfms")]),
    ])
    return wf
def _cestreg(
    datapath,
    cestprefix,
    offsetspath,
    regdir,
    outfolder=Path.cwd(),
    CESTRefImage=0,
    phantom=False,
):
    """ _cestreg7T - Co-registers CEST data, and then registers that data
    to the high resolution reference measurement set up in _reg_ref_7T
    """
    cestdir = sorted(datapath.glob(f"*{cestprefix}*.nii.gz"))

    offsets = np.loadtxt(str(offsetspath))

    n_ones = np.where(abs(offsets) < 1)[0]

    cestoutname = cestprefix

    cestvol = nib.load(str(cestdir[0]))

    if cestvol.ndim == 4:
        fslsplit = fsl.Split()
        fslsplit.inputs.in_file = str(cestdir[0])
        fslsplit.inputs.out_base_name = str(regdir / f"{cestoutname}_Presplit")
        fslsplit.inputs.output_type = "NIFTI_GZ"
        fslsplit.inputs.dimension = "t"
        fslsplit.run()
        cestdir = sorted((regdir.glob(f"*{cestoutname}_Presplit*.nii.gz")))

    concatname1 = [str(i) for v, i in enumerate(cestdir) if v < n_ones[1]]
    concatname2 = [str(i) for v, i in enumerate(cestdir) if v > n_ones[-1]]
    concatname2.append(str(cestdir[CESTRefImage]))

    # Merge first half of files
    fslmerge = fsl.Merge()
    fslmerge.inputs.in_files = concatname1
    fslmerge.inputs.dimension = "t"
    fslmerge.inputs.merged_file = str(regdir / f"{cestoutname}_merged1.nii.gz")
    fslmerge.run()

    # Merge second half of files
    fslmerge.inputs.in_files = concatname2
    fslmerge.inputs.merged_file = str(regdir / f"{cestoutname}_merged2.nii.gz")
    fslmerge.run()

    # Motion-Correct Data
    mcflirt = fsl.MCFLIRT()
    mcflirt.inputs.in_file = str(regdir / f"{cestoutname}_merged1.nii.gz")
    mcflirt.inputs.ref_vol = CESTRefImage
    mcflirt.inputs.out_file = str(regdir / f"{cestoutname}_merged1_mcf.nii.gz")
    if cestvol.ndim < 3:
        mcflirt.inputs.args = "-2d"
    mcflirt.run()

    mcflirt = fsl.MCFLIRT()
    mcflirt.inputs.in_file = str(regdir / f"{cestoutname}_merged2.nii.gz")
    mcflirt.inputs.ref_vol = len(concatname2) - 1
    mcflirt.inputs.out_file = str(regdir / f"{cestoutname}_merged2_mcf.nii.gz")
    if cestvol.ndim < 3:
        mcflirt.inputs.args = "-2d"
    mcflirt.run()

    # Extract one datapoint near middle of CEST
    fslroi = fsl.ExtractROI()
    fslroi.inputs.in_file = str(regdir / f"{cestoutname}_merged1_mcf.nii.gz")
    fslroi.inputs.roi_file = str(regdir / f"{cestoutname}_mcfMin.nii.gz")
    fslroi.inputs.t_min = len(concatname1) - 1
    fslroi.inputs.t_size = 1
    fslroi.run()

    # Remove extra reference image in merged2
    fslroi = fsl.ExtractROI()
    fslroi.inputs.in_file = str(regdir / f"{cestoutname}_merged2_mcf.nii.gz")
    fslroi.inputs.roi_file = str(regdir / f"{cestoutname}_merged2_mcf.nii.gz")
    fslroi.inputs.t_min = 0
    fslroi.inputs.t_size = len(concatname2) - 1
    fslroi.run()

    concatname3 = [str(i) for v, i in enumerate(cestdir) if v in n_ones[1:]]
    concatname3.insert(0, str(regdir / f"{cestoutname}_mcfMin.nii.gz"))

    fslmerge.inputs.in_files = concatname3
    fslmerge.inputs.merged_file = str(regdir / f"{cestoutname}_merged3.nii.gz")
    fslmerge.run()

    # MCFLIRT middle range (e.g. where abs(offsets) < 1)
    mcflirt = fsl.MCFLIRT()
    mcflirt.inputs.in_file = str(regdir / f"{cestoutname}_merged3.nii.gz")
    mcflirt.inputs.ref_vol = 0
    mcflirt.inputs.out_file = str(regdir / f"{cestoutname}_merged3_mcf.nii.gz")
    mcflirt.inputs.cost = "normmi"
    if cestvol.ndim < 3:
        mcflirt.inputs.args = "-2d"
    mcflirt.run()

    fslroi = fsl.ExtractROI()
    fslroi.inputs.in_file = str(regdir / f"{cestoutname}_merged3_mcf.nii.gz")
    fslroi.inputs.roi_file = str(regdir / f"{cestoutname}_mcfMid.nii.gz")
    fslroi.inputs.t_min = 1
    fslroi.inputs.t_size = len(n_ones) - 1
    fslroi.run()

    # Merge all CEST images together
    fslmerge = fsl.Merge()
    fslmerge.inputs.in_files = [
        str(regdir / f"{cestoutname}_merged1_mcf.nii.gz"),
        str(regdir / f"{cestoutname}_mcfMid.nii.gz"),
        str(regdir / f"{cestoutname}_merged2_mcf.nii.gz"),
    ]
    fslmerge.inputs.dimension = "t"
    fslmerge.inputs.merged_file = str(regdir / f"{cestoutname}_mergedTot_mcf.nii.gz")
    fslmerge.run()

    # Separate CEST reference image to use as registration template for CEST data
    fslroi = fsl.ExtractROI()
    fslroi.inputs.in_file = str(regdir / f"{cestoutname}_mergedTot_mcf.nii.gz")
    fslroi.inputs.roi_file = str(regdir / f"{cestoutname}_prereg.nii.gz")
    fslroi.inputs.t_min = CESTRefImage
    fslroi.inputs.t_size = 1
    fslroi.run()

    # Run FAST on Ref image
    cestfast = fsl.FAST()
    cestfast.inputs.in_files = str(regdir / f"{cestoutname}_prereg.nii.gz")
    cestfast.inputs.out_basename = str(regdir / f"{cestoutname}_bc")
    cestfast.inputs.output_biascorrected = True
    cestfast.inputs.output_biasfield = True
    cestfast.inputs.no_pve = True
    cestfast.run(ignore_exception=True)

    # Skull Strip CEST Image
    if phantom:
        fmaths = fsl.ImageMaths()
        fmaths.inputs.in_file = str(regdir / f"{cestoutname}_bc_restore.nii.gz")
        fmaths.inputs.out_file = str(regdir / f"{cestoutname}_prereg_brain.nii.gz")
        fmaths.inputs.op_string = "-thrp 10"
        fmaths.run()

        fmaths.inputs.in_file = str(regdir / f"{cestoutname}_prereg_brain.nii.gz")
        fmaths.inputs.out_file = str(regdir / f"{cestoutname}_prereg_brain_mask.nii.gz")
        fmaths.inputs.op_string = "-bin"
        fmaths.run()

    else:
        betcest0 = fsl.BET()
        betcest0.inputs.in_file = str(regdir / f"{cestoutname}_bc_restore.nii.gz")
        betcest0.inputs.out_file = str(regdir / f"{cestoutname}_prereg_brain.nii.gz")
        betcest0.inputs.mask = True
        if (
            cestvol.ndim <= 2
            or cestvol.shape[3] < 5
            or cestvol.header.get_zooms()[2] * cestvol.shape[2] < 25
        ):
            betcest0.inputs.padding = True
        betcest0.run()

    # BET rest of data
    fmaths = fsl.ImageMaths()
    fmaths.inputs.in_file = str(regdir / f"{cestoutname}_mergedTot_mcf.nii.gz")
    fmaths.inputs.op_string = "-mul"
    fmaths.inputs.in_file2 = str(regdir / f"{cestoutname}_prereg_brain_mask.nii.gz")
    fmaths.inputs.out_file = str(regdir / f"{cestoutname}_mergedTot_bc_brain.nii.gz")
    fmaths.run()

    # Move CEST data to analysis folder
    shutil.copyfile(
        str(regdir / f"{cestoutname}_mergedTot_bc_brain.nii.gz"),
        str(outfolder / f"{cestoutname}_reg.nii.gz"),
    )

    # Correct Mask so it is set at extent of CEST data
    fslmaths = fsl.ImageMaths()
    fslmaths.inputs.in_file = str(regdir / "Ref_Mask.nii.gz")
    fslmaths.inputs.op_string = "-thr 0.95 -mul"
    fslmaths.inputs.in_file2 = str(outfolder / f"{cestoutname}_reg.nii.gz")
    fslmaths.inputs.args = "-bin"
    fslmaths.inputs.out_file = str(regdir / "Ref_Mask.nii.gz")
    fslmaths.run()

    # Copy Corrected mask into Analysis folder
    shutil.copyfile(str(regdir / "Ref_Mask.nii.gz"), str(outfolder / "Ref_Mask.nii.gz"))

    # Change mask to only a single volume (instead of 4D volume from CEST data)
    maskroi = fsl.ExtractROI()
    maskroi.inputs.in_file = str(outfolder / "Ref_Mask.nii.gz")
    maskroi.inputs.roi_file = str(outfolder / "Ref_Mask.nii.gz")
    maskroi.inputs.t_min = 0
    maskroi.inputs.t_size = 1
    maskroi.run()

    return None
Exemple #24
0
def epi_pipeline(name="susceptibility_distortion_correction_using_t1"):
    """
    This workflow allows to correct for echo-planareinduced susceptibility artifacts without fieldmap
    (e.g. ADNI Database) by elastically register DWIs to their respective baseline T1-weighted
    structural scans using an inverse consistent registration algorithm with a mutual information cost
    function (SyN algorithm). This workflow allows also a coregistration of DWIs with their respective
    baseline T1-weighted structural scans in order to latter combine tracks and cortex parcelation.
    ..  warning:: This workflow rotates the `b`-vectors'
    .. References
      .. Nir et al. (Neurobiology of Aging 2015)- Connectivity network measures predict volumetric atrophy in mild cognitive impairment

        Leow et al. (IEEE Trans Med Imaging 2007)- Statistical Properties of Jacobian Maps and the Realization of Unbiased Large Deformation Nonlinear Image Registration
    Example
    -------
    >>> epi = epi_pipeline()
    >>> epi.inputs.inputnode.DWI = 'DWI.nii'
    >>> epi.inputs.inputnode.bvec = 'bvec.txt'
    >>> epi.inputs.inputnode.T1 = 'T1.nii'
    >>> epi.run() # doctest: +SKIP
    """

    import nipype.interfaces.c3 as c3
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.utility as niu
    import nipype.pipeline.engine as pe

    from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils import (
        ants_combin_transform,
        ants_registration_syn_quick,
        ants_warp_image_multi_transform,
        change_itk_transform_type,
        create_jacobian_determinant_image,
        expend_matrix_list,
        rotate_bvecs,
    )

    inputnode = pe.Node(niu.IdentityInterface(fields=["T1", "DWI", "bvec"]),
                        name="inputnode")

    split = pe.Node(fsl.Split(dimension="t"), name="SplitDWIs")
    pick_ref = pe.Node(niu.Select(), name="Pick_b0")
    pick_ref.inputs.index = [0]

    flirt_b0_2_T1 = pe.Node(interface=fsl.FLIRT(dof=6), name="flirt_B0_2_T1")
    flirt_b0_2_T1.inputs.interp = "spline"
    flirt_b0_2_T1.inputs.cost = "normmi"
    flirt_b0_2_T1.inputs.cost_func = "normmi"

    apply_xfm = pe.Node(interface=fsl.preprocess.ApplyXFM(), name="apply_xfm")
    apply_xfm.inputs.apply_xfm = True

    expend_matrix = pe.Node(
        interface=niu.Function(
            input_names=["in_matrix", "in_bvec"],
            output_names=["out_matrix_list"],
            function=expend_matrix_list,
        ),
        name="expend_matrix",
    )

    rot_bvec = pe.Node(
        niu.Function(
            input_names=["in_matrix", "in_bvec"],
            output_names=["out_file"],
            function=rotate_bvecs,
        ),
        name="Rotate_Bvec",
    )

    antsRegistrationSyNQuick = pe.Node(
        interface=niu.Function(
            input_names=["fix_image", "moving_image"],
            output_names=[
                "image_warped",
                "affine_matrix",
                "warp",
                "inverse_warped",
                "inverse_warp",
            ],
            function=ants_registration_syn_quick,
        ),
        name="antsRegistrationSyNQuick",
    )

    c3d_flirt2ants = pe.Node(c3.C3dAffineTool(), name="fsl_reg_2_itk")
    c3d_flirt2ants.inputs.itk_transform = True
    c3d_flirt2ants.inputs.fsl2ras = True

    change_transform = pe.Node(
        niu.Function(
            input_names=["input_affine_file"],
            output_names=["updated_affine_file"],
            function=change_itk_transform_type,
        ),
        name="change_transform_type",
    )

    merge_transform = pe.Node(niu.Merge(3), name="MergeTransforms")

    apply_transform = pe.MapNode(
        interface=niu.Function(
            input_names=["fix_image", "moving_image", "ants_warp_affine"],
            output_names=["out_warp_field", "out_warped"],
            function=ants_combin_transform,
        ),
        iterfield=["moving_image"],
        name="warp_filed",
    )

    jacobian = pe.MapNode(
        interface=niu.Function(
            input_names=["imageDimension", "deformationField", "outputImage"],
            output_names=["outputImage"],
            function=create_jacobian_determinant_image,
        ),
        iterfield=["deformationField"],
        name="jacobian",
    )

    jacobian.inputs.imageDimension = 3
    jacobian.inputs.outputImage = "Jacobian_image.nii.gz"

    jacmult = pe.MapNode(
        fsl.MultiImageMaths(op_string="-mul %s"),
        iterfield=["in_file", "operand_files"],
        name="ModulateDWIs",
    )

    thres = pe.MapNode(fsl.Threshold(thresh=0.0),
                       iterfield=["in_file"],
                       name="RemoveNegative")

    merge = pe.Node(fsl.Merge(dimension="t"), name="MergeDWIs")

    outputnode = pe.Node(
        niu.IdentityInterface(fields=[
            "DWI_2_T1_Coregistration_matrix",
            "epi_correction_deformation_field",
            "epi_correction_affine_transform",
            "epi_correction_image_warped",
            "DWIs_epicorrected",
            "warp_epi",
            "out_bvec",
        ]),
        name="outputnode",
    )

    wf = pe.Workflow(name="epi_pipeline")

    wf.connect([(inputnode, split, [("DWI", "in_file")])])
    wf.connect([(split, pick_ref, [("out_files", "inlist")])])
    wf.connect([(pick_ref, flirt_b0_2_T1, [("out", "in_file")])])
    wf.connect([(inputnode, flirt_b0_2_T1, [("T1", "reference")])])
    wf.connect([(inputnode, rot_bvec, [("bvec", "in_bvec")])])
    wf.connect([(flirt_b0_2_T1, expend_matrix, [("out_matrix_file",
                                                 "in_matrix")])])
    wf.connect([(inputnode, expend_matrix, [("bvec", "in_bvec")])])
    wf.connect([(expend_matrix, rot_bvec, [("out_matrix_list", "in_matrix")])])
    wf.connect([(inputnode, antsRegistrationSyNQuick, [("T1", "fix_image")])])
    wf.connect([(flirt_b0_2_T1, antsRegistrationSyNQuick, [("out_file",
                                                            "moving_image")])])

    wf.connect([(inputnode, c3d_flirt2ants, [("T1", "reference_file")])])
    wf.connect([(pick_ref, c3d_flirt2ants, [("out", "source_file")])])
    wf.connect([(flirt_b0_2_T1, c3d_flirt2ants, [("out_matrix_file",
                                                  "transform_file")])])
    wf.connect([(c3d_flirt2ants, change_transform, [("itk_transform",
                                                     "input_affine_file")])])

    wf.connect([(antsRegistrationSyNQuick, merge_transform, [("warp", "in1")])
                ])
    wf.connect([(antsRegistrationSyNQuick, merge_transform, [("affine_matrix",
                                                              "in2")])])
    wf.connect([(change_transform, merge_transform, [("updated_affine_file",
                                                      "in3")])])
    wf.connect([(inputnode, apply_transform, [("T1", "fix_image")])])
    wf.connect([(split, apply_transform, [("out_files", "moving_image")])])

    wf.connect([(merge_transform, apply_transform, [("out", "ants_warp_affine")
                                                    ])])
    wf.connect([(apply_transform, jacobian, [("out_warp_field",
                                              "deformationField")])])
    wf.connect([(apply_transform, jacmult, [("out_warped", "operand_files")])])
    wf.connect([(jacobian, jacmult, [("outputImage", "in_file")])])
    wf.connect([(jacmult, thres, [("out_file", "in_file")])])
    wf.connect([(thres, merge, [("out_file", "in_files")])])

    wf.connect([(merge, outputnode, [("merged_file", "DWIs_epicorrected")])])
    wf.connect([(
        flirt_b0_2_T1,
        outputnode,
        [("out_matrix_file", "DWI_2_T1_Coregistration_matrix")],
    )])
    wf.connect([(
        antsRegistrationSyNQuick,
        outputnode,
        [
            ("warp", "epi_correction_deformation_field"),
            ("affine_matrix", "epi_correction_affine_transform"),
            ("image_warped", "epi_correction_image_warped"),
        ],
    )])
    wf.connect([(merge_transform, outputnode, [("out", "warp_epi")])])
    wf.connect([(rot_bvec, outputnode, [("out_file", "out_bvec")])])

    return wf
Exemple #25
0
def remove_bias(name="bias_correct"):
    """
    This workflow estimates a single multiplicative bias field from the
    averaged *b0* image, as suggested in [Jeurissen2014]_.
    .. admonition:: References
      .. [Jeurissen2014] Jeurissen B. et al., `Multi-tissue constrained
        spherical deconvolution for improved analysis of multi-shell diffusion
        MRI data <http://dx.doi.org/10.1016/j.neuroimage.2014.07.061>`_.squeue

        NeuroImage (2014). doi: 10.1016/j.neuroimage.2014.07.061
    Example
    -------
    >>> from nipype.workflows.dmri.fsl.artifacts import remove_bias
    >>> bias = remove_bias()
    >>> bias.inputs.inputnode.in_file = 'epi.nii'
    >>> bias.inputs.inputnode.in_bval = 'diffusion.bval'
    >>> bias.inputs.inputnode.in_mask = 'mask.nii'
    >>> bias.run() # doctest: +SKIP
    """
    import nipype.interfaces.ants as ants
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.utility as niu
    import nipype.pipeline.engine as pe

    inputnode = pe.Node(niu.IdentityInterface(fields=["in_file"]),
                        name="inputnode")

    outputnode = pe.Node(niu.IdentityInterface(fields=["out_file", "b0_mask"]),
                         name="outputnode")

    get_b0 = pe.Node(fsl.ExtractROI(t_min=0, t_size=1), name="get_b0")

    mask_b0 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True),
                      name="mask_b0")

    n4 = pe.Node(
        ants.N4BiasFieldCorrection(dimension=3,
                                   save_bias=True,
                                   bspline_fitting_distance=600),
        name="Bias_b0",
    )
    split = pe.Node(fsl.Split(dimension="t"), name="SplitDWIs")
    mult = pe.MapNode(
        fsl.MultiImageMaths(op_string="-div %s"),
        iterfield=["in_file"],
        name="RemoveBiasOfDWIs",
    )
    thres = pe.MapNode(fsl.Threshold(thresh=0.0),
                       iterfield=["in_file"],
                       name="RemoveNegative")
    merge = pe.Node(fsl.utils.Merge(dimension="t"), name="MergeDWIs")

    wf = pe.Workflow(name=name)
    wf.connect([
        (inputnode, get_b0, [("in_file", "in_file")]),
        (get_b0, n4, [("roi_file", "input_image")]),
        (get_b0, mask_b0, [("roi_file", "in_file")]),
        (mask_b0, n4, [("mask_file", "mask_image")]),
        (inputnode, split, [("in_file", "in_file")]),
        (n4, mult, [("bias_image", "operand_files")]),
        (split, mult, [("out_files", "in_file")]),
        (mult, thres, [("out_file", "in_file")]),
        (thres, merge, [("out_file", "in_files")]),
        (merge, outputnode, [("merged_file", "out_file")]),
        (mask_b0, outputnode, [("mask_file", "b0_mask")]),
    ])
    return wf
Exemple #26
0
def ecc_pipeline(name="eddy_correct"):
    """
    ECC stands for Eddy currents correction.
    Creates a pipelines that corrects for artifacts induced by Eddy currents in
    dMRI sequences.
    It takes a series of diffusion weighted images and linearly co-registers
    them to one reference image (the average of all b0s in the dataset).
    DWIs are also modulated by the determinant of the Jacobian as indicated by
    [Jones10]_ and [Rohde04]_.
    A list of rigid transformation matrices can be provided, sourcing from a
    :func:`.hmc_pipeline` workflow, to initialize registrations in a *motion
    free* framework.
    A list of affine transformation matrices is available as output, so that
    transforms can be chained (discussion
    `here <https://github.com/nipy/nipype/pull/530#issuecomment-14505042>`_).
    .. admonition:: References
      .. [Jones10] Jones DK, `The signal intensity must be modulated by the
        determinant of the Jacobian when correcting for eddy currents in
        diffusion MRI
        <http://cds.ismrm.org/protected/10MProceedings/files/1644_129.pdf>`_,
        Proc. ISMRM 18th Annual Meeting, (2010).
      .. [Rohde04] Rohde et al., `Comprehensive Approach for Correction of
        Motion and Distortion in Diffusion-Weighted MRI
        <http://stbb.nichd.nih.gov/pdf/com_app_cor_mri04.pdf>`_, MRM
        51:103-114 (2004).
    Example
    -------
    from nipype.workflows.dmri.fsl.artifacts import ecc_pipeline
    ecc = ecc_pipeline()
    ecc.inputs.inputnode.in_file = 'diffusion.nii'
    ecc.inputs.inputnode.in_bval = 'diffusion.bval'
    ecc.inputs.inputnode.in_mask = 'mask.nii'
    ecc.run() # doctest: +SKIP
    Inputs::
        inputnode.in_file - input dwi file
        inputnode.in_mask - weights mask of reference image (a file with data \
range sin [0.0, 1.0], indicating the weight of each voxel when computing the \
metric.
        inputnode.in_bval - b-values table
        inputnode.in_xfms - list of matrices to initialize registration (from \
head-motion correction)
    Outputs::
        outputnode.out_file - corrected dwi file
        outputnode.out_xfms - list of transformation matrices
    """

    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.utility as niu
    import nipype.pipeline.engine as pe
    from nipype.workflows.data import get_flirt_schedule
    from nipype.workflows.dmri.fsl.artifacts import _xfm_jacobian
    from nipype.workflows.dmri.fsl.utils import (
        extract_bval,
        recompose_dwi,
        recompose_xfm,
    )

    from clinica.utils.dwi import merge_volumes_tdim
    from clinica.workflows.dwi_preprocessing import dwi_flirt

    params = dict(
        dof=12,
        no_search=True,
        interp="spline",
        bgvalue=0,
        schedule=get_flirt_schedule("ecc"),
    )

    inputnode = pe.Node(
        niu.IdentityInterface(
            fields=["in_file", "in_bval", "in_mask", "in_xfms"]),
        name="inputnode",
    )

    getb0 = pe.Node(fsl.ExtractROI(t_min=0, t_size=1), name="get_b0")

    pick_dws = pe.Node(
        niu.Function(
            input_names=["in_dwi", "in_bval", "b"],
            output_names=["out_file"],
            function=extract_bval,
        ),
        name="extract_dwi",
    )
    pick_dws.inputs.b = "diff"

    flirt = dwi_flirt(flirt_param=params, excl_nodiff=True)

    mult = pe.MapNode(
        fsl.BinaryMaths(operation="mul"),
        name="ModulateDWIs",
        iterfield=["in_file", "operand_value"],
    )
    thres = pe.MapNode(fsl.Threshold(thresh=0.0),
                       iterfield=["in_file"],
                       name="RemoveNegative")

    split = pe.Node(fsl.Split(dimension="t"), name="SplitDWIs")
    get_mat = pe.Node(
        niu.Function(
            input_names=["in_bval", "in_xfms"],
            output_names=["out_files"],
            function=recompose_xfm,
        ),
        name="GatherMatrices",
    )
    merge = pe.Node(
        niu.Function(
            input_names=["in_dwi", "in_bval", "in_corrected"],
            output_names=["out_file"],
            function=recompose_dwi,
        ),
        name="MergeDWIs",
    )

    merged_volumes = pe.Node(
        niu.Function(
            input_names=["in_file1", "in_file2"],
            output_names=["out_file"],
            function=merge_volumes_tdim,
        ),
        name="merge_enhanced_ref_dwis",
    )

    outputnode = pe.Node(
        niu.IdentityInterface(fields=["out_file", "out_xfms"]),
        name="outputnode")

    wf = pe.Workflow(name=name)
    wf.connect([
        (inputnode, getb0, [("in_file", "in_file")]),
        (inputnode, pick_dws, [("in_file", "in_dwi"), ("in_bval", "in_bval")]),
        (
            flirt,
            merged_volumes,
            [
                ("outputnode.out_ref", "in_file1"),
                ("outputnode.out_file", "in_file2"),
            ],
        ),
        (merged_volumes, merge, [("out_file", "in_dwi")]),
        (inputnode, merge, [("in_bval", "in_bval")]),
        (
            inputnode,
            flirt,
            [
                ("in_mask", "inputnode.ref_mask"),
                ("in_xfms", "inputnode.in_xfms"),
                ("in_bval", "inputnode.in_bval"),
            ],
        ),
        (inputnode, get_mat, [("in_bval", "in_bval")]),
        (getb0, flirt, [("roi_file", "inputnode.reference")]),
        (pick_dws, flirt, [("out_file", "inputnode.in_file")]),
        (flirt, get_mat, [("outputnode.out_xfms", "in_xfms")]),
        (flirt, mult, [(("outputnode.out_xfms", _xfm_jacobian),
                        "operand_value")]),
        (flirt, split, [("outputnode.out_file", "in_file")]),
        (split, mult, [("out_files", "in_file")]),
        (mult, thres, [("out_file", "in_file")]),
        (thres, merge, [("out_file", "in_corrected")]),
        (get_mat, outputnode, [("out_files", "out_xfms")]),
        (merge, outputnode, [("out_file", "out_file")]),
    ])
    return wf
Exemple #27
0
def create_motion_correct_pipeline(name='motion_correct'):
    """Creates a pipeline that corrects for motion artifact in dMRI sequences.
    It takes a series of diffusion weighted images and rigidly co-registers
    them to one reference image. Finally, the b-matrix is rotated accordingly
    (Leemans et al. 2009 - http://www.ncbi.nlm.nih.gov/pubmed/19319973),
    making use of the rotation matrix obtained by FLIRT.


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


    .. warning:: This workflow rotates the b-vectors, so please be adviced
      that not all the dicom converters ensure the consistency between the resulting
      nifti orientation and the b matrix table (e.g. dcm2nii checks it).


    Example
    -------

    >>> nipype_motioncorrect = create_motion_correct_pipeline('nipype_motioncorrect')
    >>> nipype_motioncorrect.inputs.inputnode.in_file = 'diffusion.nii'
    >>> nipype_motioncorrect.inputs.inputnode.in_bvec = 'diffusion.bvec'
    >>> nipype_motioncorrect.inputs.inputnode.ref_num = 0
    >>> nipype_motioncorrect.run() # doctest: +SKIP

    Inputs::

        inputnode.in_file
        inputnode.ref_num
        inputnode.in_bvec

    Outputs::

        outputnode.motion_corrected
        outputnode.out_bvec

    """

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

    inputnode = pe.Node(
        niu.IdentityInterface(fields=['in_file', 'ref_num', 'in_bvec']),
        name='inputnode')

    pipeline = pe.Workflow(name=name)

    split = pe.Node(fsl.Split(dimension='t'), name='split')
    pick_ref = pe.Node(niu.Select(), name='pick_ref')
    coregistration = pe.MapNode(fsl.FLIRT(no_search=True,
                                          interp='spline',
                                          padding_size=1,
                                          dof=6),
                                name='coregistration',
                                iterfield=['in_file'])
    rotate_bvecs = pe.Node(niu.Function(input_names=['in_bvec', 'in_matrix'],
                                        output_names=['out_file'],
                                        function=_rotate_bvecs),
                           name='rotate_b_matrix')
    merge = pe.Node(fsl.Merge(dimension='t'), name='merge')
    outputnode = pe.Node(
        niu.IdentityInterface(fields=['motion_corrected', 'out_bvec']),
        name='outputnode')

    pipeline.connect([
        (inputnode, split, [('in_file', 'in_file')]),
        (split, pick_ref, [('out_files', 'inlist')]),
        (inputnode, pick_ref, [('ref_num', 'index')]),
        (split, coregistration, [('out_files', 'in_file')]),
        (inputnode, rotate_bvecs, [('in_bvec', 'in_bvec')]),
        (coregistration, rotate_bvecs, [('out_matrix_file', 'in_matrix')]),
        (pick_ref, coregistration, [('out', 'reference')]),
        (coregistration, merge, [('out_file', 'in_files')]),
        (merge, outputnode, [('merged_file', 'motion_corrected')]),
        (rotate_bvecs, outputnode, [('out_file', 'out_bvec')])
    ])

    return pipeline
Exemple #28
0
def create_indnet_workflow(hp_cutoff=100,
                           smoothing=5,
                           smm_threshold=0.5,
                           binarise_threshold=0.5,
                           melodic_seed=None,
                           aggr_aroma=False,
                           name="indnet"):

    indnet = Workflow(name=name)

    # Input node
    inputspec = Node(utility.IdentityInterface(
        fields=['anat_file', 'func_file', 'templates', 'networks']),
                     name='inputspec')

    # T1 skullstrip
    anat_bet = Node(fsl.BET(), name="anat_bet")

    # EPI preprocessing
    func_realignsmooth = create_featreg_preproc(highpass=False,
                                                whichvol='first',
                                                name='func_realignsmooth')
    func_realignsmooth.inputs.inputspec.fwhm = smoothing

    # Transform EPI to MNI space
    func_2mni = create_reg_workflow(name='func_2mni')
    func_2mni.inputs.inputspec.target_image = fsl.Info.standard_image(
        'MNI152_T1_2mm.nii.gz')
    func_2mni.inputs.inputspec.target_image_brain = fsl.Info.standard_image(
        'MNI152_T1_2mm_brain.nii.gz')
    func_2mni.inputs.inputspec.config_file = 'T1_2_MNI152_2mm'

    # Segmentation of T1
    anat_segmentation = Node(fsl.FAST(output_biascorrected=True),
                             name='anat_segmentation')

    # Transfrom segments to EPI space
    segments_2func = create_segments_2func_workflow(
        threshold=binarise_threshold, name='segments_2func')

    # Transform templates to EPI space
    templates_2func = create_templates_2func_workflow(
        threshold=binarise_threshold, name='templates_2func')

    # Mask network templates with GM
    gm_mask_templates = MapNode(fsl.ImageMaths(op_string='-mul'),
                                iterfield=['in_file2'],
                                name='gm_mask_templates')

    # Mask for ICA-AROMA and statistics
    func_brainmask = Node(fsl.BET(frac=0.3,
                                  mask=True,
                                  no_output=True,
                                  robust=True),
                          name='func_brainmask')

    # Melodic ICA
    if melodic_seed != None:
        func_melodic = Node(fsl.MELODIC(args='--seed={}'.format(melodic_seed),
                                        out_stats=True),
                            name='func_melodic')

    # ICA-AROMA
    func_aroma = Node(fsl.ICA_AROMA(), name='func_aroma')
    if aggr_aroma:
        func_aroma.inputs.denoise_type = 'aggr'

    else:
        func_aroma.inputs.denoise_type = 'nonaggr'

    # Highpass filter ICA results
    func_highpass = create_highpass_filter(cutoff=hp_cutoff,
                                           name='func_highpass')

    # Calculate mean CSF sgnal
    csf_meansignal = Node(fsl.ImageMeants(), name='csf_meansignal')

    # Calculate mean WM signal
    wm_meansignal = Node(fsl.ImageMeants(), name='wm_meansignal')

    # Calculate mean non-brain signal
    nonbrain_meansignal = create_nonbrain_meansignal(
        name='nonbrain_meansignal')

    # Calculate first Eigenvariates
    firsteigenvariates = MapNode(fsl.ImageMeants(show_all=True, eig=True),
                                 iterfield=['mask'],
                                 name='firsteigenvariates')

    # Combine first eigenvariates and wm/csf/non-brain signals
    regressors = Node(utility.Merge(4), name='regressors')

    # z-transform regressors
    ztransform = MapNode(Ztransform(),
                         iterfield=['in_file'],
                         name='ztransform')

    # Create design matrix
    designmatrix = Node(DesignMatrix(), name='designmatrix')

    # Create contrasts
    contrasts = Node(Contrasts(), name='contrasts')

    # GLM
    glm = Node(fsl.GLM(), name='glm')
    glm.inputs.out_z_name = 'z_stats.nii.gz'
    glm.inputs.demean = True

    # Split z-maps
    zmaps = Node(fsl.Split(), name='zmaps')
    zmaps.inputs.dimension = 't'

    # Spatial Mixture Modelling
    smm = MapNode(fsl.SMM(), iterfield=['spatial_data_file'], name='smm')

    # Transform probability maps to native (anat) space
    actmaps_2anat = MapNode(fsl.ApplyXFM(),
                            iterfield=['in_file'],
                            name='actmaps_2anat')

    # Transform probability maps to MNI space
    actmaps_2mni = MapNode(fsl.ApplyWarp(),
                           iterfield=['in_file'],
                           name='actmaps_2mni')
    actmaps_2mni.inputs.ref_file = fsl.Info.standard_image(
        'MNI152_T1_2mm.nii.gz')

    # Create network masks in native (func) space
    network_masks_func = create_network_masks_workflow(
        name='network_masks_func', smm_threshold=smm_threshold)

    # Create network masks in native (anat) space
    network_masks_anat = create_network_masks_workflow(
        name='network_masks_anat', smm_threshold=smm_threshold)

    # Create network masks in MNI space
    network_masks_mni = create_network_masks_workflow(
        name='network_masks_mni', smm_threshold=smm_threshold)

    # Output node
    outputspec = Node(utility.IdentityInterface(fields=[
        'network_masks_func_main', 'network_masks_func_exclusive',
        'network_masks_anat_main', 'network_masks_anat_exclusive',
        'network_masks_mni_main', 'network_masks_mni_exclusive',
        'preprocessed_func_file', 'preprocessed_anat_file',
        'motion_parameters', 'func2anat_transform', 'anat2mni_transform'
    ]),
                      name='outputspec')

    # Helper functions
    def get_first_item(x):
        try:
            return x[0]
        except:
            return x

    def get_second_item(x):
        return x[1]

    def get_third_item(x):
        return x[2]

    def get_components(x):
        return [y['components'] for y in x]

    # Connect the nodes

    # anat_bet
    indnet.connect(inputspec, 'anat_file', anat_bet, 'in_file')

    # func_realignsmooth
    indnet.connect(inputspec, 'func_file', func_realignsmooth,
                   'inputspec.func')

    # func_2mni
    indnet.connect(func_realignsmooth,
                   ('outputspec.smoothed_files', get_first_item), func_2mni,
                   'inputspec.source_files')
    indnet.connect(inputspec, 'anat_file', func_2mni,
                   'inputspec.anatomical_image')
    indnet.connect(func_realignsmooth, 'outputspec.reference', func_2mni,
                   'inputspec.mean_image')

    # anat_segmentation
    indnet.connect(anat_bet, 'out_file', anat_segmentation, 'in_files')

    # segments_2func
    indnet.connect(anat_segmentation, 'partial_volume_files', segments_2func,
                   'inputspec.segments')
    indnet.connect(func_2mni, 'outputspec.func2anat_transform', segments_2func,
                   'inputspec.premat')
    indnet.connect(func_realignsmooth, 'outputspec.mean', segments_2func,
                   'inputspec.func_file')

    # templates_2func
    indnet.connect(func_realignsmooth, 'outputspec.mean', templates_2func,
                   'inputspec.func_file')
    indnet.connect(func_2mni, 'outputspec.func2anat_transform',
                   templates_2func, 'inputspec.premat')
    indnet.connect(func_2mni, 'outputspec.anat2target_transform',
                   templates_2func, 'inputspec.warp')
    indnet.connect(inputspec, 'templates', templates_2func,
                   'inputspec.templates')

    # gm_mask_templates
    indnet.connect(segments_2func,
                   ('outputspec.segments_2func_files', get_second_item),
                   gm_mask_templates, 'in_file')
    indnet.connect(templates_2func, 'outputspec.templates_2func_files',
                   gm_mask_templates, 'in_file2')

    # func_brainmask
    indnet.connect(func_realignsmooth, 'outputspec.mean', func_brainmask,
                   'in_file')

    # func_melodic
    if melodic_seed != None:
        indnet.connect(func_realignsmooth,
                       ('outputspec.smoothed_files', get_first_item),
                       func_melodic, 'in_files')
        indnet.connect(func_brainmask, 'mask_file', func_melodic, 'mask')

    # func_aroma
    indnet.connect(func_realignsmooth,
                   ('outputspec.smoothed_files', get_first_item), func_aroma,
                   'in_file')
    indnet.connect(func_2mni, 'outputspec.func2anat_transform', func_aroma,
                   'mat_file')
    indnet.connect(func_2mni, 'outputspec.anat2target_transform', func_aroma,
                   'fnirt_warp_file')
    indnet.connect(func_realignsmooth,
                   ('outputspec.motion_parameters', get_first_item),
                   func_aroma, 'motion_parameters')
    indnet.connect(func_brainmask, 'mask_file', func_aroma, 'mask')
    if melodic_seed != None:
        indnet.connect(func_melodic, 'out_dir', func_aroma, 'melodic_dir')

    # func_highpass
    if aggr_aroma:
        indnet.connect(func_aroma, 'aggr_denoised_file', func_highpass,
                       'inputspec.in_file')
    else:
        indnet.connect(func_aroma, 'nonaggr_denoised_file', func_highpass,
                       'inputspec.in_file')

    # csf_meansignal
    indnet.connect(segments_2func,
                   ('outputspec.segments_2func_files', get_first_item),
                   csf_meansignal, 'mask')
    indnet.connect(func_highpass, 'outputspec.filtered_file', csf_meansignal,
                   'in_file')

    # wm_meansignal
    indnet.connect(segments_2func,
                   ('outputspec.segments_2func_files', get_third_item),
                   wm_meansignal, 'mask')
    indnet.connect(func_highpass, 'outputspec.filtered_file', wm_meansignal,
                   'in_file')

    # nonbrain_meansignal
    indnet.connect(inputspec, 'func_file', nonbrain_meansignal,
                   'inputspec.func_file')

    # firsteigenvariates
    indnet.connect(gm_mask_templates, 'out_file', firsteigenvariates, 'mask')
    indnet.connect(func_highpass, 'outputspec.filtered_file',
                   firsteigenvariates, 'in_file')

    # regressors
    indnet.connect(firsteigenvariates, 'out_file', regressors, 'in1')
    indnet.connect(wm_meansignal, 'out_file', regressors, 'in2')
    indnet.connect(csf_meansignal, 'out_file', regressors, 'in3')
    indnet.connect(nonbrain_meansignal, 'outputspec.nonbrain_regressor',
                   regressors, 'in4')

    # ztransform
    indnet.connect(regressors, 'out', ztransform, 'in_file')

    # designmatrix
    indnet.connect(ztransform, 'out_file', designmatrix, 'in_files')

    # contrasts
    indnet.connect(inputspec, ('networks', get_components), contrasts,
                   'in_list')
    indnet.connect(designmatrix, 'out_file', contrasts, 'design')

    # glm
    indnet.connect(designmatrix, 'out_file', glm, 'design')
    indnet.connect(contrasts, 'out_file', glm, 'contrasts')
    indnet.connect(func_brainmask, 'mask_file', glm, 'mask')
    indnet.connect(func_highpass, 'outputspec.filtered_file', glm, 'in_file')

    # zmaps
    indnet.connect(glm, 'out_z', zmaps, 'in_file')

    # smm
    indnet.connect(zmaps, 'out_files', smm, 'spatial_data_file')
    indnet.connect(func_brainmask, 'mask_file', smm, 'mask')

    # actmaps_2anat
    indnet.connect(smm, 'activation_p_map', actmaps_2anat, 'in_file')
    indnet.connect(func_2mni, 'outputspec.func2anat_transform', actmaps_2anat,
                   'in_matrix_file')
    indnet.connect(anat_bet, 'out_file', actmaps_2anat, 'reference')

    # actmaps_2mni
    indnet.connect(smm, 'activation_p_map', actmaps_2mni, 'in_file')
    indnet.connect(templates_2func, 'outputspec.func_2mni_warp', actmaps_2mni,
                   'field_file')

    # network_masks_func
    indnet.connect(smm, 'activation_p_map', network_masks_func,
                   'inputspec.actmaps')
    indnet.connect(inputspec, 'networks', network_masks_func,
                   'inputspec.networks')

    # network_masks_anat
    indnet.connect(actmaps_2anat, 'out_file', network_masks_anat,
                   'inputspec.actmaps')
    indnet.connect(inputspec, 'networks', network_masks_anat,
                   'inputspec.networks')

    # network_masks_mni
    indnet.connect(actmaps_2mni, 'out_file', network_masks_mni,
                   'inputspec.actmaps')
    indnet.connect(inputspec, 'networks', network_masks_mni,
                   'inputspec.networks')

    # output node
    indnet.connect(network_masks_func, 'outputspec.main_masks', outputspec,
                   'network_masks_func_main')
    indnet.connect(network_masks_func, 'outputspec.exclusive_masks',
                   outputspec, 'network_masks_func_exclusive')
    indnet.connect(network_masks_anat, 'outputspec.main_masks', outputspec,
                   'network_masks_anat_main')
    indnet.connect(network_masks_anat, 'outputspec.exclusive_masks',
                   outputspec, 'network_masks_anat_exclusive')
    indnet.connect(network_masks_mni, 'outputspec.main_masks', outputspec,
                   'network_masks_mni_main')
    indnet.connect(network_masks_mni, 'outputspec.exclusive_masks', outputspec,
                   'network_masks_mni_exclusive')
    indnet.connect(func_highpass, 'outputspec.filtered_file', outputspec,
                   'preprocessed_func_file')
    indnet.connect(anat_segmentation, 'restored_image', outputspec,
                   'preprocessed_anat_file')
    indnet.connect(func_realignsmooth,
                   ('outputspec.motion_parameters', get_first_item),
                   outputspec, 'motion_parameters')
    indnet.connect(func_2mni, 'outputspec.func2anat_transform', outputspec,
                   'func2anat_transform')
    indnet.connect(func_2mni, 'outputspec.anat2target_transform', outputspec,
                   'anat2mni_transform')

    return indnet
Exemple #29
0
def dwi_flirt(name="DWICoregistration", excl_nodiff=False, flirt_param={}):
    """
    Generates a workflow for linear registration of dwi volumes using flirt.

    Inputnode
    ---------
    reference : FILE
      Mandatory input. Reference data set.
    in_file : FILE
      Mandatory input. Moving data set.
    ref_mask : FILE
      Mandatory input. Binary mask of the reference volume.
    in_xfms : FILE
      Mandatory input. Intialisation matrices for flirt.
    in_bval : FILE
      Mandatory input. B values file.

    """
    import nipype.interfaces.ants as ants
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.utility as niu
    import nipype.pipeline.engine as pe
    from nipype.workflows.dmri.fsl.utils import _checkinitxfm, enhance

    inputnode = pe.Node(
        niu.IdentityInterface(
            fields=["reference", "in_file", "ref_mask", "in_xfms", "in_bval"]),
        name="inputnode",
    )

    initmat = pe.Node(
        niu.Function(
            input_names=["in_bval", "in_xfms", "excl_nodiff"],
            output_names=["init_xfms"],
            function=_checkinitxfm,
        ),
        name="InitXforms",
    )
    initmat.inputs.excl_nodiff = excl_nodiff
    dilate = pe.Node(
        fsl.maths.MathsCommand(nan2zeros=True, args="-kernel sphere 5 -dilM"),
        name="MskDilate",
    )
    split = pe.Node(fsl.Split(dimension="t"), name="SplitDWIs")
    n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name="Bias")
    flirt = pe.MapNode(
        fsl.FLIRT(**flirt_param),
        name="CoRegistration",
        iterfield=["in_file", "in_matrix_file"],
    )
    thres = pe.MapNode(fsl.Threshold(thresh=0.0),
                       iterfield=["in_file"],
                       name="RemoveNegative")
    merge = pe.Node(fsl.Merge(dimension="t"), name="MergeDWIs")
    outputnode = pe.Node(
        niu.IdentityInterface(fields=["out_file", "out_xfms", "out_ref"]),
        name="outputnode",
    )
    enhb0 = pe.Node(
        niu.Function(
            input_names=["in_file", "in_mask", "clip_limit"],
            output_names=["out_file"],
            function=enhance,
        ),
        name="B0Equalize",
    )
    enhb0.inputs.clip_limit = 0.015
    enhdw = pe.MapNode(
        niu.Function(
            input_names=["in_file", "in_mask"],
            output_names=["out_file"],
            function=enhance,
        ),
        name="DWEqualize",
        iterfield=["in_file"],
    )
    # enhb0.inputs.clip_limit = clip_limit

    wf = pe.Workflow(name=name)
    wf.connect([
        (inputnode, split, [("in_file", "in_file")]),
        (inputnode, dilate, [("ref_mask", "in_file")]),
        (inputnode, n4, [("reference", "input_image"),
                         ("ref_mask", "mask_image")]),
        #        (inputnode,  flirt,      [('ref_mask', 'reference')]),
        (n4, enhb0, [("output_image", "in_file")]),
        (enhb0, flirt, [("out_file", "reference")]),
        (inputnode, initmat, [("in_xfms", "in_xfms"), ("in_bval", "in_bval")]),
        (split, enhdw, [("out_files", "in_file")]),
        (dilate, enhdw, [("out_file", "in_mask")]),
        (dilate, flirt, [("out_file", "ref_weight"),
                         ("out_file", "in_weight")]),
        (enhdw, flirt, [("out_file", "in_file")]),
        (initmat, flirt, [("init_xfms", "in_matrix_file")]),
        (flirt, thres, [("out_file", "in_file")]),
        (thres, merge, [("out_file", "in_files")]),
        (merge, outputnode, [("merged_file", "out_file")]),
        (enhb0, outputnode, [("out_file", "out_ref")]),
        (flirt, outputnode, [("out_matrix_file", "out_xfms")]),
    ])
    return wf
def sdc_fmb(name='fmb_correction',
            interp='Linear',
            fugue_params=dict(smooth3d=2.0)):
    """
    SDC stands for susceptibility distortion correction. FMB stands for
    fieldmap-based.

    The fieldmap based (FMB) method implements SDC by using a mapping of the
    B0 field as proposed by [Jezzard95]_. This workflow uses the implementation
    of FSL (`FUGUE <http://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FUGUE>`_). Phase
    unwrapping is performed using `PRELUDE
    <http://fsl.fmrib.ox.ac.uk/fsl/fsl-4.1.9/fugue/prelude.html>`_
    [Jenkinson03]_. Preparation of the fieldmap is performed reproducing the
    script in FSL `fsl_prepare_fieldmap
    <http://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FUGUE/Guide#SIEMENS_data>`_.



    Example
    -------

    >>> from nipype.workflows.dmri.fsl.artifacts import sdc_fmb
    >>> fmb = sdc_fmb()
    >>> fmb.inputs.inputnode.in_file = 'diffusion.nii'
    >>> fmb.inputs.inputnode.in_ref = list(range(0, 30, 6))
    >>> fmb.inputs.inputnode.in_mask = 'mask.nii'
    >>> fmb.inputs.inputnode.bmap_mag = 'magnitude.nii'
    >>> fmb.inputs.inputnode.bmap_pha = 'phase.nii'
    >>> fmb.inputs.inputnode.settings = 'epi_param.txt'
    >>> fmb.run() # doctest: +SKIP

    .. warning:: Only SIEMENS format fieldmaps are supported.

    .. admonition:: References

      .. [Jezzard95] Jezzard P, and Balaban RS, `Correction for geometric
        distortion in echo planar images from B0 field variations
        <https://doi.org/10.1002/mrm.1910340111>`_,
        MRM 34(1):65-73. (1995). doi: 10.1002/mrm.1910340111.

      .. [Jenkinson03] Jenkinson M., `Fast, automated, N-dimensional
        phase-unwrapping algorithm <https://doi.org/10.1002/mrm.10354>`_,
        MRM 49(1):193-197, 2003, doi: 10.1002/mrm.10354.

    """

    epi_defaults = {
        'delta_te': 2.46e-3,
        'echospacing': 0.77e-3,
        'acc_factor': 2,
        'enc_dir': u'AP'
    }

    inputnode = pe.Node(niu.IdentityInterface(fields=[
        'in_file', 'in_ref', 'in_mask', 'bmap_pha', 'bmap_mag', 'settings'
    ]),
                        name='inputnode')

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

    r_params = pe.Node(JSONFileGrabber(defaults=epi_defaults),
                       name='SettingsGrabber')
    eff_echo = pe.Node(niu.Function(function=_eff_t_echo,
                                    input_names=['echospacing', 'acc_factor'],
                                    output_names=['eff_echo']),
                       name='EffEcho')

    firstmag = pe.Node(fsl.ExtractROI(t_min=0, t_size=1), name='GetFirst')
    n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='Bias')
    bet = pe.Node(fsl.BET(frac=0.4, mask=True), name='BrainExtraction')
    dilate = pe.Node(fsl.maths.MathsCommand(nan2zeros=True,
                                            args='-kernel sphere 5 -dilM'),
                     name='MskDilate')
    pha2rads = pe.Node(niu.Function(input_names=['in_file'],
                                    output_names=['out_file'],
                                    function=siemens2rads),
                       name='PreparePhase')
    prelude = pe.Node(fsl.PRELUDE(process3d=True), name='PhaseUnwrap')
    rad2rsec = pe.Node(niu.Function(input_names=['in_file', 'delta_te'],
                                    output_names=['out_file'],
                                    function=rads2radsec),
                       name='ToRadSec')

    baseline = pe.Node(niu.Function(input_names=['in_file', 'index'],
                                    output_names=['out_file'],
                                    function=time_avg),
                       name='Baseline')

    fmm2b0 = pe.Node(ants.Registration(output_warped_image=True),
                     name="FMm_to_B0")
    fmm2b0.inputs.transforms = ['Rigid'] * 2
    fmm2b0.inputs.transform_parameters = [(1.0, )] * 2
    fmm2b0.inputs.number_of_iterations = [[50], [20]]
    fmm2b0.inputs.dimension = 3
    fmm2b0.inputs.metric = ['Mattes', 'Mattes']
    fmm2b0.inputs.metric_weight = [1.0] * 2
    fmm2b0.inputs.radius_or_number_of_bins = [64, 64]
    fmm2b0.inputs.sampling_strategy = ['Regular', 'Random']
    fmm2b0.inputs.sampling_percentage = [None, 0.2]
    fmm2b0.inputs.convergence_threshold = [1.e-5, 1.e-8]
    fmm2b0.inputs.convergence_window_size = [20, 10]
    fmm2b0.inputs.smoothing_sigmas = [[6.0], [2.0]]
    fmm2b0.inputs.sigma_units = ['vox'] * 2
    fmm2b0.inputs.shrink_factors = [[6], [1]]  # ,[1] ]
    fmm2b0.inputs.use_estimate_learning_rate_once = [True] * 2
    fmm2b0.inputs.use_histogram_matching = [True] * 2
    fmm2b0.inputs.initial_moving_transform_com = 0
    fmm2b0.inputs.collapse_output_transforms = True
    fmm2b0.inputs.winsorize_upper_quantile = 0.995

    applyxfm = pe.Node(ants.ApplyTransforms(dimension=3, interpolation=interp),
                       name='FMp_to_B0')

    pre_fugue = pe.Node(fsl.FUGUE(save_fmap=True), name='PreliminaryFugue')
    demean = pe.Node(niu.Function(input_names=['in_file', 'in_mask'],
                                  output_names=['out_file'],
                                  function=demean_image),
                     name='DemeanFmap')

    cleanup = cleanup_edge_pipeline()

    addvol = pe.Node(niu.Function(input_names=['in_file'],
                                  output_names=['out_file'],
                                  function=add_empty_vol),
                     name='AddEmptyVol')

    vsm = pe.Node(fsl.FUGUE(save_shift=True, **fugue_params),
                  name="ComputeVSM")

    split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs')
    merge = pe.Node(fsl.Merge(dimension='t'), name='MergeDWIs')
    unwarp = pe.MapNode(fsl.FUGUE(icorr=True, forward_warping=False),
                        iterfield=['in_file'],
                        name='UnwarpDWIs')
    thres = pe.MapNode(fsl.Threshold(thresh=0.0),
                       iterfield=['in_file'],
                       name='RemoveNegative')
    vsm2dfm = vsm2warp()
    vsm2dfm.inputs.inputnode.scaling = 1.0

    wf = pe.Workflow(name=name)
    wf.connect([(inputnode, r_params, [('settings', 'in_file')]),
                (r_params, eff_echo, [('echospacing', 'echospacing'),
                                      ('acc_factor', 'acc_factor')]),
                (inputnode, pha2rads, [('bmap_pha', 'in_file')]),
                (inputnode, firstmag, [('bmap_mag', 'in_file')]),
                (inputnode, baseline, [('in_file', 'in_file'),
                                       ('in_ref', 'index')]),
                (firstmag, n4, [('roi_file', 'input_image')]),
                (n4, bet, [('output_image', 'in_file')]),
                (bet, dilate, [('mask_file', 'in_file')]),
                (pha2rads, prelude, [('out_file', 'phase_file')]),
                (n4, prelude, [('output_image', 'magnitude_file')]),
                (dilate, prelude, [('out_file', 'mask_file')]),
                (r_params, rad2rsec, [('delta_te', 'delta_te')]),
                (prelude, rad2rsec, [('unwrapped_phase_file', 'in_file')]),
                (baseline, fmm2b0, [('out_file', 'fixed_image')]),
                (n4, fmm2b0, [('output_image', 'moving_image')]),
                (inputnode, fmm2b0, [('in_mask', 'fixed_image_mask')]),
                (dilate, fmm2b0, [('out_file', 'moving_image_mask')]),
                (baseline, applyxfm, [('out_file', 'reference_image')]),
                (rad2rsec, applyxfm, [('out_file', 'input_image')]),
                (fmm2b0, applyxfm, [('forward_transforms', 'transforms'),
                                    ('forward_invert_flags',
                                     'invert_transform_flags')]),
                (applyxfm, pre_fugue, [('output_image', 'fmap_in_file')]),
                (inputnode, pre_fugue, [('in_mask', 'mask_file')]),
                (pre_fugue, demean, [('fmap_out_file', 'in_file')]),
                (inputnode, demean, [('in_mask', 'in_mask')]),
                (demean, cleanup, [('out_file', 'inputnode.in_file')]),
                (inputnode, cleanup, [('in_mask', 'inputnode.in_mask')]),
                (cleanup, addvol, [('outputnode.out_file', 'in_file')]),
                (inputnode, vsm, [('in_mask', 'mask_file')]),
                (addvol, vsm, [('out_file', 'fmap_in_file')]),
                (r_params, vsm, [('delta_te', 'asym_se_time')]),
                (eff_echo, vsm, [('eff_echo', 'dwell_time')]),
                (inputnode, split, [('in_file', 'in_file')]),
                (split, unwarp, [('out_files', 'in_file')]),
                (vsm, unwarp, [('shift_out_file', 'shift_in_file')]),
                (r_params, unwarp, [(('enc_dir', _fix_enc_dir),
                                     'unwarp_direction')]),
                (unwarp, thres, [('unwarped_file', 'in_file')]),
                (thres, merge, [('out_file', 'in_files')]),
                (r_params, vsm2dfm, [(('enc_dir',
                                       _fix_enc_dir), 'inputnode.enc_dir')]),
                (merge, vsm2dfm, [('merged_file', 'inputnode.in_ref')]),
                (vsm, vsm2dfm, [('shift_out_file', 'inputnode.in_vsm')]),
                (merge, outputnode, [('merged_file', 'out_file')]),
                (vsm, outputnode, [('shift_out_file', 'out_vsm')]),
                (vsm2dfm, outputnode, [('outputnode.out_warp', 'out_warp')])])
    return wf