def create_dwi_preprocess_pipeline(name="preprocess"): inputnode = pe.Node(interface=util.IdentityInterface(fields=['dwi']), name="inputnode") preprocess = pe.Workflow(name=name) """ extract the volume with b=0 (nodif_brain) """ fslroi = pe.Node(interface=fsl.ExtractROI(), name='fslroi') fslroi.inputs.t_min = 0 fslroi.inputs.t_size = 1 """ create a brain mask from the nodif_brain """ bet = pe.Node(interface=fsl.BET(), name='bet') bet.inputs.mask = True bet.inputs.frac = 0.34 """ correct the diffusion weighted images for eddy_currents """ eddycorrect = create_eddy_correct_pipeline("eddycorrect") eddycorrect.inputs.inputnode.ref_num = 0 preprocess.connect([ (inputnode, fslroi, [('dwi', 'in_file')]), (inputnode, eddycorrect, [('dwi', 'inputnode.in_file')]), (fslroi, bet, [('roi_file', 'in_file')]), ]) return preprocess
def test_create_eddy_correct_pipeline(): fsl_course_dir = os.path.abspath(os.environ['FSL_COURSE_DATA']) dwi_file = os.path.join(fsl_course_dir, "fdt1/subj1/data.nii.gz") trim_dwi = pe.Node(fsl.ExtractROI(t_min=0, t_size=2), name="trim_dwi") trim_dwi.inputs.in_file = dwi_file nipype_eddycorrect = create_eddy_correct_pipeline("nipype_eddycorrect") nipype_eddycorrect.inputs.inputnode.ref_num = 0 with warnings.catch_warnings(): warnings.simplefilter("ignore") original_eddycorrect = pe.Node(interface=fsl.EddyCorrect(), name="original_eddycorrect") original_eddycorrect.inputs.ref_num = 0 test = pe.Node(util.AssertEqual(), name="eddy_corrected_dwi_test") pipeline = pe.Workflow(name="test_eddycorrect") pipeline.base_dir = tempfile.mkdtemp(prefix="nipype_test_eddycorrect_") pipeline.connect([ (trim_dwi, original_eddycorrect, [("roi_file", "in_file")]), (trim_dwi, nipype_eddycorrect, [("roi_file", "inputnode.in_file")]), (nipype_eddycorrect, test, [("outputnode.eddy_corrected", "volume1")]), (original_eddycorrect, test, [("eddy_corrected", "volume2")]), ]) pipeline.run(plugin='Linear') shutil.rmtree(pipeline.base_dir)
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.utility as niu import nipype.pipeline.engine as pe import nipype.interfaces.fsl as fsl import nipype.interfaces.ants as ants 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
def cropToSmall(input_file,outputPath): #output_file = os.path.join(os.path.dirname(input_file),os.path.basename(input_file).split('.')[0] + 'Crop.nii.gz') output_file = os.path.join(outputPath, os.path.basename(input_file).split('.')[0] + 'Crop.nii.gz') myCrop = fsl.ExtractROI(in_file=input_file,roi_file=output_file,x_min=40,x_size=130,y_min=50,y_size=110,z_min=0,z_size=12) myCrop.run() print('Cropping DONE!') return output_file
def _gen_coeff(in_file, in_ref, in_movpar): """Convert to a valid fieldcoeff""" from shutil import copy import numpy as np import nibabel as nb from nipype.interfaces import fsl def _get_fname(in_file): import os.path as op fname, fext = op.splitext(op.basename(in_file)) if fext == '.gz': fname, _ = op.splitext(fname) return op.abspath(fname) out_topup = _get_fname(in_file) # 1. Add one dimension (4D image) of 3D coordinates im0 = nb.load(in_file) data = np.zeros_like(im0.get_data()) sizes = data.shape[:3] spacings = im0.get_header().get_zooms()[:3] im1 = nb.Nifti1Image(data, im0.get_affine(), im0.get_header()) im4d = nb.concat_images([im0, im1, im1]) im4d_fname = '{}_{}'.format(out_topup, 'field4D.nii.gz') im4d.to_filename(im4d_fname) # 2. Warputils to compute bspline coefficients to_coeff = fsl.WarpUtils(out_format='spline', knot_space=(2, 2, 2)) to_coeff.inputs.in_file = im4d_fname to_coeff.inputs.reference = in_ref # 3. Remove unnecessary dims (Y and Z) get_first = fsl.ExtractROI(t_min=0, t_size=1) get_first.inputs.in_file = to_coeff.run().outputs.out_file # 4. Set correct header # see https://github.com/poldracklab/preprocessing-workflow/issues/92 img = nb.load(get_first.run().outputs.roi_file) hdr = img.get_header().copy() hdr['intent_p1'] = spacings[0] hdr['intent_p2'] = spacings[1] hdr['intent_p3'] = spacings[2] hdr['intent_code'] = 2016 sform = np.eye(4) sform[:3, 3] = sizes hdr.set_sform(sform, code='scanner') hdr['qform_code'] = 1 # For some reason, MCFLIRT's parameters # are not compatible, fill with zeroes for now mpar = np.loadtxt(in_movpar) out_movpar = '{}_movpar.txt'.format(out_topup) np.savetxt(out_movpar, np.zeros_like(mpar)) #copy(in_movpar, out_movpar) out_fieldcoef = '{}_fieldcoef.nii.gz'.format(out_topup) nb.Nifti1Image(img.get_data(), None, hdr).to_filename(out_fieldcoef) return out_fieldcoef, out_movpar
def Extract_b0_Image(input_Image, output_Image): "To run this, please first make sure you install fsl and can run it" "One method is that run fsl and thi pre-processing code in the same terminal" import nipype.interfaces.fsl as fsl fslroi = fsl.ExtractROI(in_file=input_Image, roi_file=output_Image, t_min=0, t_size=1) fslroi.run()
def mb_stripvols(NII, OUT_NII=None, STARTVOL=12): # Default: overwrite input file if not OUT_NII: OUT_NII = NII # TODO: figure out weird error message (if new file, do a touch first to create) fslroi = fsl.ExtractROI(in_file=NII, roi_file=OUT_NII, t_min=STARTVOL, t_size=-1) fslroi.run()
def delete5Slides(input_file,regr_Path): # scale Nifti data by factor 10 fslPath = scaleBy10(input_file, inv=False) # delete 5 slides output_file = os.path.join(os.path.dirname(input_file), os.path.basename(input_file).split('.')[0]) + '_f.nii.gz' myROI = fsl.ExtractROI(in_file=fslPath, roi_file=output_file, t_min=5, t_size=-1) print(myROI.cmdline) myROI.run() os.remove(fslPath) # unscale result data by factor 10ˆ(-1) output_file = scaleBy10(output_file, inv=True) return output_file
def test_MapNodeParams(): params = {"crop": {"args": "88 144 14 180 27 103"}} crop_bb = MapNodeParams(fsl.ExtractROI(), name='crop_bb', params=parse_key(params, "crop"), iterfield=["in_file"]) crop_bb.inputs.in_file = [T1_file, T2_file] with pytest.raises(ValueError): crop_bb.run()
def cbf_cl_preprocessing_initialize(): """ 1) Extracts control/label pairs from raw pCASL data 2) Motion correction with mcflirt 3) Control/Label pairwise subtraction """ cl_preproc = pe.Workflow(name='cl_preproc') cl_preproc.base_dir = (os.getcwd()) cl_inputnode = pe.Node( interface=util.IdentityInterface(fields=['func', 'm0', 'm0_mask']), name='cl_inputnode') print(cl_inputnode.inputs) cl_datasink = pe.Node(nio.DataSink(), name='cl_sinker') cl_datasink.inputs.base_directory = results_dir # Extract Control Label Pairs cl_fslroi = pe.Node(fsl.ExtractROI(roi_file='cl.nii.gz', t_min=1, t_size=-1), name='cl_fslroi') # Align Control/Label Pairs to M0 image cl_mcflirt = pe.Node(fsl.MCFLIRT(save_mats=True, save_plots=True), name='cl_mcflirt') # Mask Control Label Pairs cl_mask = pe.Node(fsl.ApplyMask(), name="cl_mask") cl_outputnode = pe.Node(interface=util.IdentityInterface( fields=['cl', 'cl_brain', 'cl_mcf', 'cl_mcf_par']), name='cl_outputnode') cl_preproc.connect([ (cl_inputnode, cl_fslroi, [('func', 'in_file')]), (cl_fslroi, cl_mcflirt, [['roi_file', 'in_file']]), (cl_inputnode, cl_mcflirt, [['m0', 'ref_file']]), (cl_mcflirt, cl_mask, [('out_file', 'in_file')]), (cl_inputnode, cl_mask, [('m0_mask', 'mask_file')]), (cl_fslroi, cl_datasink, [['roi_file', 'results.@cl']]), (cl_mcflirt, cl_datasink, [['out_file', 'results.@mcfcl']]), (cl_mask, cl_datasink, [['out_file', 'results.@cl_mask']]), (cl_fslroi, cl_outputnode, [['roi_file', 'cl']]), (cl_mcflirt, cl_outputnode, [['par_file', 'cl_mcf_par']]), (cl_mcflirt, cl_outputnode, [['out_file', 'cl_mcf']]), (cl_mask, cl_outputnode, [['out_file', 'cl_brain']]) ]) return cl_preproc
def cbf_m0_preprocessing_initialize(): """ 1) Extracts M0 image from raw pCASL data 2) Extracts brain from M0 image using BET 3) Creates png image for final CBF report """ m0_preproc = pe.Workflow(name='m0_preproc') m0_preproc.base_dir = methods_dir m0_inputnode = pe.Node(interface=util.IdentityInterface(fields=['func']), name='m0_inputnode') m0_inputnode.inputs.func = pcasl m0_fslroi = pe.Node(fsl.ExtractROI(roi_file='m0.nii.gz', t_min=0, t_size=1), name='m0_fslroi') m0_skullstrip = pe.Node(fsl.BET(mask=True), name='m0_skullstrip') m0_png = pe.Node(name='m0_png', interface=Function(input_names=['m0_skullstrip'], output_names=['m0_png'], function=m0_save_png)) m0_datasink = pe.Node(nio.DataSink(), name='m0_sinker') m0_datasink.inputs.base_directory = results_dir m0_outputnode = pe.Node( interface=util.IdentityInterface(fields=['m0', 'm0_brain', 'm0_mask']), name='m0_outputnode') m0_preproc.connect([ (m0_inputnode, m0_fslroi, [('func', 'in_file')]), (m0_fslroi, m0_skullstrip, [('roi_file', 'in_file')]), (m0_skullstrip, m0_png, [['out_file', 'm0_skullstrip']]), # Data Sink (m0_fslroi, m0_datasink, [['roi_file', 'results.@roi_file']]), (m0_skullstrip, m0_datasink, [['mask_file', 'results.@mask']]), (m0_skullstrip, m0_datasink, [['out_file', 'results.@m0']]), (m0_png, m0_datasink, [['m0_png', 'results.@m0_png']]), # Output Node (m0_fslroi, m0_outputnode, [['roi_file', 'm0']]), (m0_skullstrip, m0_outputnode, [['mask_file', 'm0_mask']]), (m0_skullstrip, m0_outputnode, [['out_file', 'm0_brain']]), ]) return m0_preproc
def slicetime(file, sliceorder): print "running slicetiming" slicetime = fsl.SliceTimer() slicetime.inputs.in_file = file sliceorder_file = os.path.abspath('FSL_custom_order.txt') with open(sliceorder_file, 'w') as custom_order_fp: for t in sliceorder: custom_order_fp.write('%d\n' % (t + 1)) slicetime.inputs.custom_order = sliceorder_file slicetime.inputs.time_repetition = tr res = slicetime.run() file_to_realign = res.outputs.slice_time_corrected_file extract = fsl.ExtractROI() extract.inputs.t_min = 0 extract.inputs.t_size = 1 extract.inputs.in_file = file_to_realign ref_vol = extract.run().outputs.roi_file return file_to_realign, ref_vol
def create_resting_state_preprocessing_WF(name="preprocess"): wf = pe.Workflow(name=name) inputspec = pe.Node( util.IdentityInterface(fields=['resting', 'structural']), name="inputspec") skip = pe.Node(fsl.ExtractROI(), name="skip") skip.inputs.t_min = 4 skip.inputs.t_size = -1 wf.connect(inputspec, "resting", skip, "in_file") slice_time_realign = pe.Node(nipy.FmriRealign4d(), name="slice_time_realign") slice_time_realign.inputs.tr = 2.3 slice_time_realign.inputs.slice_order = range(0, 34, 2) + range(1, 34, 2) slice_time_realign.inputs.time_interp = True wf.connect(skip, "roi_file", slice_time_realign, "in_file") return wf
""" Convert functional images to float representation. Since there can be more than one functional run we use a MapNode to convert each run. """ img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float', op_string='', suffix='_dtype'), iterfield=['in_file'], name='img2float') preproc.connect(inputnode, 'func', img2float, 'in_file') """ Extract the middle volume of the first run as the reference """ extract_ref = pe.Node(interface=fsl.ExtractROI(t_size=1), name='extractref') """ Define a function to pick the first file from a list of files """ def pickfirst(files): if isinstance(files, list): return files[0] else: return files preproc.connect(img2float, ('out_file', pickfirst), extract_ref, 'in_file') """ Define a function to return the 1 based index of the middle volume
# ======================================================================================================= # In[7]: # Remove skull using antsBrainExtraction.sh, i am using the study-based template that I build and remove # the skull manually using ITKsnap biasfield_correction_anat = Node(ants.N4BiasFieldCorrection(), name='biasfield_correction_anat') biasfield_correction_anat.inputs.dimension = 3 biasfield_correction_anat.inputs.save_bias = True # biasfield_correction_anat.inputs.output_image = 'anat_bet_biasfield_corrected.nii.gz' #better not to, # it confuses the Registration # ====================================================================================================== # In[8]: # Extract one fmri image to use fro brain extraction, the same one you will use for mcflirt as reference roi = Node(fsl.ExtractROI(), name='extract_one_fMRI_volume') roi.inputs.t_min = 75 roi.inputs.t_size = 1 # ====================================================================================================== brain_extraction_roi = Node(fsl.ApplyMask(), name='brain_extraction_roi') # ====================================================================================================== # Remove skull of func using antsBrainExtraction.sh, i am using the study-based template that I build and remove # the skull manually using ITKsnap brain_extraction_bold = Node(fsl.ApplyMask(), name='brain_extraction_bold') # ======================================================================================================== # In[10]:
import os # system functions ##################################################################### # Preliminaries """ 2. Setup any package specific configuration. The output file format for FSL routines is being set to uncompressed NIFTI and a specific version of matlab is being used. The uncompressed format is required because SPM does not handle compressed NIFTI. """ # Tell fsl to generate all output in compressed nifti format print fsl.Info.version() fsl.FSLCommand.set_default_output_type('NIFTI_GZ') extract_ref = pe.Node(interface=fsl.ExtractROI(t_min=42, t_size=1), name='extractref') # run FSL's bet # bet my_structural my_betted_structural """ in the provided data set, the nose is behind the head and causes problems for segmentation routines """ nosestrip = pe.Node(interface=fsl.BET(frac=0.3), name='nosestrip') skullstrip = pe.Node(interface=fsl.BET(mask=True), name='stripstruct') refskullstrip = pe.Node(interface=fsl.BET(mask=True), name='stripref') coregister = pe.Node(interface=fsl.FLIRT(dof=6), name='coregister')
def create_fsl_fs_preproc(name='preproc', highpass=True, whichvol='middle'): """Create a FEAT preprocessing workflow together with freesurfer Parameters ---------- :: name : name of workflow (default: preproc) highpass : boolean (default: True) whichvol : which volume of the first run to register to ('first', 'middle', 'mean') Inputs:: inputspec.func : functional runs (filename or list of filenames) inputspec.fwhm : fwhm for smoothing with SUSAN inputspec.highpass : HWHM in TRs (if created with highpass=True) inputspec.subject_id : freesurfer subject id inputspec.subjects_dir : freesurfer subjects dir Outputs:: outputspec.reference : volume to which runs are realigned outputspec.motion_parameters : motion correction parameters outputspec.realigned_files : motion corrected files outputspec.motion_plots : plots of motion correction parameters outputspec.mask_file : mask file used to mask the brain outputspec.smoothed_files : smoothed functional data outputspec.highpassed_files : highpassed functional data (if highpass=True) outputspec.reg_file : bbregister registration files outputspec.reg_cost : bbregister registration cost files Example ------- >>> preproc = create_fsl_fs_preproc(whichvol='first') >>> preproc.inputs.inputspec.highpass = 128./(2*2.5) >>> preproc.inputs.inputspec.func = ['f3.nii', 'f5.nii'] >>> preproc.inputs.inputspec.subjects_dir = '.' >>> preproc.inputs.inputspec.subject_id = 's1' >>> preproc.inputs.inputspec.fwhm = 6 >>> preproc.run() # doctest: +SKIP """ featpreproc = pe.Workflow(name=name) """ Set up a node to define all inputs required for the preprocessing workflow """ if highpass: inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'fwhm', 'subject_id', 'subjects_dir', 'highpass']), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['reference', 'motion_parameters', 'realigned_files', 'motion_plots', 'mask_file', 'smoothed_files', 'highpassed_files', 'reg_file', 'reg_cost' ]), name='outputspec') else: inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'fwhm', 'subject_id', 'subjects_dir' ]), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['reference', 'motion_parameters', 'realigned_files', 'motion_plots', 'mask_file', 'smoothed_files', 'reg_file', 'reg_cost' ]), name='outputspec') """ Set up a node to define outputs for the preprocessing workflow """ """ Convert functional images to float representation. Since there can be more than one functional run we use a MapNode to convert each run. """ img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float', op_string = '', suffix='_dtype'), iterfield=['in_file'], name='img2float') featpreproc.connect(inputnode, 'func', img2float, 'in_file') """ Extract the first volume of the first run as the reference """ if whichvol != 'mean': extract_ref = pe.Node(interface=fsl.ExtractROI(t_size=1), iterfield=['in_file'], name = 'extractref') featpreproc.connect(img2float, ('out_file', pickfirst), extract_ref, 'in_file') featpreproc.connect(img2float, ('out_file', pickvol, 0, whichvol), extract_ref, 't_min') featpreproc.connect(extract_ref, 'roi_file', outputnode, 'reference') """ Realign the functional runs to the reference (1st volume of first run) """ motion_correct = pe.MapNode(interface=fsl.MCFLIRT(save_mats = True, save_plots = True, interpolation = 'sinc'), name='realign', iterfield = ['in_file']) featpreproc.connect(img2float, 'out_file', motion_correct, 'in_file') if whichvol != 'mean': featpreproc.connect(extract_ref, 'roi_file', motion_correct, 'ref_file') else: motion_correct.inputs.mean_vol = True featpreproc.connect(motion_correct, 'mean_img', outputnode, 'reference') featpreproc.connect(motion_correct, 'par_file', outputnode, 'motion_parameters') featpreproc.connect(motion_correct, 'out_file', outputnode, 'realigned_files') """ Plot the estimated motion parameters """ plot_motion = pe.MapNode(interface=fsl.PlotMotionParams(in_source='fsl'), name='plot_motion', iterfield=['in_file']) plot_motion.iterables = ('plot_type', ['rotations', 'translations']) featpreproc.connect(motion_correct, 'par_file', plot_motion, 'in_file') featpreproc.connect(plot_motion, 'out_file', outputnode, 'motion_plots') """Get the mask from subject for each run """ maskflow = create_getmask_flow() featpreproc.connect([(inputnode, maskflow, [('subject_id','inputspec.subject_id'), ('subjects_dir', 'inputspec.subjects_dir')])]) maskflow.inputs.inputspec.contrast_type = 't2' if whichvol != 'mean': featpreproc.connect(extract_ref, 'roi_file', maskflow, 'inputspec.source_file') else: featpreproc.connect(motion_correct, ('mean_img', pickfirst), maskflow, 'inputspec.source_file') """ Mask the functional runs with the extracted mask """ maskfunc = pe.MapNode(interface=fsl.ImageMaths(suffix='_bet', op_string='-mas'), iterfield=['in_file'], name = 'maskfunc') featpreproc.connect(motion_correct, 'out_file', maskfunc, 'in_file') featpreproc.connect(maskflow, ('outputspec.mask_file', pickfirst), maskfunc, 'in_file2') """ Smooth each run using SUSAN with the brightness threshold set to 75% of the median value for each run and a mask consituting the mean functional """ smooth = create_susan_smooth(separate_masks=False) featpreproc.connect(inputnode, 'fwhm', smooth, 'inputnode.fwhm') featpreproc.connect(maskfunc, 'out_file', smooth, 'inputnode.in_files') featpreproc.connect(maskflow, ('outputspec.mask_file', pickfirst), smooth, 'inputnode.mask_file') """ Mask the smoothed data with the dilated mask """ maskfunc3 = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file'], name='maskfunc3') featpreproc.connect(smooth, 'outputnode.smoothed_files', maskfunc3, 'in_file') featpreproc.connect(maskflow, ('outputspec.mask_file', pickfirst), maskfunc3, 'in_file2') concatnode = pe.Node(interface=util.Merge(2), name='concat') featpreproc.connect(maskfunc, ('out_file', tolist), concatnode, 'in1') featpreproc.connect(maskfunc3, ('out_file', tolist), concatnode, 'in2') """ The following nodes select smooth or unsmoothed data depending on the fwhm. This is because SUSAN defaults to smoothing the data with about the voxel size of the input data if the fwhm parameter is less than 1/3 of the voxel size. """ selectnode = pe.Node(interface=util.Select(),name='select') featpreproc.connect(concatnode, 'out', selectnode, 'inlist') featpreproc.connect(inputnode, ('fwhm', chooseindex), selectnode, 'index') featpreproc.connect(selectnode, 'out', outputnode, 'smoothed_files') """ Scale the median value of the run is set to 10000 """ meanscale = pe.MapNode(interface=fsl.ImageMaths(suffix='_gms'), iterfield=['in_file','op_string'], name='meanscale') featpreproc.connect(selectnode, 'out', meanscale, 'in_file') """ Determine the median value of the functional runs using the mask """ medianval = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'), iterfield = ['in_file'], name='medianval') featpreproc.connect(motion_correct, 'out_file', medianval, 'in_file') featpreproc.connect(maskflow, ('outputspec.mask_file', pickfirst), medianval, 'mask_file') """ Define a function to get the scaling factor for intensity normalization """ featpreproc.connect(medianval, ('out_stat', getmeanscale), meanscale, 'op_string') """ Perform temporal highpass filtering on the data """ if highpass: highpass = pe.MapNode(interface=fsl.ImageMaths(suffix='_tempfilt'), iterfield=['in_file'], name='highpass') featpreproc.connect(inputnode, ('highpass', highpass_operand), highpass, 'op_string') featpreproc.connect(meanscale, 'out_file', highpass, 'in_file') featpreproc.connect(highpass, 'out_file', outputnode, 'highpassed_files') featpreproc.connect(maskflow, ('outputspec.mask_file', pickfirst), outputnode, 'mask_file') featpreproc.connect(maskflow, 'outputspec.reg_file', outputnode, 'reg_file') featpreproc.connect(maskflow, 'outputspec.reg_cost', outputnode, 'reg_cost') return featpreproc
def create_parallelfeat_preproc(name='featpreproc', highpass=True): """Preprocess each run with FSL independently of the others Parameters ---------- :: name : name of workflow (default: featpreproc) highpass : boolean (default: True) Inputs:: inputspec.func : functional runs (filename or list of filenames) inputspec.fwhm : fwhm for smoothing with SUSAN inputspec.highpass : HWHM in TRs (if created with highpass=True) Outputs:: outputspec.reference : volume to which runs are realigned outputspec.motion_parameters : motion correction parameters outputspec.realigned_files : motion corrected files outputspec.motion_plots : plots of motion correction parameters outputspec.mask : mask file used to mask the brain outputspec.smoothed_files : smoothed functional data outputspec.highpassed_files : highpassed functional data (if highpass=True) outputspec.mean : mean file Example ------- >>> preproc = create_parallelfeat_preproc() >>> preproc.inputs.inputspec.func = ['f3.nii', 'f5.nii'] >>> preproc.inputs.inputspec.fwhm = 5 >>> preproc.inputs.inputspec.highpass = 128./(2*2.5) >>> preproc.base_dir = '/tmp' >>> preproc.run() # doctest: +SKIP >>> preproc = create_parallelfeat_preproc(highpass=False) >>> preproc.inputs.inputspec.func = 'f3.nii' >>> preproc.inputs.inputspec.fwhm = 5 >>> preproc.base_dir = '/tmp' >>> preproc.run() # doctest: +SKIP """ featpreproc = pe.Workflow(name=name) """ Set up a node to define all inputs required for the preprocessing workflow """ if highpass: inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'fwhm', 'highpass']), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['reference', 'motion_parameters', 'realigned_files', 'motion_plots', 'mask', 'smoothed_files', 'highpassed_files', 'mean']), name='outputspec') else: inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'fwhm']), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['reference', 'motion_parameters', 'realigned_files', 'motion_plots', 'mask', 'smoothed_files', 'mean']), name='outputspec') """ Set up a node to define outputs for the preprocessing workflow """ """ Convert functional images to float representation. Since there can be more than one functional run we use a MapNode to convert each run. """ img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float', op_string = '', suffix='_dtype'), iterfield=['in_file'], name='img2float') featpreproc.connect(inputnode, 'func', img2float, 'in_file') """ Extract the first volume of the first run as the reference """ extract_ref = pe.MapNode(interface=fsl.ExtractROI(t_size=1), iterfield=['in_file', 't_min'], name = 'extractref') featpreproc.connect(img2float, 'out_file', extract_ref, 'in_file') featpreproc.connect(img2float, ('out_file', pickmiddle), extract_ref, 't_min') featpreproc.connect(extract_ref, 'roi_file', outputnode, 'reference') """ Realign the functional runs to the reference (1st volume of first run) """ motion_correct = pe.MapNode(interface=fsl.MCFLIRT(save_mats = True, save_plots = True), name='realign', iterfield = ['in_file', 'ref_file']) featpreproc.connect(img2float, 'out_file', motion_correct, 'in_file') featpreproc.connect(extract_ref, 'roi_file', motion_correct, 'ref_file') featpreproc.connect(motion_correct, 'par_file', outputnode, 'motion_parameters') featpreproc.connect(motion_correct, 'out_file', outputnode, 'realigned_files') """ Plot the estimated motion parameters """ plot_motion = pe.MapNode(interface=fsl.PlotMotionParams(in_source='fsl'), name='plot_motion', iterfield=['in_file']) plot_motion.iterables = ('plot_type', ['rotations', 'translations']) featpreproc.connect(motion_correct, 'par_file', plot_motion, 'in_file') featpreproc.connect(plot_motion, 'out_file', outputnode, 'motion_plots') """ Extract the mean volume of the first functional run """ meanfunc = pe.MapNode(interface=fsl.ImageMaths(op_string = '-Tmean', suffix='_mean'), iterfield=['in_file'], name='meanfunc') featpreproc.connect(motion_correct, 'out_file', meanfunc, 'in_file') """ Strip the skull from the mean functional to generate a mask """ meanfuncmask = pe.MapNode(interface=fsl.BET(mask = True, no_output=True, frac = 0.3), iterfield=['in_file'], name = 'meanfuncmask') featpreproc.connect(meanfunc, 'out_file', meanfuncmask, 'in_file') """ Mask the functional runs with the extracted mask """ maskfunc = pe.MapNode(interface=fsl.ImageMaths(suffix='_bet', op_string='-mas'), iterfield=['in_file', 'in_file2'], name = 'maskfunc') featpreproc.connect(motion_correct, 'out_file', maskfunc, 'in_file') featpreproc.connect(meanfuncmask, 'mask_file', maskfunc, 'in_file2') """ Determine the 2nd and 98th percentile intensities of each functional run """ getthresh = pe.MapNode(interface=fsl.ImageStats(op_string='-p 2 -p 98'), iterfield = ['in_file'], name='getthreshold') featpreproc.connect(maskfunc, 'out_file', getthresh, 'in_file') """ Threshold the first run of the functional data at 10% of the 98th percentile """ threshold = pe.MapNode(interface=fsl.ImageMaths(out_data_type='char', suffix='_thresh'), iterfield=['in_file', 'op_string'], name='threshold') featpreproc.connect(maskfunc, 'out_file', threshold, 'in_file') """ Define a function to get 10% of the intensity """ featpreproc.connect(getthresh, ('out_stat', getthreshop), threshold, 'op_string') """ Determine the median value of the functional runs using the mask """ medianval = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'), iterfield = ['in_file', 'mask_file'], name='medianval') featpreproc.connect(motion_correct, 'out_file', medianval, 'in_file') featpreproc.connect(threshold, 'out_file', medianval, 'mask_file') """ Dilate the mask """ dilatemask = pe.MapNode(interface=fsl.ImageMaths(suffix='_dil', op_string='-dilF'), iterfield=['in_file'], name='dilatemask') featpreproc.connect(threshold, 'out_file', dilatemask, 'in_file') featpreproc.connect(dilatemask, 'out_file', outputnode, 'mask') """ Mask the motion corrected functional runs with the dilated mask """ maskfunc2 = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file', 'in_file2'], name='maskfunc2') featpreproc.connect(motion_correct, 'out_file', maskfunc2, 'in_file') featpreproc.connect(dilatemask, 'out_file', maskfunc2, 'in_file2') """ Smooth each run using SUSAN with the brightness threshold set to 75% of the median value for each run and a mask consituting the mean functional """ smooth = create_susan_smooth() featpreproc.connect(inputnode, 'fwhm', smooth, 'inputnode.fwhm') featpreproc.connect(maskfunc2, 'out_file', smooth, 'inputnode.in_files') featpreproc.connect(dilatemask, 'out_file', smooth, 'inputnode.mask_file') """ Mask the smoothed data with the dilated mask """ maskfunc3 = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file', 'in_file2'], name='maskfunc3') featpreproc.connect(smooth, 'outputnode.smoothed_files', maskfunc3, 'in_file') featpreproc.connect(dilatemask, 'out_file', maskfunc3, 'in_file2') concatnode = pe.Node(interface=util.Merge(2), name='concat') featpreproc.connect(maskfunc2,('out_file', tolist), concatnode, 'in1') featpreproc.connect(maskfunc3,('out_file', tolist), concatnode, 'in2') """ The following nodes select smooth or unsmoothed data depending on the fwhm. This is because SUSAN defaults to smoothing the data with about the voxel size of the input data if the fwhm parameter is less than 1/3 of the voxel size. """ selectnode = pe.Node(interface=util.Select(),name='select') featpreproc.connect(concatnode, 'out', selectnode, 'inlist') featpreproc.connect(inputnode, ('fwhm', chooseindex), selectnode, 'index') featpreproc.connect(selectnode, 'out', outputnode, 'smoothed_files') """ Scale the median value of the run is set to 10000 """ meanscale = pe.MapNode(interface=fsl.ImageMaths(suffix='_gms'), iterfield=['in_file','op_string'], name='meanscale') featpreproc.connect(selectnode, 'out', meanscale, 'in_file') """ Define a function to get the scaling factor for intensity normalization """ featpreproc.connect(medianval, ('out_stat', getmeanscale), meanscale, 'op_string') """ Perform temporal highpass filtering on the data """ if highpass: highpass = pe.MapNode(interface=fsl.ImageMaths(suffix='_tempfilt'), iterfield=['in_file'], name='highpass') featpreproc.connect(inputnode, ('highpass', highpass_operand), highpass, 'op_string') featpreproc.connect(meanscale, 'out_file', highpass, 'in_file') featpreproc.connect(highpass, 'out_file', outputnode, 'highpassed_files') """ Generate a mean functional image from the first run """ meanfunc3 = pe.MapNode(interface=fsl.ImageMaths(op_string='-Tmean', suffix='_mean'), iterfield=['in_file'], name='meanfunc3') if highpass: featpreproc.connect(highpass, 'out_file', meanfunc3, 'in_file') else: featpreproc.connect(meanscale, 'out_file', meanfunc3, 'in_file') featpreproc.connect(meanfunc3, 'out_file', outputnode, 'mean') return featpreproc
CoReg.inputs.write_composite_transform=True CoReg.inputs.verbose=True CoReg.inputs.output_warped_image=True CoReg.inputs.float=True #----------------------------------------------------------------------------------------------------- # In[10]: #I think it is better not to apply both trasnfromations at this level #apply here only the coreg to move to anatomical and later before 3rd level, we apply #non rigid transformations to template # Merge_Transformations = Node(Merge(2), name = 'Merge_Transformations') #---------------------------------------------------------------------------------------------------- # In[10]: # fslroi ${folder} example_func 450 1; FslRoi = Node(fsl.ExtractROI(), name = 'FslRoi') FslRoi.inputs.t_min = 75 FslRoi.inputs.t_size = 1 #----------------------------------------------------------------------------------------------------- # In[11]: # mcflirt -in ${folder} -out ${folder}_mcf -refvol example_func -plots -mats -report; McFlirt = Node(fsl.MCFLIRT(), name = 'McFlirt') McFlirt.inputs.save_plots = True McFlirt.inputs.save_mats = True McFlirt.inputs.save_rms = True McFlirt.inputs.output_type = 'NIFTI' #-----------------------------------------------------------------------------------------------------
def create_workflow(contrasts, combine_runs=True): level1_workflow = pe.Workflow(name='level1flow') # =================================================================== # _____ _ # |_ _| | | # | | _ __ _ __ _ _| |_ # | | | '_ \| '_ \| | | | __| # _| |_| | | | |_) | |_| | |_ # |_____|_| |_| .__/ \__,_|\__| # | | # |_| # =================================================================== # ------------------ Specify variables inputnode = pe.Node( niu.IdentityInterface(fields=[ #'funcmasks', 'fwhm', # smoothing 'highpass', 'funcs', 'event_log', 'motion_parameters', 'motion_outlier_files', 'ref_func', 'ref_funcmask', ]), name="inputspec") def remove_runs_missing_funcs(in_files, in_funcs): import os # import pdb import re # if input.synchronize = True, then in_files and in_funcs will # be single strings assert not isinstance(in_files, str), "in_files must be list" assert not isinstance(in_funcs, str), "in_funcs must be list" if isinstance(in_files, str): in_files = [in_files] if isinstance(in_funcs, str): in_funcs = [in_funcs] has_func = set() for f in in_funcs: base = os.path.basename(f) try: sub = re.search(r'sub-([a-zA-Z0-9]+)_', base).group(1) ses = re.search(r'ses-([a-zA-Z0-9]+)_', base).group(1) run = re.search(r'run-([a-zA-Z0-9]+)_', base).group(1) except AttributeError as e: raise RuntimeError( 'Could not process "sub-*_", "ses-*_", or "run-*_" from func "%s"' % f) has_func.add((sub, ses, run)) files = [] for f in in_files: base = os.path.basename(f) try: sub = re.search(r'sub-([a-zA-Z0-9]+)_', base).group(1) ses = re.search(r'ses-([a-zA-Z0-9]+)_', base).group(1) run = re.search(r'run-([a-zA-Z0-9]+)_', base).group(1) except AttributeError as e: raise RuntimeError( 'Could not process "sub-*_", "ses-*_", or "run-*_" from event file "%s"' % f) if (sub, ses, run) in has_func: files.append(f) return files input_events = pe.Node( interface=niu.Function(input_names=['in_files', 'in_funcs'], output_names=['out_files'], function=remove_runs_missing_funcs), name='input_events', ) level1_workflow.connect([ (inputnode, input_events, [ ('funcs', 'in_funcs'), ('event_log', 'in_files'), ]), ]) # ------------------------------------------------------------------- # /~_ _ _ _ _. _ _ . _ _ |. _ _ # \_/(/_| |(/_| |(_ |_)||_)(/_||| |(/_ # | | # ------------------------------------------------------------------- """ Preliminaries ------------- Setup any package specific configuration. The output file format for FSL routines is being set to compressed NIFTI. """ fsl.FSLCommand.set_default_output_type('NIFTI_GZ') modelfit = fslflows.create_modelfit_workflow() if combine_runs: fixed_fx = fslflows.create_fixed_effects_flow() else: fixed_fx = None """ Artifact detection is done in preprocessing workflow. """ """ Add model specification nodes between the preprocessing and modelfitting workflows. """ modelspec = pe.Node(model.SpecifyModel(), name="modelspec") """ Set up first-level workflow --------------------------- """ def sort_copes(files): """ Sort by copes and the runs, ie. [[cope1_run1, cope1_run2], [cope2_run1, cope2_run2]] """ assert files[0] is not str numcopes = len(files[0]) assert numcopes > 1 outfiles = [] for i in range(numcopes): outfiles.insert(i, []) for j, elements in enumerate(files): outfiles[i].append(elements[i]) return outfiles def num_copes(files): return len(files) if fixed_fx is not None: level1_workflow.connect([ (inputnode, fixed_fx, [('ref_funcmask', 'flameo.mask_file') ]), # To-do: use reference mask!!! (modelfit, fixed_fx, [ (('outputspec.copes', sort_copes), 'inputspec.copes'), ('outputspec.dof_file', 'inputspec.dof_files'), (('outputspec.varcopes', sort_copes), 'inputspec.varcopes'), (('outputspec.copes', num_copes), 'l2model.num_copes'), ]) ]) # ------------------------------------------------------------------- # /~\ _|_ _ _|_ # \_/|_|| |_)|_|| # | # ------------------------------------------------------------------- # Datasink outputfiles = pe.Node(nio.DataSink(base_directory=ds_root, container='derivatives/modelfit', parameterization=True), name="output_files") # Use the following DataSink output substitutions outputfiles.inputs.substitutions = [ ('subject_id_', 'sub-'), ('session_id_', 'ses-'), # ('/mask/', '/'), # ('_preproc_flirt_thresh.nii.gz', '_transformedmask.nii.gz'), # ('_preproc_volreg_unwarped.nii.gz', '_preproc.nii.gz'), # ('_preproc_flirt_unwarped.nii.gz', '_preproc-mask.nii.gz'), # ('/_mc_method_afni3dvolreg/', '/'), # ('/funcs/', '/'), # ('/funcmasks/', '/'), # ('preproc_volreg.nii.gz', 'preproc.nii.gz'), ('/_mc_method_afni3dAllinSlices/', '/'), ] # Put result into a BIDS-like format outputfiles.inputs.regexp_substitutions = [ (r'_ses-([a-zA-Z0-9]+)_sub-([a-zA-Z0-9]+)', r'sub-\2/ses-\1'), # (r'/_addmean[0-9]+/', r'/func/'), # (r'/_dilatemask[0-9]+/', r'/func/'), # (r'/_funcbrain[0-9]+/', r'/func/'), # (r'/_maskfunc[0-9]+/', r'/func/'), # (r'/_mc[0-9]+/', r'/func/'), # (r'/_meanfunc[0-9]+/', r'/func/'), # (r'/_outliers[0-9]+/', r'/func/'), # (r'/_undistort_masks[0-9]+/', r'/func/'), # (r'/_undistort[0-9]+/', r'/func/'), ] level1_workflow.connect([ (modelfit, outputfiles, [ (('outputspec.copes', sort_copes), 'copes'), ('outputspec.dof_file', 'dof_files'), (('outputspec.varcopes', sort_copes), 'varcopes'), ]), ]) if fixed_fx is not None: level1_workflow.connect([ (fixed_fx, outputfiles, [ ('outputspec.res4d', 'fx.res4d'), ('outputspec.copes', 'fx.copes'), ('outputspec.varcopes', 'fx.varcopes'), ('outputspec.zstats', 'fx.zstats'), ('outputspec.tstats', 'fx.tstats'), ]), ]) # ------------------------------------------------------------------- # (~ _ _ _. _ _ _ _ _|_ _ _ _ _. |`. _ # (_><|_)(/_| || | |(/_| | | _\|_)(/_(_|~|~|(_ # | | # ------------------------------------------------------------------- # """ # Experiment specific components # ------------------------------ # """ """ Use the get_node function to retrieve an internal node by name. Then set the iterables on this node to perform two different extents of smoothing. """ featinput = level1_workflow.get_node('modelfit.inputspec') # featinput.iterables = ('fwhm', [5., 10.]) featinput.inputs.fwhm = 2.0 hpcutoff_s = 50. # FWHM in seconds TR = 2.5 hpcutoff_nvol = hpcutoff_s / 2.5 # FWHM in volumns # Use Python3 for processing. See code/requirements.txt for pip packages. featinput.inputs.highpass = hpcutoff_nvol / 2.355 # Gaussian: σ in volumes - (REMEMBER to run with Python 3) """ Setup a function that returns subject-specific information about the experimental paradigm. This is used by the :class:`nipype.modelgen.SpecifyModel` to create the information necessary to generate an SPM design matrix. In this tutorial, the same paradigm was used for every participant. Other examples of this function are available in the `doc/examples` folder. Note: Python knowledge required here. """ # from timeevents.curvetracing import calc_curvetracing_events from timeevents import process_time_events timeevents = pe.MapNode( interface=process_time_events, # calc_curvetracing_events, iterfield=('event_log', 'in_nvols', 'TR'), name='timeevents') def get_nvols(funcs): import nibabel as nib nvols = [] if isinstance(funcs, str): funcs = [funcs] for func in funcs: func_img = nib.load(func) header = func_img.header try: nvols.append(func_img.get_data().shape[3]) except IndexError as e: # if shape only has 3 dimensions, then it is only 1 volume nvols.append(1) return (nvols) def get_TR(funcs): import nibabel as nib TRs = [] if isinstance(funcs, str): funcs = [funcs] for func in funcs: func_img = nib.load(func) header = func_img.header try: TR = round(header.get_zooms()[3], 5) except IndexError as e: TR = 2.5 print("Warning: %s did not have TR defined in the header. " "Using default TR of %0.2f" % (func, TR)) assert TR > 1 TRs.append(TR) return (TRs) level1_workflow.connect([ (inputnode, timeevents, [ (('funcs', get_nvols), 'in_nvols'), (('funcs', get_TR), 'TR'), ]), (input_events, timeevents, [('out_files', 'event_log')]), (inputnode, modelspec, [('motion_parameters', 'realignment_parameters') ]), (modelspec, modelfit, [('session_info', 'inputspec.session_info')]), ]) # Ignore volumes after last good response filter_outliers = pe.MapNode(interface=FilterNumsTask(), name='filter_outliers', iterfield=('in_file', 'max_number')) level1_workflow.connect([ (inputnode, filter_outliers, [('motion_outlier_files', 'in_file')]), (filter_outliers, modelspec, [('out_file', 'outlier_files')]), (timeevents, filter_outliers, [('out_nvols', 'max_number')]), ]) def evt_info(cond_events): output = [] # for each run for ev in cond_events: from nipype.interfaces.base import Bunch from copy import deepcopy names = [] for name in ev.keys(): if ev[name].shape[0] > 0: names.append(name) onsets = [ deepcopy(ev[name].time) if ev[name].shape[0] > 0 else [] for name in names ] durations = [ deepcopy(ev[name].dur) if ev[name].shape[0] > 0 else [] for name in names ] amplitudes = [ deepcopy(ev[name].amplitude) if ev[name].shape[0] > 0 else [] for name in names ] run_results = Bunch( conditions=names, onsets=[deepcopy(ev[name].time) for name in names], durations=[deepcopy(ev[name].dur) for name in names], amplitudes=[deepcopy(ev[name].amplitude) for name in names]) output.append(run_results) return output modelspec.inputs.input_units = 'secs' modelspec.inputs.time_repetition = TR # to-do: specify per func modelspec.inputs.high_pass_filter_cutoff = hpcutoff_s modelfit.inputs.inputspec.interscan_interval = TR # to-do: specify per func modelfit.inputs.inputspec.bases = {'dgamma': {'derivs': True}} modelfit.inputs.inputspec.contrasts = contrasts modelfit.inputs.inputspec.model_serial_correlations = True modelfit.inputs.inputspec.film_threshold = 1000 # level1_workflow.base_dir = os.path.abspath('./workingdirs/level1flow') modelfit.config['execution'] = dict(crashdump_dir=os.path.abspath('.')) # Ignore volumes after subject has finished working for the run beh_roi = pe.MapNode(fsl.ExtractROI(t_min=0), name='beh_roi', iterfield=['in_file', 't_size']) level1_workflow.connect([ (timeevents, modelspec, [ (('out_events', evt_info), 'subject_info'), ]), (inputnode, beh_roi, [ ('funcs', 'in_file'), ]), (timeevents, beh_roi, [ ('out_nvols', 't_size'), ]), (beh_roi, modelspec, [ ('roi_file', 'functional_runs'), ]), (beh_roi, modelfit, [ ('roi_file', 'inputspec.functional_data'), ]), (beh_roi, outputfiles, [ ('roi_file', 'roi_file'), ]), # (inputnode, datasource, [('in_data', 'base_directory')]), # (infosource, datasource, [('subject_id', 'subject_id')]), # (infosource, modelspec, [(('subject_id', subjectinfo), 'subject_info')]), # (datasource, preproc, [('func', 'inputspec.func')]), ]) return (level1_workflow)
def sdc_peb(name='peb_correction', epi_params={ 'read_out_times': None, 'enc_dir': 'y-' }, altepi_params={ 'read_out_times': None, 'enc_dir': 'y' }): """ SDC stands for susceptibility distortion correction. PEB stands for phase-encoding-based. The phase-encoding-based (PEB) method implements SDC by acquiring diffusion images with two different enconding directions [Andersson2003]_. The most typical case is acquiring with opposed phase-gradient blips (e.g. *A>>>P* and *P>>>A*, or equivalently, *-y* and *y*) as in [Chiou2000]_, but it is also possible to use orthogonal configurations [Cordes2000]_ (e.g. *A>>>P* and *L>>>R*, or equivalently *-y* and *x*). This workflow uses the implementation of FSL (`TOPUP <http://fsl.fmrib.ox.ac.uk/fsl/fslwiki/TOPUP>`_). Example ------- >>> from nipype.workflows.dmri.fsl.artifacts import sdc_peb >>> peb = sdc_peb() >>> peb.inputs.inputnode.in_file = 'epi.nii' >>> peb.inputs.inputnode.alt_file = 'epi_rev.nii' >>> peb.inputs.inputnode.in_bval = 'diffusion.bval' >>> peb.inputs.inputnode.in_mask = 'mask.nii' >>> peb.run() # doctest: +SKIP .. admonition:: References .. [Andersson2003] Andersson JL et al., `How to correct susceptibility distortions in spin-echo echo-planar images: application to diffusion tensor imaging <http://dx.doi.org/10.1016/S1053-8119(03)00336-7>`_. Neuroimage. 2003 Oct;20(2):870-88. doi: 10.1016/S1053-8119(03)00336-7 .. [Cordes2000] Cordes D et al., Geometric distortion correction in EPI using two images with orthogonal phase-encoding directions, in Proc. ISMRM (8), p.1712, Denver, US, 2000. .. [Chiou2000] Chiou JY, and Nalcioglu O, A simple method to correct off-resonance related distortion in echo planar imaging, in Proc. ISMRM (8), p.1712, Denver, US, 2000. """ inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_bval', 'in_mask', 'alt_file', 'ref_num']), name='inputnode') outputnode = pe.Node( niu.IdentityInterface(fields=['out_file', 'out_vsm', 'out_warp']), name='outputnode') b0_ref = pe.Node(fsl.ExtractROI(t_size=1), name='b0_ref') b0_alt = pe.Node(fsl.ExtractROI(t_size=1), name='b0_alt') b0_comb = pe.Node(niu.Merge(2), name='b0_list') b0_merge = pe.Node(fsl.Merge(dimension='t'), name='b0_merged') topup = pe.Node(fsl.TOPUP(), name='topup') topup.inputs.encoding_direction = [ epi_params['enc_dir'], altepi_params['enc_dir'] ] readout = epi_params['read_out_time'] topup.inputs.readout_times = [readout, altepi_params['read_out_time']] unwarp = pe.Node(fsl.ApplyTOPUP(in_index=[1], method='jac'), name='unwarp') # scaling = pe.Node(niu.Function(input_names=['in_file', 'enc_dir'], # output_names=['factor'], function=_get_zoom), # name='GetZoom') # scaling.inputs.enc_dir = epi_params['enc_dir'] vsm2dfm = vsm2warp() vsm2dfm.inputs.inputnode.enc_dir = epi_params['enc_dir'] vsm2dfm.inputs.inputnode.scaling = readout wf = pe.Workflow(name=name) wf.connect([ (inputnode, b0_ref, [('in_file', 'in_file'), (('ref_num', _checkrnum), 't_min')]), (inputnode, b0_alt, [('alt_file', 'in_file'), (('ref_num', _checkrnum), 't_min')]), (b0_ref, b0_comb, [('roi_file', 'in1')]), (b0_alt, b0_comb, [('roi_file', 'in2')]), (b0_comb, b0_merge, [('out', 'in_files')]), (b0_merge, topup, [('merged_file', 'in_file')]), (topup, unwarp, [('out_fieldcoef', 'in_topup_fieldcoef'), ('out_movpar', 'in_topup_movpar'), ('out_enc_file', 'encoding_file')]), (inputnode, unwarp, [('in_file', 'in_files')]), (unwarp, outputnode, [('out_corrected', 'out_file')]), # (b0_ref, scaling, [('roi_file', 'in_file')]), # (scaling, vsm2dfm, [('factor', 'inputnode.scaling')]), (b0_ref, vsm2dfm, [('roi_file', 'inputnode.in_ref')]), (topup, vsm2dfm, [('out_field', 'inputnode.in_vsm')]), (topup, outputnode, [('out_field', 'out_vsm')]), (vsm2dfm, outputnode, [('outputnode.out_warp', 'out_warp')]) ]) return wf
# Extract motion parameters from regressors file runinfo = pe.Node(util.Function( input_names=['in_file', 'events_file', 'regressors_file', 'regressors_names', 'removeTR'], function=_bids2nipypeinfo, output_names=['info', 'realign_file']), name='runinfo') runinfo.inputs.removeTR = removeTR # Set the column names to be used from the confounds file runinfo.inputs.regressors_names = ['dvars', 'framewise_displacement'] + \ ['a_comp_cor_%02d' % i for i in range(6)] + ['cosine%02d' % i for i in range(4)] # %% skip = pe.Node(interface=fsl.ExtractROI(), name = 'skip') skip.inputs.t_min = removeTR skip.inputs.t_size = -1 # %% susan = pe.Node(interface=fsl.SUSAN(), name = 'susan') #create_susan_smooth() susan.inputs.fwhm = fwhm susan.inputs.brightness_threshold = 1000.0 # %% modelfit = pe.Workflow(name='modelfit', base_dir= output_dir) """ Use :class:`nipype.algorithms.modelgen.SpecifyModel` to generate design information. """
target_masks="%s.bedpostX/%s.nii.gz") datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Setup for Diffusion Tensor Computation -------------------------------------- Here we will create a generic workflow for DTI computation """ computeTensor = pe.Workflow(name='computeTensor') """ extract the volume with b=0 (nodif_brain) """ fslroi = pe.Node(interface=fsl.ExtractROI(), name='fslroi') fslroi.inputs.t_min = 0 fslroi.inputs.t_size = 1 """ create a brain mask from the nodif_brain """ bet = pe.Node(interface=fsl.BET(), name='bet') bet.inputs.mask = True bet.inputs.frac = 0.34 """ correct the diffusion weighted images for eddy_currents """ eddycorrect = create_eddy_correct_pipeline('eddycorrect') eddycorrect.inputs.inputnode.ref_num = 0
# Create SelectFiles node sf = Node(SelectFiles(templates, sort_filelist=True), name='sf') sf.iterables = [('subject_id', subject_list), ('subsession_id', session_list)] ########### # # FMRI PREPROCESSING NODES # ########### # skip dummy scans extract = Node(fsl.ExtractROI(t_min=nDelfMRI, # first volumes to be deleted t_size=-1), name="extract") # smoothing with SUSAN susan = Node(fsl.SUSAN(brightness_threshold = 2000.0, fwhm=6.0), # smoothing filter width (6mm, isotropic) name='susan') # masking the fMRI with a brain mask applymask = Node(fsl.ApplyMask(), name='applymask') ########### # # READ TASK INFO IN PREPRARATION FOR THE ANALYSIS
''' # Create a Function node to identify the best volume based # on the number of outliers at each volume. I'm searching # for the index in the first 201 volumes that has the # minimum number of outliers and will use the min() function # I will use the index function to get the best vol. getbestvol = pe.Node(Function(input_names=['outlier_count'], output_names=['best_vol_num'], function=best_vol), name='getbestvol') psb6351_wf.connect(id_outliers, 'out_file', getbestvol, 'outlier_count') # Extract the earliest volume with the # the fewest outliers of the first run as the reference extractref = pe.Node(fsl.ExtractROI(t_size=1), name="extractref") extractref.inputs.in_file = func_files[0] #extractref.inputs.t_min = int(np.ceil(nb.load(study_func_files[0]).shape[3]/2)) #PICKING MIDDLE psb6351_wf.connect(getbestvol, 'best_vol_num', extractref, 't_min') # Below is the command that runs AFNI's 3dvolreg command. # this is the node that performs the motion correction # I'm iterating over the functional files which I am passing # functional data from the slice timing correction node before # I'm using the earliest volume with the least number of outliers # during the first run as the base file to register to. volreg = pe.MapNode(afni.Volreg(), iterfield=['in_file'], name='volreg') volreg.inputs.outputtype = 'NIFTI_GZ' volreg.inputs.zpad = 4 volreg.inputs.in_file = func_files psb6351_wf.connect(extractref, 'roi_file', volreg, 'basefile')
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 smoothing_skullstrip( fmriprep_dir, output_dir, work_dir, subject_list, task, run, fwhm=6.0, name="smoothing_skullstrip", ): """ FSL smooth fMRIprep output """ workflow = pe.Workflow(name=name) workflow.base_dir = work_dir template = { "bolds": "sub-{subject}/func/sub-{subject}_task-{task}_run-{run}_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz", "mask": "sub-{subject}/func/sub-{subject}_task-{task}_run-{run}_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz", } bg = pe.Node(SelectFiles(template, base_directory=fmriprep_dir), name="datagrabber") bg.iterables = [("subject", subject_list), ("task", task), ("run", run)] # Create DataSink object sinker = pe.Node(DataSink(), name="sinker") sinker.inputs.base_directory = output_dir sinker.inputs.substitutions = [ ("_run_1_subject_", "sub-"), ("_skip0", "func"), ("desc-preproc_bold_smooth_masked_roi", f"desc-preproc-fwhm{int(fwhm)}mm_bold"), ] # Smoothing susan = create_susan_smooth() susan.inputs.inputnode.fwhm = fwhm # masking the smoothed output # note: susan workflow returns a list but apply mask only accept string of path mask_results = pe.MapNode( ApplyMask(), name="mask_results", iterfield=["in_file", "mask_file"] ) # remove first five volumes skip = pe.MapNode(fsl.ExtractROI(), name="skip", iterfield=["in_file"]) skip.inputs.t_min = 5 skip.inputs.t_size = -1 workflow.connect( [ ( bg, susan, [("bolds", "inputnode.in_files"), ("mask", "inputnode.mask_file")], ), (bg, mask_results, [("mask", "mask_file")]), (susan, mask_results, [("outputnode.smoothed_files", "in_file")]), (mask_results, skip, [("out_file", "in_file")]), (skip, sinker, [("roi_file", f"func_smooth-{int(fwhm)}mm.@out_file")]), ] ) return workflow
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
def topup_correction(name='topup_correction'): """ .. deprecated:: 0.9.3 Use :func:`nipype.workflows.dmri.preprocess.epi.sdc_peb` instead. Corrects for susceptibilty distortion of EPI images when one reverse encoding dataset has been acquired Example ------- >>> nipype_epicorrect = topup_correction('nipype_topup') >>> nipype_epicorrect.inputs.inputnode.in_file_dir = 'epi.nii' >>> nipype_epicorrect.inputs.inputnode.in_file_rev = 'epi_rev.nii' >>> nipype_epicorrect.inputs.inputnode.encoding_direction = ['y', 'y-'] >>> nipype_epicorrect.inputs.inputnode.ref_num = 0 >>> nipype_epicorrect.run() # doctest: +SKIP Inputs:: inputnode.in_file_dir - EPI volume acquired in 'forward' phase encoding inputnode.in_file_rev - EPI volume acquired in 'reversed' phase encoding inputnode.encoding_direction - Direction encoding of in_file_dir inputnode.ref_num - Identifier of the reference volumes (usually B0 volume) Outputs:: outputnode.epi_corrected """ warnings.warn(('This workflow is deprecated from v.1.0.0, use ' 'nipype.workflows.dmri.preprocess.epi.sdc_peb instead'), DeprecationWarning) pipeline = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'in_file_dir', 'in_file_rev', 'encoding_direction', 'readout_times', 'ref_num' ]), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=[ 'out_fieldcoef', 'out_movpar', 'out_enc_file', 'epi_corrected' ]), name='outputnode') b0_dir = pe.Node(fsl.ExtractROI(t_size=1), name='b0_1') b0_rev = pe.Node(fsl.ExtractROI(t_size=1), name='b0_2') combin = pe.Node(niu.Merge(2), name='merge') combin2 = pe.Node(niu.Merge(2), name='merge2') merged = pe.Node(fsl.Merge(dimension='t'), name='b0_comb') topup = pe.Node(fsl.TOPUP(), name='topup') applytopup = pe.Node(fsl.ApplyTOPUP(in_index=[1, 2]), name='applytopup') pipeline.connect([ (inputnode, b0_dir, [('in_file_dir', 'in_file'), ('ref_num', 't_min')]), (inputnode, b0_rev, [('in_file_rev', 'in_file'), ('ref_num', 't_min')]), (inputnode, combin2, [('in_file_dir', 'in1'), ('in_file_rev', 'in2')]), (b0_dir, combin, [('roi_file', 'in1')]), (b0_rev, combin, [('roi_file', 'in2')]), (combin, merged, [('out', 'in_files')]), (merged, topup, [('merged_file', 'in_file')]), (inputnode, topup, [('encoding_direction', 'encoding_direction'), ('readout_times', 'readout_times')]), (topup, applytopup, [('out_fieldcoef', 'in_topup_fieldcoef'), ('out_movpar', 'in_topup_movpar'), ('out_enc_file', 'encoding_file')]), (combin2, applytopup, [('out', 'in_files')]), (topup, outputnode, [('out_fieldcoef', 'out_fieldcoef'), ('out_movpar', 'out_movpar'), ('out_enc_file', 'out_enc_file')]), (applytopup, outputnode, [('out_corrected', 'epi_corrected')]) ]) return pipeline
def test_create_bedpostx_pipeline(): fsl_course_dir = os.path.abspath(os.environ['FSL_COURSE_DATA']) mask_file = os.path.join(fsl_course_dir, "fdt2/subj1.bedpostX/nodif_brain_mask.nii.gz") bvecs_file = os.path.join(fsl_course_dir, "fdt2/subj1/bvecs") bvals_file = os.path.join(fsl_course_dir, "fdt2/subj1/bvals") dwi_file = os.path.join(fsl_course_dir, "fdt2/subj1/data.nii.gz") z_min = 62 z_size = 2 slice_mask = pe.Node(fsl.ExtractROI(x_min=0, x_size=-1, y_min=0, y_size=-1, z_min=z_min, z_size=z_size), name="slice_mask") slice_mask.inputs.in_file = mask_file slice_dwi = pe.Node(fsl.ExtractROI(x_min=0, x_size=-1, y_min=0, y_size=-1, z_min=z_min, z_size=z_size), name="slice_dwi") slice_dwi.inputs.in_file = dwi_file nipype_bedpostx = create_bedpostx_pipeline("nipype_bedpostx") nipype_bedpostx.inputs.inputnode.bvecs = bvecs_file nipype_bedpostx.inputs.inputnode.bvals = bvals_file nipype_bedpostx.inputs.xfibres.n_fibres = 1 nipype_bedpostx.inputs.xfibres.fudge = 1 nipype_bedpostx.inputs.xfibres.burn_in = 0 nipype_bedpostx.inputs.xfibres.n_jumps = 1 nipype_bedpostx.inputs.xfibres.sample_every = 1 nipype_bedpostx.inputs.xfibres.cnlinear = True nipype_bedpostx.inputs.xfibres.seed = 0 with warnings.catch_warnings(): warnings.simplefilter("ignore") original_bedpostx = pe.Node(interface=fsl.BEDPOSTX(), name="original_bedpostx") original_bedpostx.inputs.bvecs = bvecs_file original_bedpostx.inputs.bvals = bvals_file original_bedpostx.inputs.environ['FSLPARALLEL'] = "" original_bedpostx.inputs.n_fibres = 1 original_bedpostx.inputs.fudge = 1 original_bedpostx.inputs.burn_in = 0 original_bedpostx.inputs.n_jumps = 1 original_bedpostx.inputs.sample_every = 1 original_bedpostx.inputs.seed = 0 test_f1 = pe.Node(util.AssertEqual(), name="mean_f1_test") pipeline = pe.Workflow(name="test_bedpostx") pipeline.base_dir = tempfile.mkdtemp(prefix="nipype_test_bedpostx_") pipeline.connect([ (slice_mask, original_bedpostx, [("roi_file", "mask")]), (slice_mask, nipype_bedpostx, [("roi_file", "inputnode.mask")]), (slice_dwi, original_bedpostx, [("roi_file", "dwi")]), (slice_dwi, nipype_bedpostx, [("roi_file", "inputnode.dwi")]), (nipype_bedpostx, test_f1, [(("outputnode.mean_fsamples", list_to_filename), "volume1")]), (original_bedpostx, test_f1, [("mean_fsamples", "volume2")]), ]) pipeline.run(plugin='Linear') shutil.rmtree(pipeline.base_dir)