############################################################################### # # DATA SINK NODE # ############################################################################### from nipype.interfaces.io import DataSink datasink = Node(interface=DataSink(), name='datasink') datasink.inputs.base_directory = opap('/tmp/sinks') featreg_merge.connect( merge, 'merged_file', datasink, ds.inputs.subject_id + '/' + ds.inputs.hand + '_Hand/mvpa' ) ############################################################################### # # BASE_DIR, GRAPH, AND RUN # ############################################################################### featreg_merge.base_dir = '/tmp/working_dir' featreg_merge.write_graph("graph.dot") # Uncomment the last line to run workflow. # featreg_merge.run()
def main(paths, options_binary_string, ANAT, num_proc=7): json_path = paths[0] base_directory = paths[1] motion_correction_bet_directory = paths[2] parent_wf_directory = paths[3] # functional_connectivity_directory=paths[4] coreg_reg_directory = paths[5] atlas_resize_reg_directory = paths[6] subject_list = paths[7] datasink_name = paths[8] # fc_datasink_name=paths[9] atlasPath = paths[10] # brain_path=paths[11] # mask_path=paths[12] # atlas_path=paths[13] # tr_path=paths[14] # motion_params_path=paths[15] # func2std_mat_path=paths[16] # MNI3mm_path=paths[17] # demographics_file_path = paths[18] # phenotype_file_path = paths[19] data_directory = paths[20] number_of_subjects = len(subject_list) print("Working with ", number_of_subjects, " subjects.") # Create our own custom function - BIDSDataGrabber using a Function Interface. # In[858]: def get_nifti_filenames(subject_id, data_dir): # Remember that all the necesary imports need to be INSIDE the function for the Function Interface to work! from bids.grabbids import BIDSLayout layout = BIDSLayout(data_dir) run = 1 anat_file_path = [ f.filename for f in layout.get( subject=subject_id, type='T1w', extensions=['nii', 'nii.gz']) ] func_file_path = [ f.filename for f in layout.get(subject=subject_id, type='bold', run=run, extensions=['nii', 'nii.gz']) ] if len(anat_file_path) == 0: return None, func_file_path[0] # No Anatomical files present return anat_file_path[0], func_file_path[0] BIDSDataGrabber = Node(Function( function=get_nifti_filenames, input_names=['subject_id', 'data_dir'], output_names=['anat_file_path', 'func_file_path']), name='BIDSDataGrabber') # BIDSDataGrabber.iterables = [('subject_id',subject_list)] BIDSDataGrabber.inputs.data_dir = data_directory # ## Return TR def get_TR(in_file): from bids.grabbids import BIDSLayout data_directory = '/home1/varunk/data/ABIDE1/RawDataBIDs' layout = BIDSLayout(data_directory) metadata = layout.get_metadata(path=in_file) TR = metadata['RepetitionTime'] return TR # ---------------- Added new Node to return TR and other slice timing correction params------------------------------- def _getMetadata(in_file): from bids.grabbids import BIDSLayout import logging logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # create a file handler handler = logging.FileHandler('progress.log') # add the handlers to the logger logger.addHandler(handler) interleaved = True index_dir = False data_directory = '/home1/varunk/data/ABIDE1/RawDataBIDs' layout = BIDSLayout(data_directory) metadata = layout.get_metadata(path=in_file) print(metadata) logger.info('Extracting Meta Data of file: %s', in_file) try: tr = metadata['RepetitionTime'] except KeyError: print( 'Key RepetitionTime not found in task-rest_bold.json so using a default of 2.0 ' ) tr = 2 logger.error( 'Key RepetitionTime not found in task-rest_bold.json for file %s so using a default of 2.0 ', in_file) try: slice_order = metadata['SliceAcquisitionOrder'] except KeyError: print( 'Key SliceAcquisitionOrder not found in task-rest_bold.json so using a default of interleaved ascending ' ) logger.error( 'Key SliceAcquisitionOrder not found in task-rest_bold.json for file %s so using a default of interleaved ascending', in_file) return tr, index_dir, interleaved if slice_order.split(' ')[0] == 'Sequential': interleaved = False if slice_order.split(' ')[1] == 'Descending': index_dir = True return tr, index_dir, interleaved getMetadata = Node(Function( function=_getMetadata, input_names=['in_file'], output_names=['tr', 'index_dir', 'interleaved']), name='getMetadata') # ### Skipping 4 starting scans # Extract ROI for skipping first 4 scans of the functional data # > **Arguments:** # t_min: (corresponds to time dimension) Denotes the starting time of the inclusion # t_size: Denotes the number of scans to include # # The logic behind skipping 4 initial scans is to take scans after the subject has stabalized in the scanner. # In[863]: # ExtractROI - skip dummy scans extract = Node(ExtractROI(t_min=4, t_size=-1), output_type='NIFTI', name="extract") # ### Slice time correction # Created a Node that does slice time correction # > **Arguments**: # index_dir=False -> Slices were taken bottom to top i.e. in ascending order # interleaved=True means odd slices were acquired first and then even slices [or vice versa(Not sure)] slicetimer = Node(SliceTimer(output_type='NIFTI'), name="slicetimer") # ### Motion Correction # Motion correction is done using fsl's mcflirt. It alligns all the volumes of a functional scan to each other # MCFLIRT - motion correction mcflirt = Node(MCFLIRT(mean_vol=True, save_plots=True, output_type='NIFTI'), name="mcflirt") # Just a dummy node to transfer the output of Mcflirt to the next workflow. Needed if we didnt want to use the Mcflirt from_mcflirt = Node(IdentityInterface(fields=['in_file']), name="from_mcflirt") # ### Skull striping # I used fsl's BET # In[868]: skullStrip = Node(BET(mask=False, frac=0.3, robust=True), name='skullStrip') # # *Note*: Do not include special characters in ```name``` field above coz then wf.writegraph will cause issues # ## Resample # I needed to resample the anatomical file from 1mm to 3mm. Because registering a 1mm file was taking a huge amount of time. # # In[872]: # Resample - resample anatomy to 3x3x3 voxel resolution resample_mni = Node( Resample( voxel_size=(3, 3, 3), resample_mode='Cu', # cubic interpolation outputtype='NIFTI'), name="resample_mni") resample_anat = Node( Resample( voxel_size=(3, 3, 3), resample_mode='Cu', # cubic interpolation outputtype='NIFTI'), name="resample_anat") # In[873]: resample_atlas = Node( Resample( voxel_size=(3, 3, 3), resample_mode='NN', # cubic interpolation outputtype='NIFTI'), name="resample_atlas") resample_atlas.inputs.in_file = atlasPath # # Matrix operations # ### For concatenating the transformation matrices concat_xform = Node(ConvertXFM(concat_xfm=True), name='concat_xform') # Node to calculate the inverse of func2std matrix inv_mat = Node(ConvertXFM(invert_xfm=True), name='inv_mat') # ## Extracting the mean brain meanfunc = Node(interface=ImageMaths(op_string='-Tmean', suffix='_mean'), name='meanfunc') meanfuncmask = Node(interface=BET(mask=True, no_output=True, frac=0.3), name='meanfuncmask') # ## Apply Mask # Does BET (masking) on the whole func scan [Not using this, creates bug for join node] maskfunc = Node(interface=ImageMaths(suffix='_bet', op_string='-mas'), name='maskfunc') # Does BET (masking) on the mean func scan maskfunc4mean = Node(interface=ImageMaths(suffix='_bet', op_string='-mas'), name='maskfunc4mean') # ## Datasink # I needed to define the structure of what files are saved and where. # Create DataSink object dataSink = Node(DataSink(), name='datasink') # Name of the output folder dataSink.inputs.base_directory = opj(base_directory, datasink_name) # Define substitution strings so that the data is similar to BIDS substitutions = [ ('_subject_id_', 'sub-'), ('_resample_brain_flirt.nii_brain', ''), ('_roi_st_mcf_flirt.nii_brain_flirt', ''), ('task-rest_run-1_bold_roi_st_mcf.nii', 'motion_params'), ('T1w_resample_brain_flirt_sub-0050002_task-rest_run-1_bold_roi_st_mcf_mean_bet_flirt', 'fun2std') ] # Feed the substitution strings to the DataSink node dataSink.inputs.substitutions = substitutions # ### Apply Mask to functional data # Mean file of the motion corrected functional scan is sent to # skullStrip to get just the brain and the mask_image. # Mask_image is just a binary file (containing 1 where brain is present and 0 where it isn't). # After getting the mask_image form skullStrip, apply that mask to aligned # functional image to extract its brain and remove the skull # In[889]: # Function # in_file: The file on which you want to apply mask # in_file2 = mask_file: The mask you want to use. Make sure that mask_file has same size as in_file # out_file : Result of applying mask in in_file -> Gives the path of the output file def applyMask_func(in_file, in_file2): import numpy as np import nibabel as nib import os from os.path import join as opj # convert from unicode to string : u'/tmp/tmp8daO2Q/..' -> '/tmp/tmp8daO2Q/..' i.e. removes the prefix 'u' mask_file = in_file2 brain_data = nib.load(in_file) mask_data = nib.load(mask_file) brain = brain_data.get_data().astype('float32') mask = mask_data.get_data() # applying mask by multiplying elementwise to the binary mask if len(brain.shape) == 3: # Anat file brain = np.multiply(brain, mask) elif len(brain.shape) > 3: # Functional File for t in range(brain.shape[-1]): brain[:, :, :, t] = np.multiply(brain[:, :, :, t], mask) else: pass # Saving the brain file path = os.getcwd() in_file_split_list = in_file.split('/') in_file_name = in_file_split_list[-1] out_file = in_file_name + '_brain.nii.gz' # changing name brain_with_header = nib.Nifti1Image(brain, affine=brain_data.affine, header=brain_data.header) nib.save(brain_with_header, out_file) out_file = opj(path, out_file) out_file2 = in_file2 return out_file, out_file2 # #### Things learnt: # 1. I found out that whenever a node is being executed, it becomes the current directory and whatever file you create now, will be stored here. # 2. #from IPython.core.debugger import Tracer; Tracer()() # Debugger doesnt work in nipype # Wrap the above function inside a Node # In[890]: applyMask = Node(Function(function=applyMask_func, input_names=['in_file', 'in_file2'], output_names=['out_file', 'out_file2']), name='applyMask') # ### Some nodes needed for Co-registration and Normalization # Node for getting the xformation matrix func2anat_reg = Node(FLIRT(output_type='NIFTI'), name="func2anat_reg") # Node for applying xformation matrix to functional data func2std_xform = Node(FLIRT(output_type='NIFTI', apply_xfm=True), name="func2std_xform") # Node for applying xformation matrix to functional data std2func_xform = Node(FLIRT(output_type='NIFTI', apply_xfm=True, interp='nearestneighbour'), name="std2func_xform") # Node for Normalizing/Standardizing the anatomical and getting the xformation matrix anat2std_reg = Node(FLIRT(output_type='NIFTI'), name="anat2std_reg") # I wanted to use the MNI file as input to the workflow so I created an Identity # Node that reads the MNI file path and outputs the same MNI file path. # Then I connected this node to whereever it was needed. MNI152_2mm = Node(IdentityInterface(fields=['standard_file', 'mask_file']), name="MNI152_2mm") # Set the mask_file and standard_file input in the Node. This setting sets the input mask_file permanently. MNI152_2mm.inputs.mask_file = os.path.expandvars( '$FSLDIR/data/standard/MNI152_T1_2mm_brain_mask.nii.gz') MNI152_2mm.inputs.standard_file = os.path.expandvars( '$FSLDIR/data/standard/MNI152_T1_2mm_brain.nii.gz') # MNI152_2mm.inputs.mask_file = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain_mask.nii.gz' # MNI152_2mm.inputs.standard_file = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain.nii.gz' # ## Band Pass Filtering # Let's do a band pass filtering on the data using the code from https://neurostars.org/t/bandpass-filtering-different-outputs-from-fsl-and-nipype-custom-function/824/2 ### AFNI bandpass = Node(afni.Bandpass(highpass=0.008, lowpass=0.08, despike=False, no_detrend=True, notrans=True, outputtype='NIFTI_GZ'), name='bandpass') # ### Following is a Join Node that collects the preprocessed file paths and saves them in a file # In[902]: def save_file_list_function_in_brain(in_brain): import numpy as np import os from os.path import join as opj file_list = np.asarray(in_brain) print('######################## File List ######################: \n', file_list) np.save('brain_file_list', file_list) file_name = 'brain_file_list.npy' out_brain = opj(os.getcwd(), file_name) # path return out_brain def save_file_list_function_in_mask(in_mask): import numpy as np import os from os.path import join as opj file_list2 = np.asarray(in_mask) print('######################## File List ######################: \n', file_list2) np.save('mask_file_list', file_list2) file_name2 = 'mask_file_list.npy' out_mask = opj(os.getcwd(), file_name2) # path return out_mask def save_file_list_function_in_motion_params(in_motion_params): import numpy as np import os from os.path import join as opj file_list3 = np.asarray(in_motion_params) print('######################## File List ######################: \n', file_list3) np.save('motion_params_file_list', file_list3) file_name3 = 'motion_params_file_list.npy' out_motion_params = opj(os.getcwd(), file_name3) # path return out_motion_params def save_file_list_function_in_motion_outliers(in_motion_outliers): import numpy as np import os from os.path import join as opj file_list4 = np.asarray(in_motion_outliers) print('######################## File List ######################: \n', file_list4) np.save('motion_outliers_file_list', file_list4) file_name4 = 'motion_outliers_file_list.npy' out_motion_outliers = opj(os.getcwd(), file_name4) # path return out_motion_outliers def save_file_list_function_in_joint_xformation_matrix( in_joint_xformation_matrix): import numpy as np import os from os.path import join as opj file_list5 = np.asarray(in_joint_xformation_matrix) print('######################## File List ######################: \n', file_list5) np.save('joint_xformation_matrix_file_list', file_list5) file_name5 = 'joint_xformation_matrix_file_list.npy' out_joint_xformation_matrix = opj(os.getcwd(), file_name5) # path return out_joint_xformation_matrix def save_file_list_function_in_tr(in_tr): import numpy as np import os from os.path import join as opj tr_list = np.asarray(in_tr) print('######################## TR List ######################: \n', tr_list) np.save('tr_list', tr_list) file_name6 = 'tr_list.npy' out_tr = opj(os.getcwd(), file_name6) # path return out_tr def save_file_list_function_in_atlas(in_atlas): import numpy as np import os from os.path import join as opj file_list7 = np.asarray(in_atlas) print('######################## File List ######################: \n', file_list7) np.save('atlas_file_list', file_list7) file_name7 = 'atlas_file_list.npy' out_atlas = opj(os.getcwd(), file_name7) # path return out_atlas save_file_list_in_brain = JoinNode(Function( function=save_file_list_function_in_brain, input_names=['in_brain'], output_names=['out_brain']), joinsource="infosource", joinfield=['in_brain'], name="save_file_list_in_brain") save_file_list_in_mask = JoinNode(Function( function=save_file_list_function_in_mask, input_names=['in_mask'], output_names=['out_mask']), joinsource="infosource", joinfield=['in_mask'], name="save_file_list_in_mask") save_file_list_in_motion_outliers = JoinNode( Function(function=save_file_list_function_in_motion_outliers, input_names=['in_motion_outliers'], output_names=['out_motion_outliers']), joinsource="infosource", joinfield=['in_motion_outliers'], name="save_file_list_in_motion_outliers") save_file_list_in_motion_params = JoinNode( Function(function=save_file_list_function_in_motion_params, input_names=['in_motion_params'], output_names=['out_motion_params']), joinsource="infosource", joinfield=['in_motion_params'], name="save_file_list_in_motion_params") save_file_list_in_joint_xformation_matrix = JoinNode( Function(function=save_file_list_function_in_joint_xformation_matrix, input_names=['in_joint_xformation_matrix'], output_names=['out_joint_xformation_matrix']), joinsource="infosource", joinfield=['in_joint_xformation_matrix'], name="save_file_list_in_joint_xformation_matrix") save_file_list_in_tr = JoinNode(Function( function=save_file_list_function_in_tr, input_names=['in_tr'], output_names=['out_tr']), joinsource="infosource", joinfield=['in_tr'], name="save_file_list_in_tr") save_file_list_in_atlas = JoinNode(Function( function=save_file_list_function_in_atlas, input_names=['in_atlas'], output_names=['out_atlas']), joinsource="infosource", joinfield=['in_atlas'], name="save_file_list_in_atlas") # save_file_list = JoinNode(Function(function=save_file_list_function, input_names=['in_brain', 'in_mask', 'in_motion_params','in_motion_outliers','in_joint_xformation_matrix', 'in_tr', 'in_atlas'], # output_names=['out_brain','out_mask','out_motion_params','out_motion_outliers','out_joint_xformation_matrix','out_tr', 'out_atlas']), # joinsource="infosource", # joinfield=['in_brain', 'in_mask', 'in_motion_params','in_motion_outliers','in_joint_xformation_matrix','in_tr', 'in_atlas'], # name="save_file_list") # def save_file_list_function(in_brain, in_mask, in_motion_params, in_motion_outliers, in_joint_xformation_matrix, in_tr, in_atlas): # # Imports # import numpy as np # import os # from os.path import join as opj # # # file_list = np.asarray(in_brain) # print('######################## File List ######################: \n',file_list) # # np.save('brain_file_list',file_list) # file_name = 'brain_file_list.npy' # out_brain = opj(os.getcwd(),file_name) # path # # # file_list2 = np.asarray(in_mask) # print('######################## File List ######################: \n',file_list2) # # np.save('mask_file_list',file_list2) # file_name2 = 'mask_file_list.npy' # out_mask = opj(os.getcwd(),file_name2) # path # # # file_list3 = np.asarray(in_motion_params) # print('######################## File List ######################: \n',file_list3) # # np.save('motion_params_file_list',file_list3) # file_name3 = 'motion_params_file_list.npy' # out_motion_params = opj(os.getcwd(),file_name3) # path # # # file_list4 = np.asarray(in_motion_outliers) # print('######################## File List ######################: \n',file_list4) # # np.save('motion_outliers_file_list',file_list4) # file_name4 = 'motion_outliers_file_list.npy' # out_motion_outliers = opj(os.getcwd(),file_name4) # path # # # file_list5 = np.asarray(in_joint_xformation_matrix) # print('######################## File List ######################: \n',file_list5) # # np.save('joint_xformation_matrix_file_list',file_list5) # file_name5 = 'joint_xformation_matrix_file_list.npy' # out_joint_xformation_matrix = opj(os.getcwd(),file_name5) # path # # tr_list = np.asarray(in_tr) # print('######################## TR List ######################: \n',tr_list) # # np.save('tr_list',tr_list) # file_name6 = 'tr_list.npy' # out_tr = opj(os.getcwd(),file_name6) # path # # # file_list7 = np.asarray(in_atlas) # print('######################## File List ######################: \n',file_list7) # # np.save('atlas_file_list',file_list7) # file_name7 = 'atlas_file_list.npy' # out_atlas = opj(os.getcwd(),file_name7) # path # # # # # return out_brain, out_mask, out_motion_params, out_motion_outliers, out_joint_xformation_matrix, out_tr , out_atlas # # # # save_file_list = JoinNode(Function(function=save_file_list_function, input_names=['in_brain', 'in_mask', 'in_motion_params','in_motion_outliers','in_joint_xformation_matrix', 'in_tr', 'in_atlas'], # output_names=['out_brain','out_mask','out_motion_params','out_motion_outliers','out_joint_xformation_matrix','out_tr', 'out_atlas']), # joinsource="infosource", # joinfield=['in_brain', 'in_mask', 'in_motion_params','in_motion_outliers','in_joint_xformation_matrix','in_tr', 'in_atlas'], # name="save_file_list") # ### Motion outliers motionOutliers = Node(MotionOutliers(no_motion_correction=False, metric='fd', out_metric_plot='fd_plot.png', out_metric_values='fd_raw.txt'), name='motionOutliers') # ## Workflow for atlas registration from std to functional wf_atlas_resize_reg = Workflow(name=atlas_resize_reg_directory) wf_atlas_resize_reg.connect([ # Apply the inverse matrix to the 3mm Atlas to transform it to func space (maskfunc4mean, std2func_xform, [(('out_file', 'reference'))]), (resample_atlas, std2func_xform, [('out_file', 'in_file')]), # Now, applying the inverse matrix (inv_mat, std2func_xform, [('out_file', 'in_matrix_file')] ), # output: Atlas in func space (std2func_xform, save_file_list_in_atlas, [('out_file', 'in_atlas')]), # ---------------------------Save the required files -------------------------------------------- (save_file_list_in_motion_params, dataSink, [('out_motion_params', 'motion_params_paths.@out_motion_params')]), (save_file_list_in_motion_outliers, dataSink, [('out_motion_outliers', 'motion_outliers_paths.@out_motion_outliers') ]), (save_file_list_in_brain, dataSink, [('out_brain', 'preprocessed_brain_paths.@out_brain')]), (save_file_list_in_mask, dataSink, [('out_mask', 'preprocessed_mask_paths.@out_mask')]), (save_file_list_in_joint_xformation_matrix, dataSink, [('out_joint_xformation_matrix', 'joint_xformation_matrix_paths.@out_joint_xformation_matrix')]), (save_file_list_in_tr, dataSink, [('out_tr', 'tr_paths.@out_tr')]), (save_file_list_in_atlas, dataSink, [('out_atlas', 'atlas_paths.@out_atlas')]) ]) # In[909]: wf_coreg_reg = Workflow(name=coreg_reg_directory) # wf_coreg_reg.base_dir = base_directory # Dir where all the outputs will be stored(inside coregistrationPipeline folder). if ANAT == 1: wf_coreg_reg.connect(BIDSDataGrabber, 'anat_file_path', skullStrip, 'in_file') # Resampled the anat file to 3mm wf_coreg_reg.connect(skullStrip, 'out_file', resample_anat, 'in_file') wf_coreg_reg.connect( resample_anat, 'out_file', func2anat_reg, 'reference' ) # Make the resampled file as reference in func2anat_reg # Sec 1. The above 3 steps registers the mean image to resampled anat image and # calculates the xformation matrix .. I hope the xformation matrix will be saved wf_coreg_reg.connect(MNI152_2mm, 'standard_file', resample_mni, 'in_file') wf_coreg_reg.connect(resample_mni, 'out_file', anat2std_reg, 'reference') wf_coreg_reg.connect(resample_anat, 'out_file', anat2std_reg, 'in_file') # Calculates the Xformationmatrix from anat3mm to MNI 3mm # We can get those matrices by refering to func2anat_reg.outputs.out_matrix_file and similarly for anat2std_reg wf_coreg_reg.connect(func2anat_reg, 'out_matrix_file', concat_xform, 'in_file') wf_coreg_reg.connect(anat2std_reg, 'out_matrix_file', concat_xform, 'in_file2') wf_coreg_reg.connect(concat_xform, 'out_file', dataSink, 'tranformation_matrix_fun2std.@out_file') wf_coreg_reg.connect(concat_xform, 'out_file', save_file_list_in_joint_xformation_matrix, 'in_joint_xformation_matrix') # Now inverse the func2std MAT to std2func wf_coreg_reg.connect(concat_xform, 'out_file', wf_atlas_resize_reg, 'inv_mat.in_file') # ------------------------------------------------------------------------------------------------------------------------------ # Registration of Functional to MNI 3mm space w/o using anatomical if ANAT == 0: print('Not using Anatomical high resoulution files') wf_coreg_reg.connect(MNI152_2mm, 'standard_file', resample_mni, 'in_file') wf_coreg_reg.connect( resample_mni, 'out_file', func2anat_reg, 'reference' ) # Make the resampled file as reference in func2anat_reg wf_coreg_reg.connect(func2anat_reg, 'out_matrix_file', dataSink, 'tranformation_matrix_fun2std.@out_file') wf_coreg_reg.connect(func2anat_reg, 'out_matrix_file', save_file_list_in_joint_xformation_matrix, 'in_joint_xformation_matrix') # Now inverse the func2std MAT to std2func wf_coreg_reg.connect(func2anat_reg, 'out_matrix_file', wf_atlas_resize_reg, 'inv_mat.in_file') # ## Co-Registration, Normalization and Bandpass Workflow # 1. Co-registration means alligning the func to anat # 2. Normalization means aligning func/anat to standard # 3. Applied band pass filtering in range - highpass=0.008, lowpass=0.08 # In[910]: wf_motion_correction_bet = Workflow(name=motion_correction_bet_directory) # wf_motion_correction_bet.base_dir = base_directory wf_motion_correction_bet.connect([ (from_mcflirt, meanfunc, [('in_file', 'in_file')]), (meanfunc, meanfuncmask, [('out_file', 'in_file')]), (from_mcflirt, applyMask, [('in_file', 'in_file')]), # 1 (meanfuncmask, applyMask, [ ('mask_file', 'in_file2') ]), # 2 output: 1&2, BET on coregistered fmri scan (meanfunc, maskfunc4mean, [('out_file', 'in_file')]), # 3 (meanfuncmask, maskfunc4mean, [('mask_file', 'in_file2')]), # 4 output: 3&4, BET on mean func scan (applyMask, save_file_list_in_brain, [('out_file', 'in_brain')]), (applyMask, save_file_list_in_mask, [('out_file2', 'in_mask')]), (maskfunc4mean, wf_coreg_reg, [('out_file', 'func2anat_reg.in_file')]) ]) infosource = Node(IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = [('subject_id', subject_list)] # Create the workflow wf = Workflow(name=parent_wf_directory) # base_dir = opj(s,'result') wf.base_dir = base_directory # Dir where all the outputs will be stored(inside BETFlow folder). # wf.connect([ (infosource, BIDSDataGrabber, [('subject_id','subject_id')]), # (BIDSDataGrabber, extract, [('func_file_path','in_file')]), # # (BIDSDataGrabber,getMetadata, [('func_file_path','in_file')]), # # (getMetadata,slicetimer, [('tr','time_repetition')]), # # # (getMetadata,slicetimer, [('index_dir','index_dir')]), # # (getMetadata,slicetimer, [('interleaved','interleaved')]), # # (getMetadata,save_file_list_in_tr, [('tr','in_tr')]), # # (extract,slicetimer,[('roi_file','in_file')]), # # (slicetimer, mcflirt,[('slice_time_corrected_file','in_file')]) # (mcflirt,dataSink,[('par_file','motion_params.@par_file')]), # saves the motion parameters calculated before # # (mcflirt,save_file_list_in_motion_params,[('par_file','in_motion_params')]), # # (mcflirt,wf_motion_correction_bet,[('out_file','from_mcflirt.in_file')]) # ]) # # Run it in parallel # wf.run('MultiProc', plugin_args={'n_procs': num_proc}) # # # # # Visualize the detailed graph # # from IPython.display import Image # wf.write_graph(graph2use='flat', format='png', simple_form=True) # Options: # discard 4 Volumes (extract), slicetimer, mcflirt print('Preprocessing Options:') print('Skipping 4 dummy volumes - ', options_binary_string[0]) print('Slicetiming correction - ', options_binary_string[1]) print('Finding Motion Outliers - ', options_binary_string[2]) print('Doing Motion Correction - ', options_binary_string[3]) # ANAT = 0 nodes = [extract, slicetimer, motionOutliers, mcflirt] wf.connect(infosource, 'subject_id', BIDSDataGrabber, 'subject_id') wf.connect(BIDSDataGrabber, 'func_file_path', getMetadata, 'in_file') wf.connect(getMetadata, 'tr', save_file_list_in_tr, 'in_tr') old_node = BIDSDataGrabber old_node_output = 'func_file_path' for idx, include in enumerate(options_binary_string): if old_node == extract: old_node_output = 'roi_file' elif old_node == slicetimer: old_node_output = 'slice_time_corrected_file' # elif old_node == mcflirt: # old_node_output = 'out_file' if int(include): new_node = nodes[idx] if new_node == slicetimer: wf.connect(getMetadata, 'tr', slicetimer, 'time_repetition') wf.connect(getMetadata, 'index_dir', slicetimer, 'index_dir') wf.connect(getMetadata, 'interleaved', slicetimer, 'interleaved') new_node_input = 'in_file' elif new_node == extract: new_node_input = 'in_file' elif new_node == mcflirt: new_node_input = 'in_file' wf.connect(mcflirt, 'par_file', dataSink, 'motion_params.@par_file' ) # saves the motion parameters calculated before wf.connect(mcflirt, 'par_file', save_file_list_in_motion_params, 'in_motion_params') wf.connect(mcflirt, 'out_file', wf_motion_correction_bet, 'from_mcflirt.in_file') elif new_node == motionOutliers: wf.connect(meanfuncmask, 'mask_file', motionOutliers, 'mask') wf.connect(motionOutliers, 'out_file', dataSink, 'motionOutliers.@out_file') wf.connect(motionOutliers, 'out_metric_plot', dataSink, 'motionOutliers.@out_metric_plot') wf.connect(motionOutliers, 'out_metric_values', dataSink, 'motionOutliers.@out_metric_values') wf.connect(motionOutliers, 'out_file', save_file_list_in_motion_outliers, 'in_motion_outliers') new_node_input = 'in_file' wf.connect(old_node, old_node_output, new_node, new_node_input) continue wf.connect(old_node, old_node_output, new_node, new_node_input) old_node = new_node else: if idx == 3: # new_node = from_mcflirt # new_node_input = 'from_mcflirt.in_file' wf.connect(old_node, old_node_output, wf_motion_correction_bet, 'from_mcflirt.in_file') # old_node = new_node TEMP_DIR_FOR_STORAGE = opj(base_directory, 'crash_files') wf.config = {"execution": {"crashdump_dir": TEMP_DIR_FOR_STORAGE}} # Visualize the detailed graph # from IPython.display import Image wf.write_graph(graph2use='flat', format='png', simple_form=True) # Run it in parallel wf.run('MultiProc', plugin_args={'n_procs': num_proc})
datasink_masks, 'container' ) # Pick first file from out (or in) files. def pickfirst(files): if isinstance(files, list): return files[0] else: return files mvpa_preproc.connect( featreg_merge, ('splitnode.out_files', pickfirst), datasink_masks, 'mvpa' ) ############################################################################### # # BASE_DIR, GRAPH, AND RUN # ############################################################################### mvpa_preproc.base_dir = workflow_base_directory # mvpa_preproc.base_dir = \ # '/Users/AClab/Documents/mikbuch/Maestro_Project1/mvpa/preprocessing/' mvpa_preproc.write_graph("graph.dot") # Uncomment the last line to run workflow. # mvpa_preproc.run()
import nipype.interfaces.utility as util inputnode = Node( interface=util.IdentityInterface( fields=['roi'] ), name='inputspec' ) inputnode.iterables = ('roi', rois_filelist) import nipype.interfaces.fsl as fsl masknode = Node(fsl.maths.ApplyMask(), name='masknode') masknode.inputs.mask_file = mask_file apply_mask_multiple.connect( inputnode, 'roi', masknode, 'in_file', ) sinker = Node(nio.DataSink(), name='sinker') sinker.inputs.base_directory = opap(datasink_directory) sinker.inputs.parameterization = False sinker.inputs.substitutions = [('', ''), ('_masked', '')] apply_mask_multiple.connect( masknode, 'out_file', sinker, processed_masks_directory ) apply_mask_multiple.base_dir = workflow_base_directory apply_mask_multiple.run()
def _main(subject_list,vols,subid_vol_dict, number_of_skipped_volumes,brain_path,\ mask_path,\ atlas_path,\ tr_path,\ motion_params_path,\ func2std_mat_path,\ MNI3mm_path,\ base_directory,\ fc_datasink_name,\ motion_param_regression,\ band_pass_filtering,\ global_signal_regression,\ smoothing,\ volcorrect,\ num_proc,\ functional_connectivity_directory ): # ## Volume correction # * I have already extracted 4 volumes. # * Now extract 120 - 4 = 116 volumes from each subject # * So define vols = 114 # if number_of_skipped_volumes == None: number_of_skipped_volumes = 4 vols = vols - number_of_skipped_volumes def vol_correct(sub_id, subid_vol_dict, vols, number_of_skipped_volumes): sub_vols = subid_vol_dict[sub_id] - number_of_skipped_volumes if sub_vols > vols: t_min = sub_vols - vols elif sub_vols == vols: t_min = 0 else: raise Exception('Volumes of Sub ',sub_id,' less than desired!') return int(t_min) # In[491]: volCorrect = Node(Function(function=vol_correct, input_names=['sub_id','subid_vol_dict','vols','number_of_skipped_volumes'], output_names=['t_min']), name='volCorrect') volCorrect.inputs.subid_vol_dict = subid_vol_dict volCorrect.inputs.vols = vols volCorrect.inputs.number_of_skipped_volumes = number_of_skipped_volumes # ## Define a function to fetch the filenames of a particular subject ID def get_subject_filenames(subject_id,brain_path,mask_path,atlas_path,tr_path,motion_params_path,func2std_mat_path,MNI3mm_path): import re from itertools import zip_longest for brain,mask,atlas,tr,motion_param,func2std_mat in zip_longest(brain_path,mask_path,atlas_path,tr_path,motion_params_path,func2std_mat_path): #itertools helps to zip unequal save_file_list_in_mask # Source : https://stackoverflow.com/questions/11318977/zipping-unequal-lists-in-python-in-to-a-list-which-does-not-drop-any-element-fro print('*******************',brain,mask,atlas,tr,motion_param,func2std_mat) sub_id_extracted = re.search('.+_subject_id_(\d+)', brain).group(1) if str(subject_id) in brain: # print("Files for subject ",subject_id,brain,mask,atlas,tr,motion_param) return brain,mask,atlas,tr,motion_param,func2std_mat,MNI3mm_path print ('Unable to locate Subject: ',subject_id,'extracted: ',sub_id_extracted) # print ('Unable to locate Subject: ',subject_id) raise Exception('Unable to locate Subject: ',subject_id,'extracted: ',sub_id_extracted) # raise Exception('Unable to locate Subject: ',subject_id) return 0 # Make a node getSubjectFilenames = Node(Function(function=get_subject_filenames, input_names=['subject_id','brain_path','mask_path','atlas_path','tr_path','motion_params_path','func2std_mat_path','MNI3mm_path'], output_names=['brain','mask','atlas','tr','motion_param','func2std_mat', 'MNI3mm_path']), name='getSubjectFilenames') getSubjectFilenames.inputs.brain_path = brain_path getSubjectFilenames.inputs.mask_path = mask_path getSubjectFilenames.inputs.atlas_path = atlas_path getSubjectFilenames.inputs.tr_path = tr_path getSubjectFilenames.inputs.motion_params_path = motion_params_path getSubjectFilenames.inputs.func2std_mat_path = func2std_mat_path getSubjectFilenames.inputs.MNI3mm_path = MNI3mm_path infosource = Node(IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = [('subject_id',subject_list)] # ## Band Pass Filtering # Let's do a band pass filtering on the data using the # code from https://neurostars.org/t/bandpass-filtering-different-outputs-from-fsl-and-nipype-custom-function/824/2 ### AFNI bandpass = Node(afni.Bandpass(highpass=0.01, lowpass=0.1, despike=False, no_detrend=True, notrans=True, outputtype='NIFTI_GZ'),name='bandpass') # bandpass = Node(afni.Bandpass(highpass=0.001, lowpass=0.01, # despike=False, no_detrend=True, notrans=True, # tr=2.0,outputtype='NIFTI_GZ'),name='bandpass') # ## Highpass filtering # In[506]: """ Perform temporal highpass filtering on the data """ # https://afni.nimh.nih.gov/pub/dist/doc/program_help/3dBandpass.html # os.chdir('/home1/varunk/Autism-Connectome-Analysis-bids-related/') highpass = Node(afni.Bandpass(highpass=0.009, lowpass=99999, despike=False, no_detrend=True, notrans=True, outputtype='NIFTI_GZ'),name='highpass') # FSL bandpass/Highpass # highpass = Node(interface=ImageMaths(suffix='_tempfilt'), # iterfield=['in_file'], # name='highpass') # # highpass.inputs.op_string = '-bptf 27.77775001525879 -1' # 23.64 # 31.25 # ## Smoothing # ### Using 6mm fwhm # sigma = 6/2.3548 = 2.547987090198743 spatialSmooth = Node(interface=ImageMaths(op_string='-s 2.5479', suffix='_smoothed'), name='spatialSmooth') # ## Performs Gram Schmidt Process # https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process # In[509]: def orthogonalize(in_file, mask_file): import numpy as np import nibabel as nib import os from os.path import join as opj def gram_schmidt(voxel_time_series, mean_vector): numerator = np.dot(voxel_time_series,mean_vector) dinominator = np.dot(mean_vector,mean_vector) voxel_time_series_orthogonalized = voxel_time_series - (numerator/dinominator)*mean_vector # TO CONFIRM IF THE VECTORS ARE ORTHOGONAL # sum_dot_prod = np.sum(np.dot(voxel_time_series_orthogonalized,mean_vector)) # print('Sum of entries of orthogonalized vector = ',sum_dot_prod) return voxel_time_series_orthogonalized mask_data = nib.load(mask_file) mask = mask_data.get_data() brain_data = nib.load(in_file) brain = brain_data.get_data() x_dim, y_dim, z_dim, t_dim = brain_data.shape # Find mean brain mean_vector = np.zeros(t_dim) num_brain_voxels = 0 # Count the number of brain voxels for i in range(x_dim): for j in range(y_dim): for k in range(z_dim): if mask[i,j,k] == 1: mean_vector = mean_vector + brain[i,j,k,:] num_brain_voxels = num_brain_voxels + 1 mean_vector = mean_vector / num_brain_voxels # Orthogonalize for i in range(x_dim): for j in range(y_dim): for k in range(z_dim): if mask[i,j,k] == 1: brain[i,j,k,:] = gram_schmidt(brain[i,j,k,:], mean_vector) sub_id = in_file.split('/')[-1].split('.')[0].split('_')[0].split('-')[1] gsr_file_name = 'sub-' + sub_id + '_task-rest_run-1_bold.nii.gz' # gsr_file_name_nii = gsr_file_name + '.nii.gz' out_file = opj(os.getcwd(),gsr_file_name) # path brain_with_header = nib.Nifti1Image(brain, affine=brain_data.affine,header = brain_data.header) nib.save(brain_with_header,gsr_file_name) return out_file # In[510]: globalSignalRemoval = Node(Function(function=orthogonalize, input_names=['in_file','mask_file'], output_names=['out_file']), name='globalSignalRemoval' ) # globalSignalRemoval.inputs.mask_file = mask_file # globalSignalRemoval.iterables = [('in_file',file_paths)] # ## GLM for regression of motion parameters # In[511]: def calc_residuals(in_file, motion_file): """ Calculates residuals of nuisance regressors -motion parameters for every voxel for a subject using GLM. Parameters ---------- in_file : string Path of a subject's motion corrected nifti file. motion_par_file : string path of a subject's motion parameters Returns ------- out_file : string Path of residual file in nifti format """ import nibabel as nb import numpy as np import os from os.path import join as opj nii = nb.load(in_file) data = nii.get_data().astype(np.float32) global_mask = (data != 0).sum(-1) != 0 # Check and define regressors which are provided from files if motion_file is not None: motion = np.genfromtxt(motion_file) if motion.shape[0] != data.shape[3]: raise ValueError('Motion parameters {0} do not match data ' 'timepoints {1}'.format(motion.shape[0], data.shape[3])) if motion.size == 0: raise ValueError('Motion signal file {0} is ' 'empty'.format(motion_file)) # Calculate regressors regressor_map = {'constant' : np.ones((data.shape[3],1))} regressor_map['motion'] = motion X = np.zeros((data.shape[3], 1)) for rname, rval in regressor_map.items(): X = np.hstack((X, rval.reshape(rval.shape[0],-1))) X = X[:,1:] if np.isnan(X).any() or np.isnan(X).any(): raise ValueError('Regressor file contains NaN') Y = data[global_mask].T try: B = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y) except np.linalg.LinAlgError as e: if "Singular matrix" in e: raise Exception("Error details: {0}\n\nSingular matrix error: " "The nuisance regression configuration you " "selected may have been too stringent, and the " "regression could not be completed. Ensure your " "parameters are not too " "extreme.\n\n".format(e)) else: raise Exception("Error details: {0}\n\nSomething went wrong with " "nuisance regression.\n\n".format(e)) Y_res = Y - X.dot(B) data[global_mask] = Y_res.T img = nb.Nifti1Image(data, header=nii.get_header(), affine=nii.get_affine()) subject_name = in_file.split('/')[-1].split('.')[0] filename = subject_name + '_residual.nii.gz' out_file = os.path.join(os.getcwd(),filename ) img.to_filename(out_file) # alt to nib.save return out_file # In[512]: # Create a Node for above calc_residuals = Node(Function(function=calc_residuals, input_names=['in_file','motion_file'], output_names=['out_file']), name='calc_residuals') # ## Datasink # I needed to define the structure of what files are saved and where. # In[513]: # Create DataSink object dataSink = Node(DataSink(), name='datasink') # Name of the output folder dataSink.inputs.base_directory = opj(base_directory,fc_datasink_name) # To create the substitutions I looked the `datasink` folder where I was redirecting the output. I manually selected the part of file/folder name that I wanted to change and copied below to be substituted. # # In[514]: # Define substitution strings so that the data is similar to BIDS substitutions = [('_subject_id_', 'sub-')] # Feed the substitution strings to the DataSink node dataSink.inputs.substitutions = substitutions # ### Following is a Join Node that collects the preprocessed file paths and saves them in a file # In[516]: def save_file_list_function(in_fc_map_brain_file): # Imports import numpy as np import os from os.path import join as opj file_list = np.asarray(in_fc_map_brain_file) print('######################## File List ######################: \n',file_list) np.save('fc_map_brain_file_list',file_list) file_name = 'fc_map_brain_file_list.npy' out_fc_map_brain_file = opj(os.getcwd(),file_name) # path return out_fc_map_brain_file # In[517]: save_file_list = JoinNode(Function(function=save_file_list_function, input_names=['in_fc_map_brain_file'], output_names=['out_fc_map_brain_file']), joinsource="infosource", joinfield=['in_fc_map_brain_file'], name="save_file_list") # ## Create a FC node # # This node: # 1. Exracts the average time series of the brain ROI's using the atlas and stores # it as a matrix of size [ROIs x Volumes]. # 2. Extracts the Voxel time series and stores it in matrix of size [Voxels x Volumes] # # And save FC matrix files in shape of brains def pear_coff(in_file, atlas_file, mask_file): # code to find how many voxels are in the brain region using the mask # imports import numpy as np import nibabel as nib import os from os.path import join as opj mask_data = nib.load(mask_file) mask = mask_data.get_data() x_dim, y_dim, z_dim = mask_data.shape atlasPath = atlas_file # Read the atlas atlasObject = nib.load(atlasPath) atlas = atlasObject.get_data() num_ROIs = int((np.max(atlas) - np.min(atlas) )) # Read the brain in_file brain_data = nib.load(in_file) brain = brain_data.get_data() x_dim, y_dim, z_dim, num_volumes = brain.shape num_brain_voxels = 0 x_dim, y_dim, z_dim = mask_data.shape for i in range(x_dim): for j in range(y_dim): for k in range(z_dim): if mask[i,j,k] == 1: num_brain_voxels = num_brain_voxels + 1 # Initialize a matrix of ROI time series and voxel time series ROI_matrix = np.zeros((num_ROIs, num_volumes)) voxel_matrix = np.zeros((num_brain_voxels, num_volumes)) # Fill up the voxel_matrix voxel_counter = 0 for i in range(x_dim): for j in range(y_dim): for k in range(z_dim): if mask[i,j,k] == 1: voxel_matrix[voxel_counter,:] = brain[i,j,k,:] voxel_counter = voxel_counter + 1 # Fill up the ROI_matrix # Keep track of number of voxels per ROI as well by using an array - num_voxels_in_ROI[] num_voxels_in_ROI = np.zeros((num_ROIs,1)) # A column arrray containing number of voxels in each ROI for i in range(x_dim): for j in range(y_dim): for k in range(z_dim): label = int(atlas[i,j,k]) - 1 if label != -1: ROI_matrix[label,:] = np.add(ROI_matrix[label,:], brain[i,j,k,:]) num_voxels_in_ROI[label,0] = num_voxels_in_ROI[label,0] + 1 ROI_matrix = np.divide(ROI_matrix,num_voxels_in_ROI) # Check if divide is working correctly X, Y = ROI_matrix, voxel_matrix # Subtract mean from X and Y X = np.subtract(X, np.mean(X, axis=1, keepdims=True)) Y = np.subtract(Y, np.mean(Y, axis=1, keepdims=True)) temp1 = np.dot(X,Y.T) temp2 = np.sqrt(np.sum(np.multiply(X,X), axis=1, keepdims=True)) temp3 = np.sqrt(np.sum(np.multiply(Y,Y), axis=1, keepdims=True)) temp4 = np.dot(temp2,temp3.T) coff_matrix = np.divide(temp1, (temp4 + 1e-7)) # Check if any ROI is missing and replace the NAN values in coff_matrix by 0 if np.argwhere(np.isnan(coff_matrix)).shape[0] != 0: print("Some ROIs are not present. Replacing NAN in coff matrix by 0") np.nan_to_num(coff_matrix, copy=False) # TODO: when I have added 1e-7 in the dinominator, then why did I feel the need to replace NAN by zeros sub_id = in_file.split('/')[-1].split('.')[0].split('_')[0].split('-')[1] fc_file_name = sub_id + '_fc_map' print ("Pear Matrix calculated for subject: ",sub_id) roi_brain_matrix = coff_matrix brain_file = in_file x_dim, y_dim, z_dim, t_dim = brain.shape (brain_data.header).set_data_shape([x_dim,y_dim,z_dim,num_ROIs]) brain_roi_tensor = np.zeros((brain_data.header.get_data_shape())) print("Creating brain for Subject-",sub_id) for roi in range(num_ROIs): brain_voxel_counter = 0 for i in range(x_dim): for j in range(y_dim): for k in range(z_dim): if mask[i,j,k] == 1: brain_roi_tensor[i,j,k,roi] = roi_brain_matrix[roi,brain_voxel_counter] brain_voxel_counter = brain_voxel_counter + 1 assert (brain_voxel_counter == len(roi_brain_matrix[roi,:])) print("Created brain for Subject-",sub_id) path = os.getcwd() fc_file_name = fc_file_name + '.nii.gz' out_file = opj(path,fc_file_name) brain_with_header = nib.Nifti1Image(brain_roi_tensor, affine=brain_data.affine,header = brain_data.header) nib.save(brain_with_header,out_file) fc_map_brain_file = out_file return fc_map_brain_file # In[521]: # Again Create the Node and set default values to paths pearcoff = Node(Function(function=pear_coff, input_names=['in_file','atlas_file','mask_file'], output_names=['fc_map_brain_file']), name='pearcoff') # # IMPORTANT: # * The ROI 255 has been removed due to resampling. Therefore the FC maps will have nan at that row. So don't use that ROI :) # * I came to know coz I keep getting this error: RuntimeWarning: invalid value encountered in true_divide # * To debug it, I read the coff matrix and checked its diagnol to discover the nan value. # # # # ## Extract volumes # ExtractROI - For volCorrect extract = Node(ExtractROI(t_size=-1), output_type='NIFTI', name="extract") # ### Node for applying xformation matrix to functional data # # In[523]: func2std_xform = Node(FLIRT(output_type='NIFTI_GZ', apply_xfm=True), name="func2std_xform") # motion_param_regression = 1 # band_pass_filtering = 0 # global_signal_regression = 0 # smoothing = 1 # volcorrect = 1 if num_proc == None: num_proc = 7 combination = 'motionRegress' + str(int(motion_param_regression)) + \ 'global' + str(int(global_signal_regression)) + 'smoothing' + str(int(smoothing)) +\ 'filt' + str(int(band_pass_filtering)) print("Combination: ",combination) binary_string = str(int(motion_param_regression)) + str(int(global_signal_regression)) + \ str(int(smoothing)) + str(int(band_pass_filtering)) + str(int(volcorrect)) base_dir = opj(base_directory,functional_connectivity_directory) # wf = Workflow(name=functional_connectivity_directory) wf = Workflow(name=combination) wf.base_dir = base_dir # Dir where all the outputs will be stored. wf.connect(infosource ,'subject_id', getSubjectFilenames, 'subject_id') # ------- Dynamic Pipeline ------------------------ nodes = [ calc_residuals, globalSignalRemoval, spatialSmooth, bandpass, volCorrect] # from nipype.interfaces import fsl old_node = getSubjectFilenames old_node_output = 'brain' binary_string = binary_string+'0' # so that the loop runs one more time for idx, include in enumerate(binary_string): # 11111 # motion_param_regression # global_signal_regression # smoothing # band_pass_filtering # volcorrect if old_node == calc_residuals: old_node_output = 'out_file' elif old_node == extract : old_node_output = 'roi_file' elif old_node == globalSignalRemoval: old_node_output = 'out_file' elif old_node == bandpass: old_node_output = 'out_file' elif old_node == highpass: old_node_output = 'out_file' elif old_node == spatialSmooth: old_node_output = 'out_file' elif old_node == volCorrect: old_node_output = 'out_file' if int(include): # if old_node is None: # # wf.add_nodes([nodes[idx]]) # # else: new_node = nodes[idx] if new_node == calc_residuals: wf.connect([(getSubjectFilenames, calc_residuals, [('motion_param', 'motion_file')])]) new_node_input = 'in_file' elif new_node == extract : wf.connect([( volCorrect, extract, [('t_min','t_min')])]) new_node_input = 'in_file' elif new_node == globalSignalRemoval: wf.connect([(getSubjectFilenames, globalSignalRemoval, [('mask','mask_file')])]) new_node_input = 'in_file' elif new_node == bandpass: wf.connect([(getSubjectFilenames, bandpass, [('tr','tr')])]) new_node_input = 'in_file' elif new_node == highpass: wf.connect([(getSubjectFilenames, highpass, [('tr','tr')])]) #Commenting for FSL new_node_input = 'in_file' elif new_node == spatialSmooth: new_node_input = 'in_file' elif new_node == volCorrect: wf.connect([(infosource, volCorrect, [('subject_id','sub_id')])]) wf.connect([( volCorrect, extract, [('t_min','t_min')])]) new_node = extract new_node_input = 'in_file' wf.connect(old_node, old_node_output, new_node, new_node_input) old_node = new_node else: if idx == 3: # bandpas == 0 => Highpass new_node = highpass wf.connect([(getSubjectFilenames, highpass, [('tr','tr')])]) #Commenting for FSL new_node_input = 'in_file' wf.connect(old_node, old_node_output, new_node, new_node_input) old_node = new_node wf.connect(old_node, old_node_output, pearcoff, 'in_file') wf.connect(getSubjectFilenames,'atlas', pearcoff, 'atlas_file') wf.connect(getSubjectFilenames, 'mask', pearcoff, 'mask_file') wf.connect(pearcoff, 'fc_map_brain_file', func2std_xform ,'in_file') wf.connect(getSubjectFilenames,'func2std_mat', func2std_xform, 'in_matrix_file') wf.connect(getSubjectFilenames, 'MNI3mm_path', func2std_xform,'reference') folder_name = combination + '.@fc_map_brain_file' wf.connect(func2std_xform, 'out_file', save_file_list, 'in_fc_map_brain_file') wf.connect(save_file_list, 'out_fc_map_brain_file', dataSink,folder_name) TEMP_DIR_FOR_STORAGE = opj(base_directory,'crash_files') wf.config = {"execution": {"crashdump_dir": TEMP_DIR_FOR_STORAGE}} wf.write_graph(graph2use='flat', format='png') wf.run('MultiProc', plugin_args={'n_procs': num_proc})
inputsub, 'sub', add_two_strings_node, 'subject' ) flirt_apply_all_subs.connect( inputhand, 'hand', add_two_strings_node, 'hand' ) flirt_apply_all_subs.connect( add_two_strings_node, 'sub_hand_name', datasink, 'container' ) flirt_apply_all_subs.connect( flt, 'out_file', datasink, 'mvpa/ROIs' ) ############################################################################### # # BASE_DIR, GRAPH, AND RUN # ############################################################################### flirt_apply_all_subs.base_dir = '/tmp/working_dir' flirt_apply_all_subs.write_graph("graph.dot") # Uncomment the last line to run workflow. flirt_apply_all_subs.run()
feat_node.inputs.bet = True feat_node.inputs.prewhitening = False feat_node.inputs.motion_regression = False feat_node.inputs.thresholding = 'uncorrected' feat_node.inputs.hrf = 'doublegamma' feat_node.inputs.open_feat_html = False feat_node.inputs.highpass = 100 feat_node.inputs.contrasts = 'single-trial' meta_wf.connect(select_files, 'func', feat_node, 'func_file') meta_wf.connect(modelgen_wf, 'outputspec.session_info', feat_node, 'session_info') meta_wf.connect(input_node, 'sub_id', feat_node, 'output_dirname') meta_wf.connect(select_files, 'func_mask', feat_node, 'mask') run_feat_node = Node(FEAT(), name='run_feat') meta_wf.connect(feat_node, 'feat_dir', run_feat_node, 'fsf_file') datasink = Node(interface=DataSink(), name='datasink') datasink.inputs.parameterization = False datasink.inputs.base_directory = out_dir meta_wf.connect(feat_node, 'confound_file', datasink, 'confound_file') meta_wf.connect(feat_node, 'ev_files', datasink, 'ev_files') meta_wf.connect(run_feat_node, 'feat_dir', datasink, 'firstlevel_FEAT') meta_wf.connect(concat_iterables_node, 'out', datasink, 'container') meta_wf.base_dir = op.join(out_dir, 'workingdir') meta_wf.run(plugin='MultiProc', plugin_args={'n_procs': 8})
from nipype.workflows.fmri.fsl import create_featreg_preproc import nipype.interfaces.fsl as fsl from nipype.pipeline import Workflow, Node # get filelist from file nifti_filelist = open('nifti_filelist.txt').read().splitlines() featreg_merge = Workflow(name='featreg_merge') preproc = create_featreg_preproc(highpass=True, whichvol='mean') preproc.inputs.inputspec.func = nifti_filelist preproc.inputs.inputspec.fwhm = 0 preproc.inputs.inputspec.highpass = 128. / (2 * 2.5) # preproc.base_dir = '/tmp/pre/working_dir' # preproc.run() merge = Node(interface=fsl.utils.Merge(dimension='t', output_type='NIFTI_GZ', merged_file='merged.nii.gz'), name='merge') featreg_merge.connect(preproc, 'outputspec.highpassed_files', merge, 'in_files') # TODO: add: create directory if it doesn't exist featreg_merge.base_dir = '/tmp/working_dir' featreg_merge.write_graph("graph.dot") featreg_merge.run()