def FuncProc_despike_afni(stdrefvol="mid", SinkTag="func_preproc", wf_name="func_preproc_dspk_afni", fwhm=0, carpet_plot=""): """ Performs processing of functional (resting-state) images: Images should be already reoriented, e.g. with fsl fslreorient2std (see scripts/ex_pipeline.py) Workflow inputs: :param func: The functional image file. :param SinkDir: where to write important ouputs :param SinkTag: The output directory in which the returned images (see workflow outputs) could be found. Workflow outputs: :param :return: anatproc_workflow Tamas Spisak [email protected] 2018 """ SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag) if not os.path.exists(SinkDir): os.makedirs(SinkDir) wf_mc = nipype.Workflow(wf_name) # Basic interface class generates identity mappings inputspec = pe.Node( utility.IdentityInterface(fields=['func', 'cc_noise_roi']), name='inputspec') # build the actual pipeline #myonevol = onevol.onevol_workflow(SinkDir=SinkDir) mybet = bet.bet_workflow(SinkTag="func_preproc", fmri=True, wf_name="brain_extraction_func") mymc = mc.mc_workflow_fsl(reference_vol=stdrefvol) if carpet_plot: # create "atlas" add_masks = pe.MapNode(fsl.ImageMaths(op_string=' -add'), iterfield=['in_file', 'in_file2'], name="addimgs") wf_mc.connect(inputspec, 'cc_noise_roi', add_masks, 'in_file') wf_mc.connect(mybet, 'outputspec.brain_mask', add_masks, 'in_file2') fmri_qc_mc = qc.fMRI2QC(carpet_plot, tag="mc", indiv_atlas=True) wf_mc.connect(add_masks, 'out_file', fmri_qc_mc, 'inputspec.atlas') wf_mc.connect(mymc, 'outputspec.FD_file', fmri_qc_mc, 'inputspec.confounds') wf_mc.connect(mymc, 'outputspec.func_out_file', fmri_qc_mc, 'inputspec.func') mydespike = pe.MapNode( afni.Despike( outputtype="NIFTI_GZ"), # I do it after motion correction... iterfield=['in_file'], name="DeSpike") if carpet_plot: fmri_qc_mc_dspk = qc.fMRI2QC(carpet_plot, tag="mc_dspk", indiv_atlas=True) wf_mc.connect(add_masks, 'out_file', fmri_qc_mc_dspk, 'inputspec.atlas') wf_mc.connect(mymc, 'outputspec.FD_file', fmri_qc_mc_dspk, 'inputspec.confounds') wf_mc.connect(mydespike, 'out_file', fmri_qc_mc_dspk, 'inputspec.func') mycmpcor = cmpcor.compcor_workflow() # to WM+CSF signal myconc = conc.concat_workflow(numconcat=2) mynuisscor = nuisscorr.nuissremov_workflow( ) # regress out 5 compcor variables and the Friston24 if carpet_plot: fmri_qc_mc_dspk_nuis = qc.fMRI2QC(carpet_plot, tag="mc_dspk_nuis", indiv_atlas=True) wf_mc.connect(add_masks, 'out_file', fmri_qc_mc_dspk_nuis, 'inputspec.atlas') wf_mc.connect(mymc, 'outputspec.FD_file', fmri_qc_mc_dspk_nuis, 'inputspec.confounds') wf_mc.connect(mynuisscor, 'outputspec.out_file', fmri_qc_mc_dspk_nuis, 'inputspec.func') # optional smoother: if fwhm > 0: smoother = pe.MapNode(interface=Smooth(fwhm=fwhm), iterfield=['in_file'], name="smoother") if carpet_plot: fmri_qc_mc_dspk_smooth_nuis_bpf = qc.fMRI2QC( carpet_plot, tag="mc_dspk_nuis_smooth", indiv_atlas=True) wf_mc.connect(add_masks, 'out_file', fmri_qc_mc_dspk_smooth_nuis_bpf, 'inputspec.atlas') wf_mc.connect(mymc, 'outputspec.FD_file', fmri_qc_mc_dspk_smooth_nuis_bpf, 'inputspec.confounds') wf_mc.connect(smoother, 'smoothed_file', fmri_qc_mc_dspk_smooth_nuis_bpf, 'inputspec.func') #mymedangcor = medangcor.mac_workflow() #skip it this time mytmpfilt = tmpfilt.tmpfilt_workflow( highpass_Hz=0.008, lowpass_Hz=0.08) #will be done by the masker? if carpet_plot: fmri_qc_mc_dspk_nuis_bpf = qc.fMRI2QC(carpet_plot, tag="mc_dspk_nuis_bpf", indiv_atlas=True) wf_mc.connect(add_masks, 'out_file', fmri_qc_mc_dspk_nuis_bpf, 'inputspec.atlas') wf_mc.connect(mymc, 'outputspec.FD_file', fmri_qc_mc_dspk_nuis_bpf, 'inputspec.confounds') wf_mc.connect(mytmpfilt, 'outputspec.func_tmplfilt', fmri_qc_mc_dspk_nuis_bpf, 'inputspec.func') myscrub = scrub.datacens_workflow_threshold(ex_before=0, ex_after=0) # "liberal scrubbing" since despiking was already performed if carpet_plot: fmri_qc_mc_dspk_nuis_bpf_scrub = qc.fMRI2QC( carpet_plot, tag="mc_dspk_nuis_bpf_scrub", indiv_atlas=True) wf_mc.connect(add_masks, 'out_file', fmri_qc_mc_dspk_nuis_bpf_scrub, 'inputspec.atlas') wf_mc.connect(myscrub, 'outputspec.FD_scrubbed', fmri_qc_mc_dspk_nuis_bpf_scrub, 'inputspec.confounds') wf_mc.connect(myscrub, 'outputspec.scrubbed_image', fmri_qc_mc_dspk_nuis_bpf_scrub, 'inputspec.func') # Basic interface class generates identity mappings outputspec = pe.Node( utility.IdentityInterface(fields=[ 'func_preprocessed', 'func_preprocessed_scrubbed', # non-image data 'FD' ]), name='outputspec') wf_mc.connect([ (inputspec, mybet, [('func', 'inputspec.in_file')]), (mybet, mymc, [('outputspec.brain', 'inputspec.func')]), (mymc, mydespike, [('outputspec.func_out_file', 'in_file')]), (mydespike, mycmpcor, [('out_file', 'inputspec.func_aligned')]), (inputspec, mycmpcor, [('cc_noise_roi', 'inputspec.mask_file')]), (mycmpcor, myconc, [('outputspec.components_file', 'inputspec.par1')]), (mymc, myconc, [('outputspec.first24_file', 'inputspec.par2')]), (myconc, mynuisscor, [('outputspec.concat_file', 'inputspec.design_file')]), (mydespike, mynuisscor, [('out_file', 'inputspec.in_file')]) ]) if fwhm > 0: wf_mc.connect([ (mynuisscor, smoother, [('outputspec.out_file', 'in_file')]), (smoother, mytmpfilt, [('smoothed_file', 'inputspec.func')]), (mytmpfilt, myscrub, [('outputspec.func_tmplfilt', 'inputspec.func')]), (mymc, myscrub, [('outputspec.FD_file', 'inputspec.FD')]), (mytmpfilt, outputspec, [('outputspec.func_tmplfilt', 'func_preprocessed')]) ]) else: wf_mc.connect([(mynuisscor, mytmpfilt, [('outputspec.out_file', 'inputspec.func')]), (mytmpfilt, myscrub, [('outputspec.func_tmplfilt', 'inputspec.func')]), (mymc, myscrub, [('outputspec.FD_file', 'inputspec.FD') ]), (mytmpfilt, outputspec, [('outputspec.func_tmplfilt', 'func_preprocessed')])]) wf_mc.connect([ # non-image data: (mymc, outputspec, [('outputspec.FD_file', 'FD')]), (myscrub, outputspec, [('outputspec.scrubbed_image', 'func_preprocessed_scrubbed')]), ]) return wf_mc
def func2mni(stdreg, carpet_plot="", wf_name='func2mni', SinkTag="func_preproc"): """ stdreg: either globals._RegType_.ANTS or globals._RegType_.FSL (do default value to make sure the user has to decide explicitly) Transaform 4D functional image to MNI space. carpet_plot: string specifying the tag parameter for carpet plot of the standardized MRI measurement (default is "": no carpet plot) if not "", inputs atlaslabels and confounds should be defined (it might work with defaults, though) Workflow inputs: :param func :param linear_reg_mtrx :param nonlinear_reg_mtrx :param reference_brain :param atlas (optional) :param confounds (optional) :param confound_names (optional) Workflow outputs: :return: anat2mni_workflow - workflow anat="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres.nii.gz", brain="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres_brain.nii.gz", Balint Kincses [email protected] 2018 """ import os import nipype.pipeline as pe import nipype.interfaces.utility as utility import nipype.interfaces.fsl as fsl import nipype.interfaces.fsl as fsl import nipype.interfaces.ants as ants from nipype.interfaces.c3 import C3dAffineTool import PUMI.utils.globals as globals import PUMI.func_preproc.Onevol as onevol import PUMI.utils.QC as qc import nipype.interfaces.io as io from nipype.interfaces.utility import Function SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag) if not os.path.exists(SinkDir): os.makedirs(SinkDir) inputspec = pe.Node( utility.IdentityInterface(fields=[ 'func', 'anat', # only obligatory if stdreg==globals._RegType_.ANTS 'linear_reg_mtrx', 'nonlinear_reg_mtrx', 'reference_brain', 'atlas', 'confounds', 'confound_names' ]), name='inputspec') inputspec.inputs.atlas = globals._FSLDIR_ + '/data/atlases/HarvardOxford/HarvardOxford-cort-maxprob-thr25-2mm.nii.gz' inputspec.inputs.reference_brain = globals._FSLDIR_ + "/data/standard/MNI152_T1_3mm_brain.nii.gz" #3mm by default # TODO: this does not work with the iterfiled definition for ref_file below: # TODO: it should be sepcified in a function argument, whether it shopuld be iterated #TODO_ready: ANTS #TODO: make resampling voxel size for func parametrizable # apply transformation martices if stdreg == globals._RegType_.FSL: applywarp = pe.MapNode(interface=fsl.ApplyWarp(interp="spline", ), iterfield=['in_file', 'field_file', 'premat'], name='applywarp') myqc = qc.vol2png("func2mni", wf_name + "_FSL", overlayiterated=False) myqc.inputs.slicer.image_width = 500 # 500 # for the 2mm template myqc.inputs.slicer.threshold_edges = 0.1 # 0.1 # for the 2mm template else: #ANTs # source file for C3dAffineToolmust not be 4D, so we extract the one example vol myonevol = onevol.onevol_workflow() # concat premat and ants transform bbr2ants = pe.MapNode( interface=C3dAffineTool(fsl2ras=True, itk_transform=True), iterfield=['source_file', 'transform_file', 'reference_file'], # output: 'itk_transform' name="bbr2ants") #concat trfs into a list trflist = pe.MapNode(interface=Function( input_names=['trf_first', 'trf_second'], output_names=['trflist'], function=transformlist), iterfield=['trf_first', 'trf_second'], name="collect_trf") applywarp = pe.MapNode(interface=ants.ApplyTransforms( interpolation="BSpline", input_image_type=3), iterfield=['input_image', 'transforms'], name='applywarp') myqc = qc.vol2png("func2mni", wf_name + "_ANTS3", overlayiterated=False) myqc.inputs.slicer.image_width = 500 # 500 # for the 2mm template myqc.inputs.slicer.threshold_edges = 0.1 # 0.1 # for the 2mm template if carpet_plot: fmri_qc = qc.fMRI2QC("carpet_plots", tag=carpet_plot) outputspec = pe.Node(utility.IdentityInterface(fields=['func_std']), name='outputspec') # Save outputs which are important ds_nii = pe.Node(interface=io.DataSink(), name='ds_nii') ds_nii.inputs.base_directory = SinkDir ds_nii.inputs.regexp_substitutions = [("(\/)[^\/]*$", wf_name + ".nii.gz")] analysisflow = pe.Workflow(wf_name) analysisflow.base_dir = '.' if stdreg == globals._RegType_.FSL: analysisflow.connect(inputspec, 'func', applywarp, 'in_file') analysisflow.connect(inputspec, 'linear_reg_mtrx', applywarp, 'premat') analysisflow.connect(inputspec, 'nonlinear_reg_mtrx', applywarp, 'field_file') analysisflow.connect(inputspec, 'reference_brain', applywarp, 'ref_file') analysisflow.connect(applywarp, 'out_file', outputspec, 'func_std') analysisflow.connect(applywarp, 'out_file', myqc, 'inputspec.bg_image') analysisflow.connect(inputspec, 'reference_brain', myqc, 'inputspec.overlay_image') analysisflow.connect(applywarp, 'out_file', ds_nii, 'func2mni') else: # ANTs analysisflow.connect(inputspec, 'func', myonevol, 'inputspec.func') analysisflow.connect(myonevol, 'outputspec.func1vol', bbr2ants, 'source_file') analysisflow.connect(inputspec, 'linear_reg_mtrx', bbr2ants, 'transform_file') analysisflow.connect(inputspec, 'anat', bbr2ants, 'reference_file') analysisflow.connect(bbr2ants, 'itk_transform', trflist, 'trf_first') analysisflow.connect(inputspec, 'nonlinear_reg_mtrx', trflist, 'trf_second') analysisflow.connect(trflist, 'trflist', applywarp, 'transforms') analysisflow.connect(inputspec, 'func', applywarp, 'input_image') analysisflow.connect(inputspec, 'reference_brain', applywarp, 'reference_image') analysisflow.connect(applywarp, 'output_image', outputspec, 'func_std') analysisflow.connect(applywarp, 'output_image', myqc, 'inputspec.bg_image') analysisflow.connect(inputspec, 'reference_brain', myqc, 'inputspec.overlay_image') analysisflow.connect(applywarp, 'output_image', ds_nii, 'func2mni') if carpet_plot: if stdreg == globals._RegType_.FSL: analysisflow.connect(applywarp, 'out_file', fmri_qc, 'inputspec.func') else: # ANTs analysisflow.connect(applywarp, 'output_image', fmri_qc, 'inputspec.func') analysisflow.connect(inputspec, 'atlas', fmri_qc, 'inputspec.atlas') analysisflow.connect(inputspec, 'confounds', fmri_qc, 'inputspec.confounds') return analysisflow
iterfield=['in_file'], name='scale') #todo: parametrize fwhm myaroma = aroma.aroma_workflow(fwhm=8) func2std = func2standard.func2mni(stdreg=globals._RegType_.FSL, wf_name='func2std') func2std_aroma_nonaggr = func2standard.func2mni( stdreg=globals._RegType_.FSL, wf_name='func2std_aroma_nonaggr') func2std_aroma_nonaggr.inputs.inputspec.reference_brain = globals._FSLDIR_ + "/data/standard/MNI152_T1_3mm_brain.nii.gz" func2std_aroma_aggr = func2standard.func2mni(stdreg=globals._RegType_.FSL, wf_name='func2std_aroma_aggr') func2std_aroma_aggr.inputs.inputspec.reference_brain = globals._FSLDIR_ + "/data/standard/MNI152_T1_3mm_brain.nii.gz" fmri_qc_original = qc.fMRI2QC("carpet_aroma", tag="1_orinal") fmri_qc_nonaggr = qc.fMRI2QC("carpet_aroma", tag="2_nonaggressive") fmri_qc_aggr = qc.fMRI2QC("carpet_aroma", tag="3_aggressive") # compute mean FD meanFD = pe.MapNode(interface=utils_math.Txt2meanTxt, iterfield=['in_file'], name='meanFD') meanFD.inputs.axis = 0 # global mean pop_FD = pe.Node(interface=utils_convert.List2TxtFileOpen, name='pop_FD') # TODO sink this pop_FD.inputs.rownum = 0 pop_FD.inputs.out_file = "FD.txt" totalWorkflow = nipype.Workflow('exAROMA')