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
def create_corr_ts(name='corr_ts'): corr_ts = Workflow(name='corr_ts') # Define nodes inputnode = Node(util.IdentityInterface(fields=[ 'ts', 'hc_mask', ]), name='inputnode') outputnode = Node(interface=util.IdentityInterface( fields=['corrmap', 'corrmap_z', 'hc_ts']), name='outputnode') #extract mean time series of mask mean_TS = MapNode(interface=fsl.ImageMeants(), name="mean_TS", iterfield='mask') #iterate over using Eigenvalues or mean #mean_TS.iterables = ("eig", [True, False]) #mean_TS.inputs.order = 1 #mean_TS.inputs.show_all = True mean_TS.inputs.eig = False #use only mean of ROI mean_TS.inputs.out_file = "TS.1D" #calculate correlation of all voxels with seed voxel corr_TS = MapNode(interface=afni.Fim(), name='corr_TS', iterfield='ideal_file') corr_TS.inputs.out = 'Correlation' corr_TS.inputs.out_file = "corr.nii.gz" apply_FisherZ = MapNode(interface=afni.Calc(), name="apply_FisherZ", iterfield='in_file_a') apply_FisherZ.inputs.expr = 'log((1+a)/(1-a))/2' #log = ln apply_FisherZ.inputs.out_file = 'corr_Z.nii.gz' apply_FisherZ.inputs.outputtype = "NIFTI" corr_ts.connect([(inputnode, mean_TS, [('hc_mask', 'mask')]), (inputnode, mean_TS, [('ts', 'in_file')]), (mean_TS, outputnode, [('out_file', 'hc_ts')]), (inputnode, corr_TS, [('ts', 'in_file')]), (mean_TS, corr_TS, [('out_file', 'ideal_file')]), (corr_TS, apply_FisherZ, [('out_file', 'in_file_a')]), (corr_TS, outputnode, [('out_file', 'corrmap')]), (apply_FisherZ, outputnode, [('out_file', 'corrmap_z')])]) return corr_ts
def init_brain_atlas_wf(atlases, name="firstlevel"): """ create workflow to calculate seed connectivity maps for resting state functional scans :param atlases: dictionary of filenames by user-defined names of atlases :param name: workflow name (Default value = "firstlevel") """ workflow = pe.Workflow(name=name) # inputs are the bold file, the mask file and the confounds file # that contains the movement parameters inputnode = pe.Node(niu.IdentityInterface( fields=["bold_file", "mask_file", "confounds_file"]), name="inputnode") # make two (ordered) lists from (unordered) dictionary of seeds atlasnames = list(atlases.keys()) # contains the keys (seed names) atlas_args = ['--label=' + atlases[k] for k in atlasnames] # contains the values (filenames) # calculate the mean time series of the region defined by each mask meants = pe.MapNode(interface=fsl.ImageMeants(), name="meants", iterfield=["args"]) meants.inputs.args = atlas_args # outputs are cope, varcope and zstat for each seed region and a dof_file outputnode = pe.Node( niu.IdentityInterface(fields=["brainatlas_matrix_file"]), name="outputnode") workflow.connect([ (inputnode, meants, [("bold_file", "in_file")]), (meants, outputnode, [ ("out_file", "brainatlas_matrix_file"), ]), ]) # # connect outputs named for the seeds # for i, atlasname in enumerate(atlasnames): # workflow.connect(splitimgs, "out%i" % (i + 1), outputnode, "%s_img" % atlasname) return workflow, atlasnames
def init_global_signal(): input_node = Node(interface=IdentityInterface(fields=['img']), name='input_node') output_node = Node(interface=IdentityInterface(fields=['timeseries']), name='output_node') bet = Node(fsl.BET(functional=True), name='bet') extract = Node(fsl.ImageMeants(), name='extract') wf = Workflow(name='global_signal') wf.connect([ (input_node, bet, [('img', 'in_file')]), (input_node, extract, [('img', 'in_file')]), (bet, extract, [('mask_file', 'mask')]), (extract, output_node, [('out_file', 'timeseries')]), ]) return wf
def mask_and_extract(featdir, allmasks, img_to_extract): regdir = os.path.join(featdir, 'reg') #registration directory ind_maskdir = os.path.join(featdir, 'masks') #individual mask directory if not os.path.exists(ind_maskdir): os.mkdir(ind_maskdir) #make the individual directory if not there #for each mask for maskname in allmasks: mask_out_file = os.path.join(ind_maskdir, maskname) if not os.path.exists(mask_out_file): temp_mat = tempfile.NamedTemporaryFile() #create a temporary file #nipype wrapper for FSL's applyxfm, warps mask from standard into native space applyxfm = fsl.ApplyXfm() applyxfm.inputs.in_file = maskname applyxfm.inputs.in_matrix_file = os.path.join( regdir, 'standard2example_func.mat') applyxfm.inputs.out_file = mask_out_file applyxfm.inputs.out_matrix_file = temp_mat.name applyxfm.inputs.reference = os.path.join(featdir, 'example_func.nii.gz') applyxfm.inputs.apply_xfm = True result = applyxfm.run() # print result.outputs imgname = img_to_extract.split('.')[0].replace('/', '_') ts_out_file = img_to_extract.replace('/', '_') ts_out_file = os.path.join(ind_maskdir, maskname.split('.')[0] + imgname + '.txt') in_file = featdir + img_to_extract print "extracting from %s into file %s" % (in_file, ts_out_file) #nipype wrapper for fslmeants meants = fsl.ImageMeants() meants.inputs.in_file = in_file meants.inputs.mask = os.path.join(ind_maskdir, maskname) meants.inputs.out_file = ts_out_file result2 = meants.run()
def init_seedconnectivity_wf(seeds, use_mov_pars, name="firstlevel"): """ create workflow to calculate seed connectivity maps for resting state functional scans :param seeds: dictionary of filenames by user-defined names of binary masks that define the seed regions :param use_mov_pars: if true, regress out movement parameters when calculating seed connectivity :param name: workflow name (Default value = "firstlevel") """ workflow = pe.Workflow(name=name) # inputs are the bold file, the mask file and the confounds file # that contains the movement parameters inputnode = pe.Node(niu.IdentityInterface( fields=["bold_file", "mask_file", "confounds_file"]), name="inputnode") # make two (ordered) lists from (unordered) dictionary of seeds seednames = list(seeds.keys()) # contains the keys (seed names) seed_paths = [seeds[k] for k in seednames] # contains the values (filenames) # calculate the mean time series of the region defined by each mask meants = pe.MapNode(interface=fsl.ImageMeants(), name="meants", iterfield=["mask"]) meants.inputs.mask = seed_paths # calculate the regression of the mean time series onto the functional image # the result is the seed connectivity map glm = pe.MapNode(interface=fsl.GLM(out_file="beta.nii.gz", out_cope="cope.nii.gz", out_varcb_name="varcope.nii.gz", out_z_name="zstat.nii.gz", demean=True), name="glm", iterfield=["design"]) # generate dof text file gendoffile = pe.Node(interface=Dof(num_regressors=1), name="gendoffile") # split regression outputs by name splitimgs = pe.Node( interface=niu.Split(splits=[1 for seedname in seednames]), name="splitimgs") splitvarcopes = pe.Node( interface=niu.Split(splits=[1 for seedname in seednames]), name="splitvarcopes") splitzstats = pe.Node( interface=niu.Split(splits=[1 for seedname in seednames]), name="splitzstats") # outputs are cope, varcope and zstat for each seed region and a dof_file outputnode = pe.Node(niu.IdentityInterface(fields=sum( [["%s_img" % seedname, "%s_varcope" % seedname, "%s_zstat" % seedname] for seedname in seednames], []) + ["dof_file"]), name="outputnode") workflow.connect([ (inputnode, meants, [("bold_file", "in_file")]), (inputnode, glm, [("bold_file", "in_file"), ("mask_file", "mask")]), (meants, glm, [("out_file", "design")]), (glm, splitimgs, [ ("out_cope", "inlist"), ]), (glm, splitvarcopes, [ ("out_varcb", "inlist"), ]), (glm, splitzstats, [ ("out_z", "inlist"), ]), (inputnode, gendoffile, [ ("bold_file", "in_file"), ]), (gendoffile, outputnode, [ ("out_file", "dof_file"), ]), ]) # connect outputs named for the seeds for i, seedname in enumerate(seednames): workflow.connect(splitimgs, "out%i" % (i + 1), outputnode, "%s_img" % seedname) workflow.connect(splitvarcopes, "out%i" % (i + 1), outputnode, "%s_varcope" % seedname) workflow.connect(splitzstats, "out%i" % (i + 1), outputnode, "%s_zstat" % seedname) return workflow, seednames
def plot_vbm_correlation(vbm_4D_image, mat, p_value_image): import numpy as np import matplotlib.pyplot as plt import nipype.interfaces.fsl as fsl import ntpath import sys import matplotlib import os img_basename_no_ext = ntpath.basename(vbm_4D_image)[:-7] mat_basename_no_ext = ntpath.basename(mat)[:-4] contrast_no = ntpath.basename(p_value_image)[-9:-7] # get the coordinates of voxel with highest p value fslstats = fsl.ImageStats() fslstats.inputs.in_file = p_value_image fslstats.inputs.op_string = '-x' # returns co-ordinates of maximum voxel stat_output = fslstats.run() voxel_coordinate = stat_output.outputs.out_stat # convert coordinates to int from float to suit fslmeants voxel_coordinate = [int(dim) for dim in voxel_coordinate] # we use fslmeants from fsl to get the intensity of the 4D image from a specific coordinate # fslmeants -i 4d_image -c 47 73 9 fslmeants = fsl.ImageMeants() fslmeants.inputs.in_file = vbm_4D_image fslmeants.inputs.spatial_coord = voxel_coordinate outputs = fslmeants.run() # here the output is not displayed on the screen, rather as a simple txt # the return results are in dict format, we extract the name of the file ts = outputs.outputs.get()['out_file'] voxel_values = np.loadtxt(ts) # returns the values as an array voxel_values = list(voxel_values) # now we extract the behavior vector from .mat file f = open(mat, 'r') lines = f.readlines() f.close() behav = [] i = 5 for item in lines: while i < 37: behav.append(float(lines[i][13:-2])) i = i + 1 # now we have a list # sanity check print("length of voxel_values -> {0}".format(len(voxel_values))) print("length of behav_values -> {0}".format(len(behav))) if len(voxel_values) != len(behav): sys.error('######ERROR####') # the regression line coef = np.polyfit(voxel_values, behav, 1) poly1d_fn = np.poly1d(coef) # get the correlation coeeficient # round to 4 digits after the decimal point correlation_coef = round(np.corrcoef(voxel_values, behav)[0, 1], 5) plt.rcParams['font.family'] = 'Arial' ax = plt.axes() ax.spines['bottom'].set_color('#ffffffff') ax.spines['top'].set_color('#ffffffff') ax.spines['right'].set_color('#ffffffff') ax.spines['left'].set_color('#ffffffff') ax.tick_params(axis='x', colors='#ffffffff') ax.tick_params(axis='y', colors='#ffffffff') plt.xticks(fontsize=14, rotation=45, color='#ffffffff') plt.yticks(fontsize=14, color='#ffffffff') plt.scatter(voxel_values[:16], behav[:16], marker='o', color='#e41a1c') # e41a1c -> red plt.scatter(voxel_values[16:], behav[16:], marker='<', color='#377eb8') # 377eb8 -> blue plt.ylabel("{0}".format(mat_basename_no_ext), fontsize=18, fontname='Arial', color='#ffffffff') plt.plot(voxel_values, poly1d_fn(voxel_values), color='#ffffffff') # plot the regression line # type the coef on the graph, first two arguments the coordinates of the text (top left corner) plt.text(min(voxel_values), max(behav), "r $= {0}$".format( correlation_coef), fontname="Arial", style='italic', fontsize=14, color='#ffffffff') plt.savefig("/Users/amr/Dropbox/thesis/3D/VBM_corr/{0}_{1}_{2}.svg".format( img_basename_no_ext, mat_basename_no_ext, contrast_no), format='svg') plt.close() os.remove(ts) # delete the file of the voxel values as it is no longer needed os.remove('stat_result.json')
aCompCor = pe.Node(conf.ACompCor(merge_method='union', variance_threshold=aCompCor_varThresh, repetition_time=TR, pre_filter='cosine', failure_mode='NaN'), name='aCompCor') tCompCor = pe.Node(conf.TCompCor(merge_method='union', variance_threshold=tCompCor_varThresh, repetition_time=TR, pre_filter='cosine', percentile_threshold=0.05, failure_mode='NaN'), name='tCompCor') WMmeanTS = pe.Node(fsl.ImageMeants(), name='WMmeanTS') CSFmeanTS = pe.Node(fsl.ImageMeants(), name='CSFmeanTS') # Create regressor file (concatenate regressors to make a matrix) def create_Regressor(motionMatrix, outlierMatrix, CSFinput, WMinput, aCompCor_in, tCompCor_in): import pandas as pd import os df_motion = pd.read_table(motionMatrix, header=None, sep=' ', engine='python') df_motion.columns = [ 'trans_x', 'trans_y', 'trans_z', 'rot_x', 'rot_y', 'rot_z'
MaskTumorADC = pe.MapNode(interface=fsl.ApplyMask(), name='MaskTumorADC', iterfield=['in_file']) ThresholdADC = pe.MapNode(interface=fsl.Threshold(), name='ThresholdADC', iterfield=['in_file']) ThresholdADC.inputs.in_file = ADC ThresholdADC.inputs.thresh = 10 MaskNormalADC = pe.MapNode(interface=fsl.ApplyMask(), name='MaskNormalADC', iterfield=['in_file']) MaskNormalADC.inputs.in_file = ADC ExtractTumorValue = pe.MapNode(interface=fsl.ImageMeants(), name='ExtractTumorValues', iterfield=['in_file']) ExtractTumorValue.inputs.show_all = True ExtractTumorValue.inputs.transpose = True ExtractNormalValue = pe.MapNode(interface=fsl.ImageMeants(), name='ExtractNormalValues', iterfield=['in_file']) ExtractNormalValue.inputs.show_all = True ExtractNormalValue.inputs.transpose = True ExtractMaskValue = pe.Node(interface=fsl.ImageMeants(), name='ExtractMaskValues') ExtractMaskValue.inputs.show_all = True ExtractMaskValue.inputs.transpose = True
overlay_f_contrast.inputs.auto_thresh_bg = True overlay_f_contrast.inputs.stat_thresh = (2.300302, 5) overlay_f_contrast.inputs.transparency = True # ============================================================================================================================ # In[15]: # slicer slicer_f_contrast = Node(fsl.Slicer(), name='generate_f_contrast_image') slicer_f_contrast.inputs.all_axial = True slicer_f_contrast.inputs.image_width = 500 # ============================================================================================================================ # In[15]: # get average timeseries using the tstat threshold as a mask get_timeseries = Node(fsl.ImageMeants(), name='get_timeseries') get_timeseries.inputs.out_file = 'average_timeseries.txt' # ============================================================================================================================ stimulation_1st_level.connect([ (infosource, selectfiles, [('subject_id', 'subject_id'), ('session_id', 'session_id'), ('frequency_id', 'frequency_id')]), (selectfiles, film_gls, [('preproc_img', 'in_file')]), (selectfiles, smooth_est, [('bold_mask', 'mask_file')]), (film_gls, smooth_est, [('residual4d', 'residual_fit_file')]), (selectfiles, mask_zstat, [('bold_mask', 'mask_file')]), (film_gls, mask_zstat, [('zstats', 'in_file')]), (mask_zstat, clustering_t, [('out_file', 'in_file')]), (film_gls, clustering_t, [('copes', 'cope_file')]),
def init_seedbasedconnectivity_wf(workdir=None, feature=None, seed_files=None, seed_spaces=None, memcalc=MemoryCalculator()): """ create workflow to calculate seed connectivity maps """ if feature is not None: name = f"{formatlikebids(feature.name)}_wf" else: name = "seedbasedconnectivity_wf" workflow = pe.Workflow(name=name) # input inputnode = pe.Node( niu.IdentityInterface(fields=[ "tags", "vals", "metadata", "bold", "mask", "confounds_selected", "seed_names", "seed_files", "seed_spaces", ]), name="inputnode", ) outputnode = pe.Node(niu.IdentityInterface(fields=["resultdicts"]), name="outputnode") min_seed_coverage = 1 if feature is not None: inputnode.inputs.seed_names = feature.seeds if hasattr(feature, "min_seed_coverage"): min_seed_coverage = feature.min_seed_coverage if seed_files is not None: inputnode.inputs.seed_files = seed_files if seed_spaces is not None: inputnode.inputs.seed_spaces = seed_spaces # statmaps = ["effect", "variance", "z", "dof", "mask"] make_resultdicts = pe.Node( MakeResultdicts( tagkeys=["feature", "seed"], imagekeys=[*statmaps, "design_matrix", "contrast_matrix"], metadatakeys=["mean_t_s_n_r", "coverage"], ), name="make_resultdicts", ) if feature is not None: make_resultdicts.inputs.feature = feature.name workflow.connect(inputnode, "tags", make_resultdicts, "tags") workflow.connect(inputnode, "vals", make_resultdicts, "vals") workflow.connect(inputnode, "metadata", make_resultdicts, "metadata") workflow.connect(inputnode, "mask", make_resultdicts, "mask") workflow.connect(make_resultdicts, "resultdicts", outputnode, "resultdicts") # resultdict_datasink = pe.Node(ResultdictDatasink(base_directory=workdir), name="resultdict_datasink") workflow.connect(make_resultdicts, "resultdicts", resultdict_datasink, "indicts") # reference_dict = dict(reference_space=constants.reference_space, reference_res=constants.reference_res) resample = pe.MapNode( Resample(interpolation="MultiLabel", **reference_dict), name="resample", iterfield=["input_image", "input_space"], n_procs=config.nipype.omp_nthreads, mem_gb=memcalc.series_std_gb, ) workflow.connect(inputnode, "seed_files", resample, "input_image") workflow.connect(inputnode, "seed_spaces", resample, "input_space") # Delete zero voxels for the seeds maskseeds = pe.Node( MaskCoverage(keys=["names"], min_coverage=min_seed_coverage), name="maskseeds", mem_gb=memcalc.volume_std_gb, ) workflow.connect(inputnode, "mask", maskseeds, "mask_file") workflow.connect(inputnode, "seed_names", maskseeds, "names") workflow.connect(resample, "output_image", maskseeds, "in_files") workflow.connect(maskseeds, "names", make_resultdicts, "seed") workflow.connect(maskseeds, "coverage", make_resultdicts, "coverage") # calculate the mean time series of the region defined by each mask meants = pe.MapNode( fsl.ImageMeants(), name="meants", iterfield="mask", mem_gb=memcalc.series_std_gb, ) workflow.connect(inputnode, "bold", meants, "in_file") workflow.connect(maskseeds, "out_files", meants, "mask") # design = pe.MapNode(MergeColumns(2), iterfield=["in1", "column_names1"], name="design") workflow.connect(meants, "out_file", design, "in1") workflow.connect(maskseeds, "names", design, "column_names1") workflow.connect(inputnode, "confounds_selected", design, "in2") workflow.connect(design, "out_with_header", make_resultdicts, "design_matrix") contrasts = pe.MapNode( niu.Function( input_names=["design_file"], output_names=["out_with_header", "out_no_header"], function=_contrasts, ), iterfield="design_file", name="contrasts", ) workflow.connect(design, "out_with_header", contrasts, "design_file") workflow.connect(contrasts, "out_with_header", make_resultdicts, "contrast_matrix") fillna = pe.MapNode(FillNA(), iterfield="in_tsv", name="fillna") workflow.connect(design, "out_no_header", fillna, "in_tsv") # calculate the regression of the mean time series # onto the functional image. # the result is the seed connectivity map glm = pe.MapNode( fsl.GLM( out_file="beta.nii.gz", out_cope="cope.nii.gz", out_varcb_name="varcope.nii.gz", out_z_name="zstat.nii.gz", demean=True, ), name="glm", iterfield=["design", "contrasts"], mem_gb=memcalc.series_std_gb * 5, ) workflow.connect(inputnode, "bold", glm, "in_file") workflow.connect(inputnode, "mask", glm, "mask") workflow.connect(fillna, "out_no_header", glm, "design") workflow.connect(contrasts, "out_no_header", glm, "contrasts") # make dof volume makedofvolume = pe.MapNode(MakeDofVolume(), iterfield=["design"], name="makedofvolume") workflow.connect(inputnode, "bold", makedofvolume, "bold_file") workflow.connect(fillna, "out_no_header", makedofvolume, "design") workflow.connect(glm, "out_cope", make_resultdicts, "effect") workflow.connect(glm, "out_varcb", make_resultdicts, "variance") workflow.connect(glm, "out_z", make_resultdicts, "z") workflow.connect(makedofvolume, "out_file", make_resultdicts, "dof") # tsnr = pe.Node(nac.TSNR(), name="tsnr", mem_gb=memcalc.series_std_gb) workflow.connect(inputnode, "bold", tsnr, "in_file") calcmean = pe.MapNode(CalcMean(), iterfield="mask", name="calcmean", mem_gb=memcalc.series_std_gb) workflow.connect(maskseeds, "out_files", calcmean, "mask") workflow.connect(tsnr, "tsnr_file", calcmean, "in_file") workflow.connect(calcmean, "mean", make_resultdicts, "mean_t_s_n_r") return workflow
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
def init_seedbasedconnectivity_wf(analysis, memcalc=MemoryCalculator()): """ create workflow to calculate seed connectivity maps """ assert isinstance(analysis, Analysis) assert isinstance(analysis.tags, Tags) # make bold file variant specification confoundsfilefields = [] varianttupls = [("space", analysis.tags.space)] if analysis.tags.grand_mean_scaled is not None: assert isinstance(analysis.tags.grand_mean_scaled, GrandMeanScaledTag) varianttupls.append(analysis.tags.grand_mean_scaled.as_tupl()) if analysis.tags.band_pass_filtered is not None: assert isinstance(analysis.tags.band_pass_filtered, BandPassFilteredTag) varianttupls.append(analysis.tags.band_pass_filtered.as_tupl()) if analysis.tags.confounds_removed is not None: assert isinstance(analysis.tags.confounds_removed, ConfoundsRemovedTag) confounds_removed_names = tuple( name for name in analysis.tags.confounds_removed.names if "aroma_motion" in name) varianttupls.append(("confounds_removed", confounds_removed_names)) confounds_extract_names = tuple( name for name in analysis.tags.confounds_removed.names if "aroma_motion" not in name) if len(confounds_extract_names) > 0: confoundsfilefields.append("confounds_file") varianttupls.append(("confounds_extract", confounds_extract_names)) if analysis.tags.smoothed is not None: assert isinstance(analysis.tags.smoothed, SmoothedTag) varianttupls.append(analysis.tags.smoothed.as_tupl()) boldfilevariant = (("bold_file", *confoundsfilefields), tuple(varianttupls)) assert analysis.name is not None workflow = pe.Workflow(name=analysis.name) # input inputnode = pe.Node( niu.IdentityInterface(fields=[ "bold_file", *confoundsfilefields, "mask_file", "seed_files", "seed_names", "metadata", ]), name="inputnode", ) resampleifneeded = pe.MapNode( interface=ResampleIfNeeded(method="nearest"), name="resampleifneeded", iterfield=["in_file"], mem_gb=memcalc.series_std_gb, ) workflow.connect(inputnode, "seed_files", resampleifneeded, "in_file") workflow.connect(inputnode, "bold_file", resampleifneeded, "ref_file") # Delete zero voxels for the seeds applymask = pe.MapNode( interface=fsl.ApplyMask(), name="applymask", iterfield="in_file", mem_gb=memcalc.volume_std_gb, ) workflow.connect([ (inputnode, applymask, [("mask_file", "mask_file")]), (resampleifneeded, applymask, [("out_file", "in_file")]), ]) # calculate the mean time series of the region defined by each mask meants = pe.MapNode( interface=fsl.ImageMeants(), name="meants", iterfield="mask", mem_gb=memcalc.series_std_gb, ) workflow.connect([ (inputnode, meants, [("bold_file", "in_file")]), (applymask, meants, [("out_file", "mask")]), ]) def make_contrastmat(confounds_file=None): import os from os import path as op from pipeline.utils import ncol import numpy as np if confounds_file is not None: nconfounds = ncol(confounds_file) else: nconfounds = 0 contrastmat = np.zeros((1, 1 + nconfounds)) contrastmat[0, 0] = 1 out_file = op.join(os.getcwd(), "contrasts.tsv") np.savetxt(out_file, contrastmat, delimiter="\t") return out_file contrastmat = pe.Node( interface=niu.Function( input_names=[*confoundsfilefields], output_names=["out_file"], function=make_contrastmat, ), name="contrastmat", ) if confoundsfilefields: workflow.connect([(inputnode, contrastmat, [(*confoundsfilefields, *confoundsfilefields)])]) designnode = pe.Node(niu.IdentityInterface(fields=["design"]), name="designnode") if confoundsfilefields: mergecolumns = pe.MapNode( interface=MergeColumnsTSV(2), name="mergecolumns", mem_gb=memcalc.min_gb, iterfield="in1", run_without_submitting=True, ) workflow.connect([ (meants, mergecolumns, [("out_file", "in1")]), (inputnode, mergecolumns, [(*confoundsfilefields, "in2")]), (mergecolumns, designnode, [("out_file", "design")]), ]) else: workflow.connect([(meants, designnode, [("out_file", "design")])]) # calculate the regression of the mean time series # onto the functional image. # the result is the seed connectivity map glm = pe.MapNode( interface=fsl.GLM( out_file="beta.nii.gz", out_cope="cope.nii.gz", out_varcb_name="varcope.nii.gz", out_z_name="zstat.nii.gz", demean=True, ), name="glm", iterfield="design", mem_gb=memcalc.series_std_gb * 5, ) workflow.connect([ (inputnode, glm, [("bold_file", "in_file")]), (contrastmat, glm, [("out_file", "contrasts")]), (designnode, glm, [("design", "design")]), ]) # make dof volume makedofvolume = pe.MapNode( interface=MakeDofVolume(), iterfield=["design"], name="makedofvolume", ) workflow.connect([ (inputnode, makedofvolume, [("bold_file", "bold_file")]), (designnode, makedofvolume, [("design", "design")]), ]) outputnode = pe.Node( interface=MakeResultdicts(keys=[ "firstlevelanalysisname", "firstlevelfeaturename", "cope", "varcope", "zstat", "dof_file", "mask_file", ]), name="outputnode", ) outputnode.inputs.firstlevelanalysisname = analysis.name workflow.connect([ ( inputnode, outputnode, [ ("metadata", "basedict"), ("mask_file", "mask_file"), ("seed_names", "firstlevelfeaturename"), ], ), (makedofvolume, outputnode, [("out_file", "dof_file")]), ( glm, outputnode, [ (("out_cope", ravel), "cope"), (("out_varcb", ravel), "varcope"), (("out_z", ravel), "zstat"), ], ), ]) return workflow, (boldfilevariant, )
def prepro_func(i): try: subj = i for s in (['session2']): # Define input files: 2xfMRI + 1xMPRAGE func1 = data_path + subj + '/Functional_scans/' + s[:-2] + s[ -1] + '_a/epi.nii.gz' #choose this for patients func2 = data_path + subj + '/Functional_scans/' + s[:-2] + s[ -1] + '_b/epi.nii.gz' #choose this for patients #anat = glob.glob(anat_path + subj +'/'+ s + '/anat/reorient/anat_*.nii.gz') #choose this for session 1 lesion_mask_file = anat_path + subj + '/session1/anat/reorient/lesion_seg.nii.gz' old_lesion_mask_file = glob.glob( anat_path + subj + '/session1/anat/reorient/old_lesion_seg.nii.gz' ) #choose this for ones with no old lesion #old_lesion_mask_file = anat_path + subj +'/session1/anat/reorient/old_lesion_seg.nii.gz' #choose this for ones with old lesion anat = glob.glob(anat_path + subj + '/' + s + '/anat/anat2hr/anat_*.nii.gz' ) #choose this for sessions 2 and 3 anat_CSF = glob.glob( anat_path + subj + '/session1/seg_anat/segmentation/anat_*_pve_0.nii.gz' ) # don't change, same for all sessions anat_WM = glob.glob( anat_path + subj + '/session1/seg_anat/segmentation/anat_*_pve_2.nii.gz' ) # don't change, same for all sessions anat_GM = glob.glob( anat_path + subj + '/session1/seg_anat/segmentation/anat_*_pve_1.nii.gz' ) # don't change, same for all sessions anat2MNI_fieldwarp = glob.glob( anat_path + subj + '/session1/anat/nonlinear_reg/anat_*_fieldwarp.nii.gz' ) # don't change, same for all sessions if not os.path.isdir(data_path + subj + '/' + s): # No data exists continue if not os.path.isfile(func1): print '1. functional file ' + func1 + ' not found. Skipping!' continue if not os.path.isfile(func2): print '2. functional file ' + func2 + ' not found. Skipping!' continue if not anat: print 'Preprocessed anatomical file not found. Skipping!' continue if len(anat) > 1: print 'WARNING: found multiple files of preprocessed anatomical image!' continue anat = anat[0] if not anat2MNI_fieldwarp: print 'Anatomical registration to MNI152-space field file not found. Skipping!' continue if len(anat2MNI_fieldwarp) > 1: print 'WARNING: found multiple files of anat2MNI fieldwarp!' continue anat2MNI_fieldwarp = anat2MNI_fieldwarp[0] if not anat_CSF: anat_CSF = glob.glob( anat_path + subj + '/' + s + '/seg_anat/segmentation/anat_*_pve_0.nii.gz') if not anat_CSF: print 'Anatomical segmentation CSF file not found. Skipping!' continue if len(anat_CSF) > 1: print 'WARNING: found multiple files of anatomical CSF file!' continue anat_CSF = anat_CSF[0] if not anat_WM: anat_WM = glob.glob( anat_path + subj + '/' + s + '/seg_anat/segmentation/anat_*_pve_2.nii.gz') if not anat_WM: print 'Anatomical segmentation WM file not found. Skipping!' continue if len(anat_WM) > 1: print 'WARNING: found multiple files of anatomical WM file!' continue anat_WM = anat_WM[0] if not anat_GM: anat_GM = glob.glob( anat_path + subj + '/' + s + '/seg_anat/segmentation/anat_*_pve_1.nii.gz') if not anat_GM: print 'Anatomical segmentation GM file not found. Skipping!' continue if len(anat_GM) > 1: print 'WARNING: found multiple files of anatomical GM file!' continue anat_GM = anat_GM[0] if not os.path.isdir(results_path + subj): os.mkdir(results_path + subj) if not os.path.isdir(results_path + subj + '/' + s): os.mkdir(results_path + subj + '/' + s) for data in acquisitions: os.chdir(results_path + subj + '/' + s) print "Currently processing subject: " + subj + '/' + s + ' ' + data #Initialize workflows workflow = pe.Workflow(name=data) workflow.base_dir = '.' inputnode = pe.Node( interface=util.IdentityInterface(fields=['source_file']), name='inputspec') outputnode = pe.Node( interface=util.IdentityInterface(fields=['result_func']), name='outputspec') if data == 'func1': inputnode.inputs.source_file = func1 else: inputnode.inputs.source_file = func2 # Remove n_dummies first volumes trim = pe.Node(interface=Trim(begin_index=n_dummies), name='trim') workflow.connect(inputnode, 'source_file', trim, 'in_file') # Motion correction + slice timing correction realign4d = pe.Node(interface=SpaceTimeRealigner(), name='realign4d') #realign4d.inputs.ignore_exception=True realign4d.inputs.slice_times = 'asc_alt_siemens' realign4d.inputs.slice_info = 2 # horizontal slices realign4d.inputs.tr = mytr # TR in seconds workflow.connect(trim, 'out_file', realign4d, 'in_file') # Reorient #deoblique = pe.Node(interface=afni.Warp(deoblique=True, outputtype='NIFTI_GZ'), name='deoblique') #leave out if you don't need this #workflow.connect(realign4d, 'out_file', deoblique, 'in_file') reorient = pe.Node( interface=fsl.Reorient2Std(output_type='NIFTI_GZ'), name='reorient') workflow.connect(realign4d, 'out_file', reorient, 'in_file') # AFNI skullstrip and mean image skullstrip tstat1 = pe.Node(interface=afni.TStat(args='-mean', outputtype="NIFTI_GZ"), name='tstat1') automask = pe.Node(interface=afni.Automask( dilate=1, outputtype="NIFTI_GZ"), name='automask') skullstrip = pe.Node(interface=afni.Calc( expr='a*b', outputtype="NIFTI_GZ"), name='skullstrip') tstat2 = pe.Node(interface=afni.TStat(args='-mean', outputtype="NIFTI_GZ"), name='tstat2') workflow.connect(reorient, 'out_file', tstat1, 'in_file') workflow.connect(tstat1, 'out_file', automask, 'in_file') workflow.connect(automask, 'out_file', skullstrip, 'in_file_b') workflow.connect(reorient, 'out_file', skullstrip, 'in_file_a') workflow.connect(skullstrip, 'out_file', tstat2, 'in_file') # Register to anatomical space #can be changed #mean2anat = pe.Node(fsl.FLIRT(bins=40, cost='normmi', dof=7, interp='nearestneighbour', searchr_x=[-180,180], searchr_y=[-180,180], searchr_z=[-180,180]), name='mean2anat') mean2anat = pe.Node(fsl.FLIRT(bins=40, cost='normmi', dof=7, interp='nearestneighbour'), name='mean2anat') #mean2anat = pe.Node(fsl.FLIRT(no_search=True), name='mean2anat') mean2anat.inputs.reference = anat workflow.connect(tstat2, 'out_file', mean2anat, 'in_file') # Transform mean functional image warpmean = pe.Node(interface=fsl.ApplyWarp(), name='warpmean') warpmean.inputs.ref_file = MNI_brain warpmean.inputs.field_file = anat2MNI_fieldwarp workflow.connect(mean2anat, 'out_matrix_file', warpmean, 'premat') workflow.connect(tstat2, 'out_file', warpmean, 'in_file') # ----- inversion matrix and eroded brain mask for regression ----- # create inverse matrix from mean2anat registration invmat = pe.Node(fsl.ConvertXFM(), name='invmat') invmat.inputs.invert_xfm = True workflow.connect(mean2anat, 'out_matrix_file', invmat, 'in_file') # erode functional brain mask erode_brain = pe.Node(fsl.ImageMaths(), name='erode_brain') erode_brain.inputs.args = '-kernel boxv 3 -ero' workflow.connect(automask, 'out_file', erode_brain, 'in_file') # register GM mask to functional image space, this is done for quality control reg_GM = pe.Node(fsl.preprocess.ApplyXFM(), name='register_GM') reg_GM.inputs.apply_xfm = True reg_GM.inputs.in_file = anat_GM workflow.connect(tstat2, 'out_file', reg_GM, 'reference') workflow.connect(invmat, 'out_file', reg_GM, 'in_matrix_file') # --------- motion regression and censor signals ------------------ # normalize motion parameters norm_motion = pe.Node(interface=Function( input_names=['in_file'], output_names=['out_file'], function=normalize_motion_data), name='normalize_motion') workflow.connect(realign4d, 'par_file', norm_motion, 'in_file') # create censor file, for censoring motion get_censor = pe.Node(afni.OneDToolPy(), name='motion_censors') get_censor.inputs.set_nruns = 1 get_censor.inputs.censor_motion = (censor_thr, 'motion') get_censor.inputs.show_censor_count = True if overwrite: get_censor.inputs.args = '-overwrite' workflow.connect(norm_motion, 'out_file', get_censor, 'in_file') # compute motion parameter derivatives (for use in regression) deriv_motion = pe.Node(afni.OneDToolPy(), name='deriv_motion') deriv_motion.inputs.set_nruns = 1 deriv_motion.inputs.derivative = True if overwrite: deriv_motion.inputs.args = '-overwrite' deriv_motion.inputs.out_file = 'motion_derivatives.txt' workflow.connect(norm_motion, 'out_file', deriv_motion, 'in_file') # scale motion parameters and get quadratures quadr_motion = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_motion') quadr_motion.inputs.multicol = True workflow.connect(norm_motion, 'out_file', quadr_motion, 'in_file') # scale motion derivatives and get quadratures quadr_motion_deriv = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_motion_deriv') quadr_motion_deriv.inputs.multicol = True workflow.connect(deriv_motion, 'out_file', quadr_motion_deriv, 'in_file') # -------- CSF regression signals --------------- # threshold and erode CSF mask erode_CSF_mask = pe.Node(fsl.ImageMaths(), name='erode_CSF_mask') erode_CSF_mask.inputs.args = '-thr 0.5 -kernel boxv 3 -ero' erode_CSF_mask.inputs.in_file = anat_CSF # register CSF mask to functional image space reg_CSF_mask = pe.Node(fsl.preprocess.ApplyXFM(), name='register_CSF_mask') reg_CSF_mask.inputs.apply_xfm = True workflow.connect(tstat2, 'out_file', reg_CSF_mask, 'reference') workflow.connect(invmat, 'out_file', reg_CSF_mask, 'in_matrix_file') # inverse lesion mask and remove it from CSF mask #remove this if you don't have a lesion mask inverse_lesion_mask = pe.Node(fsl.ImageMaths(), name='inverse_lesion_mask') inverse_lesion_mask.inputs.args = '-add 1 -rem 2' inverse_lesion_mask.inputs.in_file = lesion_mask_file rem_lesion = pe.Node(fsl.ImageMaths(), name='remove_lesion') workflow.connect(erode_CSF_mask, 'out_file', rem_lesion, 'in_file') workflow.connect(inverse_lesion_mask, 'out_file', rem_lesion, 'mask_file') ''' # Transform lesion mask to MNI152 space #remove if lesion masks are already in MNI152 space warp_lesion = pe.Node(interface=fsl.ApplyWarp(), name='warp_lesion') warp_lesion.inputs.ref_file = MNI_brain warp_lesion.inputs.field_file = anat2MNI_fieldwarp warp_lesion.inputs.in_file = lesion_mask_file warp_lesion.inputs.out_file = anat_path + subj +'/'+ s + '/anat/nonlinear_reg/lesion_seg_warp.nii.gz' warp_lesion.run() ''' # inverse old lesion mask and remove it from CSF mask #remove this if you don't have a lesion mask if old_lesion_mask_file: inverse_old_lesion_mask = pe.Node( fsl.ImageMaths(), name='inverse_old_lesion_mask') inverse_old_lesion_mask.inputs.args = '-add 1 -rem 3' #inverse_old_lesion_mask.inputs.in_file = old_lesion_mask_file[0] inverse_old_lesion_mask.inputs.in_file = old_lesion_mask_file rem_old_lesion = pe.Node(fsl.ImageMaths(), name='remove_old_lesion') workflow.connect(rem_lesion, 'out_file', rem_old_lesion, 'in_file') workflow.connect(inverse_old_lesion_mask, 'out_file', rem_old_lesion, 'mask_file') workflow.connect(rem_old_lesion, 'out_file', reg_CSF_mask, 'in_file') ''' # Transform old lesion mask to MNI152 space #remove if lesion masks are already in MNI152 space warp_old_lesion = pe.Node(interface=fsl.ApplyWarp(), name='warp_old_lesion') warp_old_lesion.inputs.ref_file = MNI_brain warp_old_lesion.inputs.field_file = anat2MNI_fieldwarp warp_old_lesion.inputs.in_file = old_lesion_mask_file warp_old_lesion.inputs.out_file = anat_path + subj +'/'+ s + '/anat/nonlinear_reg/old_lesion_seg_warp.nii.gz' warp_old_lesion.run() ''' else: workflow.connect(rem_lesion, 'out_file', reg_CSF_mask, 'in_file') # threshold CSF mask and intersect with functional brain mask thr_CSF_mask = pe.Node(fsl.ImageMaths(), name='threshold_CSF_mask') thr_CSF_mask.inputs.args = '-thr 0.25' workflow.connect(reg_CSF_mask, 'out_file', thr_CSF_mask, 'in_file') workflow.connect(erode_brain, 'out_file', thr_CSF_mask, 'mask_file') # extract CSF values get_CSF_noise = pe.Node(fsl.ImageMeants(), name='get_CSF_noise') workflow.connect(skullstrip, 'out_file', get_CSF_noise, 'in_file') workflow.connect(thr_CSF_mask, 'out_file', get_CSF_noise, 'mask') # compute CSF noise derivatives deriv_CSF = pe.Node(afni.OneDToolPy(), name='deriv_CSF') deriv_CSF.inputs.set_nruns = 1 deriv_CSF.inputs.derivative = True if overwrite: deriv_CSF.inputs.args = '-overwrite' deriv_CSF.inputs.out_file = 'CSF_derivatives.txt' workflow.connect(get_CSF_noise, 'out_file', deriv_CSF, 'in_file') # scale SCF noise and get quadratures quadr_CSF = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_CSF') quadr_CSF.inputs.multicol = False workflow.connect(get_CSF_noise, 'out_file', quadr_CSF, 'in_file') # scale CSF noise derivatives and get quadratures quadr_CSF_deriv = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_CSF_deriv') quadr_CSF_deriv.inputs.multicol = False workflow.connect(deriv_CSF, 'out_file', quadr_CSF_deriv, 'in_file') # -------- WM regression signals ----------------- # threshold and erode WM mask erode_WM_mask = pe.Node(fsl.ImageMaths(), name='erode_WM_mask') erode_WM_mask.inputs.args = '-thr 0.5 -kernel boxv 7 -ero' erode_WM_mask.inputs.in_file = anat_WM # registrer WM mask to functional image space reg_WM_mask = pe.Node(fsl.preprocess.ApplyXFM(), name='register_WM_mask') reg_WM_mask.inputs.apply_xfm = True workflow.connect(tstat2, 'out_file', reg_WM_mask, 'reference') workflow.connect(invmat, 'out_file', reg_WM_mask, 'in_matrix_file') workflow.connect(erode_WM_mask, 'out_file', reg_WM_mask, 'in_file') # create inverse nonlinear registration MNI2anat invwarp = pe.Node(fsl.InvWarp(output_type='NIFTI_GZ'), name='invwarp') invwarp.inputs.warp = anat2MNI_fieldwarp invwarp.inputs.reference = anat # transform ventricle mask to functional space reg_ventricles = pe.Node(fsl.ApplyWarp(), name='register_ventricle_mask') reg_ventricles.inputs.in_file = ventricle_mask workflow.connect(tstat2, 'out_file', reg_ventricles, 'ref_file') workflow.connect(invwarp, 'inverse_warp', reg_ventricles, 'field_file') workflow.connect(invmat, 'out_file', reg_ventricles, 'postmat') # threshold WM mask and intersect with functional brain mask thr_WM_mask = pe.Node(fsl.ImageMaths(), name='threshold_WM_mask') thr_WM_mask.inputs.args = '-thr 0.25' workflow.connect(reg_WM_mask, 'out_file', thr_WM_mask, 'in_file') workflow.connect(erode_brain, 'out_file', thr_WM_mask, 'mask_file') # remove ventricles from WM mask exclude_ventricles = pe.Node(fsl.ImageMaths(), name='exclude_ventricles') workflow.connect(thr_WM_mask, 'out_file', exclude_ventricles, 'in_file') workflow.connect(reg_ventricles, 'out_file', exclude_ventricles, 'mask_file') # check that WM is collected from both hemispheres check_WM_bilat = pe.Node(interface=Function( input_names=['in_file'], output_names=['errors'], function=check_bilateralism), name='check_WM_bilateralism') workflow.connect(exclude_ventricles, 'out_file', check_WM_bilat, 'in_file') # extract WM values get_WM_noise = pe.Node(fsl.ImageMeants(), name='get_WM_noise') workflow.connect(skullstrip, 'out_file', get_WM_noise, 'in_file') workflow.connect(exclude_ventricles, 'out_file', get_WM_noise, 'mask') # compute WM noise derivatives deriv_WM = pe.Node(afni.OneDToolPy(), name='deriv_WM') deriv_WM.inputs.set_nruns = 1 deriv_WM.inputs.derivative = True if overwrite: deriv_WM.inputs.args = '-overwrite' deriv_WM.inputs.out_file = 'WM_derivatives.txt' workflow.connect(get_WM_noise, 'out_file', deriv_WM, 'in_file') # scale WM noise and get quadratures quadr_WM = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_WM') quadr_WM.inputs.multicol = False workflow.connect(get_WM_noise, 'out_file', quadr_WM, 'in_file') # scale WM noise derivatives and get quadratures quadr_WM_deriv = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_WM_deriv') quadr_WM_deriv.inputs.multicol = False workflow.connect(deriv_WM, 'out_file', quadr_WM_deriv, 'in_file') # ---------- global regression signals ---------------- if global_reg: # register anatomical whole brain mask to functional image space reg_glob_mask = pe.Node(fsl.preprocess.ApplyXFM(), name='register_global_mask') reg_glob_mask.inputs.apply_xfm = True reg_glob_mask.inputs.in_file = anat workflow.connect(tstat2, 'out_file', reg_glob_mask, 'reference') workflow.connect(invmat, 'out_file', reg_glob_mask, 'in_matrix_file') # threshold anatomical brain mask and intersect with functional brain mask thr_glob_mask = pe.Node(fsl.ImageMaths(), name='threshold_global_mask') thr_glob_mask.inputs.args = '-thr -0.1' workflow.connect(reg_glob_mask, 'out_file', thr_glob_mask, 'in_file') workflow.connect(erode_brain, 'out_file', thr_glob_mask, 'mask_file') # extract global signal values get_glob_noise = pe.Node(fsl.ImageMeants(), name='get_global_noise') workflow.connect(skullstrip, 'out_file', get_glob_noise, 'in_file') workflow.connect(thr_glob_mask, 'out_file', get_glob_noise, 'mask') # compute global noise derivative deriv_glob = pe.Node(afni.OneDToolPy(), name='deriv_global') deriv_glob.inputs.set_nruns = 1 deriv_glob.inputs.derivative = True if overwrite: deriv_glob.inputs.args = '-overwrite' deriv_glob.inputs.out_file = 'global_derivatives.txt' workflow.connect(get_glob_noise, 'out_file', deriv_glob, 'in_file') # scale global noise and get quadratures quadr_glob = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_glob') quadr_glob.inputs.multicol = False workflow.connect(get_glob_noise, 'out_file', quadr_glob, 'in_file') # scale global noise derivatives and get quadratures quadr_glob_deriv = pe.Node(interface=Function( input_names=['in_file', 'multicol'], output_names=['out_file', 'out_quadr_file'], function=scale_and_quadrature), name='quadr_glob_deriv') quadr_glob_deriv.inputs.multicol = False workflow.connect(deriv_glob, 'out_file', quadr_glob_deriv, 'in_file') # ---------- regression matrix ---------- # create bandpass regressors, can not be easily implemented to workflow get_bandpass = pe.Node(interface=Function( input_names=['minf', 'maxf', 'example_file', 'tr'], output_names=['out_tuple'], function=bandpass), name='bandpass_regressors') get_bandpass.inputs.minf = myminf get_bandpass.inputs.maxf = mymaxf get_bandpass.inputs.tr = mytr workflow.connect(norm_motion, 'out_file', get_bandpass, 'example_file') # concatenate regressor time series cat_reg_name = 'cat_regressors' if global_reg: cat_reg_name = cat_reg_name + '_global' cat_reg = pe.Node(interface=Function( input_names=[ 'mot', 'motd', 'motq', 'motdq', 'CSF', 'CSFd', 'CSFq', 'CSFdq', 'WM', 'WMd', 'WMq', 'WMdq', 'include_global', 'glob', 'globd', 'globq', 'globdq' ], output_names=['reg_file_args'], function=concatenate_regressors), name=cat_reg_name) cat_reg.inputs.include_global = global_reg workflow.connect(quadr_motion, 'out_file', cat_reg, 'mot') workflow.connect(quadr_motion_deriv, 'out_file', cat_reg, 'motd') workflow.connect(quadr_motion, 'out_quadr_file', cat_reg, 'motq') workflow.connect(quadr_motion_deriv, 'out_quadr_file', cat_reg, 'motdq') workflow.connect(quadr_CSF, 'out_file', cat_reg, 'CSF') workflow.connect(quadr_CSF_deriv, 'out_file', cat_reg, 'CSFd') workflow.connect(quadr_CSF, 'out_quadr_file', cat_reg, 'CSFq') workflow.connect(quadr_CSF_deriv, 'out_quadr_file', cat_reg, 'CSFdq') workflow.connect(quadr_WM, 'out_file', cat_reg, 'WM') workflow.connect(quadr_WM_deriv, 'out_file', cat_reg, 'WMd') workflow.connect(quadr_WM, 'out_quadr_file', cat_reg, 'WMq') workflow.connect(quadr_WM_deriv, 'out_quadr_file', cat_reg, 'WMdq') if global_reg: workflow.connect(quadr_glob, 'out_file', cat_reg, 'glob') workflow.connect(quadr_glob_deriv, 'out_file', cat_reg, 'globd') workflow.connect(quadr_glob, 'out_quadr_file', cat_reg, 'globq') workflow.connect(quadr_glob_deriv, 'out_quadr_file', cat_reg, 'globdq') else: cat_reg.inputs.glob = None cat_reg.inputs.globd = None cat_reg.inputs.globq = None cat_reg.inputs.globdq = None # create regression matrix deconvolve_name = 'deconvolve' if global_reg: deconvolve_name = deconvolve_name + '_global' deconvolve = pe.Node(afni.Deconvolve(), name=deconvolve_name) deconvolve.inputs.polort = 2 # contstant, linear and quadratic background signals removed deconvolve.inputs.fout = True deconvolve.inputs.tout = True deconvolve.inputs.x1D_stop = True deconvolve.inputs.force_TR = mytr workflow.connect(cat_reg, 'reg_file_args', deconvolve, 'args') workflow.connect(get_bandpass, 'out_tuple', deconvolve, 'ortvec') workflow.connect([(skullstrip, deconvolve, [(('out_file', str2list), 'in_files')])]) # regress out motion and other unwanted signals tproject_name = 'tproject' if global_reg: tproject_name = tproject_name + '_global' tproject = pe.Node(afni.TProject(outputtype="NIFTI_GZ"), name=tproject_name) tproject.inputs.TR = mytr tproject.inputs.polort = 0 # use matrix created with 3dDeconvolve, higher order polynomials not needed tproject.inputs.cenmode = 'NTRP' # interpolate removed time points workflow.connect(get_censor, 'out_file', tproject, 'censor') workflow.connect(skullstrip, 'out_file', tproject, 'in_file') workflow.connect(automask, 'out_file', tproject, 'mask') workflow.connect(deconvolve, 'x1D', tproject, 'ort') # Transform all images warpall_name = 'warpall' if global_reg: warpall_name = warpall_name + '_global' warpall = pe.Node(interface=fsl.ApplyWarp(), name=warpall_name) warpall.inputs.ref_file = MNI_brain warpall.inputs.field_file = anat2MNI_fieldwarp workflow.connect(mean2anat, 'out_matrix_file', warpall, 'premat') workflow.connect(tproject, 'out_file', warpall, 'in_file') workflow.connect(warpall, 'out_file', outputnode, 'result_func') # Run workflow workflow.write_graph() workflow.run() print "FUNCTIONAL PREPROCESSING DONE! Results in ", results_path + subj + '/' + s except: print "Error with patient: ", subj traceback.print_exc()
mul_by_scaling_factor = Node(fsl.BinaryMaths(), name='multiply_by_scaling_factor') mul_by_scaling_factor.inputs.operation = 'mul' mul_by_scaling_factor.inputs.operand_value = scale_factor mul_by_scaling_factor.inputs.out_file = 'multiplied_by_scaling_factor.nii.gz' # ============================================================================================================================ # divide by mean image div_by_mean_img = Node(fsl.BinaryMaths(), name='div_by_mean_img') div_by_mean_img.inputs.operation = 'div' div_by_mean_img.inputs.out_file = 'divided_by_mean_img.nii.gz' # ============================================================================================================================ # fslmeants to get the timesereis get_percent_change_timeseries = Node(fsl.ImageMeants(), name='get_percent_change_timeseries') get_percent_change_timeseries.inputs.out_file = 'percent_change_timeseries.txt' # ============================================================================================================================ stimulation_1st_level_percent_change.connect([ (infosource, selectfiles, [('subject_id', 'subject_id'), ('session_id', 'session_id'), ('frequency_id', 'frequency_id')]), (selectfiles, get_filtered_mean, [('preproc_img', 'in_file')]), (selectfiles, merge_transforms, [('tem2anat', 'in1')]), (selectfiles, merge_transforms, [('ant2func', 'in2')]), (selectfiles, transform_hpc_mask, [('bold_brain', 'reference_image')]), (merge_transforms, transform_hpc_mask, [('out', 'transforms')]), (selectfiles, mul_by_scaling_factor, [('preproc_img', 'in_file')]),
def main(derivatives, ds): func_template = { 'func': op.join( derivatives, ds, 'fmriprep', 'sub-{subject}', 'func', 'sub-{subject}_task-randomdotmotion_run-*_space-T1w_desc-preproc_bold.nii.gz' ), 'boldref': op.join( derivatives, ds, 'fmriprep', 'sub-{subject}', 'func', 'sub-{subject}_task-randomdotmotion_run-*_space-T1w_boldref.nii.gz' ), } if ds == 'ds-01': mask_fn = 'sub-{subject}_space-FLASH_desc-{mask}_space-T1w.nii.gz' subjects = ['{:02d}'.format(si) for si in range(1, 20)] elif ds == 'ds-02': mask_fn = 'sub-{subject}_desc-{mask}_mask.nii.gz' subjects = ['{:02d}'.format(si) for si in range(1, 16)] subjects.pop(3) subjects.pop(0) mask_template = { 'mask': op.join(derivatives, ds, 'conjunct_masks', 'sub-{subject}', 'anat', mask_fn) } wf = pe.Workflow(name='get_tsnr_{}'.format(ds), base_dir='/tmp/workflow_folders') identity = pe.Node(niu.IdentityInterface(fields=['subject']), name='identity') identity.iterables = [('subject', subjects)] func_selector = pe.Node(nio.SelectFiles(func_template), name='func_selector') func_selector.inputs.subject = '01' mask_identity = pe.Node(niu.IdentityInterface(fields=['mask']), name='mask_identity') mask_identity.iterables = [('mask', ['stnl', 'stnr'])] mask_selector = pe.Node(nio.SelectFiles(mask_template), name='mask_selector') wf.connect(identity, 'subject', mask_selector, 'subject') wf.connect(mask_identity, 'mask', mask_selector, 'mask') tsnr = pe.MapNode(TSNR(regress_poly=2), iterfield=['in_file'], name='tsnr') wf.connect(identity, 'subject', func_selector, 'subject') wf.connect(func_selector, 'func', tsnr, 'in_file') def resample_to_img(source_file, target_file): import os.path as op from nilearn import image from nipype.utils.filemanip import split_filename _, fn, ext = split_filename(source_file) new_fn = op.abspath('{}_resampled{}'.format(fn, ext)) im = image.resample_to_img(source_file, target_file, interpolation='nearest') im.to_filename(new_fn) return new_fn resampler = pe.Node(niu.Function( function=resample_to_img, input_names=['source_file', 'target_file'], output_names=['resampled_file']), name='resampler') wf.connect(mask_selector, 'mask', resampler, 'source_file') wf.connect(func_selector, 'boldref', resampler, 'target_file') extractor = pe.MapNode(fsl.ImageMeants(), iterfield=['in_file'], name='extractor') wf.connect(resampler, 'resampled_file', extractor, 'mask') wf.connect(tsnr, 'tsnr_file', extractor, 'in_file') ds_tsnrmaps = pe.MapNode(bids.DerivativesDataSink(base_directory=op.join( derivatives, ds), suffix='tsnr', out_path_base='tsnr'), iterfield=['source_file', 'in_file'], name='datasink_tsnrmaps') wf.connect(func_selector, 'func', ds_tsnrmaps, 'source_file') wf.connect(tsnr, 'tsnr_file', ds_tsnrmaps, 'in_file') ds_values_stn = pe.MapNode(bids.DerivativesDataSink(base_directory=op.join( derivatives, ds), suffix='tsnr', out_path_base='tsnr'), iterfield=['source_file', 'in_file'], name='ds_values_stnr') wf.connect(func_selector, 'func', ds_values_stn, 'source_file') wf.connect(extractor, 'out_file', ds_values_stn, 'in_file') wf.connect(mask_identity, 'mask', ds_values_stn, 'desc') wf.run(plugin='MultiProc', plugin_args={'n_procs': 6})
interpolation = 'BSpline', invert_transform_flags = [True], terminal_output = 'file'), name='applyTransInvWM') createWMmask = pe.Node(fsl.Threshold( thresh=WMthresh, output_type='NIFTI_GZ'), name='createWMmask') createCSFmask = pe.Node(fsl.Threshold( thresh=CSFthresh, output_type='NIFTI_GZ'), name='createCSFmask') WMmeanTS = pe.Node(fsl.ImageMeants(), name='WMmeanTS') CSFmeanTS = pe.Node(fsl.ImageMeants(), name='CSFmeanTS') # Create regressor file (concatenate regressors to make a matrix) def create_Regressor(motionMatrix,outlierMatrix,CSFinput,WMinput): import pandas as pd import os df_motion = [] df_outlier = [] df_CSF = [] df_WM = [] df_concat = [] df_motion = pd.read_table(motionMatrix,sep=' ',engine='python')
""" applyReg2CSFmask = pe.Node(interface=fsl.ApplyXfm(apply_xfm=True), name='applyreg2csfmask') """ Threshold CSF segmentation mask from .90 to 1 """ threshCSFseg = pe.Node( interface=fsl.ImageMaths(op_string=' -thr .90 -uthr 1 -bin '), name='threshcsfsegmask') """ Extract CSF timeseries """ avgCSF = pe.Node(interface=fsl.ImageMeants(), name='extractcsfts') def pickfirst(files): return files[0] """ Create the workflow """ csffilter = pe.Workflow(name='csffilter') csffilter.connect([ (extract_ref, motion_correct, [('roi_file', 'ref_file')]), (extract_ref, refskullstrip, [('roi_file', 'in_file')]), (nosestrip, skullstrip, [('out_file', 'in_file')]),
def timecourse2png(qcname, tag="", type=TsPlotType.ALL, SinkDir=".", QCDIR="QC"): import os import nipype import nipype.pipeline as pe import nipype.interfaces.utility as utility import nipype.interfaces.fsl as fsl import nipype.interfaces.io as io QCDir = os.path.abspath(globals._SinkDir_ + "/" + globals._QCDir_) if not os.path.exists(QCDir): os.makedirs(QCDir) if tag: tag = "_" + tag # Basic interface class generates identity mappings inputspec = pe.Node( utility.IdentityInterface(fields=['func', 'mask', 'x', 'y', 'z']), name='inputspec') if type == TsPlotType.VOX: voxroi = pe.MapNode(fsl.ImageMaths(), iterfield=['in_file'], name='voxroi') #TODO add voxel coordinates # TODO test def setInputs(x, y, z): return '-roi '\ + str(x) + ' 1 '\ + str(y) + ' 1 '\ + str(z) + ' 1 0 -1 -bin' voxroi_args = pe.Node(Function(input_names=['x', 'y', 'z'], output_names=['args'], function=setInputs), name="voxroi_args") elif type == TsPlotType.ALL: voxroi = pe.MapNode(fsl.ImageMaths(op_string='-bin'), iterfield=['in_file'], name='voxroi') # elif type == TsPloType.ROI: nothing to do here in this case, just connect it meants = pe.MapNode(fsl.ImageMeants(), iterfield=['in_file', 'mask'], name='meants') plottimeser = pe.MapNode(fsl.PlotTimeSeries(), iterfield=['in_file'], name='plottimeser') # Save outputs which are important ds_qc = pe.Node(interface=io.DataSink(), name='ds_qc') ds_qc.inputs.base_directory = QCDir ds_qc.inputs.regexp_substitutions = [("(\/)[^\/]*$", tag + ".png")] # Create a workflow analysisflow = nipype.Workflow(name=qcname + tag + '_qc') if type == TsPlotType.VOX: analysisflow.connect(inputspec, 'func', voxroi, 'in_file') analysisflow.connect(inputspec, 'x', voxroi_args, 'x') analysisflow.connect(inputspec, 'y', voxroi_args, 'y') analysisflow.connect(inputspec, 'z', voxroi_args, 'z') analysisflow.connect(voxroi_args, 'args', voxroi, 'args') analysisflow.connect(voxroi, 'out_file', meants, 'mask') elif type == TsPlotType.ALL: analysisflow.connect(inputspec, 'func', voxroi, 'in_file') analysisflow.connect(voxroi, 'out_file', meants, 'mask') elif type == TsPlotType.ROI: analysisflow.connect(inputspec, 'mask', meants, 'mask') analysisflow.connect(inputspec, 'func', meants, 'in_file') analysisflow.connect(meants, 'out_file', plottimeser, 'in_file') analysisflow.connect(plottimeser, 'out_file', ds_qc, qcname) return analysisflow