def make_neuromet1_workflow(self): # Infosource: Iterate through subject names infosource = Node(interface=IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = ('subject_id', self.subject_list) # unidensource, return for every subject uni and den unidensource = Node(interface=IdentityInterface(fields=['uniden']), name="unidensource") unidensource.iterables = ('uniden', ['UNI', 'DEN']) info = dict(t1=[['subject_id', 'subject_id', 'uniden']]) datasource = Node(interface=DataGrabber( infields=['subject_id', 'uniden'], outfields=['t1']), name='datasource') datasource.inputs.base_directory = self.w_dir datasource.inputs.template = '{prefix}%s/{prefix}%s.%s_mp2rage_orig.nii.gz'.format( prefix=self.subject_prefix) datasource.inputs.template_args = info datasource.inputs.sort_filelist = False sink = self.make_sink() segment = self.make_segment() mask = self.make_mask() neuromet = Workflow(name=self.subject_prefix, base_dir=self.temp_dir) neuromet.connect(infosource, 'subject_id', datasource, 'subject_id') neuromet.connect(unidensource, 'uniden', datasource, 'uniden') neuromet.connect(datasource, 't1', segment, 'ro.in_file') # neuromet.connect() neuromet.connect(segment, 'spm_tissues_split.gm', mask, 'sum_tissues1.in_file') neuromet.connect(segment, 'spm_tissues_split.wm', mask, 'sum_tissues1.operand_files') neuromet.connect(segment, 'spm_tissues_split.csf', mask, 'sum_tissues2.operand_files') neuromet.connect(segment, 'spm_tissues_split.gm', sink, '@gm') neuromet.connect(segment, 'spm_tissues_split.wm', sink, '@wm') neuromet.connect(segment, 'spm_tissues_split.csf', sink, '@csf') neuromet.connect(segment, 'seg.bias_corrected_images', sink, '@biascorr') # neuromet.connect(comb_imgs, 'uni_brain_den_surr_add.out_file', sink, '@img') neuromet.connect(mask, 'gen_mask.out_file', sink, '@mask') neuromet.connect(segment, 'ro.out_file', sink, '@ro') return neuromet
def create(self): #, **kwargs): """ Create the nodes and connections for the workflow """ # Preamble csvReader = CSVReader() csvReader.inputs.in_file = self.csv_file.default_value csvReader.inputs.header = self.hasHeader.default_value csvOut = csvReader.run() print("=" * 80) print(csvOut.outputs.__dict__) print("=" * 80) iters = {} label = list(csvOut.outputs.__dict__.keys())[0] result = eval("csvOut.outputs.{0}".format(label)) iters['tests'], iters['trains'] = subsample_crossValidationSet( result, self.sample_size.default_value) # Main event out_fields = ['T1', 'T2', 'Label', 'trainindex', 'testindex'] inputsND = Node(interface=IdentityInterface(fields=out_fields), run_without_submitting=True, name='inputs') inputsND.iterables = [('trainindex', iters['trains']), ('testindex', iters['tests'])] if not self.hasHeader.default_value: inputsND.inputs.T1 = csvOut.outputs.column_0 inputsND.inputs.Label = csvOut.outputs.column_1 inputsND.inputs.T2 = csvOut.outputs.column_2 else: inputsND.inputs.T1 = csvOut.outputs.__dict__['t1'] inputsND.inputs.Label = csvOut.outputs.__dict__['label'] inputsND.inputs.T2 = csvOut.outputs.__dict__['t2'] pass #TODO metaflow = Workflow(name='metaflow') metaflow.config['execution'] = { 'plugin': 'Linear', 'stop_on_first_crash': 'false', 'stop_on_first_rerun': 'false', # This stops at first attempt to rerun, before running, and before deleting previous results. 'hash_method': 'timestamp', 'single_thread_matlab': 'true', # Multi-core 2011a multi-core for matrix multiplication. 'remove_unnecessary_outputs': 'true', 'use_relative_paths': 'false', # relative paths should be on, require hash update when changed. 'remove_node_directories': 'false', # Experimental 'local_hash_check': 'false' } metaflow.add_nodes([inputsND]) """import pdb; pdb.set_trace()""" fusionflow = FusionLabelWorkflow() self.connect([ (metaflow, fusionflow, [('inputs.trainindex', 'trainT1s.index'), ('inputs.T1', 'trainT1s.inlist')]), (metaflow, fusionflow, [('inputs.trainindex', 'trainLabels.index'), ('inputs.Label', 'trainLabels.inlist')]), (metaflow, fusionflow, [('inputs.testindex', 'testT1s.index'), ('inputs.T1', 'testT1s.inlist')]) ])
def make_workflow(): flairs = [os.path.abspath(i) for i in glob.glob(args.flair)] weights = [os.path.abspath(i) for i in glob.glob(args.weights)] weights_source = Node(interface=IdentityInterface(fields=['weights']), name='weights_source') weights_source.inputs.weights = weights data_source = Node(IdentityInterface(fields=['flairs']), name='data_source') data_source.iterables = ('flairs', flairs) sink = Node(interface=DataSink(), name='sink') sink.inputs.base_directory = wmh_dir sink.inputs.substitutions = [ ('_flairs_', ''), ('_FLAIR.nii.gz/', '/'), ] sink.inputs.regexp_substitutions = [ ('\.\..*\.\.', ''), ] test_wf = ibbmTum_wf.get_test_wf(row_st=192, cols_st=192, thres_mask=10) wmh = Workflow(name='wmh', base_dir=wf_temp) wmh.connect(weights_source, 'weights', test_wf, 'inputspec.weights') wmh.connect(data_source, 'flairs', test_wf, 'inputspec.flair') wmh.connect(test_wf, 'outputspec.wmh_mask', sink, '@pred') return wmh
def test_nipype_srtm_zhou2003_roi(self): from temporalimage import Quantity from temporalimage.t4d import _csvwrite_frameTiming import pandas as pd from .generate_test_data import generate_fakeTAC_SRTM self.t, self.dt, self.TAC, self.refTAC = generate_fakeTAC_SRTM(BP=0.5, R1=0.7) frameStart = self.t - self.dt/2 frameEnd = self.t + self.dt/2 csvfilename = os.path.join(self.tmpdirname,'srtm_roi_timing.csv') _csvwrite_frameTiming(frameStart, frameEnd, csvfilename, time_unit='min') roiTACcsvfile = os.path.join(self.tmpdirname,'roi_tacs.csv') roiTACs = pd.DataFrame({'target': self.TAC, 'ref': self.refTAC}) roiTACs.T.to_csv(roiTACcsvfile, index_label='ROI') infosource = Node(IdentityInterface(fields=['in_file']), name="infosource") infosource.iterables = ('in_file', [roiTACcsvfile]) km = Node(KineticModelROI(model='SRTM_Zhou2003', #roiTACcsvFile=roiTACcsvfile, frameTimingFile=csvfilename, refRegion='ref', startActivity=self.startActivity, weights=self.weights), name="km") km_workflow = Workflow(name="km_workflow", base_dir=self.tmpdirname) km_workflow.connect([ (infosource, km, [('in_file', 'roiTACcsvFile')]) ]) km_workflow.run()
def create_workflow_allin_slices(name='motion_correction', iterfield=['in_file']): workflow = Workflow(name=name) inputs = Node(IdentityInterface(fields=[ 'subject_id', 'session_id', 'ref_func', 'ref_func_weights', 'funcs', 'funcs_masks', 'mc_method', ]), name='in') inputs.iterables = [ ('mc_method', ['afni:3dAllinSlices']) ] mc = MapNode( AFNIAllinSlices(), iterfield=iterfield, name='mc') workflow.connect( [(inputs, mc, [('funcs', 'in_file'), ('ref_func_weights', 'in_weight_file'), ('ref_func', 'ref_file'), ])]) return workflow
def make_infosource(self): # Infosource: Iterate through subject names infosource = Node(interface=IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = ('subject_id', self.subject_list) return infosource
def create(self): # , **kwargs): """ Create the nodes and connections for the workflow """ # Preamble csvReader = CSVReader() csvReader.inputs.in_file = self.csv_file.default_value csvReader.inputs.header = self.hasHeader.default_value csvOut = csvReader.run() print(("=" * 80)) print((csvOut.outputs.__dict__)) print(("=" * 80)) iters = OrderedDict() label = list(csvOut.outputs.__dict__.keys())[0] result = eval("csvOut.outputs.{0}".format(label)) iters['tests'], iters['trains'] = subsample_crossValidationSet(result, self.sample_size.default_value) # Main event out_fields = ['T1', 'T2', 'Label', 'trainindex', 'testindex'] inputsND = Node(interface=IdentityInterface(fields=out_fields), run_without_submitting=True, name='inputs') inputsND.iterables = [('trainindex', iters['trains']), ('testindex', iters['tests'])] if not self.hasHeader.default_value: inputsND.inputs.T1 = csvOut.outputs.column_0 inputsND.inputs.Label = csvOut.outputs.column_1 inputsND.inputs.T2 = csvOut.outputs.column_2 else: inputsND.inputs.T1 = csvOut.outputs.__dict__['t1'] inputsND.inputs.Label = csvOut.outputs.__dict__['label'] inputsND.inputs.T2 = csvOut.outputs.__dict__['t2'] pass # TODO metaflow = Workflow(name='metaflow') metaflow.config['execution'] = { 'plugin': 'Linear', 'stop_on_first_crash': 'false', 'stop_on_first_rerun': 'false', # This stops at first attempt to rerun, before running, and before deleting previous results. 'hash_method': 'timestamp', 'single_thread_matlab': 'true', # Multi-core 2011a multi-core for matrix multiplication. 'remove_unnecessary_outputs': 'true', 'use_relative_paths': 'false', # relative paths should be on, require hash update when changed. 'remove_node_directories': 'false', # Experimental 'local_hash_check': 'false' } metaflow.add_nodes([inputsND]) """import pdb; pdb.set_trace()""" fusionflow = FusionLabelWorkflow() self.connect( [(metaflow, fusionflow, [('inputs.trainindex', 'trainT1s.index'), ('inputs.T1', 'trainT1s.inlist')]), (metaflow, fusionflow, [('inputs.trainindex', 'trainLabels.index'), ('inputs.Label', 'trainLabels.inlist')]), (metaflow, fusionflow, [('inputs.testindex', 'testT1s.index'), ('inputs.T1', 'testT1s.inlist')]) ])
def create_conversion(name, subject, scans, working_dir, out_dir, folder, xnat_server, xnat_user, xnat_pass, project_id, exp_id): convert = Workflow(name=name) convert.base_dir = working_dir convert.config['execution'][ 'crashdump_dir'] = convert.base_dir + "/crash_files" # infosource to iterate over scans scan_infosource = Node( util.IdentityInterface(fields=['scan_key', 'scan_val']), name='scan_infosource') scan_infosource.iterables = [('scan_key', scans.keys()), ('scan_val', scans.values())] scan_infosource.synchronize = True # xnat source xnatsource = Node(nio.XNATSource( infields=['project_id', 'subject_id', 'exp_id', 'scan_id'], outfields=['dicom'], server=xnat_server, user=xnat_user, pwd=xnat_pass, cache_dir=working_dir), name='xnatsource') xnatsource.inputs.query_template = ( '/projects/%s/subjects/%s/experiments/%s/scans/%d/resources/DICOM/files' ) #files') xnatsource.inputs.query_template_args['dicom'] = [[ 'project_id', 'subject_id', 'exp_id', 'scan_id' ]] xnatsource.inputs.project_id = project_id xnatsource.inputs.subject_id = subject xnatsource.inputs.exp_id = exp_id convert.connect([(scan_infosource, xnatsource, [('scan_val', 'scan_id')])]) # workflow to convert dicoms dcmconvert = create_dcmconvert_pipeline() convert.connect([ (scan_infosource, dcmconvert, [('scan_key', 'inputnode.filename')]), (xnatsource, dcmconvert, [('dicom', 'inputnode.dicoms')]) ]) # xnat sink sink = Node(nio.DataSink(base_directory=out_dir, parameterization=False), name='sink') convert.connect([(dcmconvert, sink, [('outputnode.nifti', folder)])]) convert.run()
def create_conversion( name, subject, scans, working_dir, out_dir, folder, xnat_server, xnat_user, xnat_pass, project_id, exp_id ): convert = Workflow(name=name) convert.base_dir = working_dir convert.config["execution"]["crashdump_dir"] = convert.base_dir + "/crash_files" # infosource to iterate over scans scan_infosource = Node(util.IdentityInterface(fields=["scan_key", "scan_val"]), name="scan_infosource") scan_infosource.iterables = [("scan_key", scans.keys()), ("scan_val", scans.values())] scan_infosource.synchronize = True # xnat source xnatsource = Node( nio.XNATSource( infields=["project_id", "subject_id", "exp_id", "scan_id"], outfields=["dicom"], server=xnat_server, user=xnat_user, pwd=xnat_pass, cache_dir=working_dir, ), name="xnatsource", ) xnatsource.inputs.query_template = ( "/projects/%s/subjects/%s/experiments/%s/scans/%d/resources/DICOM/files" ) # files') xnatsource.inputs.query_template_args["dicom"] = [["project_id", "subject_id", "exp_id", "scan_id"]] xnatsource.inputs.project_id = project_id xnatsource.inputs.subject_id = subject xnatsource.inputs.exp_id = exp_id convert.connect([(scan_infosource, xnatsource, [("scan_val", "scan_id")])]) # workflow to convert dicoms dcmconvert = create_dcmconvert_pipeline() convert.connect( [ (scan_infosource, dcmconvert, [("scan_key", "inputnode.filename")]), (xnatsource, dcmconvert, [("dicom", "inputnode.dicoms")]), ] ) # xnat sink sink = Node(nio.DataSink(base_directory=out_dir, parameterization=False), name="sink") convert.connect([(dcmconvert, sink, [("outputnode.nifti", folder)])]) convert.run()
def results(cenc_participant_id, cenc_participant_dir, cenc_freesurfer_dir,cenc_results_dir, verbose): util.mkcd_dir( [ cenc_results_dir ], True) files_to_convert = [ os.path.join( cenc_freesurfer_dir, cenc_participant_id, 'mri', 'nu.mgz'), os.path.join( cenc_freesurfer_dir, cenc_participant_id, 'mri', 'aseg.mgz'), os.path.join( cenc_freesurfer_dir, cenc_participant_id, 'mri', 'brainmask.mgz'), os.path.join( cenc_freesurfer_dir, cenc_participant_id, 'mri', 'aparc.a2009s+aseg.mgz'), os.path.join( cenc_freesurfer_dir, cenc_participant_id, 'mri', 'wmparc.mgz') ] # Check if files exist print files_to_convert if util.check_files(files_to_convert, True) == False: sys.exit() # Create link to directory freesurfer_results_dir = os.path.abspath(os.path.join( cenc_participant_dir, 'freesurfer','results')) if not os.path.exists(freesurfer_results_dir): util.force_symbolic_link( os.path.join( cenc_freesurfer_dir, cenc_participant_id ), freesurfer_results_dir) # TODO use input node to run this instead of a loop mc = Node( fs.MRIConvert( out_type = 'niigz' ), name="mri_convert" ) mc.iterables = ( "in_file", files_to_convert ) reorient = Node( fsl.Reorient2Std(), name="reorient" ) workflow_convert = Workflow(name='cenc_freesurfer_nipype_workflow') workflow_convert.base_dir = cenc_results_dir workflow_convert.connect( [ (mc, reorient, [('out_file', 'in_file')] )] ) workflow_convert.run() # Create final brain mask. This takes forever. Speeding it up would be helpful. cenc.create_mask( os.path.join( cenc_results_dir, 'brainmask.nii.gz'), os.path.join( cenc_results_dir, 'aparc.a2009s+aseg.nii.gz'), os.path.join( cenc_results_dir, 'mask.nii.gz') )
def create(self): #, **kwargs): """ Create the nodes and connections for the workflow """ # Preamble csvReader = CSVReader() csvReader.inputs.in_file = self.csv_file.default_value csvReader.inputs.header = self.hasHeader.default_value csvOut = csvReader.run() iters = {} label = csvOut.outputs.__dict__.keys()[0] result = eval("csvOut.outputs.{0}".format(label)) iters['tests'], iters['samples'] = sample_test_lists( result, self.sample_size.default_value) # Main event out_fields = ['T1', 'T2', 'Label', 'sampleindex', 'testindex'] inputs = Node(interface=IdentityInterface(fields=out_fields), run_without_submitting=True, name='inputs') inputs.iterables = [('sampleindex', iters['samples']), ('testindex', iters['tests'])] if not self.hasHeader.default_value: inputs.inputs.T1 = csvOut.outputs.column_0 inputs.inputs.Label = csvOut.outputs.column_1 inputs.inputs.T2 = csvOut.outputs.column_2 else: pass #TODO metaflow = Workflow(name='metaflow') metaflow.add_nodes([inputs]) import pdb pdb.set_trace() fusionflow = FusionLabelWorkflow() self.connect([ (metaflow, fusionflow, [('inputs.sampleindex', 'sampleT1s.index'), ('inputs.T1', 'sampleT1s.inlist')]), (metaflow, fusionflow, [('inputs.sampleindex', 'sampleT2s.index'), ('inputs.T2', 'sampleT2s.inlist')]), (metaflow, fusionflow, [('inputs.sampleindex', 'sampleLabels.index'), ('inputs.Label', 'sampleLabels.inlist')]), (metaflow, fusionflow, [('inputs.testindex', 'testT1s.index'), ('inputs.T1', 'testT1s.inlist')]), (metaflow, fusionflow, [('inputs.testindex', 'testT2s.index'), ('inputs.T2', 'testT2s.inlist')]), (metaflow, fusionflow, [('inputs.testindex', 'testLabels.index'), ('inputs.Label', 'testLabels.inlist')]) ])
def test_nipype_srtm_zhou2003(self): infosource = Node(IdentityInterface(fields=['in_file']), name="infosource") infosource.iterables = ('in_file', [self.pet4D_file]) km = Node(KineticModel(model='SRTM_Zhou2003', #timeSeriesImgFile=self.pet4D_file, frameTimingFile=self.timing_file, refRegionMaskFile=self.refRegionMaskFile, startActivity=self.startActivity, weights=self.weights, fwhm=self.fwhm), name="km") km_workflow = Workflow(name="km_workflow", base_dir=self.tmpdirname) km_workflow.connect([ (infosource, km, [('in_file', 'timeSeriesImgFile')]) ]) km_workflow.run()
def builder(subject_id, subId, project_dir, data_dir, output_dir, output_final_dir, output_interm_dir, layout, anat=None, funcs=None, fmaps=None, task_name='', session=None, apply_trim=False, apply_dist_corr=False, apply_smooth=False, apply_filter=False, mni_template='2mm', apply_n4=True, ants_threads=8, readable_crash_files=False, write_logs=True): """ Core function that returns a workflow. See wfmaker for more details. Args: subject_id: name of subject folder for final outputted sub-folder name subId: abbreviate name of subject for intermediate outputted sub-folder name project_dir: full path to root of project data_dir: full path to raw data files output_dir: upper level output dir (others will be nested within this) output_final_dir: final preprocessed sub-dir name output_interm_dir: intermediate preprcess sub-dir name layout: BIDS layout instance """ ################## ### PATH SETUP ### ################## if session is not None: session = int(session) if session < 10: session = '0' + str(session) else: session = str(session) # Set MNI template MNItemplate = os.path.join(get_resource_path(), 'MNI152_T1_' + mni_template + '_brain.nii.gz') MNImask = os.path.join(get_resource_path(), 'MNI152_T1_' + mni_template + '_brain_mask.nii.gz') MNItemplatehasskull = os.path.join(get_resource_path(), 'MNI152_T1_' + mni_template + '.nii.gz') # Set ANTs files bet_ants_template = os.path.join(get_resource_path(), 'OASIS_template.nii.gz') bet_ants_prob_mask = os.path.join( get_resource_path(), 'OASIS_BrainCerebellumProbabilityMask.nii.gz') bet_ants_registration_mask = os.path.join( get_resource_path(), 'OASIS_BrainCerebellumRegistrationMask.nii.gz') ################################# ### NIPYPE IMPORTS AND CONFIG ### ################################# # Update nipype global config because workflow.config[] = ..., doesn't seem to work # Can't store nipype config/rc file in container anyway so set them globaly before importing and setting up workflow as suggested here: http://nipype.readthedocs.io/en/latest/users/config_file.html#config-file # Create subject's intermediate directory before configuring nipype and the workflow because that's where we'll save log files in addition to intermediate files if not os.path.exists(os.path.join(output_interm_dir, subId, 'logs')): os.makedirs(os.path.join(output_interm_dir, subId, 'logs')) log_dir = os.path.join(output_interm_dir, subId, 'logs') from nipype import config if readable_crash_files: cfg = dict(execution={'crashfile_format': 'txt'}) config.update_config(cfg) config.update_config({ 'logging': { 'log_directory': log_dir, 'log_to_file': write_logs }, 'execution': { 'crashdump_dir': log_dir } }) from nipype import logging logging.update_logging(config) # Now import everything else from nipype.interfaces.io import DataSink from nipype.interfaces.utility import Merge, IdentityInterface from nipype.pipeline.engine import Node, Workflow from nipype.interfaces.nipy.preprocess import ComputeMask from nipype.algorithms.rapidart import ArtifactDetect from nipype.interfaces.ants.segmentation import BrainExtraction, N4BiasFieldCorrection from nipype.interfaces.ants import Registration, ApplyTransforms from nipype.interfaces.fsl import MCFLIRT, TOPUP, ApplyTOPUP from nipype.interfaces.fsl.maths import MeanImage from nipype.interfaces.fsl import Merge as MERGE from nipype.interfaces.fsl.utils import Smooth from nipype.interfaces.nipy.preprocess import Trim from .interfaces import Plot_Coregistration_Montage, Plot_Quality_Control, Plot_Realignment_Parameters, Create_Covariates, Down_Sample_Precision, Create_Encoding_File, Filter_In_Mask ################## ### INPUT NODE ### ################## # Turn functional file list into interable Node func_scans = Node(IdentityInterface(fields=['scan']), name='func_scans') func_scans.iterables = ('scan', funcs) # Get TR for use in filtering below; we're assuming all BOLD runs have the same TR tr_length = layout.get_metadata(funcs[0])['RepetitionTime'] ##################################### ## TRIM ## ##################################### if apply_trim: trim = Node(Trim(), name='trim') trim.inputs.begin_index = apply_trim ##################################### ## DISTORTION CORRECTION ## ##################################### if apply_dist_corr: # Get fmap file locations fmaps = [ f.filename for f in layout.get( subject=subId, modality='fmap', extensions='.nii.gz') ] if not fmaps: raise IOError( "Distortion Correction requested but field map scans not found..." ) # Get fmap metadata totalReadoutTimes, measurements, fmap_pes = [], [], [] for i, fmap in enumerate(fmaps): # Grab total readout time for each fmap totalReadoutTimes.append( layout.get_metadata(fmap)['TotalReadoutTime']) # Grab measurements (for some reason pyBIDS doesn't grab dcm_meta... fields from side-car json file and json.load, doesn't either; so instead just read the header using nibabel to determine number of scans) measurements.append(nib.load(fmap).header['dim'][4]) # Get phase encoding direction fmap_pe = layout.get_metadata(fmap)["PhaseEncodingDirection"] fmap_pes.append(fmap_pe) encoding_file_writer = Node(interface=Create_Encoding_File(), name='create_encoding') encoding_file_writer.inputs.totalReadoutTimes = totalReadoutTimes encoding_file_writer.inputs.fmaps = fmaps encoding_file_writer.inputs.fmap_pes = fmap_pes encoding_file_writer.inputs.measurements = measurements encoding_file_writer.inputs.file_name = 'encoding_file.txt' merge_to_file_list = Node(interface=Merge(2), infields=['in1', 'in2'], name='merge_to_file_list') merge_to_file_list.inputs.in1 = fmaps[0] merge_to_file_list.inputs.in1 = fmaps[1] # Merge AP and PA distortion correction scans merger = Node(interface=MERGE(dimension='t'), name='merger') merger.inputs.output_type = 'NIFTI_GZ' merger.inputs.in_files = fmaps merger.inputs.merged_file = 'merged_epi.nii.gz' # Create distortion correction map topup = Node(interface=TOPUP(), name='topup') topup.inputs.output_type = 'NIFTI_GZ' # Apply distortion correction to other scans apply_topup = Node(interface=ApplyTOPUP(), name='apply_topup') apply_topup.inputs.output_type = 'NIFTI_GZ' apply_topup.inputs.method = 'jac' apply_topup.inputs.interp = 'spline' ################################### ### REALIGN ### ################################### realign_fsl = Node(MCFLIRT(), name="realign") realign_fsl.inputs.cost = 'mutualinfo' realign_fsl.inputs.mean_vol = True realign_fsl.inputs.output_type = 'NIFTI_GZ' realign_fsl.inputs.save_mats = True realign_fsl.inputs.save_rms = True realign_fsl.inputs.save_plots = True ################################### ### MEAN EPIs ### ################################### # For coregistration after realignment mean_epi = Node(MeanImage(), name='mean_epi') mean_epi.inputs.dimension = 'T' # For after normalization is done to plot checks mean_norm_epi = Node(MeanImage(), name='mean_norm_epi') mean_norm_epi.inputs.dimension = 'T' ################################### ### MASK, ART, COV CREATION ### ################################### compute_mask = Node(ComputeMask(), name='compute_mask') compute_mask.inputs.m = .05 art = Node(ArtifactDetect(), name='art') art.inputs.use_differences = [True, False] art.inputs.use_norm = True art.inputs.norm_threshold = 1 art.inputs.zintensity_threshold = 3 art.inputs.mask_type = 'file' art.inputs.parameter_source = 'FSL' make_cov = Node(Create_Covariates(), name='make_cov') ################################ ### N4 BIAS FIELD CORRECTION ### ################################ if apply_n4: n4_correction = Node(N4BiasFieldCorrection(), name='n4_correction') n4_correction.inputs.copy_header = True n4_correction.inputs.save_bias = False n4_correction.inputs.num_threads = ants_threads n4_correction.inputs.input_image = anat ################################### ### BRAIN EXTRACTION ### ################################### brain_extraction_ants = Node(BrainExtraction(), name='brain_extraction') brain_extraction_ants.inputs.dimension = 3 brain_extraction_ants.inputs.use_floatingpoint_precision = 1 brain_extraction_ants.inputs.num_threads = ants_threads brain_extraction_ants.inputs.brain_probability_mask = bet_ants_prob_mask brain_extraction_ants.inputs.keep_temporary_files = 1 brain_extraction_ants.inputs.brain_template = bet_ants_template brain_extraction_ants.inputs.extraction_registration_mask = bet_ants_registration_mask brain_extraction_ants.inputs.out_prefix = 'bet' ################################### ### COREGISTRATION ### ################################### coregistration = Node(Registration(), name='coregistration') coregistration.inputs.float = False coregistration.inputs.output_transform_prefix = "meanEpi2highres" coregistration.inputs.transforms = ['Rigid'] coregistration.inputs.transform_parameters = [(0.1, ), (0.1, )] coregistration.inputs.number_of_iterations = [[1000, 500, 250, 100]] coregistration.inputs.dimension = 3 coregistration.inputs.num_threads = ants_threads coregistration.inputs.write_composite_transform = True coregistration.inputs.collapse_output_transforms = True coregistration.inputs.metric = ['MI'] coregistration.inputs.metric_weight = [1] coregistration.inputs.radius_or_number_of_bins = [32] coregistration.inputs.sampling_strategy = ['Regular'] coregistration.inputs.sampling_percentage = [0.25] coregistration.inputs.convergence_threshold = [1e-08] coregistration.inputs.convergence_window_size = [10] coregistration.inputs.smoothing_sigmas = [[3, 2, 1, 0]] coregistration.inputs.sigma_units = ['mm'] coregistration.inputs.shrink_factors = [[4, 3, 2, 1]] coregistration.inputs.use_estimate_learning_rate_once = [True] coregistration.inputs.use_histogram_matching = [False] coregistration.inputs.initial_moving_transform_com = True coregistration.inputs.output_warped_image = True coregistration.inputs.winsorize_lower_quantile = 0.01 coregistration.inputs.winsorize_upper_quantile = 0.99 ################################### ### NORMALIZATION ### ################################### # Settings Explanations # Only a few key settings are worth adjusting and most others relate to how ANTs optimizer starts or iterates and won't make a ton of difference # Brian Avants referred to these settings as the last "best tested" when he was aligning fMRI data: https://github.com/ANTsX/ANTsRCore/blob/master/R/antsRegistration.R#L275 # Things that matter the most: # smoothing_sigmas: # how much gaussian smoothing to apply when performing registration, probably want the upper limit of this to match the resolution that the data is collected at e.g. 3mm # Old settings [[3,2,1,0]]*3 # shrink_factors # The coarseness with which to do registration # Old settings [[8,4,2,1]] * 3 # >= 8 may result is some problems causing big chunks of cortex with little fine grain spatial structure to be moved to other parts of cortex # Other settings # transform_parameters: # how much regularization to do for fitting that transformation # for syn this pertains to both the gradient regularization term, and the flow, and elastic terms. Leave the syn settings alone as they seem to be the most well tested across published data sets # radius_or_number_of_bins # This is the bin size for MI metrics and 32 is probably adequate for most use cases. Increasing this might increase precision (e.g. to 64) but takes exponentially longer # use_histogram_matching # Use image intensity distribution to guide registration # Leave it on for within modality registration (e.g. T1 -> MNI), but off for between modality registration (e.g. EPI -> T1) # convergence_threshold # threshold for optimizer # convergence_window_size # how many samples should optimizer average to compute threshold? # sampling_strategy # what strategy should ANTs use to initialize the transform. Regular here refers to approximately random sampling around the center of the image mass normalization = Node(Registration(), name='normalization') normalization.inputs.float = False normalization.inputs.collapse_output_transforms = True normalization.inputs.convergence_threshold = [1e-06] normalization.inputs.convergence_window_size = [10] normalization.inputs.dimension = 3 normalization.inputs.fixed_image = MNItemplate normalization.inputs.initial_moving_transform_com = True normalization.inputs.metric = ['MI', 'MI', 'CC'] normalization.inputs.metric_weight = [1.0] * 3 normalization.inputs.number_of_iterations = [[1000, 500, 250, 100], [1000, 500, 250, 100], [100, 70, 50, 20]] normalization.inputs.num_threads = ants_threads normalization.inputs.output_transform_prefix = 'anat2template' normalization.inputs.output_inverse_warped_image = True normalization.inputs.output_warped_image = True normalization.inputs.radius_or_number_of_bins = [32, 32, 4] normalization.inputs.sampling_percentage = [0.25, 0.25, 1] normalization.inputs.sampling_strategy = ['Regular', 'Regular', 'None'] normalization.inputs.shrink_factors = [[8, 4, 2, 1]] * 3 normalization.inputs.sigma_units = ['vox'] * 3 normalization.inputs.smoothing_sigmas = [[3, 2, 1, 0]] * 3 normalization.inputs.transforms = ['Rigid', 'Affine', 'SyN'] normalization.inputs.transform_parameters = [(0.1, ), (0.1, ), (0.1, 3.0, 0.0)] normalization.inputs.use_histogram_matching = True normalization.inputs.winsorize_lower_quantile = 0.005 normalization.inputs.winsorize_upper_quantile = 0.995 normalization.inputs.write_composite_transform = True # NEW SETTINGS (need to be adjusted; specifically shink_factors and smoothing_sigmas need to be the same length) # normalization = Node(Registration(), name='normalization') # normalization.inputs.float = False # normalization.inputs.collapse_output_transforms = True # normalization.inputs.convergence_threshold = [1e-06, 1e-06, 1e-07] # normalization.inputs.convergence_window_size = [10] # normalization.inputs.dimension = 3 # normalization.inputs.fixed_image = MNItemplate # normalization.inputs.initial_moving_transform_com = True # normalization.inputs.metric = ['MI', 'MI', 'CC'] # normalization.inputs.metric_weight = [1.0]*3 # normalization.inputs.number_of_iterations = [[1000, 500, 250, 100], # [1000, 500, 250, 100], # [100, 70, 50, 20]] # normalization.inputs.num_threads = ants_threads # normalization.inputs.output_transform_prefix = 'anat2template' # normalization.inputs.output_inverse_warped_image = True # normalization.inputs.output_warped_image = True # normalization.inputs.radius_or_number_of_bins = [32, 32, 4] # normalization.inputs.sampling_percentage = [0.25, 0.25, 1] # normalization.inputs.sampling_strategy = ['Regular', # 'Regular', # 'None'] # normalization.inputs.shrink_factors = [[4, 3, 2, 1]]*3 # normalization.inputs.sigma_units = ['vox']*3 # normalization.inputs.smoothing_sigmas = [[2, 1], [2, 1], [3, 2, 1, 0]] # normalization.inputs.transforms = ['Rigid', 'Affine', 'SyN'] # normalization.inputs.transform_parameters = [(0.1,), # (0.1,), # (0.1, 3.0, 0.0)] # normalization.inputs.use_histogram_matching = True # normalization.inputs.winsorize_lower_quantile = 0.005 # normalization.inputs.winsorize_upper_quantile = 0.995 # normalization.inputs.write_composite_transform = True ################################### ### APPLY TRANSFORMS AND SMOOTH ### ################################### merge_transforms = Node(Merge(2), iterfield=['in2'], name='merge_transforms') # Used for epi -> mni, via (coreg + norm) apply_transforms = Node(ApplyTransforms(), iterfield=['input_image'], name='apply_transforms') apply_transforms.inputs.input_image_type = 3 apply_transforms.inputs.float = False apply_transforms.inputs.num_threads = 12 apply_transforms.inputs.environ = {} apply_transforms.inputs.interpolation = 'BSpline' apply_transforms.inputs.invert_transform_flags = [False, False] apply_transforms.inputs.reference_image = MNItemplate # Used for t1 segmented -> mni, via (norm) apply_transform_seg = Node(ApplyTransforms(), name='apply_transform_seg') apply_transform_seg.inputs.input_image_type = 3 apply_transform_seg.inputs.float = False apply_transform_seg.inputs.num_threads = 12 apply_transform_seg.inputs.environ = {} apply_transform_seg.inputs.interpolation = 'MultiLabel' apply_transform_seg.inputs.invert_transform_flags = [False] apply_transform_seg.inputs.reference_image = MNItemplate ################################### ### PLOTS ### ################################### plot_realign = Node(Plot_Realignment_Parameters(), name="plot_realign") plot_qa = Node(Plot_Quality_Control(), name="plot_qa") plot_normalization_check = Node(Plot_Coregistration_Montage(), name="plot_normalization_check") plot_normalization_check.inputs.canonical_img = MNItemplatehasskull ############################################ ### FILTER, SMOOTH, DOWNSAMPLE PRECISION ### ############################################ # Use cosanlab_preproc for down sampling down_samp = Node(Down_Sample_Precision(), name="down_samp") # Use FSL for smoothing if apply_smooth: smooth = Node(Smooth(), name='smooth') if isinstance(apply_smooth, list): smooth.iterables = ("fwhm", apply_smooth) elif isinstance(apply_smooth, int) or isinstance(apply_smooth, float): smooth.inputs.fwhm = apply_smooth else: raise ValueError("apply_smooth must be a list or int/float") # Use cosanlab_preproc for low-pass filtering if apply_filter: lp_filter = Node(Filter_In_Mask(), name='lp_filter') lp_filter.inputs.mask = MNImask lp_filter.inputs.sampling_rate = tr_length lp_filter.inputs.high_pass_cutoff = 0 if isinstance(apply_filter, list): lp_filter.iterables = ("low_pass_cutoff", apply_filter) elif isinstance(apply_filter, int) or isinstance(apply_filter, float): lp_filter.inputs.low_pass_cutoff = apply_filter else: raise ValueError("apply_filter must be a list or int/float") ################### ### OUTPUT NODE ### ################### # Collect all final outputs in the output dir and get rid of file name additions datasink = Node(DataSink(), name='datasink') if session: datasink.inputs.base_directory = os.path.join(output_final_dir, subject_id) datasink.inputs.container = 'ses-' + session else: datasink.inputs.base_directory = output_final_dir datasink.inputs.container = subject_id # Remove substitutions data_dir_parts = data_dir.split('/')[1:] if session: prefix = ['_scan_'] + data_dir_parts + [subject_id] + [ 'ses-' + session ] + ['func'] else: prefix = ['_scan_'] + data_dir_parts + [subject_id] + ['func'] func_scan_names = [os.path.split(elem)[-1] for elem in funcs] to_replace = [] for elem in func_scan_names: bold_name = elem.split(subject_id + '_')[-1] bold_name = bold_name.split('.nii.gz')[0] to_replace.append(('..'.join(prefix + [elem]), bold_name)) datasink.inputs.substitutions = to_replace ##################### ### INIT WORKFLOW ### ##################### # If we have sessions provide the full path to the subject's intermediate directory # and only rely on workflow init to create the session container *within* that directory # Otherwise just point to the intermediate directory and let the workflow init create the subject container within the intermediate directory if session: workflow = Workflow(name='ses_' + session) workflow.base_dir = os.path.join(output_interm_dir, subId) else: workflow = Workflow(name=subId) workflow.base_dir = output_interm_dir ############################ ######### PART (1a) ######### # func -> discorr -> trim -> realign # OR # func -> trim -> realign # OR # func -> discorr -> realign # OR # func -> realign ############################ if apply_dist_corr: workflow.connect([(encoding_file_writer, topup, [('encoding_file', 'encoding_file')]), (encoding_file_writer, apply_topup, [('encoding_file', 'encoding_file')]), (merger, topup, [('merged_file', 'in_file')]), (func_scans, apply_topup, [('scan', 'in_files')]), (topup, apply_topup, [('out_fieldcoef', 'in_topup_fieldcoef'), ('out_movpar', 'in_topup_movpar')])]) if apply_trim: # Dist Corr + Trim workflow.connect([(apply_topup, trim, [('out_corrected', 'in_file') ]), (trim, realign_fsl, [('out_file', 'in_file')])]) else: # Dist Corr + No Trim workflow.connect([(apply_topup, realign_fsl, [('out_corrected', 'in_file')])]) else: if apply_trim: # No Dist Corr + Trim workflow.connect([(func_scans, trim, [('scan', 'in_file')]), (trim, realign_fsl, [('out_file', 'in_file')])]) else: # No Dist Corr + No Trim workflow.connect([ (func_scans, realign_fsl, [('scan', 'in_file')]), ]) ############################ ######### PART (1n) ######### # anat -> N4 -> bet # OR # anat -> bet ############################ if apply_n4: workflow.connect([(n4_correction, brain_extraction_ants, [('output_image', 'anatomical_image')])]) else: brain_extraction_ants.inputs.anatomical_image = anat ########################################## ############### PART (2) ################# # realign -> coreg -> mni (via t1) # t1 -> mni # covariate creation # plot creation ########################################### workflow.connect([ (realign_fsl, plot_realign, [('par_file', 'realignment_parameters')]), (realign_fsl, plot_qa, [('out_file', 'dat_img')]), (realign_fsl, art, [('out_file', 'realigned_files'), ('par_file', 'realignment_parameters')]), (realign_fsl, mean_epi, [('out_file', 'in_file')]), (realign_fsl, make_cov, [('par_file', 'realignment_parameters')]), (mean_epi, compute_mask, [('out_file', 'mean_volume')]), (compute_mask, art, [('brain_mask', 'mask_file')]), (art, make_cov, [('outlier_files', 'spike_id')]), (art, plot_realign, [('outlier_files', 'outliers')]), (plot_qa, make_cov, [('fd_outliers', 'fd_outliers')]), (brain_extraction_ants, coregistration, [('BrainExtractionBrain', 'fixed_image')]), (mean_epi, coregistration, [('out_file', 'moving_image')]), (brain_extraction_ants, normalization, [('BrainExtractionBrain', 'moving_image')]), (coregistration, merge_transforms, [('composite_transform', 'in2')]), (normalization, merge_transforms, [('composite_transform', 'in1')]), (merge_transforms, apply_transforms, [('out', 'transforms')]), (realign_fsl, apply_transforms, [('out_file', 'input_image')]), (apply_transforms, mean_norm_epi, [('output_image', 'in_file')]), (normalization, apply_transform_seg, [('composite_transform', 'transforms')]), (brain_extraction_ants, apply_transform_seg, [('BrainExtractionSegmentation', 'input_image')]), (mean_norm_epi, plot_normalization_check, [('out_file', 'wra_img')]) ]) ################################################## ################### PART (3) ##################### # epi (in mni) -> filter -> smooth -> down sample # OR # epi (in mni) -> filter -> down sample # OR # epi (in mni) -> smooth -> down sample # OR # epi (in mni) -> down sample ################################################### if apply_filter: workflow.connect([(apply_transforms, lp_filter, [('output_image', 'in_file')])]) if apply_smooth: # Filtering + Smoothing workflow.connect([(lp_filter, smooth, [('out_file', 'in_file')]), (smooth, down_samp, [('smoothed_file', 'in_file') ])]) else: # Filtering + No Smoothing workflow.connect([(lp_filter, down_samp, [('out_file', 'in_file')]) ]) else: if apply_smooth: # No Filtering + Smoothing workflow.connect([ (apply_transforms, smooth, [('output_image', 'in_file')]), (smooth, down_samp, [('smoothed_file', 'in_file')]) ]) else: # No Filtering + No Smoothing workflow.connect([(apply_transforms, down_samp, [('output_image', 'in_file')])]) ########################################## ############### PART (4) ################# # down sample -> save # plots -> save # covs -> save # t1 (in mni) -> save # t1 segmented masks (in mni) -> save # realignment parms -> save ########################################## workflow.connect([ (down_samp, datasink, [('out_file', 'functional.@down_samp')]), (plot_realign, datasink, [('plot', 'functional.@plot_realign')]), (plot_qa, datasink, [('plot', 'functional.@plot_qa')]), (plot_normalization_check, datasink, [('plot', 'functional.@plot_normalization')]), (make_cov, datasink, [('covariates', 'functional.@covariates')]), (normalization, datasink, [('warped_image', 'structural.@normanat')]), (apply_transform_seg, datasink, [('output_image', 'structural.@normanatseg')]), (realign_fsl, datasink, [('par_file', 'functional.@motionparams')]) ]) if not os.path.exists(os.path.join(output_dir, 'pipeline.png')): workflow.write_graph(dotfilename=os.path.join(output_dir, 'pipeline'), format='png') print(f"Creating workflow for subject: {subject_id}") if ants_threads != 8: print( f"ANTs will utilize the user-requested {ants_threads} threads for parallel processing." ) return workflow
# directories working_dir = '/home/julia/projects/real_data/working_dir/' data_dir = '/home/julia/projects/real_data/mouse_visual/%s/' % dataset out_dir = '/home/julia/projects/real_data/mouse_visual/%s/processed/func/' % dataset # main workflow preproc_func = Workflow(name='preproc_func') preproc_func.base_dir = working_dir preproc_func.config['execution'][ 'crashdump_dir'] = preproc_func.base_dir + "/crash_files" # iterate over scans scan_infosource = Node(util.IdentityInterface(fields=['scan']), name='scan_infosource') scan_infosource.iterables = [('scan', scans)] # iterate over recons recon_infosource = Node(util.IdentityInterface(fields=['recon']), name='recon_infosource') recon_infosource.iterables = [('recon', recons)] # select files templates = { 'func': 'processed/func/{scan}/data_{recon}.nii.gz', 'mask': 'processed/func/{scan}/func_mask.nii.gz', 'struct': 'processed/struct/struct_masked.nii.gz' } selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="selectfiles") preproc_func.connect([(recon_infosource, selectfiles, [('recon', 'recon')]),
no_runs = 3 proc_2nd_level = Workflow(name='proc_2nd_level') proc_2nd_level.base_dir = opj(experiment_dir, working_dir) #========================================================================================================================================================== # In[3]: #to prevent nipype from iterating over the anat image with each func run-, you need seperate #nodes to select the files #and this will solve the problem I have for almost 6 months #but notice that in the sessions, you have to iterate also over subject_id to get the {subject_id} var # Infosource - a function free node to iterate over the list of subject names infosource = Node(IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = [('subject_id', subject_list)] #========================================================================================================================================================== # In[4]: # sub-001_task-MGT_run--02_bold.nii.gz, sub-001_task-MGT_run--02_sbref.nii.gz #/preproc_img/run--04sub-119/smoothed_all_maths_filt_maths.nii.gz #functional run-s out_1st = '/home/in/aeed/poldrack_gabmling/output_MGT_poldrack_proc_1st_level' out_pre = '/home/in/aeed/poldrack_gabmling/output_MGT_poldrack_preproc_preproc' standard_brain = '/home/in/aeed/fsl/fsl/data/standard/MNI152_T1_1mm_brain.nii.gz' standard_mask = '/home/in/aeed/fsl/fsl/data/standard/MNI152_T1_1mm_brain_mask.nii.gz' templates = { 'anat_brain': '/home/in/aeed/poldrack_gabmling/workingdir_MGT_poldrack_preproc_preproc/preproc/_subject_id_{subject_id}/brain_extraction_anat/{subject_id}_T1w_brain.nii.gz',
def learning_prepare_data_wf(working_dir, ds_dir, template_lookup_dict, behav_file, qc_file, in_data_name_list, data_lookup_dict, use_n_procs, plugin_name): import os from nipype import config from nipype.pipeline.engine import Node, Workflow import nipype.interfaces.utility as util import nipype.interfaces.io as nio from prepare_data_utils import vectorize_and_aggregate from itertools import chain # ensure in_data_name_list is list of lists in_data_name_list = [i if type(i) == list else [i] for i in in_data_name_list] in_data_name_list_unique = list(set(chain.from_iterable(in_data_name_list))) ##################################### # GENERAL SETTINGS ##################################### wf = Workflow(name='learning_prepare_data_wf') wf.base_dir = os.path.join(working_dir) nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': False, 'remove_unnecessary_outputs': False, 'job_finished_timeout': 120, 'hash_method': 'timestamp'}) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash') ds = Node(nio.DataSink(), name='ds') ds.inputs.base_directory = os.path.join(ds_dir, 'group_learning_prepare_data') ds.inputs.regexp_substitutions = [ # ('subject_id_', ''), ('_parcellation_', ''), ('_bp_freqs_', 'bp_'), ('_extraction_method_', ''), ('_subject_id_[A0-9]*/', '') ] ds_X = Node(nio.DataSink(), name='ds_X') ds_X.inputs.base_directory = os.path.join(ds_dir, 'vectorized_aggregated_data') ds_pdf = Node(nio.DataSink(), name='ds_pdf') ds_pdf.inputs.base_directory = os.path.join(ds_dir, 'pdfs') ds_pdf.inputs.parameterization = False ##################################### # SET ITERATORS ##################################### # SUBJECTS ITERATOR in_data_name_infosource = Node(util.IdentityInterface(fields=['in_data_name']), name='in_data_name_infosource') in_data_name_infosource.iterables = ('in_data_name', in_data_name_list_unique) mulitmodal_in_data_name_infosource = Node(util.IdentityInterface(fields=['multimodal_in_data_name']), name='mulitmodal_in_data_name_infosource') mulitmodal_in_data_name_infosource.iterables = ('multimodal_in_data_name', in_data_name_list) ############################################################################################################### # GET SUBJECTS INFO # create subjects list based on selection criteria def create_df_fct(behav_file, qc_file): import pandas as pd import os df = pd.read_pickle(behav_file) qc = pd.read_pickle(qc_file) df_all = qc.join(df, how='inner') assert df_all.index.is_unique, 'duplicates in df index. fix before cont.' df_all_subjects_pickle_file = os.path.abspath('df_all.pkl') df_all.to_pickle(df_all_subjects_pickle_file) full_subjects_list = df_all.index.values return df_all_subjects_pickle_file, full_subjects_list create_df = Node(util.Function(input_names=['behav_file', 'qc_file'], output_names=['df_all_subjects_pickle_file', 'full_subjects_list'], function=create_df_fct), name='create_df') create_df.inputs.behav_file = behav_file create_df.inputs.qc_file = qc_file ############################################################################################################### # CREAE FILE LIST # of files that will be aggregted def create_file_list_fct(subjects_list, in_data_name, data_lookup_dict, template_lookup_dict): file_list = [] for s in subjects_list: file_list.append(data_lookup_dict[in_data_name]['path_str'].format(subject_id=s)) if 'matrix_name' in data_lookup_dict[in_data_name].keys(): matrix_name = data_lookup_dict[in_data_name]['matrix_name'] else: matrix_name = None if 'parcellation_path' in data_lookup_dict[in_data_name].keys(): parcellation_path = data_lookup_dict[in_data_name]['parcellation_path'] else: parcellation_path = None if 'fwhm' in data_lookup_dict[in_data_name].keys(): fwhm = data_lookup_dict[in_data_name]['fwhm'] if fwhm == 0: fwhm = None else: fwhm = None if 'mask_name' in data_lookup_dict[in_data_name].keys(): mask_path = template_lookup_dict[data_lookup_dict[in_data_name]['mask_name']] else: mask_path = None if 'use_diagonal' in data_lookup_dict[in_data_name].keys(): use_diagonal = data_lookup_dict[in_data_name]['use_diagonal'] else: use_diagonal = False if 'use_fishers_z' in data_lookup_dict[in_data_name].keys(): use_fishers_z = data_lookup_dict[in_data_name]['use_fishers_z'] else: use_fishers_z = False if 'df_col_names' in data_lookup_dict[in_data_name].keys(): df_col_names = data_lookup_dict[in_data_name]['df_col_names'] else: df_col_names = None return file_list, matrix_name, parcellation_path, fwhm, mask_path, use_diagonal, use_fishers_z, df_col_names create_file_list = Node(util.Function(input_names=['subjects_list', 'in_data_name', 'data_lookup_dict', 'template_lookup_dict', ], output_names=['file_list', 'matrix_name', 'parcellation_path', 'fwhm', 'mask_path', 'use_diagonal', 'use_fishers_z', 'df_col_names'], function=create_file_list_fct), name='create_file_list') wf.connect(create_df, 'full_subjects_list', create_file_list, 'subjects_list') wf.connect(in_data_name_infosource, 'in_data_name', create_file_list, 'in_data_name') create_file_list.inputs.data_lookup_dict = data_lookup_dict create_file_list.inputs.template_lookup_dict = template_lookup_dict ############################################################################################################### # VECTORIZE AND AGGREGATE SUBJECTS # stack single subject np arrays vertically vectorize_aggregate_subjects = Node(util.Function(input_names=['in_data_file_list', 'mask_file', 'matrix_name', 'parcellation_path', 'fwhm', 'use_diagonal', 'use_fishers_z', 'df_file', 'df_col_names'], output_names=['vectorized_aggregated_file', 'unimodal_backprojection_info_file'], function=vectorize_and_aggregate), name='vectorize_aggregate_subjects') wf.connect(create_file_list, 'file_list', vectorize_aggregate_subjects, 'in_data_file_list') wf.connect(create_file_list, 'mask_path', vectorize_aggregate_subjects, 'mask_file') wf.connect(create_file_list, 'matrix_name', vectorize_aggregate_subjects, 'matrix_name') wf.connect(create_file_list, 'parcellation_path', vectorize_aggregate_subjects, 'parcellation_path') wf.connect(create_file_list, 'fwhm', vectorize_aggregate_subjects, 'fwhm') wf.connect(create_file_list, 'use_diagonal', vectorize_aggregate_subjects, 'use_diagonal') wf.connect(create_file_list, 'use_fishers_z', vectorize_aggregate_subjects, 'use_fishers_z') wf.connect(create_df, 'df_all_subjects_pickle_file', vectorize_aggregate_subjects, 'df_file') wf.connect(create_file_list, 'df_col_names', vectorize_aggregate_subjects, 'df_col_names') wf.connect(create_df, 'df_all_subjects_pickle_file', ds_X, 'df_all_subjects_pickle_file') wf.connect(vectorize_aggregate_subjects, 'vectorized_aggregated_file', ds_X, 'X_file') wf.connect(vectorize_aggregate_subjects, 'unimodal_backprojection_info_file', ds_X, 'unimodal_backprojection_info_file') ##################################### # RUN WF ##################################### wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == 'CondorDAGMan': wf.run(plugin=plugin_name) if plugin_name == 'MultiProc': wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
def make_neuromet_fs_workflow(self): # Infosource: Iterate through subject names infosource = Node(interface=IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = ('subject_id', self.subject_list) mask_source = Node(interface=GetMaskValue(csv_file=self.mask_file), name='get_mask') split_sub_str = Node(Function(['subject_str'], ['subject_id', 'session_id'], self.split_subject_ses), name='split_sub_str') # Datasource: Build subjects' filenames from IDs info = dict(mask=[[ 'subject_id', 'session_id', 'anat', 'subject_id', 'session_id', 'mask', 'ro_brain_bin.nii.gz' ]], uni_bias_corr=[[ 'subject_id', 'session_id', 'anat', 'subject_id', 'session_id', 'UNI', 'ro_bfcorr.nii' ]], den_ro=[[ 'subject_id', 'session_id', 'anat', 'subject_id', 'session_id', 'UNIDEN', 'ro_bfcorr.nii' ]]) datasource = Node(interface=DataGrabber( infields=['subject_id', 'session_id', 'mask'], outfields=['mask', 'uni_bias_corr', 'den_ro']), name='datasource') datasource.inputs.base_directory = self.derivatives_dir datasource.inputs.template = 'sub-NeuroMET%s/ses-0%s/%s/sub-NeuroMET%s_ses-0%s_desc-%s_%s' datasource.inputs.template_args = info datasource.inputs.sort_filelist = False sink = self.make_sink() comb_imgs = self.make_comb_imgs() freesurfer = self.make_freesurfer() neuromet_fs = Workflow(name='NeuroMET', base_dir=self.temp_dir) neuromet_fs.connect(infosource, 'subject_id', split_sub_str, 'subject_str') neuromet_fs.connect(split_sub_str, 'subject_id', datasource, 'subject_id') neuromet_fs.connect(split_sub_str, 'session_id', datasource, 'session_id') neuromet_fs.connect(infosource, 'subject_id', mask_source, 'subject_id') neuromet_fs.connect(mask_source, 'mask_value', datasource, 'mask') neuromet_fs.connect(datasource, 'uni_bias_corr', comb_imgs, 'mask_uni_bias.in_file') neuromet_fs.connect(datasource, 'mask', comb_imgs, 'mask_uni_bias.mask_file') neuromet_fs.connect(datasource, 'den_ro', comb_imgs, 'uni_brain_den_surr_mas.in_file') neuromet_fs.connect(comb_imgs, 'uni_brain_den_surr_add.out_file', freesurfer, 'fs_recon1.T1_files') neuromet_fs.connect(datasource, 'mask', freesurfer, 'fs_mriconv.in_file') out_dir_source = Node(interface=IdentityInterface( fields=['out_dir'], mandatory_inputs=True), name='out_dir_source') out_dir_source.inputs.out_dir = self.bids_root make_list_str = Node(interface=Merge(2), name='make_list_of_paths') merge_strs = Node(interface=OsPathJoin(), name='merge_sub_id_dir') neuromet_fs.connect(comb_imgs, 'uni_brain_den_surr_add.out_file', sink, '@img') #neuromet_fs.connect(infosource, 'subject_id', copy_freesurfer_dir, 'sub_id') #neuromet_fs.connect(freesurfer, 'segment_hp.subjects_dir', copy_freesurfer_dir, 'in_dir') neuromet_fs.connect(freesurfer, 'segment_hp.subjects_dir', make_list_str, 'in1') neuromet_fs.connect(freesurfer, 'segment_hp.subject_id', make_list_str, 'in2') neuromet_fs.connect(make_list_str, 'out', merge_strs, 'str_list') neuromet_fs.connect(merge_strs, 'out_path', sink, '@recon_all') #neuromet_fs.connect(out_dir_source, 'out_dir', copy_freesurfer_dir, 'out_dir') #ToDo: # 04.12.2020 QDec + Adjust volumes. It hangs if qdec is in a workflow, works a single interface #neuromet_fs.connect(freesurfer, 'segment_hp.subject_id', qdec, 'devnull') #neuromet_fs.connect(datasource, 'base_directory', qdec, 'basedir') #neuromet_fs.connect(qdec, 'stats_directory', adj_vol, 'stats_directory') #neuromet_fs.connect(qdec, 'stats_directory', sink, '@stat_dir') #neuromet_fs.connect(adj_vol, 'adjusted_stats', sink, '@adj_stats') return neuromet_fs
def create_preproc_func_pipeline(data_dir=None, subject_id=None, task_list=None): ############################### ## Set up Nodes ############################### ds = Node(nio.DataGrabber(infields=['subject_id', 'task_id'], outfields=['func', 'struc']),name='datasource') ds.inputs.base_directory = os.path.abspath(data_dir + '/' + subject_id) ds.inputs.template = '*' ds.inputs.sort_filelist = True ds.inputs.template_args = {'func': [['task_id']], 'struc':[]} ds.inputs.field_template = {'func': 'Functional/Raw/%s/func.nii','struc': 'Structural/SPGR/spgr.nii'} ds.inputs.subject_id = subject_id ds.inputs.task_id = task_list ds.iterables = ('task_id',task_list) # ds.run().outputs #show datafiles # #Setup Data Sinker for writing output files # datasink = Node(nio.DataSink(), name='sinker') # datasink.inputs.base_directory = '/path/to/output' # workflow.connect(realigner, 'realignment_parameters', datasink, 'motion.@par') # datasink.inputs.substitutions = [('_variable', 'variable'),('file_subject_', '')] #Get Timing Acquisition for slice timing tr = 2 ta = Node(interface=util.Function(input_names=['tr', 'n_slices'], output_names=['ta'], function = get_ta), name="ta") ta.inputs.tr=tr #Slice Timing: sequential ascending slice_timing = Node(interface=spm.SliceTiming(), name="slice_timing") slice_timing.inputs.time_repetition = tr slice_timing.inputs.ref_slice = 1 #Realignment - 6 parameters - realign to first image of very first series. realign = Node(interface=spm.Realign(), name="realign") realign.inputs.register_to_mean = True #Plot Realignment plot_realign = Node(interface=PlotRealignmentParameters(), name="plot_realign") #Artifact Detection art = Node(interface=ra.ArtifactDetect(), name="art") art.inputs.use_differences = [True,False] art.inputs.use_norm = True art.inputs.norm_threshold = 1 art.inputs.zintensity_threshold = 3 art.inputs.mask_type = 'file' art.inputs.parameter_source = 'SPM' #Coregister - 12 parameters, cost function = 'nmi', fwhm 7, interpolate, don't mask #anatomical to functional mean across all available data. coregister = Node(interface=spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' # Segment structural, gray/white/csf,mni, segment = Node(interface=spm.Segment(), name="segment") segment.inputs.save_bias_corrected = True #Normalize - structural to MNI - then apply this to the coregistered functionals normalize = Node(interface=spm.Normalize(), name = "normalize") normalize.inputs.template = os.path.abspath(t1_template_file) #Plot normalization Check plot_normalization_check = Node(interface=Plot_Coregistration_Montage(), name="plot_normalization_check") plot_normalization_check.inputs.canonical_img = canonical_file #Create Mask compute_mask = Node(interface=ComputeMask(), name="compute_mask") #remove lower 5% of histogram of mean image compute_mask.inputs.m = .05 #Smooth #implicit masking (.im) = 0, dtype = 0 smooth = Node(interface=spm.Smooth(), name = "smooth") fwhmlist = [8] smooth.iterables = ('fwhm',fwhmlist) #Create Covariate matrix make_covariates = Node(interface=Create_Covariates(), name="make_covariates") ############################### ## Create Pipeline ############################### Preprocessed = Workflow(name="Preprocessed") Preprocessed.base_dir = os.path.abspath(data_dir + '/' + subject_id + '/Functional') Preprocessed.connect([(ds, ta, [(('func', get_n_slices), "n_slices")]), (ta, slice_timing, [("ta", "time_acquisition")]), (ds, slice_timing, [('func', 'in_files'), (('func', get_n_slices), "num_slices"), (('func', get_slice_order), "slice_order"), ]), (slice_timing, realign, [('timecorrected_files', 'in_files')]), (realign, compute_mask, [('mean_image','mean_volume')]), (realign,coregister, [('mean_image', 'target')]), (ds,coregister, [('struc', 'source')]), (coregister,segment, [('coregistered_source', 'data')]), (segment, normalize, [('transformation_mat','parameter_file'), ('bias_corrected_image', 'source'),]), (realign,normalize, [('realigned_files', 'apply_to_files'), (('realigned_files', get_vox_dims), 'write_voxel_sizes')]), (normalize, smooth, [('normalized_files', 'in_files')]), (compute_mask,art,[('brain_mask','mask_file')]), (realign,art,[('realignment_parameters','realignment_parameters')]), (realign,art,[('realigned_files','realigned_files')]), (realign,plot_realign, [('realignment_parameters', 'realignment_parameters')]), (normalize, plot_normalization_check, [('normalized_files', 'wra_img')]), (realign, make_covariates, [('realignment_parameters', 'realignment_parameters')]), (art, make_covariates, [('outlier_files', 'spike_id')]), ]) return Preprocessed
def run_workflow(session=None, csv_file=None): from nipype import config #config.enable_debug_mode() method = 'fs' # freesurfer's mri_convert is faster if method == 'fs': import nipype.interfaces.freesurfer as fs # freesurfer else: assert method == 'fsl' import nipype.interfaces.fsl as fsl # fsl # ------------------ Specify variables ds_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) data_dir = ds_root output_dir = 'derivatives/resampled-isotropic-06mm' working_dir = 'workingdirs' # ------------------ Input Files infosource = Node(IdentityInterface(fields=[ 'subject_id', 'session_id', 'datatype', ]), name="infosource") if csv_file is not None: # Read csv and use pandas to set-up image and ev-processing df = pd.read_csv(csv_file) # init lists sub_img = [] ses_img = [] dt_img = [] # fill lists to iterate mapnodes for index, row in df.iterrows(): for dt in row.datatype.strip("[]").split(" "): if dt in ['anat']: # only for anatomicals sub_img.append(row.subject) ses_img.append(row.session) dt_img.append(dt) # check if the file definitions are ok if len(dt_img) > 0: print('There are images to process. Will continue.') else: print('No images specified. Check your csv-file.') infosource.iterables = [('session_id', ses_img), ('subject_id', sub_img), ('datatype', dt_img)] infosource.synchronize = True else: print('No csv-file specified. Cannot continue.') # SelectFiles templates = { 'image': 'sub-{subject_id}/ses-{session_id}/{datatype}/' 'sub-{subject_id}_ses-{session_id}_*.nii.gz', } inputfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="input_files") # ------------------ Output Files # Datasink outputfiles = Node(nio.DataSink(base_directory=ds_root, container=output_dir, parameterization=True), name="output_files") # Use the following DataSink output substitutions outputfiles.inputs.substitutions = [ ('subject_id_', 'sub-'), ('session_id_', 'ses-'), # BIDS Extension Proposal: BEP003 ('_resample.nii.gz', '_res-06x06x06_preproc.nii.gz'), # remove subdirectories: ('resampled-isotropic-06mm/isoxfm-06mm', 'resampled-isotropic-06mm'), ('resampled-isotropic-06mm/mriconv-06mm', 'resampled-isotropic-06mm'), ] # Put result into a BIDS-like format outputfiles.inputs.regexp_substitutions = [ # this works only if datatype is specified in input (r'_datatype_([a-z]*)_ses-([a-zA-Z0-9]*)_sub-([a-zA-Z0-9]*)', r'sub-\3/ses-\2/\1'), (r'_fs_iso06mm[0-9]*/', r''), (r'/_ses-([a-zA-Z0-9]*)_sub-([a-zA-Z0-9]*)', r'/sub-\2/ses-\1/'), # stupid hacks for when datatype is not specified (r'//(sub-[^/]*_bold_res-.*)', r'/func/\1'), (r'//(sub-[^/]*_phasediff_res-.*.nii.gz)', r'/fmap/\1'), (r'//(sub-[^/]*_magnitude1_res-.*.nii.gz)', r'/fmap/\1'), (r'//(sub-[^/]*_epi_res-.*.nii.gz)', r'/fmap/\1'), (r'//(sub-[^/]*_T1w_res-.*.nii.gz)', r'/anat/\1'), (r'//(sub-[^/]*_T2w_res-.*.nii.gz)', r'/anat/\1'), (r'//(sub-[^/]*_dwi_res-.*.nii.gz)', r'/dwi/\1'), ] # -------------------------------------------- Create Pipeline isotropic_flow = Workflow(name='resample_isotropic06mm', base_dir=os.path.join(ds_root, working_dir)) isotropic_flow.connect([(infosource, inputfiles, [ ('subject_id', 'subject_id'), ('session_id', 'session_id'), ('datatype', 'datatype'), ])]) # --- Convert to 1m isotropic voxels if method == 'fs': fs_iso06mm = MapNode( fs.Resample( voxel_size=(0.6, 0.6, 0.6), # suffix is not accepted by fs.Resample # suffix='_res-1x1x1_preproc', # BIDS Extension Proposal: BEP003 ), name='fs_iso06mm', iterfield=['in_file'], ) isotropic_flow.connect(inputfiles, 'image', fs_iso06mm, 'in_file') isotropic_flow.connect(fs_iso06mm, 'resampled_file', outputfiles, 'mriconv-06mm') elif method == 'fsl': # in_file --> out_file isoxfm = Node(fsl.FLIRT(apply_isoxfm=0.6, ), name='isoxfm') isotropic_flow.connect(inputfiles, 'image', isoxfm, 'in_file') isotropic_flow.connect(inputfiles, 'image', isoxfm, 'reference') isotropic_flow.connect(isoxfm, 'out_file', outputfiles, 'isoxfm-06mm') isotropic_flow.stop_on_first_crash = False # True isotropic_flow.keep_inputs = True isotropic_flow.remove_unnecessary_outputs = False isotropic_flow.write_graph() outgraph = isotropic_flow.run()
# ====================================================================== # time of repetition, in seconds: time_repetition = 1.25 # total number of runs: num_runs = 8 # smoothing kernel, in mm: fwhm = 4 # number of dummy variables to remove from each run: num_dummy = 0 # ====================================================================== # DEFINE NODE: INFOSOURCE # ====================================================================== # define the infosource node that collects the data: infosource = Node(IdentityInterface(fields=['subject_id']), name='infosource') # let the node iterate (paralellize) over all subjects: infosource.iterables = [('subject_id', sub_list)] # ====================================================================== # DEFINE SELECTFILES NODE # ====================================================================== path_confounds = glob.glob( opj(path_root, 'fmriprep', 'fmriprep', '*', '*', 'func', '*highspeed*confounds_regressors.tsv')) path_events = glob.glob(opj(path_root, 'bids', '*', '*', 'func', '*events.tsv')) path_func = glob.glob( opj(path_root, 'fmriprep', 'fmriprep', '*', '*', 'func', '*highspeed*space-T1w*preproc_bold.nii.gz')) path_anat = glob.glob( opj(path_root, 'fmriprep', 'fmriprep', '*', 'anat', '*_desc-preproc_T1w.nii.gz')) path_wholemask = glob.glob(
# if s.endswith('_roi.mat'): # mat_to_nii(s) # s = s.replace('_roi.mat', '.nii') # Nuisance variables nuisance_masks = ['/data/mridata/SeeleyToolbox/SeeleyFirstLevel/proc/csf_ant_post_bilateral.nii', '/data/mridata/SeeleyToolbox/SeeleyFirstLevel/proc/avg152T1_white_mask.nii'] # TR TR = 2.0 ## CREATE NODES # For distributing subject paths infosource = Node(IdentityInterface(fields=['subject_path', 'seed']), name="infosource") infosource.iterables = [('subject_path', subjdir), ('seed', all_seeds)] info = dict(func = [['subject_path', '/processedfmri_TRCNnSFmDI/images/swua_filteredf*.nii']], motion = [['subject_path', '/processedfmri_TRCNnSFmDI/motion_params_filtered.txt']]) selectfiles = Node(DataGrabber(infields = ['subject_path'], outfields = ['func', 'motion'], base_directory = '/', template = '%s/%s', template_args = info, sort_filelist = True), name = 'selectfiles') # For merging seed and nuisance mask paths and then distributing them downstream seed_plus_nuisance = Node(utilMerge(2), name = 'seed_plus_nuisance') seed_plus_nuisance.inputs.in2 = nuisance_masks
def extract_values_mask(working_dir, data_dir, out_dir, preproc_dir, subject_id, mask_list, scan_group_list): afni.base.AFNICommand.set_default_output_type('NIFTI_GZ') fsl.FSLCommand.set_default_output_type('NIFTI_GZ') ######################## ### SPECIFY WORKFLOW ### ######################## # Create a local_metrics workflow extract_vals_wf = Workflow(name='extract_vals_wf') extract_vals_wf.base_dir = working_dir extract_vals_wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash') ##################### ### SPECIFY NODES ### ##################### ### INPUT ### # Infosource - a function free node to iterate over the list scans scan_group_infosource = Node(util.IdentityInterface(fields=['scan_group']), name='scan_group_infosource') scan_group_infosource.iterables= [('scan_group', scan_group_list)] # select Z maps, 2 versions of func (bpf: band pass filtered; no_bpf:no temporal filtering) templates={'z_map_le_amy': 'MRI/' + subject_id + '/analysis/sca/nilearn/{scan_group}/left_amygdala/fwhm_6/corr_map_le_amy_z.nii.gz', 'z_map_ri_amy': 'MRI/' + subject_id + '/analysis/sca/nilearn/{scan_group}/right_amygdala/fwhm_6/corr_map_ri_amy_z.nii.gz', } select_zmaps = Node(nio.SelectFiles(templates, base_directory = data_dir), name="select_zmaps") extract_vals_wf.connect(scan_group_infosource, 'scan_group', select_zmaps, 'scan_group') # roi_infosource = Node(util.IdentityInterface(fields=['epi_mask']), # name='roi_infosource') # roi_infosource.iterables= [('epi_mask',roi_list)] # # select files, 2 versions of func (bpf: band pass filtered; no_bpf:no temporal filtering) # templates={'epi_mask' : 'templates/harvard_oxford/{epi_mask}' # } # selectmasks = Node(nio.SelectFiles(templates, # base_directory = project_dir), # name="selectmasks") ### ANALYSIS NODES ### def get_vals(le_amy_nii): from nipype.interfaces.afni import ROIStats import numpy as np import os #from nipype.interfaces.fsl import ImageMeants #from nilearn.input_data import NiftiMasker, NiftiMapsMasker #import numpy as np #import os ROIStats(mask = '/scr/nil3/reinelt/NECOS/templates/interaction_masks/mask_intact_bl2vs1_str_vs_con_le_amy.nii.gz', quiet = True) mean_le_amy = ROIStats.run(le_amy_nii) # initialize an empty file & "fill" it with the calculated value, necessary becaus nipype need file types or so... aehm hmm mean_le_amy_file = os.path.abspath('mean_le_amy.txt') np.savetxt(mean_le_amy_file, np.atleast_1d(mean_le_amy)) return mean_le_amy_file vals_inside_mask = Node(util.Function(input_names = ['le_amy_nii'], output_names = ['mean_le_amy_file'], function = get_vals), name='sca_prob_seeds') extract_vals_wf.connect(select_zmaps, 'z_map_le_amy', vals_inside_mask, 'le_amy_nii') # vals_inside_mask = Node(afni.ROIStats(), # name = 'vals_inside_mask') # vals_inside_mask.inputs.mask = '/scr/nil3/reinelt/NECOS/templates/interaction_masks/mask_intact_bl2vs1_str_vs_con_le_amy.nii.gz' # # extract_vals_wf.connect(select_zmaps, 'z_map_le_amy', vals_inside_mask, 'in_file') ### OUTPUT ### # Node to sink data (function DataSink from nipype.interfaces.io) datasink = Node(nio.DataSink(base_directory = out_dir, substitutions=[('_scan_id_', ''), ('_epi_mask_',''), ('rest_preprocessed2mni_2mm_maths.nii.gz','temporal_std_2mni_2mm.nii.gz') ]), name="datasink") extract_vals_wf.connect(vals_inside_mask, 'mean_le_amy_file', datasink, 'mean_le_amy') #################### ### RUN WORKFLOW ### #################### #extract_vals_wf.write_graph(dotfilename='sca', graph2use='flat', format='pdf') #extract_vals_wf.run()rest_preprocessed2mn #extract_vals_wf.run(plugin='CondorDAGMan') extract_vals_wf.run(plugin='MultiProc', plugin_args={'n_procs' : 30})
def learning_prepare_data_wf(working_dir, ds_dir, template_dir, df_file, in_data_name_list, data_lookup_dict, use_n_procs, plugin_name): import os from nipype import config from nipype.pipeline.engine import Node, Workflow, MapNode, JoinNode import nipype.interfaces.utility as util import nipype.interfaces.io as nio from nipype.interfaces.freesurfer.utils import ImageInfo from utils import aggregate_data, vectorize_data from itertools import chain # ensure in_data_name_list is list of lists in_data_name_list = [i if type(i) == list else [i] for i in in_data_name_list] in_data_name_list_unique = list(set(chain.from_iterable(in_data_name_list))) ##################################### # GENERAL SETTINGS ##################################### wf = Workflow(name='learning_prepare_data_wf') wf.base_dir = os.path.join(working_dir) nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True, 'remove_unnecessary_outputs': False, 'job_finished_timeout': 120}) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash') ds = Node(nio.DataSink(), name='ds') ds.inputs.base_directory = os.path.join(ds_dir, 'group_learning_prepare_data') ds.inputs.regexp_substitutions = [ # ('subject_id_', ''), ('_parcellation_', ''), ('_bp_freqs_', 'bp_'), ('_extraction_method_', ''), ('_subject_id_[A0-9]*/', '') ] ds_pdf = Node(nio.DataSink(), name='ds_pdf') ds_pdf.inputs.base_directory = os.path.join(ds_dir, 'pdfs') ds_pdf.inputs.parameterization = False # get atlas data templates_atlases = {'GM_mask_MNI_2mm': 'SPM_GM/SPM_GM_mask_2mm.nii.gz', 'GM_mask_MNI_3mm': 'SPM_GM/SPM_GM_mask_3mm.nii.gz', 'brain_mask_MNI_3mm': 'cpac_image_resources/MNI_3mm/MNI152_T1_3mm_brain_mask.nii.gz', 'brain_template_MNI_3mm': 'cpac_image_resources/MNI_3mm/MNI152_T1_3mm.nii.gz' } selectfiles_anat_templates = Node(nio.SelectFiles(templates_atlases, base_directory=template_dir), name="selectfiles_anat_templates") ##################################### # SET ITERATORS ##################################### # SUBJECTS ITERATOR in_data_name_infosource = Node(util.IdentityInterface(fields=['in_data_name']), name='in_data_name_infosource') in_data_name_infosource.iterables = ('in_data_name', in_data_name_list_unique) mulitmodal_in_data_name_infosource = Node(util.IdentityInterface(fields=['multimodal_in_data_name']), name='mulitmodal_in_data_name_infosource') mulitmodal_in_data_name_infosource.iterables = ('multimodal_in_data_name', in_data_name_list) subjects_selection_crit_dict = {} subjects_selection_crit_dict['adult_healthy_F'] = ["df[df.sex == \'F\']", 'df[df.no_axis_1]', 'df[df.age >= 18]'] subjects_selection_crit_dict['adult_F'] = ["df[df.sex == \'F\']", 'df[df.age >= 18]'] subjects_selection_crit_dict['F'] = ["df[df.sex == \'F\']"] subjects_selection_crit_dict['adult_healthy_M'] = ["df[df.sex == \'M\']", 'df[df.no_axis_1]', 'df[df.age >= 18]'] subjects_selection_crit_dict['adult_M'] = ["df[df.sex == \'M\']", 'df[df.age >= 18]'] subjects_selection_crit_dict['adult'] = ['df[df.age >= 18]'] # subjects_selection_crit_names_list = subjects_selection_crit_dict.keys() subjects_selection_crit_names_list = ['adult_F'] subject_selection_infosource = Node(util.IdentityInterface(fields=['selection_criterium']), name='subject_selection_infosource') subject_selection_infosource.iterables = ('selection_criterium', subjects_selection_crit_names_list) def out_name_str_fct(selection_criterium, in_data_name): return selection_criterium + '_' + in_data_name out_name_str = Node(util.Function(input_names=['selection_criterium', 'in_data_name'], output_names=['out_name_str'], function=out_name_str_fct), name='out_name_str') wf.connect(in_data_name_infosource, 'in_data_name', out_name_str, 'in_data_name') wf.connect(subject_selection_infosource, 'selection_criterium', out_name_str, 'selection_criterium') def get_subjects_info_fct(df_file, subjects_selection_crit_dict, selection_criterium): import pandas as pd import os import numpy as np df = pd.read_pickle(df_file) # EXCLUSION HERE: for eval_str in subjects_selection_crit_dict[selection_criterium]: df = eval(eval_str) df_out_file = os.path.join(os.getcwd(), 'df_use.csv') df.to_csv(df_out_file) subjects_list = df.leica_id.values age = df.age.values age_file = os.path.join(os.getcwd(), 'age.npy') np.save(age_file, age) return (age_file, df_out_file, subjects_list) get_subjects_info = Node( util.Function(input_names=['df_file', 'subjects_selection_crit_dict', 'selection_criterium'], output_names=['age_file', 'df_out_file', 'subjects_list'], function=get_subjects_info_fct), name='get_subjects_info') get_subjects_info.inputs.df_file = df_file get_subjects_info.inputs.subjects_selection_crit_dict = subjects_selection_crit_dict wf.connect(subject_selection_infosource, 'selection_criterium', get_subjects_info, 'selection_criterium') wf.connect(get_subjects_info, 'df_out_file', ds, 'test') wf.connect(get_subjects_info, 'age_file', ds, 'test_age_file') def create_file_list_fct(subjects_list, in_data_name, data_lookup_dict, brain_mask_path, gm_mask_path): file_list = [] for s in subjects_list: file_list.append(data_lookup_dict[in_data_name]['path_str'].format(subject_id=s)) if 'matrix_name' in data_lookup_dict[in_data_name].keys(): matrix_name = data_lookup_dict[in_data_name]['matrix_name'] else: matrix_name = None if 'parcellation_path' in data_lookup_dict[in_data_name].keys(): parcellation_path = data_lookup_dict[in_data_name]['parcellation_path'] else: parcellation_path = None if 'fwhm' in data_lookup_dict[in_data_name].keys(): fwhm = data_lookup_dict[in_data_name]['fwhm'] else: fwhm = None mask_path = brain_mask_path if 'use_gm_mask' in data_lookup_dict[in_data_name].keys(): if data_lookup_dict[in_data_name]['use_gm_mask']: mask_path = gm_mask_path return file_list, matrix_name, parcellation_path, fwhm, mask_path create_file_list = Node(util.Function(input_names=['subjects_list', 'in_data_name', 'data_lookup_dict', 'brain_mask_path', 'gm_mask_path'], output_names=['file_list', 'matrix_name', 'parcellation_path', 'fwhm', 'mask_path'], function=create_file_list_fct), name='create_file_list') wf.connect(get_subjects_info, 'subjects_list', create_file_list, 'subjects_list') wf.connect(in_data_name_infosource, 'in_data_name', create_file_list, 'in_data_name') create_file_list.inputs.data_lookup_dict = data_lookup_dict wf.connect(selectfiles_anat_templates, 'brain_mask_MNI_3mm', create_file_list, 'brain_mask_path') wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', create_file_list, 'gm_mask_path') aggregate_subjects = Node(util.Function(input_names=['file_list'], output_names=['merged_file'], function=aggregate_data), name='aggregate_subjects') wf.connect(create_file_list, 'file_list', aggregate_subjects, 'file_list') vectorized_data = Node( util.Function(input_names=['in_data_file', 'mask_file', 'matrix_name', 'parcellation_path', 'fwhm'], output_names=['vectorized_data', 'vectorized_data_file'], function=vectorize_data), name='vectorized_data') wf.connect(aggregate_subjects, 'merged_file', vectorized_data, 'in_data_file') wf.connect(create_file_list, 'mask_path', vectorized_data, 'mask_file') wf.connect(create_file_list, 'matrix_name', vectorized_data, 'matrix_name') wf.connect(create_file_list, 'parcellation_path', vectorized_data, 'parcellation_path') wf.connect(create_file_list, 'fwhm', vectorized_data, 'fwhm') def aggregate_multimodal_metrics_fct(multimodal_list, vectorized_data_file, vectorized_data_names, selection_criterium): import numpy as np import os metrics_index_list = [vectorized_data_names.index(m) for m in multimodal_list] X = None for i in metrics_index_list: X_file = vectorized_data_file[i] X_single = np.load(X_file) if X is None: X = X_single else: X = np.hstack((X, X_single)) multimodal_in_name = '_'.join(multimodal_list) multimodal_out_name = selection_criterium + '_' + multimodal_in_name X_file = os.path.join(os.getcwd(), multimodal_in_name + '.npy') np.save(X_file, X) return multimodal_in_name, multimodal_out_name, X_file aggregate_multimodal_metrics = JoinNode(util.Function(input_names=['multimodal_list', 'vectorized_data_file', 'vectorized_data_names', 'selection_criterium'], output_names=['multimodal_in_name', 'multimodal_out_name', 'X_file'], function=aggregate_multimodal_metrics_fct), joinfield='vectorized_data_file', joinsource=in_data_name_infosource, name='aggregate_multimodal_metrics') wf.connect(mulitmodal_in_data_name_infosource, 'multimodal_in_data_name', aggregate_multimodal_metrics, 'multimodal_list') wf.connect(vectorized_data, 'vectorized_data_file', aggregate_multimodal_metrics, 'vectorized_data_file') wf.connect(subject_selection_infosource, 'selection_criterium', aggregate_multimodal_metrics, 'selection_criterium') wf.connect(aggregate_multimodal_metrics, 'X_file', ds, 'multimodal_test') aggregate_multimodal_metrics.inputs.vectorized_data_names = in_data_name_list_unique def run_prediction(reg_model, X_file, y_file, data_str): def _pred_real_scatter(y_test, y_test_predicted, title_str, in_data_name): import os import pylab as plt from matplotlib.backends.backend_pdf import PdfPages plt.scatter(y_test, y_test_predicted) plt.plot([10, 80], [10, 80], 'k') plt.xlabel('real') plt.ylabel('predicted') ax = plt.gca() ax.set_aspect('equal') plt.title(title_str) plt.tight_layout() scatter_file = os.path.join(os.getcwd(), 'scatter_' + in_data_name + '.pdf') pp = PdfPages(scatter_file) pp.savefig() pp.close() return scatter_file import os, pickle import numpy as np from sklearn.svm import SVR from sklearn.cross_validation import cross_val_score, cross_val_predict from sklearn.feature_selection import VarianceThreshold from sklearn.preprocessing import MinMaxScaler from sklearn.preprocessing import Imputer from sklearn.pipeline import Pipeline from sklearn.metrics import r2_score, mean_absolute_error X = np.load(X_file) y = np.load(y_file) # fixme pipe fill_missing = Imputer() # X = fill_missing.fit_transform(X) # fixme? pipe # remove low variance features var_thr = VarianceThreshold() # X = var_thr.fit_transform(X) # fixme pipe normalize normalize = MinMaxScaler() # X = normalize.fit_transform(X) regression_model = reg_model # SVR(kernel='linear') pipe = Pipeline([ ('fill_missing', fill_missing), ('var_thr', var_thr), ('normalize', normalize), ('regression_model', regression_model), ]) # cv_scores = cross_val_score(pipe, X, y, cv=5, n_jobs=5, # scoring='mean_absolute_error') # cv_scores_r2 = cross_val_score(pipe, X, y, cv=5, n_jobs=5, # scoring='r2') y_predicted = cross_val_predict(pipe, X, y, cv=5, n_jobs=5) cv_scores = mean_absolute_error(y, y_predicted) cv_scores_r2 = r2_score(y, y_predicted) title_str = '{}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}'.format( data_str, cv_scores.mean(), cv_scores.std(), cv_scores.min(), cv_scores.max(), cv_scores_r2.mean(), cv_scores_r2.std(), cv_scores_r2.min(), cv_scores_r2.max()) scatter_file = _pred_real_scatter(y, y_predicted, title_str, data_str) out_file = os.path.join(os.getcwd(), 'cv_scores.pkl') with open(out_file, 'w') as f: pickle.dump(cv_scores, f) y_pred_file = os.path.join(os.getcwd(), 'y_pred.npy') np.save(y_pred_file, y_predicted) return out_file, regression_model, scatter_file, y_pred_file # from sklearn.svm import SVR from sklearn.linear_model import (LassoCV, ElasticNetCV) prediction = Node(util.Function(input_names=['reg_model', 'X_file', 'y_file', 'data_str'], output_names=['out_file', 'regression_model', 'scatter_file', 'y_pred_file'], function=run_prediction), name='prediction') # prediction.inputs.reg_model = SVR(kernel='linear') # wf.connect(aggregate_multimodal_metrics, 'X_file', prediction, 'X_file') # # wf.connect(vectorized_data, 'vectorized_data_file', prediction, 'X_file') # wf.connect(get_subjects_info, 'age_file', prediction, 'y_file') # wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction, 'data_str') # wf.connect(prediction, 'out_file', ds, 'test_naiv_cv_score') # wf.connect(prediction, 'scatter_file', ds_pdf, 'test_naive_scatter_svr') # wf.connect(prediction, 'y_pred_file', ds_pdf, 'test_naive_predicted_svr') # # prediction_lasso = prediction.clone('prediction_lasso') # prediction_lasso.inputs.reg_model = LassoCV(n_jobs=5) # wf.connect(aggregate_multimodal_metrics, 'X_file', prediction_lasso, 'X_file') # wf.connect(get_subjects_info, 'age_file', prediction_lasso, 'y_file') # wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction_lasso, 'data_str') # wf.connect(prediction_lasso, 'out_file', ds, 'test_cv_score_lasso') # wf.connect(prediction_lasso, 'scatter_file', ds_pdf, 'test_naive_scatter_lasso') # def run_prediction_split(reg_model, X_file, y_file, data_str): def _pred_real_scatter(y_test, y_test_predicted, title_str, in_data_name): import os import pylab as plt from matplotlib.backends.backend_pdf import PdfPages plt.scatter(y_test, y_test_predicted) plt.plot([10, 80], [10, 80], 'k') plt.xlabel('real') plt.ylabel('predicted') ax = plt.gca() ax.set_aspect('equal') plt.title(title_str) plt.tight_layout() scatter_file = os.path.join(os.getcwd(), 'scatter_' + in_data_name + '.pdf') pp = PdfPages(scatter_file) pp.savefig() pp.close() return scatter_file import os, pickle import numpy as np from sklearn.svm import SVR from sklearn.cross_validation import cross_val_score, cross_val_predict from sklearn.feature_selection import VarianceThreshold from sklearn.preprocessing import MinMaxScaler from sklearn.preprocessing import Imputer from sklearn.pipeline import Pipeline from sklearn.metrics import r2_score, mean_absolute_error from sklearn.cross_validation import train_test_split X = np.load(X_file) y = np.load(y_file) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) fill_missing = Imputer() var_thr = VarianceThreshold() normalize = MinMaxScaler() regression_model = reg_model # SVR(kernel='linear') pipe = Pipeline([ ('fill_missing', fill_missing), ('var_thr', var_thr), ('normalize', normalize), ('regression_model', regression_model), ]) pipe.fit(X_train, y_train) fitted_enet_model = pipe.steps[3][1] results_str = 'n_iter: %s. l1_r: %s. alpha: %s' % ( fitted_enet_model.n_iter_, fitted_enet_model.l1_ratio_, fitted_enet_model.alpha_) y_predicted = pipe.predict(X_test) cv_scores = mean_absolute_error(y_test, y_predicted) cv_scores_r2 = r2_score(y_test, y_predicted) title_str = '{}\n{}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}'.format( data_str, results_str, cv_scores.mean(), cv_scores.std(), cv_scores.min(), cv_scores.max(), cv_scores_r2.mean(), cv_scores_r2.std(), cv_scores_r2.min(), cv_scores_r2.max()) scatter_file = _pred_real_scatter(y_test, y_predicted, title_str, data_str) out_file = os.path.join(os.getcwd(), 'cv_scores.pkl') with open(out_file, 'w') as f: pickle.dump(cv_scores, f) model_out_file = os.path.join(os.getcwd(), 'trained_model.pkl') with open(model_out_file, 'w') as f: pickle.dump(pipe, f) y_pred_file = os.path.join(os.getcwd(), 'y_pred.npy') np.save(y_pred_file, y_predicted) return out_file, regression_model, scatter_file, y_pred_file, model_out_file, fitted_enet_model prediction_enet = Node(util.Function(input_names=['reg_model', 'X_file', 'y_file', 'data_str'], output_names=['out_file', 'regression_model', 'scatter_file', 'y_pred_file', 'model_out_file', 'fitted_enet_model'], function=run_prediction_split), name='prediction_enet') # fixme n_jobs prediction_enet.inputs.reg_model = ElasticNetCV(cv=5, n_jobs=10, selection='random', max_iter=2000, l1_ratio=[0, .01, .05, .1, .5, .7, .9, .95, .99, 1]) wf.connect(aggregate_multimodal_metrics, 'X_file', prediction_enet, 'X_file') wf.connect(get_subjects_info, 'age_file', prediction_enet, 'y_file') wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction_enet, 'data_str') wf.connect(prediction_enet, 'out_file', ds, 'test_split_cv_score_enet') wf.connect(prediction_enet, 'model_out_file', ds, 'test_split_trained_model_enet') wf.connect(prediction_enet, 'scatter_file', ds_pdf, 'test_split_scatter_enet') wf.connect(prediction_enet, 'y_pred_file', ds_pdf, 'test_split_predicted_enet') # prediction_enet = prediction.clone('prediction_enet') # prediction_enet.inputs.reg_model = ElasticNetCV(cv=5, n_jobs=7, selection='random', max_iter=2000, # l1_ratio=[.1, .5, .7, .9, .95, .99, 1]) # wf.connect(aggregate_multimodal_metrics, 'X_file', prediction_enet, 'X_file') # wf.connect(get_subjects_info, 'age_file', prediction_enet, 'y_file') # wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction_enet, 'data_str') # wf.connect(prediction_enet, 'out_file', ds, 'test_cv_score_enet') # wf.connect(prediction_enet, 'scatter_file', ds_pdf, 'test_naive_scatter_enet') # wf.connect(prediction_enet, 'y_pred_file', ds_pdf, 'test_naive_predicted_enet') # # # # # # # # # # # # # # # GS # # # # # # # # # # # # # # def run_prediction_gs(X_file, y_file, data_str): # fixme copied function def _pred_real_scatter(y_test, y_test_predicted, title_str, in_data_name): import os import pylab as plt from matplotlib.backends.backend_pdf import PdfPages plt.scatter(y_test, y_test_predicted) plt.plot([10, 80], [10, 80], 'k') plt.xlabel('real') plt.ylabel('predicted') ax = plt.gca() ax.set_aspect('equal') plt.title(title_str) plt.tight_layout() scatter_file = os.path.join(os.getcwd(), 'scatter_' + in_data_name + '.pdf') pp = PdfPages(scatter_file) pp.savefig() pp.close() return scatter_file import os, pickle import numpy as np from sklearn.svm import SVR from sklearn.cross_validation import cross_val_score, cross_val_predict from sklearn.feature_selection import VarianceThreshold from sklearn.grid_search import GridSearchCV from sklearn.preprocessing import MinMaxScaler from sklearn.preprocessing import Imputer X = np.load(X_file) y = np.load(y_file) # fixme pipe imp = Imputer() X = imp.fit_transform(X) # fixme? pipe # remove low variance features var_thr = VarianceThreshold() X = var_thr.fit_transform(X) # fixme pipe normalize normalize = MinMaxScaler() X = normalize.fit_transform(X) # fixme? # remove low variance features var_thr = VarianceThreshold() X = var_thr.fit_transform(X) regression_model = SVR(kernel='linear') # GRID SEARCH params = { 'C': [.0001, .001, .01, .1, 1, 10, 20, 30], 'epsilon': [.0001, .001, .01, .1, 1], } gs = GridSearchCV(regression_model, params, cv=5, scoring='mean_absolute_error', n_jobs=10) gs.fit(X, y) sorted_grid_score = sorted(gs.grid_scores_, key=lambda x: x.mean_validation_score, reverse=True) score_str = [str(n) + ': ' + str(g) for n, g in enumerate(sorted_grid_score)] gs_file = os.path.join(os.getcwd(), 'gs_' + data_str + '.txt') with open(gs_file, 'w') as f: f.write('\n'.join(score_str)) # GS WITH NESTED CV gs_cv = GridSearchCV(regression_model, params, cv=5, scoring='mean_absolute_error', n_jobs=5) cv_scores = cross_val_score(regression_model, X, y, cv=5, scoring='mean_absolute_error') cv_scores_r2 = cross_val_score(regression_model, X, y, cv=5, scoring='r2') cv_prediction = cross_val_predict(regression_model, X, y, cv=5) title_str = '{}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}'.format( data_str, cv_scores.mean(), cv_scores.std(), cv_scores.min(), cv_scores.max(), cv_scores_r2.mean(), cv_scores_r2.std(), cv_scores_r2.min(), cv_scores_r2.max()) cv_scatter_file = _pred_real_scatter(y, cv_prediction, title_str, data_str + '_cv_pred') ## # # # # # # # # # BEST PARAMETERS best_params = sorted_grid_score[0].parameters regression_model = SVR(kernel='linear', **best_params) y_predicted = cross_val_predict(regression_model, X, y, cv=5, n_jobs=5) best_params_scatter_file = _pred_real_scatter(y, y_predicted, data_str, data_str) return regression_model, gs_file, best_params_scatter_file, cv_scatter_file gs = Node(util.Function(input_names=['X_file', 'y_file', 'data_str'], output_names=['regression_model', 'gs_file', 'best_params_scatter_file', 'cv_scatter_file'], function=run_prediction_gs), name='gs') # wf.connect(aggregate_multimodal_metrics, 'X_file', gs, 'X_file') # wf.connect(get_subjects_info, 'age_file', gs, 'y_file') # wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', gs, 'data_str') # wf.connect(gs, 'gs_file', ds_pdf, 'test_gs') # wf.connect(gs, 'best_params_scatter_file', ds_pdf, 'test_gs_best_params_scatters') # wf.connect(gs, 'cv_scatter_file', ds_pdf, 'test_gs_cv_scatters') # # # # # # # # # # # # # # # PIPELINE # # # # # # # # # # # # # # def run_prediction_gs_split(X_file, y_file, data_str): # fixme copied function def _pred_real_scatter(y_test, y_test_predicted, title_str, in_data_name): import os import pylab as plt from matplotlib.backends.backend_pdf import PdfPages plt.scatter(y_test, y_test_predicted) plt.plot([10, 80], [10, 80], 'k') plt.xlabel('real') plt.ylabel('predicted') ax = plt.gca() ax.set_aspect('equal') plt.title(title_str) plt.tight_layout() scatter_file = os.path.join(os.getcwd(), 'scatter_' + in_data_name + '.pdf') pp = PdfPages(scatter_file) pp.savefig() pp.close() return scatter_file import os, pickle import numpy as np from sklearn.svm import SVR from sklearn.cross_validation import cross_val_score, cross_val_predict, train_test_split from sklearn.grid_search import GridSearchCV from sklearn.pipeline import Pipeline from sklearn.feature_selection import VarianceThreshold from sklearn.preprocessing import MinMaxScaler, StandardScaler from sklearn.preprocessing import Imputer from sklearn.feature_selection import SelectPercentile, f_regression from sklearn.metrics import mean_absolute_error, r2_score from sklearn.svm import LinearSVR from sklearn.decomposition import PCA X = np.load(X_file) y = np.load(y_file) # fixme add squared values to X # X = np.hstack([X, np.square(X)]) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) # remove low variance features fill_missing = Imputer() var_thr = VarianceThreshold() normalize = StandardScaler() # MinMaxScaler() selection = SelectPercentile(f_regression) # regression_model = LinearSVR() #SVR(kernel='linear') from sklearn.svm import NuSVR regression_model = LinearSVR() # NuSVR(kernel='linear') #SVR(kernel='linear') pipe = Pipeline([ ('fill_missing', fill_missing), ('var_thr', var_thr), ('normalize', normalize), ('selection', selection), ('regression_model', regression_model), ]) # GRID SEARCH params = { 'selection__percentile': [70, 75, 80, 85, 90, 95, 99, 100], 'regression_model__C': [1, 98, 106, 110, 130, 150, 170, 200, 14450], # [.0001, .001, .01, .1, 1, 10, 20, 30], 'regression_model__epsilon': [0, .005, .01, .05, .1, 1, 5, 10], 'regression_model__loss': ['epsilon_insensitive', 'squared_epsilon_insensitive'], # 'regression_model__nu': [0.01, .25, .5, .75, .8, .85, .9, .95, .99], } # fixme njobs gs = GridSearchCV(pipe, params, cv=5, scoring='mean_absolute_error', n_jobs=30) gs.fit(X_train, y_train) best_estimator = gs.best_estimator_ grid_scores = gs.grid_scores_ gs_file = os.path.join(os.getcwd(), 'gs_' + data_str + '.pkl') with open(gs_file, 'w') as f: pickle.dump(grid_scores, f) sorted_grid_score = sorted(gs.grid_scores_, key=lambda x: x.mean_validation_score, reverse=True) score_str = [str(n) + ': ' + str(g) for n, g in enumerate(sorted_grid_score)] gs_text_file = os.path.join(os.getcwd(), 'gs_txt_' + data_str + '.txt') with open(gs_text_file, 'w') as f: f.write('\n'.join(score_str)) # fitted_model = gs.steps[-1][1] model_out_file = os.path.join(os.getcwd(), 'trained_model.pkl') with open(model_out_file, 'w') as f: pickle.dump(gs, f) y_predicted = gs.predict(X_test) cv_scores = mean_absolute_error(y_test, y_predicted) cv_scores_r2 = r2_score(y_test, y_predicted) title_str = '{}\n mae: {:.3f}\n r2: {:.3f}'.format( data_str, cv_scores, cv_scores_r2) scatter_file = _pred_real_scatter(y_test, y_predicted, title_str, data_str) return model_out_file, scatter_file, gs_text_file, gs_file, best_estimator prediction_gs_split = Node(util.Function(input_names=['X_file', 'y_file', 'data_str'], output_names=['model_out_file', 'scatter_file', 'gs_text_file', 'gs_file', 'best_estimator'], function=run_prediction_gs_split), name='prediction_gs_split') wf.connect(aggregate_multimodal_metrics, 'X_file', prediction_gs_split, 'X_file') wf.connect(get_subjects_info, 'age_file', prediction_gs_split, 'y_file') wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction_gs_split, 'data_str') wf.connect(prediction_gs_split, 'scatter_file', ds_pdf, 'test_gs_split_scatter') wf.connect(prediction_gs_split, 'model_out_file', ds, 'test_gs_split_trained_model') wf.connect(prediction_gs_split, 'gs_text_file', ds_pdf, 'test_gs_split_gs_params') wf.connect(prediction_gs_split, 'gs_file', ds_pdf, 'grid_scores') # RANDOM CV def run_prediction_random_gs_split(X_file, y_file, data_str): # fixme copied function def _pred_real_scatter(y_test, y_test_predicted, title_str, in_data_name): import os import pylab as plt from matplotlib.backends.backend_pdf import PdfPages plt.scatter(y_test, y_test_predicted) plt.plot([10, 80], [10, 80], 'k') plt.xlabel('real') plt.ylabel('predicted') ax = plt.gca() ax.set_aspect('equal') plt.title(title_str) plt.tight_layout() scatter_file = os.path.join(os.getcwd(), 'scatter_' + in_data_name + '.pdf') pp = PdfPages(scatter_file) pp.savefig() pp.close() return scatter_file import os, pickle import numpy as np from sklearn.svm import SVR from sklearn.cross_validation import cross_val_score, cross_val_predict, train_test_split from sklearn.grid_search import RandomizedSearchCV from sklearn.pipeline import Pipeline from sklearn.feature_selection import VarianceThreshold from sklearn.preprocessing import MinMaxScaler, StandardScaler from sklearn.preprocessing import Imputer from sklearn.feature_selection import SelectPercentile, f_regression from sklearn.metrics import mean_absolute_error, r2_score from sklearn.svm import LinearSVR from sklearn.decomposition import PCA from scipy.stats import randint as sp_randint from scipy.stats import expon X = np.load(X_file) y = np.load(y_file) # fixme add squared values to X # X = np.hstack([X, np.square(X)]) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) # remove low variance features fill_missing = Imputer() var_thr = VarianceThreshold() normalize = StandardScaler() # MinMaxScaler() selection = SelectPercentile(f_regression) # regression_model = LinearSVR() #SVR(kernel='linear') from sklearn.svm import NuSVR regression_model = LinearSVR() # NuSVR(kernel='linear') #SVR(kernel='linear') pipe = Pipeline([ ('fill_missing', fill_missing), ('var_thr', var_thr), ('normalize', normalize), ('selection', selection), ('regression_model', regression_model), ]) param_dist = { 'selection__percentile': sp_randint(10, 100), 'regression_model__C': expon(scale=100), # sp_randint(.001, 14450), 'regression_model__epsilon': sp_randint(0, 100), 'regression_model__loss': ['epsilon_insensitive', 'squared_epsilon_insensitive'], } # fixme njobs n_iter_search = 400 gs = RandomizedSearchCV(pipe, param_distributions=param_dist, cv=5, scoring='mean_absolute_error', n_jobs=15, n_iter=n_iter_search) gs.fit(X_train, y_train) best_estimator = gs.best_estimator_ grid_scores = gs.grid_scores_ gs_file = os.path.join(os.getcwd(), 'gs_' + data_str + '.pkl') with open(gs_file, 'w') as f: pickle.dump(grid_scores, f) sorted_grid_score = sorted(gs.grid_scores_, key=lambda x: x.mean_validation_score, reverse=True) score_str = [str(n) + ': ' + str(g) for n, g in enumerate(sorted_grid_score)] gs_text_file = os.path.join(os.getcwd(), 'gs_txt_' + data_str + '.txt') with open(gs_text_file, 'w') as f: f.write('\n'.join(score_str)) # fitted_model = gs.steps[-1][1] # fixme pickle crashes model_out_file = '' # model_out_file = os.path.join(os.getcwd(), 'trained_model.pkl') # with open(model_out_file, 'w') as f: # pickle.dump(gs, f) y_predicted = gs.predict(X_test) cv_scores = mean_absolute_error(y_test, y_predicted) cv_scores_r2 = r2_score(y_test, y_predicted) title_str = '{}\n mae: {:.3f}\n r2: {:.3f}'.format( data_str, cv_scores, cv_scores_r2) scatter_file = _pred_real_scatter(y_test, y_predicted, title_str, data_str) return model_out_file, scatter_file, gs_text_file, gs_file, best_estimator prediction_random_gs_split = Node(util.Function(input_names=['X_file', 'y_file', 'data_str'], output_names=['model_out_file', 'scatter_file', 'gs_text_file', 'gs_file', 'best_estimator'], function=run_prediction_random_gs_split), name='prediction_random_gs_split') wf.connect(aggregate_multimodal_metrics, 'X_file', prediction_random_gs_split, 'X_file') wf.connect(get_subjects_info, 'age_file', prediction_random_gs_split, 'y_file') wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction_random_gs_split, 'data_str') wf.connect(prediction_random_gs_split, 'scatter_file', ds_pdf, 'test_random_gs_split_scatter') #wf.connect(prediction_random_gs_split, 'model_out_file', ds, 'test_random_gs_split_trained_model') wf.connect(prediction_random_gs_split, 'gs_text_file', ds_pdf, 'test_random_gs_split_gs_params') wf.connect(prediction_random_gs_split, 'gs_file', ds_pdf, 'random_grid_scores') from learning_curve import learning_curve_fct learning_curve_svr = Node(util.Function(input_names=['X_file', 'y_file', 'out_name', 'best_estimator'], output_names=['curve_file'], function=learning_curve_fct), name='learning_curve_svr') wf.connect(aggregate_multimodal_metrics, 'X_file', learning_curve_svr, 'X_file') wf.connect(get_subjects_info, 'age_file', learning_curve_svr, 'y_file') wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', learning_curve_svr, 'out_name') wf.connect(prediction_gs_split, 'best_estimator', learning_curve_svr, 'best_estimator') # wf.connect(prediction_gs_split, 'model_out_file', learning_curve_svr, 'fitted_model_file') wf.connect(learning_curve_svr, 'curve_file', ds_pdf, 'learning_curve_svr') def _create_best_enet(fitted_enet): from sklearn.linear_model import ElasticNet best_estimator = ElasticNet(selection='random', max_iter=2000, alpha=fitted_enet.alpha_, l1_ratio=fitted_enet.l1_ratio_) return best_estimator best_estimator_enet = Node(util.Function(input_names=['fitted_enet'], output_names=['best_estimator'], function=_create_best_enet), name='best_estimator_enet') wf.connect(prediction_enet, 'fitted_enet_model', best_estimator_enet, 'fitted_enet') learning_curve_enet = Node(util.Function(input_names=['X_file', 'y_file', 'out_name', 'best_estimator'], output_names=['curve_file'], function=learning_curve_fct), name='learning_curve_enet') wf.connect(aggregate_multimodal_metrics, 'X_file', learning_curve_enet, 'X_file') wf.connect(get_subjects_info, 'age_file', learning_curve_enet, 'y_file') wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', learning_curve_enet, 'out_name') wf.connect(best_estimator_enet, 'best_estimator', learning_curve_enet, 'best_estimator') wf.connect(learning_curve_enet, 'curve_file', ds_pdf, 'learning_curve_enet') def plot_grid_scores_fct(gs_file, data_str): import pylab as plt import pickle, os import pandas as pd import numpy as np with open(gs_file) as fi: gs = pickle.load(fi) # build data frame names_params = gs[0].parameters.keys() c_names = names_params + ['m', 'sd'] df = pd.DataFrame([], columns=c_names) for g in gs: data_params = [g.parameters[n] for n in names_params] data_m = [np.abs(g.mean_validation_score), g.cv_validation_scores.std()] data = data_params + data_m df.loc[len(df)] = data # plot plt.figure(figsize=(5, 4 * len(names_params))) for i, p in enumerate(names_params): plt.subplot(len(names_params), 1, i + 1) x = df[p].values y = df['m'].values if type(x[0]) is str: rep_dict = {} for i, o in enumerate(np.unique(x)): rep_dict[o] = i x = np.array([rep_dict[o] for o in x]) x_ticks = rep_dict.keys() x_vals = map(rep_dict.get, x_ticks) plt.xticks(x_vals, x_ticks, rotation='vertical') u_x = x_vals u_y = [np.mean(df['m'][df[p] == v]) for v in rep_dict.keys()] else: u_x = np.unique(x) u_y = [np.mean(df['m'][df[p] == v]) for v in u_x] plt.scatter(x, y, color='black') plt.plot(u_x, u_y) plt.scatter(u_x, u_y, marker='+') plt.title(p) plt.tight_layout() fig_file = os.path.join(os.getcwd(), 'gs_plot_' + data_str + '.pdf') plt.savefig(fig_file) return fig_file plot_grid_scores = Node(util.Function(input_names=['gs_file', 'data_str'], output_names=['fig_file'], function=plot_grid_scores_fct), name='plot_grid_scores') wf.connect(prediction_gs_split, 'gs_file', plot_grid_scores, 'gs_file') wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', plot_grid_scores, 'data_str') wf.connect(plot_grid_scores, 'fig_file', ds_pdf, 'gs_grid_score_plots') plot_random_grid_scores = Node(util.Function(input_names=['gs_file', 'data_str'], output_names=['fig_file'], function=plot_grid_scores_fct), name='plot_random_grid_scores') wf.connect(prediction_random_gs_split, 'gs_file', plot_random_grid_scores, 'gs_file') wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', plot_random_grid_scores, 'data_str') wf.connect(plot_random_grid_scores, 'fig_file', ds_pdf, 'gs_random_grid_score_plots') def plot_validation_curve_fct(X_file, y_file, best_estimator, data_str): import pylab as plt import pickle, os import pandas as pd import numpy as np from sklearn.learning_curve import validation_curve from matplotlib.backends.backend_pdf import PdfPages X = np.load(X_file) y = np.load(y_file) params = { 'selection__percentile': [70, 75, 80, 85, 90, 95, 99, 100], 'regression_model__C': [1, 98, 106, 110, 130, 150, 170, 200, 1000, 10000, 14450], # [.0001, .001, .01, .1, 1, 10, 20, 30], 'regression_model__epsilon': [0, .005, .01, .05, .1, 1, 5, 10], 'regression_model__loss': ['epsilon_insensitive', 'squared_epsilon_insensitive'], # 'regression_model__nu': [0.01, .25, .5, .75, .8, .85, .9, .95, .99], } fig_file = os.path.abspath('validation_curve_' + data_str + '.pdf') fig_file_log = os.path.abspath('validation_curve_log' + data_str + '.pdf') with PdfPages(fig_file, 'w') as pdf: with PdfPages(fig_file_log, 'w') as pdf_log: for p in sorted(params.keys()): param_range = params[p] if type(param_range[0]) is not str: train_scores, test_scores = validation_curve(best_estimator, X, y, param_name=p, param_range=param_range, cv=5, n_jobs=5) train_scores_mean = np.mean(train_scores, axis=1) train_scores_std = np.std(train_scores, axis=1) test_scores_mean = np.mean(test_scores, axis=1) test_scores_std = np.std(test_scores, axis=1) # LINEAR AXIS plt.title('Validation Curve') plt.xlabel(p) plt.ylim(0.0, 1.1) plt.plot(param_range, train_scores_mean, label='Training score', color='r') plt.fill_between(param_range, train_scores_mean - train_scores_std, train_scores_mean + train_scores_std, alpha=0.2, color='r') plt.plot(param_range, test_scores_mean, label='Cross-validation score', color='g') plt.fill_between(param_range, test_scores_mean - test_scores_std, test_scores_mean + test_scores_std, alpha=0.2, color='g') plt.legend(loc='best') pdf.savefig() plt.close() # LOG AXIS plt.title('Validation Curve') plt.xlabel(p) plt.ylim(0.0, 1.1) plt.semilogx(param_range, train_scores_mean, label='Training score', color='r') plt.fill_between(param_range, train_scores_mean - train_scores_std, train_scores_mean + train_scores_std, alpha=0.2, color='r') plt.semilogx(param_range, test_scores_mean, label='Cross-validation score', color='g') plt.fill_between(param_range, test_scores_mean - test_scores_std, test_scores_mean + test_scores_std, alpha=0.2, color='g') plt.legend(loc='best') pdf_log.savefig() plt.close() return fig_file, fig_file_log plot_validation_curve = Node(util.Function(input_names=['X_file', 'y_file', 'best_estimator', 'data_str'], output_names=['fig_file', 'fig_file_log'], function=plot_validation_curve_fct), name='plot_validation_curve') wf.connect(aggregate_multimodal_metrics, 'X_file', plot_validation_curve, 'X_file') wf.connect(get_subjects_info, 'age_file', plot_validation_curve, 'y_file') wf.connect(prediction_gs_split, 'best_estimator', plot_validation_curve, 'best_estimator') wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', plot_validation_curve, 'data_str') wf.connect(plot_validation_curve, 'fig_file', ds_pdf, 'validation_curve.@lin') wf.connect(plot_validation_curve, 'fig_file_log', ds_pdf, 'validation_curve.@log') def run_pca_fct(X_file, data_str): from sklearn.decomposition import PCA import numpy as np import pylab as plt import os from sklearn.feature_selection import VarianceThreshold from sklearn.grid_search import GridSearchCV from sklearn.preprocessing import MinMaxScaler from sklearn.preprocessing import Imputer X = np.load(X_file) # fixme pipe imp = Imputer() X = imp.fit_transform(X) # fixme? pipe # remove low variance features var_thr = VarianceThreshold() X = var_thr.fit_transform(X) # fixme pipe normalize normalize = MinMaxScaler() X = normalize.fit_transform(X) # fixme? # remove low variance features var_thr = VarianceThreshold() X = var_thr.fit_transform(X) pca = PCA() p = pca.fit_transform(X) explained_var = sum(pca.explained_variance_ratio_) plt.plot(range(1, len(pca.explained_variance_ratio_) + 1), np.cumsum(pca.explained_variance_ratio_)) plt.title('explained var: %s' % explained_var) plt.xlabel('n_components') plt.tight_layout() out_fig = os.path.join(os.getcwd(), 'pca_var_%s.pdf' % data_str) plt.savefig(out_fig) return out_fig run_pca = Node(util.Function(input_names=['X_file', 'data_str'], output_names=['out_fig'], function=run_pca_fct), name='run_pca') wf.connect(aggregate_multimodal_metrics, 'X_file', run_pca, 'X_file') wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', run_pca, 'data_str') wf.connect(run_pca, 'out_fig', ds_pdf, 'pca') ##################################### # RUN WF ##################################### wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == 'CondorDAGMan': wf.run(plugin=plugin_name) if plugin_name == 'MultiProc': wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
def preprocessing_pipeline(cfg): import os from nipype import config from nipype.pipeline.engine import Node, Workflow, JoinNode import nipype.interfaces.utility as util import nipype.interfaces.io as nio import nipype.interfaces.fsl as fsl import nipype.interfaces.freesurfer as freesurfer # LeiCA modules from utils import zip_and_save_running_scripts from preprocessing.rsfMRI_preprocessing import create_rsfMRI_preproc_pipeline from preprocessing.converter import create_converter_structural_pipeline, create_converter_functional_pipeline, \ create_converter_diffusion_pipeline from sca import create_sca_pipeline # INPUT PARAMETERS dicom_dir = cfg['dicom_dir'] working_dir = cfg['working_dir'] freesurfer_dir = cfg['freesurfer_dir'] template_dir = cfg['template_dir'] script_dir = cfg['script_dir'] ds_dir = cfg['ds_dir'] subject_id = cfg['subject_id'] TR_list = cfg['TR_list'] vols_to_drop = cfg['vols_to_drop'] rois_list = cfg['rois_list'] lp_cutoff_freq = cfg['lp_cutoff_freq'] hp_cutoff_freq = cfg['hp_cutoff_freq'] use_fs_brainmask = cfg['use_fs_brainmask'] use_n_procs = cfg['use_n_procs'] plugin_name = cfg['plugin_name'] ##################################### # GENERAL SETTINGS ##################################### fsl.FSLCommand.set_default_output_type('NIFTI_GZ') freesurfer.FSCommand.set_default_subjects_dir(freesurfer_dir) wf = Workflow(name='LeiCA_resting') wf.base_dir = os.path.join(working_dir) nipype_cfg = dict(logging=dict(workflow_level = 'DEBUG'), execution={'stop_on_first_crash': True, 'remove_unnecessary_outputs': True, 'job_finished_timeout': 120}) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash') ds = Node(nio.DataSink(base_directory=ds_dir), name='ds') ##################################### # SET ITERATORS ##################################### # GET SCAN TR_ID ITERATOR scan_infosource = Node(util.IdentityInterface(fields=['TR_id']), name='scan_infosource') scan_infosource.iterables = ('TR_id', TR_list) ##################################### # FETCH MRI DATA ##################################### # GET LATERAL VENTRICLE MASK templates_atlases = {'lat_ventricle_mask_MNI': 'cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz'} selectfiles_templates = Node(nio.SelectFiles(templates_atlases, base_directory=template_dir), name="selectfiles_templates") if not subject_id.startswith('A000'): # releases 1-6 with 01... format subject_id # GET FUNCTIONAL DATA templates_funct = {'funct_dicom': '{subject_id}/session_1/RfMRI_*_{TR_id}'} selectfiles_funct = Node(nio.SelectFiles(templates_funct, base_directory=dicom_dir), name="selectfiles_funct") selectfiles_funct.inputs.subject_id = subject_id wf.connect(scan_infosource, 'TR_id', selectfiles_funct, 'TR_id') # GET STRUCTURAL DATA templates_struct = {'t1w_dicom': '{subject_id}/anat', 'dMRI_dicom': '{subject_id}/session_1/DTI_mx_137/*.dcm'} # *.dcm for dMRI as Dcm2nii requires this selectfiles_struct = Node(nio.SelectFiles(templates_struct, base_directory=dicom_dir), name="selectfiles_struct") selectfiles_struct.inputs.subject_id = subject_id else: #startin with release 6 new folder structure templates_funct = {'funct_dicom': '*/{subject_id}/*_V2/REST_{TR_id}*/*.dcm'} selectfiles_funct = Node(nio.SelectFiles(templates_funct, base_directory=dicom_dir), name="selectfiles_funct") selectfiles_funct.inputs.subject_id = subject_id wf.connect(scan_infosource, 'TR_id', selectfiles_funct, 'TR_id') # GET STRUCTURAL DATA templates_struct = {'t1w_dicom': '*/{subject_id}/*_V2/MPRAGE_SIEMENS_DEFACED*/*.dcm', 'dMRI_dicom': '*/{subject_id}/*_V2/DIFF_137_AP*/*.dcm'} # *.dcm for dMRI as Dcm2nii requires this selectfiles_struct = Node(nio.SelectFiles(templates_struct, base_directory=dicom_dir), name="selectfiles_struct") selectfiles_struct.inputs.subject_id = subject_id ##################################### # COPY RUNNING SCRIPTS ##################################### copy_scripts = Node(util.Function(input_names=['subject_id', 'script_dir'], output_names=['zip_file'], function=zip_and_save_running_scripts), name='copy_scripts') copy_scripts.inputs.script_dir = script_dir copy_scripts.inputs.subject_id = subject_id wf.connect(copy_scripts, 'zip_file', ds, 'scripts') ##################################### # CONVERT DICOMs ##################################### # CONVERT STRUCT 2 NIFTI converter_struct = create_converter_structural_pipeline(working_dir, ds_dir, 'converter_struct') wf.connect(selectfiles_struct, 't1w_dicom', converter_struct, 'inputnode.t1w_dicom') # CONVERT dMRI 2 NIFTI converter_dMRI = create_converter_diffusion_pipeline(working_dir, ds_dir, 'converter_dMRI') wf.connect(selectfiles_struct, 'dMRI_dicom', converter_dMRI, 'inputnode.dMRI_dicom') # CONVERT FUNCT 2 NIFTI converter_funct = create_converter_functional_pipeline(working_dir, ds_dir, 'converter_funct') wf.connect(selectfiles_funct, 'funct_dicom', converter_funct, 'inputnode.epi_dicom') wf.connect(scan_infosource, 'TR_id', converter_funct, 'inputnode.out_format') ##################################### # START RSFMRI PREPROCESSING ANALYSIS ##################################### # rsfMRI PREPROCESSING rsfMRI_preproc = create_rsfMRI_preproc_pipeline(working_dir,freesurfer_dir, ds_dir, use_fs_brainmask, 'rsfMRI_preprocessing') rsfMRI_preproc.inputs.inputnode.vols_to_drop = vols_to_drop rsfMRI_preproc.inputs.inputnode.lp_cutoff_freq = lp_cutoff_freq rsfMRI_preproc.inputs.inputnode.hp_cutoff_freq = hp_cutoff_freq rsfMRI_preproc.inputs.inputnode.subject_id = subject_id wf.connect(converter_struct, 'outputnode.t1w', rsfMRI_preproc, 'inputnode.t1w') wf.connect(converter_funct, 'outputnode.epi', rsfMRI_preproc, 'inputnode.epi') wf.connect(converter_funct, 'outputnode.TR_ms', rsfMRI_preproc, 'inputnode.TR_ms') #wf.connect(subjects_infosource, 'subject_id', rsfMRI_preproc, 'inputnode.subject_id') wf.connect(selectfiles_templates, 'lat_ventricle_mask_MNI', rsfMRI_preproc, 'inputnode.lat_ventricle_mask_MNI') ##################################### # SCA ##################################### # sca = create_sca_pipeline(working_dir, rois_list, ds_dir, name='sca') # wf.connect(rsfMRI_preproc, 'outputnode.rs_preprocessed', sca, 'inputnode.rs_preprocessed') # wf.connect(rsfMRI_preproc, 'outputnode.epi_2_MNI_warp', sca, 'inputnode.epi_2_MNI_warp') # if len(subjects_list)>1: # def test_fct(in_files): # print('cxcxcx') # print in_files # out_files = in_files # return out_files # # collect_files = JoinNode(util.Function(input_names=['in_files'], # output_names=['out_files'], # function=test_fct), # joinsource='subjects_infosource', #'selectfiles_funct', # joinfield='in_files', # name='collect_files') # wf.connect(sca, 'outputnode.seed_based_z', collect_files, 'in_files') # # # collect_sca = Node(fsl.Merge(dimension='t', merged_file='concat_corr_z.nii.gz'), # joinsource='subjects_infosource', #'selectfiles_funct', # joinfield='in_files', # name='collect_sca') # wf.connect(collect_files, 'out_files', collect_sca, 'in_files') # # mean_sca = Node(fsl.MeanImage(), name='mean_sca') # wf.connect(collect_sca, 'merged_file', mean_sca, 'in_file') ##################################### # RUN WF ##################################### wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == 'CondorDAGMan': wf.run(plugin=plugin_name) if plugin_name == 'MultiProc': wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
def create_lsd_resting(subject, working_dir, out_dir, freesurfer_dir, data_dir, echo_space, te_diff, vol_to_remove, scans, epi_resolution, TR, highpass, lowpass): # main workflow func_preproc = Workflow(name='lsd_resting') func_preproc.base_dir = working_dir func_preproc.config['execution']['crashdump_dir'] = func_preproc.base_dir + "/crash_files" # set fsl output type to nii.gz fsl.FSLCommand.set_default_output_type('NIFTI_GZ') # infosource to iterate over scans scan_infosource = Node(util.IdentityInterface(fields=['scan_id']), name='scan_infosource') scan_infosource.iterables=('scan_id', scans) # function node to get fieldmap information def fmap_info(scan_id): if scan_id=='rest1a': fmap_id='fmap1' pe_dir='y-' elif scan_id=='rest1b': fmap_id='fmap1' pe_dir='y' elif scan_id=='rest2a': fmap_id='fmap2' pe_dir='y-' elif scan_id=='rest2b': fmap_id='fmap2' pe_dir='y' return fmap_id, pe_dir fmap_infosource=Node(util.Function(input_names=['scan_id'], output_names=['fmap_id', 'pe_dir'], function=fmap_info), name='fmap_infosource') # select files templates={'func': 'nifti/lsd_resting/{scan_id}.nii.gz', 'fmap_phase' : 'nifti/lsd_resting/{fmap_id}_phase.nii.gz', 'fmap_mag' : 'nifti/lsd_resting/{fmap_id}_mag.nii.gz', 'anat_head' : 'preprocessed/anat/T1.nii.gz', 'anat_brain' : 'preprocessed/anat/T1_brain.nii.gz', 'func_mask' : 'preprocessed/anat/func_mask.nii.gz', } selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="selectfiles") # node to strip rois remove_vol = Node(util.Function(input_names=['in_file','t_min'], output_names=["out_file"], function=strip_rois_func), name='remove_vol') remove_vol.inputs.t_min = vol_to_remove # workflow for motion correction moco=create_moco_pipeline() # workflow for fieldmap correction and coregistration fmap_coreg=create_fmap_coreg_pipeline() fmap_coreg.inputs.inputnode.fs_subjects_dir=freesurfer_dir fmap_coreg.inputs.inputnode.fs_subject_id=subject fmap_coreg.inputs.inputnode.echo_space=echo_space fmap_coreg.inputs.inputnode.te_diff=te_diff # workflow for applying transformations to timeseries transform_ts = create_transform_pipeline() transform_ts.inputs.inputnode.resolution=epi_resolution # workflow to denoise timeseries denoise = create_denoise_pipeline() denoise.inputs.inputnode.highpass_sigma= 1./(2*TR*highpass) denoise.inputs.inputnode.lowpass_sigma= 1./(2*TR*lowpass) # https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1205&L=FSL&P=R57592&1=FSL&9=A&I=-3&J=on&d=No+Match%3BMatch%3BMatches&z=4 denoise.inputs.inputnode.tr = TR #sink to store files of single scans sink = Node(nio.DataSink(parameterization=False, base_directory=out_dir, substitutions=[('fmap1_phase_fslprepared', 'fieldmap'), ('fmap2_phase_fslprepared', 'fieldmap'), ('fieldmap_fslprepared_fieldmap_unmasked_vsm', 'shiftmap'), ('plot.rest_coregistered', 'outlier_plot'), ('filter_motion_comp_norm_compcor_art_dmotion', 'nuissance_matrix'), ('rest_realigned.nii.gz_abs.rms', 'rest_realigned_abs.rms'), ('rest_realigned.nii.gz.par','rest_realigned.par'), ('rest_realigned.nii.gz_rel.rms', 'rest_realigned_rel.rms'), ('rest_realigned.nii.gz_abs_disp', 'abs_displacement_plot'), ('rest_realigned.nii.gz_rel_disp', 'rel_displacment_plot'), ('art.rest_coregistered_outliers', 'outliers'), ('global_intensity.rest_coregistered', 'global_intensity'), ('norm.rest_coregistered', 'composite_norm'), ('stats.rest_coregistered', 'stats'), ('rest_denoised_bandpassed_norm.nii.gz', 'rest_preprocessed.nii.gz') ]), name='sink') # connections func_preproc.connect([(scan_infosource, selectfiles, [('scan_id', 'scan_id')]), (scan_infosource, fmap_infosource, [('scan_id', 'scan_id')]), (fmap_infosource, selectfiles, [('fmap_id', 'fmap_id')]), (fmap_infosource, fmap_coreg, [('pe_dir', 'inputnode.pe_dir')]), (scan_infosource, sink, [('scan_id', 'container')]), (selectfiles, remove_vol, [('func', 'in_file')]), (remove_vol, moco, [('out_file', 'inputnode.epi')]), (selectfiles, fmap_coreg, [('fmap_phase', 'inputnode.phase'), ('fmap_mag', 'inputnode.mag'), ('anat_head', 'inputnode.anat_head'), ('anat_brain', 'inputnode.anat_brain') ]), (moco, fmap_coreg, [('outputnode.epi_mean', 'inputnode.epi_mean')]), (remove_vol, transform_ts, [('out_file', 'inputnode.orig_ts')]), (selectfiles, transform_ts, [('anat_head', 'inputnode.anat_head')]), (moco, transform_ts, [('outputnode.mat_moco', 'inputnode.mat_moco')]), (fmap_coreg, transform_ts, [('outputnode.fmap_fullwarp', 'inputnode.fullwarp')]), (selectfiles, denoise, [('func_mask', 'inputnode.brain_mask'), ('anat_brain', 'inputnode.anat_brain')]), (fmap_coreg, denoise, [('outputnode.epi2anat_dat', 'inputnode.epi2anat_dat'), ('outputnode.unwarped_mean_epi2fmap', 'inputnode.unwarped_mean')]), (moco, denoise, [('outputnode.par_moco', 'inputnode.moco_par')]), (transform_ts, denoise, [('outputnode.trans_ts','inputnode.epi_coreg')]), (moco, sink, [#('outputnode.epi_moco', 'realign.@realigned_ts'), ('outputnode.par_moco', 'realign.@par'), ('outputnode.rms_moco', 'realign.@rms'), ('outputnode.mat_moco', 'realign.MAT.@mat'), ('outputnode.epi_mean', 'realign.@mean'), ('outputnode.rotplot', 'realign.plots.@rotplot'), ('outputnode.transplot', 'realign.plots.@transplot'), ('outputnode.dispplots', 'realign.plots.@dispplots'), ('outputnode.tsnr_file', 'realign.@tsnr')]), (fmap_coreg, sink, [('outputnode.fmap','coregister.transforms2anat.@fmap'), #('outputnode.unwarpfield_epi2fmap', 'coregister.@unwarpfield_epi2fmap'), ('outputnode.unwarped_mean_epi2fmap', 'coregister.@unwarped_mean_epi2fmap'), ('outputnode.epi2fmap', 'coregister.@epi2fmap'), #('outputnode.shiftmap', 'coregister.@shiftmap'), ('outputnode.fmap_fullwarp', 'coregister.transforms2anat.@fmap_fullwarp'), ('outputnode.epi2anat', 'coregister.@epi2anat'), ('outputnode.epi2anat_mat', 'coregister.transforms2anat.@epi2anat_mat'), ('outputnode.epi2anat_dat', 'coregister.transforms2anat.@epi2anat_dat'), ('outputnode.epi2anat_mincost', 'coregister.@epi2anat_mincost') ]), (transform_ts, sink, [#('outputnode.trans_ts', 'coregister.@full_transform_ts'), ('outputnode.trans_ts_mean', 'coregister.@full_transform_mean'), ('outputnode.resamp_brain', 'coregister.@resamp_brain')]), (denoise, sink, [('outputnode.wmcsf_mask', 'denoise.mask.@wmcsf_masks'), ('outputnode.combined_motion','denoise.artefact.@combined_motion'), ('outputnode.outlier_files','denoise.artefact.@outlier'), ('outputnode.intensity_files','denoise.artefact.@intensity'), ('outputnode.outlier_stats','denoise.artefact.@outlierstats'), ('outputnode.outlier_plots','denoise.artefact.@outlierplots'), ('outputnode.mc_regressor', 'denoise.regress.@mc_regressor'), ('outputnode.comp_regressor', 'denoise.regress.@comp_regressor'), ('outputnode.mc_F', 'denoise.regress.@mc_F'), ('outputnode.mc_pF', 'denoise.regress.@mc_pF'), ('outputnode.comp_F', 'denoise.regress.@comp_F'), ('outputnode.comp_pF', 'denoise.regress.@comp_pF'), ('outputnode.brain_mask_resamp', 'denoise.mask.@brain_resamp'), ('outputnode.brain_mask2epi', 'denoise.mask.@brain_mask2epi'), ('outputnode.normalized_file', '@normalized') ]) ]) #joinnode for concatenation # concatenate=JoinNode(fsl.Merge(dimension='t', # merged_file='rest_preprocessed_concat.nii.gz'), # joinsource='scan_infosource', # joinfield='in_files', # name='concatenate') # #concatenate.plugin_args={'submit_specs': 'request_memory = 20000'} # # concat_sink=Node(nio.DataSink(parameterization=False, # base_directory=out_dir), # name='concat_sink') # # # func_preproc.connect([(denoise, concatenate, [('outputnode.normalized_file', 'in_files')]), # (concatenate, concat_sink, [('merged_file', '@rest_concat')]) # ]) #func_preproc.write_graph(dotfilename='func_preproc.dot', graph2use='colored', format='pdf', simple_form=True) func_preproc.run() #func_preproc.run(plugin='CondorDAGMan') #func_preproc.run(plugin='MultiProc')
working_dir = "/scr/ilz3/myelinconnect/working_dir/mappings_fixhdr/" data_dir = "/scr/ilz3/myelinconnect/" out_dir = "/scr/ilz3/myelinconnect/transformations/" # set fsl output type to nii.gz fsl.FSLCommand.set_default_output_type("NIFTI_GZ") # main workflow mappings = Workflow(name="mappings") mappings.base_dir = working_dir mappings.config["execution"]["crashdump_dir"] = mappings.base_dir + "/crash_files" # iterate over subjects subject_infosource = Node(util.IdentityInterface(fields=["subject"]), name="subject_infosource") subject_infosource.iterables = [("subject", subjects_db)] # iterate over sessions session_infosource = Node(util.IdentityInterface(fields=["session"]), name="session_infosource") session_infosource.iterables = [("session", sessions)] # select files templates = { "median": "resting/preprocessed/{subject}/{session}/realignment/corr_{subject}_{session}_roi_detrended_median_corrected.nii.gz", "median_mapping": "mappings/rest/fixed_hdr/corr_{subject}_{session}_*mapping_fixed.nii.gz", #'t1_mapping': 'mappings/t1/{subject}*T1_Images_merged_mapping.nii.gz', "t1_highres": "struct/t1/{subject}*T1_Images_merged.nii.gz", "epi2highres_lin_itk": "resting/preprocessed/{subject}/{session}/registration/epi2highres_lin.txt", "epi2highres_warp": "resting/preprocessed/{subject}/{session}/registration/transform0Warp.nii.gz", "epi2highres_invwarp": "resting/preprocessed/{subject}/{session}/registration/transform0InverseWarp.nii.gz", #'t1_prep_rh' : 'struct/surf_rh/prep_t1/smooth_1.5/{subject}_rh_mid_T1_avg_smoothdata_data.nii.gz',
background = Node(JistIntensityMp2rageMasking(outMasked=True, outMasked2=True, outSignal2=True), name='background') # skullstrip strip = Node(MedicAlgorithmSPECTRE2010(outStripped=True, outMask=True, outOriginal=True, inOutput='true', inFind='true', #maxMemoryUsage = 6000, #inMMC=4 ), name='strip') strip.iterables=('inMMC',[2,4]) # connections mp2rage.connect([(inputnode, background, [('inv2', 'inSecond'), ('t1map', 'inQuantitative'), ('uni', 'inT1weighted')]), (background, strip, [('outMasked2','inInput')]), (background, outputnode, [('outMasked2','uni_masked'), ('outMasked','t1map_masked'), ('outSignal2','background_mask')]), (strip, outputnode, [('outStripped','uni_stripped'), ('outMask', 'skullstrip_mask'), ('outOriginal','uni_reoriented')]) ])
def preprocessing_pipeline(cfg): import os from nipype import config from nipype.pipeline.engine import Node, Workflow import nipype.interfaces.utility as util import nipype.interfaces.io as nio import nipype.interfaces.fsl as fsl import nipype.interfaces.freesurfer as freesurfer # LeiCA modules from utils import zip_and_save_running_scripts from preprocessing.rsfMRI_preprocessing import create_rsfMRI_preproc_pipeline from preprocessing.converter import create_converter_structural_pipeline, create_converter_functional_pipeline, \ create_converter_diffusion_pipeline # INPUT PARAMETERS dicom_dir = cfg['dicom_dir'] working_dir = cfg['working_dir'] freesurfer_dir = cfg['freesurfer_dir'] template_dir = cfg['template_dir'] script_dir = cfg['script_dir'] ds_dir = cfg['ds_dir'] subject_id = cfg['subject_id'] TR_list = cfg['TR_list'] vols_to_drop = cfg['vols_to_drop'] lp_cutoff_freq = cfg['lp_cutoff_freq'] hp_cutoff_freq = cfg['hp_cutoff_freq'] use_fs_brainmask = cfg['use_fs_brainmask'] use_n_procs = cfg['use_n_procs'] plugin_name = cfg['plugin_name'] ##################################### # GENERAL SETTINGS ##################################### fsl.FSLCommand.set_default_output_type('NIFTI_GZ') freesurfer.FSCommand.set_default_subjects_dir(freesurfer_dir) wf = Workflow(name='LeiCA_resting') wf.base_dir = os.path.join(working_dir) nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={ 'stop_on_first_crash': True, 'remove_unnecessary_outputs': True, 'job_finished_timeout': 120 }) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join( working_dir, 'crash') ds = Node(nio.DataSink(base_directory=ds_dir), name='ds') ##################################### # SET ITERATORS ##################################### # GET SCAN TR_ID ITERATOR scan_infosource = Node(util.IdentityInterface(fields=['TR_id']), name='scan_infosource') scan_infosource.iterables = ('TR_id', TR_list) ##################################### # FETCH MRI DATA ##################################### # GET LATERAL VENTRICLE MASK templates_atlases = { 'lat_ventricle_mask_MNI': 'cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz' } selectfiles_templates = Node(nio.SelectFiles(templates_atlases, base_directory=template_dir), name="selectfiles_templates") if not True: # releases 1-6 with 01... format subject_id # GET FUNCTIONAL DATA templates_funct = { 'funct_dicom': '{subject_id}/session_1/RfMRI_*_{TR_id}' } selectfiles_funct = Node(nio.SelectFiles(templates_funct, base_directory=dicom_dir), name="selectfiles_funct") selectfiles_funct.inputs.subject_id = subject_id wf.connect(scan_infosource, 'TR_id', selectfiles_funct, 'TR_id') # GET STRUCTURAL DATA templates_struct = { 't1w_dicom': '{subject_id}/anat', 'dMRI_dicom': '{subject_id}/session_1/DTI_mx_137/*.dcm' } # *.dcm for dMRI as Dcm2nii requires this selectfiles_struct = Node(nio.SelectFiles(templates_struct, base_directory=dicom_dir), name="selectfiles_struct") selectfiles_struct.inputs.subject_id = subject_id else: #startin with release 6 new folder structure templates_funct = { 'funct_dicom': '*/{subject_id}/*_V2/REST_{TR_id}*/*.dcm' } selectfiles_funct = Node(nio.SelectFiles(templates_funct, base_directory=dicom_dir), name="selectfiles_funct") selectfiles_funct.inputs.subject_id = subject_id wf.connect(scan_infosource, 'TR_id', selectfiles_funct, 'TR_id') # GET STRUCTURAL DATA templates_struct = { 't1w_dicom': '*/{subject_id}/*_V2/MPRAGE_SIEMENS_DEFACED*/*.dcm', 'dMRI_dicom': '*/{subject_id}/*_V2/DIFF_137_AP*/*.dcm' } # *.dcm for dMRI as Dcm2nii requires this selectfiles_struct = Node(nio.SelectFiles(templates_struct, base_directory=dicom_dir), name="selectfiles_struct") selectfiles_struct.inputs.subject_id = subject_id ##################################### # COPY RUNNING SCRIPTS ##################################### copy_scripts = Node(util.Function(input_names=['subject_id', 'script_dir'], output_names=['zip_file'], function=zip_and_save_running_scripts), name='copy_scripts') copy_scripts.inputs.script_dir = script_dir copy_scripts.inputs.subject_id = subject_id wf.connect(copy_scripts, 'zip_file', ds, 'scripts') ##################################### # CONVERT DICOMs ##################################### # CONVERT STRUCT 2 NIFTI converter_struct = create_converter_structural_pipeline( working_dir, ds_dir, 'converter_struct') wf.connect(selectfiles_struct, 't1w_dicom', converter_struct, 'inputnode.t1w_dicom') # CONVERT dMRI 2 NIFTI converter_dMRI = create_converter_diffusion_pipeline( working_dir, ds_dir, 'converter_dMRI') wf.connect(selectfiles_struct, 'dMRI_dicom', converter_dMRI, 'inputnode.dMRI_dicom') # CONVERT FUNCT 2 NIFTI converter_funct = create_converter_functional_pipeline( working_dir, ds_dir, 'converter_funct') wf.connect(selectfiles_funct, 'funct_dicom', converter_funct, 'inputnode.epi_dicom') wf.connect(scan_infosource, 'TR_id', converter_funct, 'inputnode.out_format') ##################################### # START RSFMRI PREPROCESSING ANALYSIS ##################################### # rsfMRI PREPROCESSING rsfMRI_preproc = create_rsfMRI_preproc_pipeline(working_dir, freesurfer_dir, ds_dir, use_fs_brainmask, 'rsfMRI_preprocessing') rsfMRI_preproc.inputs.inputnode.vols_to_drop = vols_to_drop rsfMRI_preproc.inputs.inputnode.lp_cutoff_freq = lp_cutoff_freq rsfMRI_preproc.inputs.inputnode.hp_cutoff_freq = hp_cutoff_freq rsfMRI_preproc.inputs.inputnode.subject_id = subject_id wf.connect(converter_struct, 'outputnode.t1w', rsfMRI_preproc, 'inputnode.t1w') wf.connect(converter_funct, 'outputnode.epi', rsfMRI_preproc, 'inputnode.epi') wf.connect(converter_funct, 'outputnode.TR_ms', rsfMRI_preproc, 'inputnode.TR_ms') wf.connect(selectfiles_templates, 'lat_ventricle_mask_MNI', rsfMRI_preproc, 'inputnode.lat_ventricle_mask_MNI') ##################################### # RUN WF ##################################### wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == 'CondorDAGMan': wf.run(plugin=plugin_name) if plugin_name == 'MultiProc': wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
def calc_local_metrics(cfg): import os from nipype import config from nipype.pipeline.engine import Node, Workflow, MapNode import nipype.interfaces.utility as util import nipype.interfaces.io as nio import nipype.interfaces.fsl as fsl import nipype.interfaces.freesurfer as freesurfer import CPAC.alff.alff as cpac_alff import CPAC.reho.reho as cpac_reho import CPAC.utils.utils as cpac_utils import CPAC.vmhc.vmhc as cpac_vmhc import CPAC.registration.registration as cpac_registration import CPAC.network_centrality.z_score as cpac_centrality_z_score import utils as calc_metrics_utils # INPUT PARAMETERS dicom_dir = cfg['dicom_dir'] preprocessed_data_dir = cfg['preprocessed_data_dir'] working_dir = cfg['working_dir'] freesurfer_dir = cfg['freesurfer_dir'] template_dir = cfg['template_dir'] script_dir = cfg['script_dir'] ds_dir = cfg['ds_dir'] subject_id = cfg['subject_id'] TR_list = cfg['TR_list'] vols_to_drop = cfg['vols_to_drop'] rois_list = cfg['rois_list'] lp_cutoff_freq = cfg['lp_cutoff_freq'] hp_cutoff_freq = cfg['hp_cutoff_freq'] use_fs_brainmask = cfg['use_fs_brainmask'] use_n_procs = cfg['use_n_procs'] plugin_name = cfg['plugin_name'] ##################################### # GENERAL SETTINGS ##################################### fsl.FSLCommand.set_default_output_type('NIFTI_GZ') freesurfer.FSCommand.set_default_subjects_dir(freesurfer_dir) wf = Workflow(name='LeiCA_metrics') wf.base_dir = os.path.join(working_dir) nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True, 'remove_unnecessary_outputs': True, 'job_finished_timeout': 120}) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash') ds = Node(nio.DataSink(base_directory=ds_dir), name='ds') ds.inputs.substitutions = [('_TR_id_', 'TR_')] ds.inputs.regexp_substitutions = [('_variabilty_MNIspace_3mm[0-9]*/', ''), ('_z_score[0-9]*/', '')] ##################################### # SET ITERATORS ##################################### # GET SCAN TR_ID ITERATOR scan_infosource = Node(util.IdentityInterface(fields=['TR_id']), name='scan_infosource') scan_infosource.iterables = ('TR_id', TR_list) # get atlas data templates_atlases = { # 'GM_mask_MNI_2mm': 'SPM_GM/SPM_GM_mask_2mm.nii.gz', # 'GM_mask_MNI_3mm': 'SPM_GM/SPM_GM_mask_3mm.nii.gz', 'FSL_MNI_3mm_template': 'MNI152_T1_3mm_brain.nii.gz', 'vmhc_symm_brain': 'cpac_image_resources/symmetric/MNI152_T1_2mm_brain_symmetric.nii.gz', 'vmhc_symm_brain_3mm': 'cpac_image_resources/symmetric/MNI152_T1_3mm_brain_symmetric.nii.gz', 'vmhc_symm_skull': 'cpac_image_resources/symmetric/MNI152_T1_2mm_symmetric.nii.gz', 'vmhc_symm_brain_mask_dil': 'cpac_image_resources/symmetric/MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz', 'vmhc_config_file_2mm': 'cpac_image_resources/symmetric/T1_2_MNI152_2mm_symmetric.cnf' } selectfiles_anat_templates = Node(nio.SelectFiles(templates_atlases, base_directory=template_dir), name="selectfiles_anat_templates") # GET SUBJECT SPECIFIC FUNCTIONAL AND STRUCTURAL DATA selectfiles_templates = { 'epi_2_MNI_warp': '{subject_id}/rsfMRI_preprocessing/registration/epi_2_MNI_warp/TR_{TR_id}/*.nii.gz', 'epi_mask': '{subject_id}/rsfMRI_preprocessing/masks/brain_mask_epiSpace/TR_{TR_id}/*.nii.gz', 'preproc_epi_full_spectrum': '{subject_id}/rsfMRI_preprocessing/epis/01_denoised/TR_{TR_id}/*.nii.gz', 'preproc_epi_bp': '{subject_id}/rsfMRI_preprocessing/epis/02_denoised_BP/TR_{TR_id}/*.nii.gz', 'preproc_epi_bp_tNorm': '{subject_id}/rsfMRI_preprocessing/epis/03_denoised_BP_tNorm/TR_{TR_id}/*.nii.gz', 'epi_2_struct_mat': '{subject_id}/rsfMRI_preprocessing/registration/epi_2_struct_mat/TR_{TR_id}/*.mat', 't1w': '{subject_id}/raw_niftis/sMRI/t1w_reoriented.nii.gz', 't1w_brain': '{subject_id}/rsfMRI_preprocessing/struct_prep/t1w_brain/t1w_reoriented_maths.nii.gz', } selectfiles = Node(nio.SelectFiles(selectfiles_templates, base_directory=preprocessed_data_dir), name="selectfiles") wf.connect(scan_infosource, 'TR_id', selectfiles, 'TR_id') selectfiles.inputs.subject_id = subject_id # CREATE TRANSFORMATIONS # creat MNI 2 epi warp MNI_2_epi_warp = Node(fsl.InvWarp(), name='MNI_2_epi_warp') MNI_2_epi_warp.inputs.reference = fsl.Info.standard_image('MNI152_T1_2mm.nii.gz') wf.connect(selectfiles, 'epi_mask', MNI_2_epi_warp, 'reference') wf.connect(selectfiles, 'epi_2_MNI_warp', MNI_2_epi_warp, 'warp') # # CREATE GM MASK IN EPI SPACE # GM_mask_epiSpace = Node(fsl.ApplyWarp(), name='GM_mask_epiSpace') # GM_mask_epiSpace.inputs.out_file = 'GM_mask_epiSpace.nii.gz' # # wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_2mm', GM_mask_epiSpace, 'in_file') # wf.connect(selectfiles, 'epi_mask', GM_mask_epiSpace, 'ref_file') # wf.connect(MNI_2_epi_warp, 'inverse_warp', GM_mask_epiSpace, 'field_file') # wf.connect(GM_mask_epiSpace, 'out_file', ds, 'GM_mask_epiSpace') # fixme # # CREATE TS IN MNI SPACE # # is it ok to apply the 2mm warpfield to the 3mm template? # # seems ok: https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind0904&L=FSL&P=R14011&1=FSL&9=A&J=on&d=No+Match%3BMatch%3BMatches&z=4 # epi_bp_MNIspace_3mm = Node(fsl.ApplyWarp(), name='epi_bp_MNIspace_3mm') # epi_bp_MNIspace_3mm.inputs.interp = 'spline' # epi_bp_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'} # wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', epi_bp_MNIspace_3mm, 'ref_file') # wf.connect(selectfiles, 'preproc_epi_bp', epi_bp_MNIspace_3mm, 'in_file') # wf.connect(selectfiles, 'epi_2_MNI_warp', epi_bp_MNIspace_3mm, 'field_file') # CREATE EPI MASK IN MNI SPACE epi_mask_MNIspace_3mm = Node(fsl.ApplyWarp(), name='epi_mask_MNIspace_3mm') epi_mask_MNIspace_3mm.inputs.interp = 'nn' epi_mask_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'} wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', epi_mask_MNIspace_3mm, 'ref_file') wf.connect(selectfiles, 'epi_mask', epi_mask_MNIspace_3mm, 'in_file') wf.connect(selectfiles, 'epi_2_MNI_warp', epi_mask_MNIspace_3mm, 'field_file') wf.connect(epi_mask_MNIspace_3mm, 'out_file', ds, 'epi_mask_MNIspace_3mm') ##################### # CALCULATE METRICS ##################### # f/ALFF alff = cpac_alff.create_alff('alff') alff.inputs.hp_input.hp = 0.01 alff.inputs.lp_input.lp = 0.1 wf.connect(selectfiles, 'preproc_epi_full_spectrum', alff, 'inputspec.rest_res') # wf.connect(GM_mask_epiSpace, 'out_file', alff, 'inputspec.rest_mask') wf.connect(selectfiles, 'epi_mask', alff, 'inputspec.rest_mask') wf.connect(alff, 'outputspec.alff_img', ds, 'alff.alff') wf.connect(alff, 'outputspec.falff_img', ds, 'alff.falff') # f/ALFF 2 MNI # fixme spline or default? alff_MNIspace_3mm = Node(fsl.ApplyWarp(), name='alff_MNIspace_3mm') alff_MNIspace_3mm.inputs.interp = 'spline' alff_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'} wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', alff_MNIspace_3mm, 'ref_file') wf.connect(alff, 'outputspec.alff_img', alff_MNIspace_3mm, 'in_file') wf.connect(selectfiles, 'epi_2_MNI_warp', alff_MNIspace_3mm, 'field_file') wf.connect(alff_MNIspace_3mm, 'out_file', ds, 'alff.alff_MNI_3mm') falff_MNIspace_3mm = Node(fsl.ApplyWarp(), name='falff_MNIspace_3mm') falff_MNIspace_3mm.inputs.interp = 'spline' falff_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'} wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', falff_MNIspace_3mm, 'ref_file') wf.connect(alff, 'outputspec.falff_img', falff_MNIspace_3mm, 'in_file') wf.connect(selectfiles, 'epi_2_MNI_warp', falff_MNIspace_3mm, 'field_file') wf.connect(falff_MNIspace_3mm, 'out_file', ds, 'alff.falff_MNI_3mm') # f/ALFF_MNI Z-SCORE alff_MNIspace_3mm_Z = cpac_utils.get_zscore(input_name='alff_MNIspace_3mm', wf_name='alff_MNIspace_3mm_Z') wf.connect(alff_MNIspace_3mm, 'out_file', alff_MNIspace_3mm_Z, 'inputspec.input_file') # wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', alff_MNIspace_3mm_Z, 'inputspec.mask_file') wf.connect(epi_mask_MNIspace_3mm, 'out_file', alff_MNIspace_3mm_Z, 'inputspec.mask_file') wf.connect(alff_MNIspace_3mm_Z, 'outputspec.z_score_img', ds, 'alff.alff_MNI_3mm_Z') falff_MNIspace_3mm_Z = cpac_utils.get_zscore(input_name='falff_MNIspace_3mm', wf_name='falff_MNIspace_3mm_Z') wf.connect(falff_MNIspace_3mm, 'out_file', falff_MNIspace_3mm_Z, 'inputspec.input_file') # wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', falff_MNIspace_3mm_Z, 'inputspec.mask_file') wf.connect(epi_mask_MNIspace_3mm, 'out_file', falff_MNIspace_3mm_Z, 'inputspec.mask_file') wf.connect(falff_MNIspace_3mm_Z, 'outputspec.z_score_img', ds, 'alff.falff_MNI_3mm_Z') # f/ALFF_MNI STANDARDIZE BY MEAN alff_MNIspace_3mm_standardized_mean = calc_metrics_utils.standardize_divide_by_mean( wf_name='alff_MNIspace_3mm_standardized_mean') wf.connect(alff_MNIspace_3mm, 'out_file', alff_MNIspace_3mm_standardized_mean, 'inputnode.in_file') wf.connect(epi_mask_MNIspace_3mm, 'out_file', alff_MNIspace_3mm_standardized_mean, 'inputnode.mask_file') wf.connect(alff_MNIspace_3mm_standardized_mean, 'outputnode.out_file', ds, 'alff.alff_MNI_3mm_standardized_mean') falff_MNIspace_3mm_standardized_mean = calc_metrics_utils.standardize_divide_by_mean( wf_name='falff_MNIspace_3mm_standardized_mean') wf.connect(falff_MNIspace_3mm, 'out_file', falff_MNIspace_3mm_standardized_mean, 'inputnode.in_file') wf.connect(epi_mask_MNIspace_3mm, 'out_file', falff_MNIspace_3mm_standardized_mean, 'inputnode.mask_file') wf.connect(falff_MNIspace_3mm_standardized_mean, 'outputnode.out_file', ds, 'alff.falff_MNI_3mm_standardized_mean') # REHO reho = cpac_reho.create_reho() reho.inputs.inputspec.cluster_size = 27 wf.connect(selectfiles, 'preproc_epi_bp', reho, 'inputspec.rest_res_filt') # wf.connect(GM_mask_epiSpace, 'out_file', reho, 'inputspec.rest_mask') wf.connect(selectfiles, 'epi_mask', reho, 'inputspec.rest_mask') wf.connect(reho, 'outputspec.raw_reho_map', ds, 'reho.reho') # REHO 2 MNI # fixme spline or default? reho_MNIspace_3mm = Node(fsl.ApplyWarp(), name='reho_MNIspace_3mm') reho_MNIspace_3mm.inputs.interp = 'spline' reho_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'} wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', reho_MNIspace_3mm, 'ref_file') wf.connect(reho, 'outputspec.raw_reho_map', reho_MNIspace_3mm, 'in_file') wf.connect(selectfiles, 'epi_2_MNI_warp', reho_MNIspace_3mm, 'field_file') wf.connect(reho_MNIspace_3mm, 'out_file', ds, 'reho.reho_MNI_3mm') # REHO_MNI Z-SCORE reho_MNIspace_3mm_Z = cpac_utils.get_zscore(input_name='reho_MNIspace_3mm', wf_name='reho_MNIspace_3mm_Z') wf.connect(alff_MNIspace_3mm, 'out_file', reho_MNIspace_3mm_Z, 'inputspec.input_file') # wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', reho_MNIspace_3mm_Z, 'inputspec.mask_file') wf.connect(epi_mask_MNIspace_3mm, 'out_file', reho_MNIspace_3mm_Z, 'inputspec.mask_file') wf.connect(reho_MNIspace_3mm_Z, 'outputspec.z_score_img', ds, 'reho.reho_MNI_3mm_Z') # REHO_MNI STANDARDIZE BY MEAN reho_MNIspace_3mm_standardized_mean = calc_metrics_utils.standardize_divide_by_mean( wf_name='reho_MNIspace_3mm_standardized_mean') wf.connect(reho_MNIspace_3mm, 'out_file', reho_MNIspace_3mm_standardized_mean, 'inputnode.in_file') wf.connect(epi_mask_MNIspace_3mm, 'out_file', reho_MNIspace_3mm_standardized_mean, 'inputnode.mask_file') wf.connect(reho_MNIspace_3mm_standardized_mean, 'outputnode.out_file', ds, 'reho.reho_MNI_3mm_standardized_mean') # VMHC # create registration to symmetrical MNI template struct_2_MNI_symm = cpac_registration.create_nonlinear_register(name='struct_2_MNI_symm') wf.connect(selectfiles_anat_templates, 'vmhc_config_file_2mm', struct_2_MNI_symm, 'inputspec.fnirt_config') wf.connect(selectfiles_anat_templates, 'vmhc_symm_brain', struct_2_MNI_symm, 'inputspec.reference_brain') wf.connect(selectfiles_anat_templates, 'vmhc_symm_skull', struct_2_MNI_symm, 'inputspec.reference_skull') wf.connect(selectfiles_anat_templates, 'vmhc_symm_brain_mask_dil', struct_2_MNI_symm, 'inputspec.ref_mask') wf.connect(selectfiles, 't1w', struct_2_MNI_symm, 'inputspec.input_skull') wf.connect(selectfiles, 't1w_brain', struct_2_MNI_symm, 'inputspec.input_brain') wf.connect(struct_2_MNI_symm, 'outputspec.output_brain', ds, 'vmhc.symm_reg.@output_brain') wf.connect(struct_2_MNI_symm, 'outputspec.linear_xfm', ds, 'vmhc.symm_reg.@linear_xfm') wf.connect(struct_2_MNI_symm, 'outputspec.invlinear_xfm', ds, 'vmhc.symm_reg.@invlinear_xfm') wf.connect(struct_2_MNI_symm, 'outputspec.nonlinear_xfm', ds, 'vmhc.symm_reg.@nonlinear_xfm') # fixme vmhc = cpac_vmhc.create_vmhc(use_ants=False, name='vmhc') vmhc.inputs.fwhm_input.fwhm = 4 wf.connect(selectfiles_anat_templates, 'vmhc_symm_brain_3mm', vmhc, 'inputspec.standard_for_func') wf.connect(selectfiles, 'preproc_epi_bp_tNorm', vmhc, 'inputspec.rest_res') wf.connect(selectfiles, 'epi_2_struct_mat', vmhc, 'inputspec.example_func2highres_mat') wf.connect(struct_2_MNI_symm, 'outputspec.nonlinear_xfm', vmhc, 'inputspec.fnirt_nonlinear_warp') # wf.connect(GM_mask_epiSpace, 'out_file', vmhc, 'inputspec.rest_mask') wf.connect(selectfiles, 'epi_mask', vmhc, 'inputspec.rest_mask') wf.connect(vmhc, 'outputspec.rest_res_2symmstandard', ds, 'vmhc.rest_res_2symmstandard') wf.connect(vmhc, 'outputspec.VMHC_FWHM_img', ds, 'vmhc.VMHC_FWHM_img') wf.connect(vmhc, 'outputspec.VMHC_Z_FWHM_img', ds, 'vmhc.VMHC_Z_FWHM_img') wf.connect(vmhc, 'outputspec.VMHC_Z_stat_FWHM_img', ds, 'vmhc.VMHC_Z_stat_FWHM_img') # VARIABILITY SCORES variability = Node(util.Function(input_names=['in_file'], output_names=['out_file_list'], function=calc_metrics_utils.calc_variability), name='variability') wf.connect(selectfiles, 'preproc_epi_bp', variability, 'in_file') wf.connect(variability, 'out_file_list', ds, 'variability.subjectSpace.@out_files') # #fixme spline? variabilty_MNIspace_3mm = MapNode(fsl.ApplyWarp(), iterfield=['in_file'], name='variabilty_MNIspace_3mm') variabilty_MNIspace_3mm.inputs.interp = 'spline' variabilty_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'} wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', variabilty_MNIspace_3mm, 'ref_file') wf.connect(selectfiles, 'epi_2_MNI_warp', variabilty_MNIspace_3mm, 'field_file') wf.connect(variability, 'out_file_list', variabilty_MNIspace_3mm, 'in_file') wf.connect(variabilty_MNIspace_3mm, 'out_file', ds, 'variability.MNI_3mm.@out_file') # CALC Z SCORE variabilty_MNIspace_3mm_Z = cpac_centrality_z_score.get_cent_zscore(wf_name='variabilty_MNIspace_3mm_Z') wf.connect(variabilty_MNIspace_3mm, 'out_file', variabilty_MNIspace_3mm_Z, 'inputspec.input_file') # wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', variabilty_MNIspace_3mm_Z, 'inputspec.mask_file') wf.connect(epi_mask_MNIspace_3mm, 'out_file', variabilty_MNIspace_3mm_Z, 'inputspec.mask_file') wf.connect(variabilty_MNIspace_3mm_Z, 'outputspec.z_score_img', ds, 'variability.MNI_3mm_Z.@out_file') # STANDARDIZE BY MEAN variabilty_MNIspace_3mm_standardized_mean = calc_metrics_utils.standardize_divide_by_mean( wf_name='variabilty_MNIspace_3mm_standardized_mean') wf.connect(variabilty_MNIspace_3mm, 'out_file', variabilty_MNIspace_3mm_standardized_mean, 'inputnode.in_file') wf.connect(epi_mask_MNIspace_3mm, 'out_file', variabilty_MNIspace_3mm_standardized_mean, 'inputnode.mask_file') wf.connect(variabilty_MNIspace_3mm_standardized_mean, 'outputnode.out_file', ds, 'variability.MNI_3mm_standardized_mean.@out_file') wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == 'CondorDAGMan': wf.run(plugin=plugin_name) if plugin_name == 'MultiProc': wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
from variables_AFNI import data_dir, work_dir, subject_list, plugin, plugin_args import nibabel as nb Afni_workflow = Workflow(name="Afni_volreg_workflow") Afni_workflow.base_dir = work_dir from nipype import SelectFiles templates = dict(epi="*_{subject_id}_*/rfMRI_REST_{pe_dir}_BIC_v2/*_00001.nii*") file_list = Node(SelectFiles(templates), name = "EPI_and_T1_File_Selection") file_list.inputs.base_directory = data_dir file_list.iterables = [("subject_id", subject_list), ("pe_dir", ["LR", "RL"])] from nipype.interfaces.afni import Volreg volreg_motion = MapNode(Volreg(), name="Afni_Motion_Correction", iterfield="in_file") volreg_motion.inputs.args = '-Fourier -twopass' volreg_motion.inputs.zpad = 1 #volreg_motion.inputs.basefile = "in_file" volreg_motion.inputs.outputtype = "NIFTI_GZ" volreg_motion.inputs.verbose = True volreg_motion.inputs.out_file = "afni_test" volreg_motion.inputs.oned_file = "S0799AAW_P126317_6_7_00001" volreg_motion.inputs.oned_matrix_save = "S0799AAW_P126317_6_7_00001"
def create(self): # , **kwargs): """ Create the nodes and connections for the workflow """ # Preamble csvReader = CSVReader() csvReader.inputs.in_file = self.csv_file.default_value csvReader.inputs.header = self.hasHeader.default_value csvOut = csvReader.run() print(("=" * 80)) print((csvOut.outputs.__dict__)) print(("=" * 80)) iters = OrderedDict() label = list(csvOut.outputs.__dict__.keys())[0] result = eval("csvOut.outputs.{0}".format(label)) iters["tests"], iters["trains"] = sample_crossvalidation_set( result, self.sample_size.default_value ) # Main event out_fields = ["T1", "T2", "Label", "trainindex", "testindex"] inputsND = Node( interface=IdentityInterface(fields=out_fields), run_without_submitting=True, name="inputs", ) inputsND.iterables = [ ("trainindex", iters["trains"]), ("testindex", iters["tests"]), ] if not self.hasHeader.default_value: inputsND.inputs.T1 = csvOut.outputs.column_0 inputsND.inputs.Label = csvOut.outputs.column_1 inputsND.inputs.T2 = csvOut.outputs.column_2 else: inputsND.inputs.T1 = csvOut.outputs.__dict__["t1"] inputsND.inputs.Label = csvOut.outputs.__dict__["label"] inputsND.inputs.T2 = csvOut.outputs.__dict__["t2"] pass # TODO metaflow = Workflow(name="metaflow") metaflow.config["execution"] = { "plugin": "Linear", "stop_on_first_crash": "false", "stop_on_first_rerun": "false", # This stops at first attempt to rerun, before running, and before deleting previous results. "hash_method": "timestamp", "single_thread_matlab": "true", # Multi-core 2011a multi-core for matrix multiplication. "remove_unnecessary_outputs": "true", "use_relative_paths": "false", # relative paths should be on, require hash update when changed. "remove_node_directories": "false", # Experimental "local_hash_check": "false", } metaflow.add_nodes([inputsND]) """import pdb; pdb.set_trace()""" fusionflow = FusionLabelWorkflow() self.connect( [ ( metaflow, fusionflow, [ ("inputs.trainindex", "trainT1s.index"), ("inputs.T1", "trainT1s.inlist"), ], ), ( metaflow, fusionflow, [ ("inputs.trainindex", "trainLabels.index"), ("inputs.Label", "trainLabels.inlist"), ], ), ( metaflow, fusionflow, [ ("inputs.testindex", "testT1s.index"), ("inputs.T1", "testT1s.inlist"), ], ), ] )
def calc_local_metrics(brain_mask, preprocessed_data_dir, subject_id, parcellations_dict, bp_freq_list, TR, selectfiles_templates, working_dir, ds_dir, use_n_procs, plugin_name): import os from nipype import config from nipype.pipeline.engine import Node, Workflow, MapNode import nipype.interfaces.utility as util import nipype.interfaces.io as nio import nipype.interfaces.fsl as fsl from nipype.interfaces.freesurfer.preprocess import MRIConvert import CPAC.alff.alff as cpac_alff import CPAC.reho.reho as cpac_reho import CPAC.utils.utils as cpac_utils import utils as calc_metrics_utils from motion import calculate_FD_P, calculate_FD_J ##################################### # GENERAL SETTINGS ##################################### fsl.FSLCommand.set_default_output_type('NIFTI_GZ') wf = Workflow(name='LeiCA_LIFE_metrics') wf.base_dir = os.path.join(working_dir) nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True, 'remove_unnecessary_outputs': True, 'job_finished_timeout': 15}) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash') ds = Node(nio.DataSink(base_directory=ds_dir), name='ds') ds.inputs.regexp_substitutions = [('MNI_resampled_brain_mask_calc.nii.gz', 'falff.nii.gz'), ('residual_filtered_3dT.nii.gz', 'alff.nii.gz'), ('_parcellation_', ''), ('_bp_freqs_', 'bp_'), ] ##################### # ITERATORS ##################### # PARCELLATION ITERATOR parcellation_infosource = Node(util.IdentityInterface(fields=['parcellation']), name='parcellation_infosource') parcellation_infosource.iterables = ('parcellation', parcellations_dict.keys()) # BP FILTER ITERATOR bp_filter_infosource = Node(util.IdentityInterface(fields=['bp_freqs']), name='bp_filter_infosource') bp_filter_infosource.iterables = ('bp_freqs', bp_freq_list) selectfiles = Node(nio.SelectFiles(selectfiles_templates, base_directory=preprocessed_data_dir), name='selectfiles') selectfiles.inputs.subject_id = subject_id # ##################### # # FIX TR IN HEADER # ##################### # tr_msec = int(TR * 1000) # tr_str = '-tr %s' % tr_msec # # fixed_tr_bp = Node(MRIConvert(out_type='niigz', args=tr_str), name='fixed_tr_bp') # wf.connect(selectfiles, 'epi_MNI_bp', fixed_tr_bp, 'in_file') # # fixed_tr_fullspectrum = Node(MRIConvert(out_type='niigz', args=tr_str), name='fixed_tr_fullspectrum') # wf.connect(selectfiles, 'epi_MNI_fullspectrum', fixed_tr_fullspectrum, 'in_file') ##################### # calc FD ##################### FD_P = Node(util.Function(input_names=['in_file'], output_names=['FD_ts_file', 'mean_FD_file', 'max_FD_file'], function=calculate_FD_P), name='FD_P') wf.connect(selectfiles, 'moco_parms_file', FD_P, 'in_file') wf.connect(FD_P, 'FD_ts_file', ds, 'QC.@FD') wf.connect(FD_P, 'mean_FD_file', ds, 'QC.@mean_FD') wf.connect(FD_P, 'max_FD_file', ds, 'QC.@max_FD') FD_J = Node(util.Function(input_names=['in_file'], output_names=['FD_ts_file', 'mean_FD_file', 'max_FD_file'], function=calculate_FD_J), name='FD_J') wf.connect(selectfiles, 'jenkinson_file', FD_J, 'in_file') wf.connect(FD_J, 'FD_ts_file', ds, 'QC.@FD_J') wf.connect(FD_J, 'mean_FD_file', ds, 'QC.@mean_FD_J') wf.connect(FD_J, 'max_FD_file', ds, 'QC.@max_FD_J') wf.connect(selectfiles, 'rest2anat_cost_file', ds, 'QC.@cost_file') ##################### # CALCULATE METRICS ##################### # f/ALFF alff = cpac_alff.create_alff('alff') alff.inputs.hp_input.hp = 0.01 alff.inputs.lp_input.lp = 0.1 alff.inputs.inputspec.rest_mask = brain_mask #wf.connect(fixed_tr_fullspectrum, 'out_file', alff, 'inputspec.rest_res') wf.connect(selectfiles, 'epi_MNI_fullspectrum', alff, 'inputspec.rest_res') wf.connect(alff, 'outputspec.alff_img', ds, 'alff.@alff') wf.connect(alff, 'outputspec.falff_img', ds, 'alff.@falff') # f/ALFF_MNI Z-SCORE alff_z = cpac_utils.get_zscore(input_name='alff', wf_name='alff_z') alff_z.inputs.inputspec.mask_file = brain_mask wf.connect(alff, 'outputspec.alff_img', alff_z, 'inputspec.input_file') wf.connect(alff_z, 'outputspec.z_score_img', ds, 'alff_z.@alff') falff_z = cpac_utils.get_zscore(input_name='falff', wf_name='falff_z') falff_z.inputs.inputspec.mask_file = brain_mask wf.connect(alff, 'outputspec.falff_img', falff_z, 'inputspec.input_file') wf.connect(falff_z, 'outputspec.z_score_img', ds, 'alff_z.@falff') # REHO reho = cpac_reho.create_reho() reho.inputs.inputspec.cluster_size = 27 reho.inputs.inputspec.rest_mask = brain_mask #wf.connect(fixed_tr_bp, 'out_file', reho, 'inputspec.rest_res_filt') wf.connect(selectfiles, 'epi_MNI_BP', reho, 'inputspec.rest_res_filt') wf.connect(reho, 'outputspec.raw_reho_map', ds, 'reho.@reho') # VARIABILITY SCORES variability = Node(util.Function(input_names=['in_file'], output_names=['out_file'], function=calc_metrics_utils.calc_variability), name='variability') #wf.connect(fixed_tr_bp, 'out_file', variability, 'in_file') wf.connect(selectfiles, 'epi_MNI_BP', variability, 'in_file') wf.connect(variability, 'out_file', ds, 'variability.@SD') variability_z = cpac_utils.get_zscore(input_name='ts_std', wf_name='variability_z') variability_z.inputs.inputspec.mask_file = brain_mask wf.connect(variability, 'out_file', variability_z, 'inputspec.input_file') wf.connect(variability_z, 'outputspec.z_score_img', ds, 'variability_z.@variability_z') ############## ## CON MATS ############## ############## ## extract ts ############## parcellated_ts = Node( util.Function(input_names=['in_data', 'parcellation_name', 'parcellations_dict', 'bp_freqs', 'tr'], output_names=['parcellation_time_series', 'parcellation_time_series_file', 'masker_file'], function=calc_metrics_utils.extract_parcellation_time_series), name='parcellated_ts') parcellated_ts.inputs.parcellations_dict = parcellations_dict parcellated_ts.inputs.tr = TR #wf.connect(fixed_tr_fullspectrum, 'out_file', parcellated_ts, 'in_data') wf.connect(selectfiles, 'epi_MNI_fullspectrum', parcellated_ts, 'in_data') wf.connect(parcellation_infosource, 'parcellation', parcellated_ts, 'parcellation_name') wf.connect(bp_filter_infosource, 'bp_freqs', parcellated_ts, 'bp_freqs') ############## ## get conmat ############## con_mat = Node(util.Function(input_names=['in_data', 'extraction_method'], output_names=['matrix', 'matrix_file'], function=calc_metrics_utils.calculate_connectivity_matrix), name='con_mat') con_mat.inputs.extraction_method = 'correlation' wf.connect(parcellated_ts, 'parcellation_time_series', con_mat, 'in_data') ############## ## ds ############## wf.connect(parcellated_ts, 'parcellation_time_series_file', ds, 'con_mat.parcellated_time_series.@parc_ts') wf.connect(parcellated_ts, 'masker_file', ds, 'con_mat.parcellated_time_series.@masker') wf.connect(con_mat, 'matrix_file', ds, 'con_mat.matrix.@mat') wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == 'CondorDAGMan': wf.run(plugin=plugin_name, plugin_args={'initial_specs': 'request_memory = 1500'}) if plugin_name == 'MultiProc': wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
def calc_centrality_metrics(cfg): import os from nipype import config from nipype.pipeline.engine import Node, Workflow import nipype.interfaces.utility as util import nipype.interfaces.io as nio import nipype.interfaces.fsl as fsl import nipype.interfaces.freesurfer as freesurfer import CPAC.network_centrality.resting_state_centrality as cpac_centrality import CPAC.network_centrality.z_score as cpac_centrality_z_score # INPUT PARAMETERS dicom_dir = cfg['dicom_dir'] preprocessed_data_dir = cfg['preprocessed_data_dir'] working_dir = cfg['working_dir'] freesurfer_dir = cfg['freesurfer_dir'] template_dir = cfg['template_dir'] script_dir = cfg['script_dir'] ds_dir = cfg['ds_dir'] subjects_list = cfg['subjects_list'] TR_list = cfg['TR_list'] use_n_procs = cfg['use_n_procs'] plugin_name = cfg['plugin_name'] ##################################### # GENERAL SETTINGS ##################################### fsl.FSLCommand.set_default_output_type('NIFTI_GZ') freesurfer.FSCommand.set_default_subjects_dir(freesurfer_dir) wf = Workflow(name='LeiCA_metrics') wf.base_dir = os.path.join(working_dir) nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': False, 'remove_unnecessary_outputs': True, 'job_finished_timeout': 120}) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash') ds = Node(nio.DataSink(), name='ds') ds.inputs.substitutions = [('_TR_id_', 'TR_')] ds.inputs.regexp_substitutions = [('_subject_id_[A0-9]*/', ''), ( '_z_score[0-9]*/', '')] # , #('dc/_TR_id_[0-9]*/', ''), ('evc/_TR_id_[0-9]*/','')] ##################################### # SET ITERATORS ##################################### # GET SCAN TR_ID ITERATOR scan_infosource = Node(util.IdentityInterface(fields=['TR_id']), name='scan_infosource') scan_infosource.iterables = ('TR_id', TR_list) subjects_infosource = Node(util.IdentityInterface(fields=['subject_id']), name='subjects_infosource') subjects_infosource.iterables = ('subject_id', subjects_list) def add_subject_id_to_ds_dir_fct(subject_id, ds_path): import os out_path = os.path.join(ds_path, subject_id) return out_path add_subject_id_to_ds_dir = Node(util.Function(input_names=['subject_id', 'ds_path'], output_names=['out_path'], function=add_subject_id_to_ds_dir_fct), name='add_subject_id_to_ds_dir') wf.connect(subjects_infosource, 'subject_id', add_subject_id_to_ds_dir, 'subject_id') add_subject_id_to_ds_dir.inputs.ds_path = ds_dir wf.connect(add_subject_id_to_ds_dir, 'out_path', ds, 'base_directory') # get atlas data templates_atlases = {'GM_mask_MNI_2mm': 'SPM_GM/SPM_GM_mask_2mm.nii.gz', 'GM_mask_MNI_3mm': 'SPM_GM/SPM_GM_mask_3mm.nii.gz', 'FSL_MNI_3mm_template': 'MNI152_T1_3mm_brain.nii.gz', 'vmhc_symm_brain': 'cpac_image_resources/symmetric/MNI152_T1_2mm_brain_symmetric.nii.gz', 'vmhc_symm_brain_3mm': 'cpac_image_resources/symmetric/MNI152_T1_3mm_brain_symmetric.nii.gz', 'vmhc_symm_skull': 'cpac_image_resources/symmetric/MNI152_T1_2mm_symmetric.nii.gz', 'vmhc_symm_brain_mask_dil': 'cpac_image_resources/symmetric/MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz', 'vmhc_config_file_2mm': 'cpac_image_resources/symmetric/T1_2_MNI152_2mm_symmetric.cnf' } selectfiles_anat_templates = Node(nio.SelectFiles(templates_atlases, base_directory=template_dir), name="selectfiles_anat_templates") # GET SUBJECT SPECIFIC FUNCTIONAL AND STRUCTURAL DATA selectfiles_templates = { 'epi_2_MNI_warp': '{subject_id}/rsfMRI_preprocessing/registration/epi_2_MNI_warp/TR_{TR_id}/*.nii.gz', 'epi_mask': '{subject_id}/rsfMRI_preprocessing/masks/brain_mask_epiSpace/TR_{TR_id}/*.nii.gz', 'preproc_epi_full_spectrum': '{subject_id}/rsfMRI_preprocessing/epis/01_denoised/TR_{TR_id}/*.nii.gz', 'preproc_epi_bp': '{subject_id}/rsfMRI_preprocessing/epis/02_denoised_BP/TR_{TR_id}/*.nii.gz', 'preproc_epi_bp_tNorm': '{subject_id}/rsfMRI_preprocessing/epis/03_denoised_BP_tNorm/TR_{TR_id}/*.nii.gz', 'epi_2_struct_mat': '{subject_id}/rsfMRI_preprocessing/registration/epi_2_struct_mat/TR_{TR_id}/*.mat', 't1w': '{subject_id}/raw_niftis/sMRI/t1w_reoriented.nii.gz', 't1w_brain': '{subject_id}/rsfMRI_preprocessing/struct_prep/t1w_brain/t1w_reoriented_maths.nii.gz', 'epi_bp_tNorm_MNIspace_3mm': '{subject_id}/rsfMRI_preprocessing/epis_MNI_3mm/03_denoised_BP_tNorm/TR_645/residual_filt_norm_warp.nii.gz' } selectfiles = Node(nio.SelectFiles(selectfiles_templates, base_directory=preprocessed_data_dir), name="selectfiles") wf.connect(scan_infosource, 'TR_id', selectfiles, 'TR_id') wf.connect(subjects_infosource, 'subject_id', selectfiles, 'subject_id') # selectfiles.inputs.subject_id = subject_id # CREATE TRANSFORMATIONS # creat MNI 2 epi warp MNI_2_epi_warp = Node(fsl.InvWarp(), name='MNI_2_epi_warp') MNI_2_epi_warp.inputs.reference = fsl.Info.standard_image('MNI152_T1_2mm.nii.gz') wf.connect(selectfiles, 'epi_mask', MNI_2_epi_warp, 'reference') wf.connect(selectfiles, 'epi_2_MNI_warp', MNI_2_epi_warp, 'warp') ##################### # CALCULATE METRICS ##################### # DEGREE # fixme # a_mem = 5 # fixme a_mem = 20 dc = cpac_centrality.create_resting_state_graphs(allocated_memory=a_mem, wf_name='dc') # allocated_memory = a_mem, wf_name = 'dc') # dc.plugin_args = {'submit_specs': 'request_memory = 6000'} # fixme dc.plugin_args = {'submit_specs': 'request_memory = 20000'} dc.inputs.inputspec.method_option = 0 # 0 for degree centrality, 1 for eigenvector centrality, 2 for lFCD dc.inputs.inputspec.threshold_option = 0 # 0 for probability p_value, 1 for sparsity threshold, any other for threshold value dc.inputs.inputspec.threshold = 0.0001 dc.inputs.inputspec.weight_options = [True, True] # list of two booleans for binarize and weighted options respectively wf.connect(selectfiles, 'epi_bp_tNorm_MNIspace_3mm', dc, 'inputspec.subject') wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', dc, 'inputspec.template') wf.connect(dc, 'outputspec.centrality_outputs', ds, 'metrics.centrality.dc.@centrality_outputs') wf.connect(dc, 'outputspec.correlation_matrix', ds, 'metrics.centrality.dc.@correlation_matrix') wf.connect(dc, 'outputspec.graph_outputs', ds, 'metrics.centrality.dc.@graph_outputs') # DC Z-SCORE dc_Z = cpac_centrality_z_score.get_cent_zscore(wf_name='dc_Z') wf.connect(dc, 'outputspec.centrality_outputs', dc_Z, 'inputspec.input_file') wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', dc_Z, 'inputspec.mask_file') wf.connect(dc_Z, 'outputspec.z_score_img', ds, 'metrics.centrality.dc_z.@output') a_mem = 20 evc = cpac_centrality.create_resting_state_graphs(allocated_memory=a_mem, wf_name='evc') evc.plugin_args = {'submit_specs': 'request_memory = 20000'} evc.inputs.inputspec.method_option = 1 # 0 for degree centrality, 1 for eigenvector centrality, 2 for lFCD evc.inputs.inputspec.threshold_option = 0 # 0 for probability p_value, 1 for sparsity threshold, any other for threshold value evc.inputs.inputspec.threshold = 0.0001 evc.inputs.inputspec.weight_options = [True, True] # list of two booleans for binarize and weighted options respectively wf.connect(selectfiles, 'epi_bp_tNorm_MNIspace_3mm', evc, 'inputspec.subject') wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', evc, 'inputspec.template') wf.connect(evc, 'outputspec.centrality_outputs', ds, 'metrics.centrality.evc.@centrality_outputs') wf.connect(evc, 'outputspec.correlation_matrix', ds, 'metrics.centrality.evc.@correlation_matrix') wf.connect(evc, 'outputspec.graph_outputs', ds, 'metrics.centrality.evc.@graph_outputs') # EVC Z-SCORE evc_Z = cpac_centrality_z_score.get_cent_zscore(wf_name='evc_Z') wf.connect(evc, 'outputspec.centrality_outputs', evc_Z, 'inputspec.input_file') wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', evc_Z, 'inputspec.mask_file') wf.connect(evc_Z, 'outputspec.z_score_img', ds, 'metrics.centrality.evc_z.@output') wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == 'CondorDAGMan': wf.run(plugin=plugin_name) if plugin_name == 'MultiProc': wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
(level2estimate, level2conestimate, [('spm_mat_file', 'spm_mat_file'), ('beta_images', 'beta_images'), ('residual_image', 'residual_image')]), ]) ### # Input & Output Stream # Infosource - a function free node to iterate over the list of subject names infosource = Node(IdentityInterface(fields=['contrast_id']), name="infosource") infosource.iterables = [('contrast_id', contrast_list)] # SelectFiles - to grab the data (alternative to DataGrabber) con_file = opj(input_dir_norm, 'warp_complete', 'sub*', 'warpall*', '{contrast_id}_trans.nii') templates = {'cons': con_file} selectfiles = Node(SelectFiles(templates, base_directory=experiment_dir), name="selectfiles") # Datasink - creates output folder for important outputs datasink = Node(DataSink(base_directory=experiment_dir, container=output_dir), name="datasink") # Use the following DataSink output substitutions
def make_neuromet1_workflow(self): # Infosource: Iterate through subject names infosource = Node(interface=IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = ('subject_id', self.subject_list) #unidensource, return for every subject uni and den unidensource = Node(interface=IdentityInterface( fields=['uniden_prefix', 'uniden_suffix']), name="unidensource") unidensource.iterables = [ ('uniden_prefix', ['', 'derivatives/Siemens/']), ('uniden_suffix', ['T1w', 'desc-UNIDEN_MP2RAGE']) ] unidensource.synchronize = True split_sub_str = Node(Function(['subject_str'], ['subject_id', 'session_id'], self.split_subject_ses), name='split_sub_str') info = dict(T1w=[[ 'uniden_prefix', 'subject_id', 'session_id', 'anat', 'subject_id', 'session_id', 'uniden_suffix' ]]) datasource = Node(interface=DataGrabber(infields=[ 'subject_id', 'session_id', 'uniden_prefix', 'uniden_suffix' ], outfields=['T1w']), name='datasource') datasource.inputs.base_directory = self.bids_root datasource.inputs.template = '%ssub-NeuroMET%s/ses-0%s/%s/sub-NeuroMET%s_ses-0%s_%s.nii.gz' datasource.inputs.template_args = info datasource.inputs.sort_filelist = False sink = self.make_sink() segment = self.make_segment() mask = self.make_mask() neuromet = Workflow(name='NeuroMET', base_dir=self.temp_dir) neuromet.connect(infosource, 'subject_id', split_sub_str, 'subject_str') neuromet.connect(split_sub_str, 'subject_id', datasource, 'subject_id') neuromet.connect(split_sub_str, 'session_id', datasource, 'session_id') neuromet.connect(unidensource, 'uniden_prefix', datasource, 'uniden_prefix') neuromet.connect(unidensource, 'uniden_suffix', datasource, 'uniden_suffix') neuromet.connect(datasource, 'T1w', segment, 'ro.in_file') # neuromet.connect() neuromet.connect(segment, 'spm_tissues_split.gm', mask, 'sum_tissues1.in_file') neuromet.connect(segment, 'spm_tissues_split.wm', mask, 'sum_tissues1.operand_files') neuromet.connect(segment, 'spm_tissues_split.csf', mask, 'sum_tissues2.operand_files') neuromet.connect(segment, 'spm_tissues_split.gm', sink, '@gm') neuromet.connect(segment, 'spm_tissues_split.wm', sink, '@wm') neuromet.connect(segment, 'spm_tissues_split.csf', sink, '@csf') neuromet.connect(segment, 'seg.bias_corrected_images', sink, '@biascorr') # neuromet.connect(comb_imgs, 'uni_brain_den_surr_add.out_file', sink, '@img') neuromet.connect(mask, 'gen_mask.out_file', sink, '@mask') neuromet.connect(segment, 'ro.out_file', sink, '@ro') return neuromet
wf.base_dir = os.path.join(wd_dir) nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True, 'remove_unnecessary_outputs': True, 'job_finished_timeout': 120}) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join(wd_dir, 'crash') ds = Node(nio.DataSink(base_directory=ds_dir), name='ds') ###################### # GET DATA ###################### age_infosource = Node(util.IdentityInterface(fields=['age_switch']), name='age_infosource') age_infosource.iterables = ('age_switch', ['full_range', 'adults_only', 'under_18']) def get_subjects_list_and_age_fct(age_switch, df): import os df = df[df.no_axis_1] if age_switch == 'adults_only': df = df[df.AGE_04 >= 18] elif age_switch == 'under_18': df = df[df.AGE_04 < 18] subjects_list = df.leica_id.values age = df.AGE_04.values df_used = os.path.join(os.getcwd(), 'df_used.csv')
def learning_predict_data_2samp_wf(working_dir, ds_dir, in_data_name_list, subjects_selection_crit_dict, subjects_selection_crit_names_list, aggregated_subjects_dir, target_list, use_n_procs, plugin_name, confound_regression=[False, True], run_cv=False, n_jobs_cv=1, run_tuning=False, run_2sample_training=False, aggregated_subjects_dir_nki=None, subjects_selection_crit_dict_nki=None, subjects_selection_crit_name_nki=None, reverse_split=False, random_state_nki=666, run_learning_curve=False, life_test_size=0.5): import os from nipype import config from nipype.pipeline.engine import Node, Workflow import nipype.interfaces.utility as util import nipype.interfaces.io as nio from itertools import chain from learning_utils import aggregate_multimodal_metrics_fct, run_prediction_split_fct, \ backproject_and_split_weights_fct, select_subjects_fct, select_multimodal_X_fct, learning_curve_plot import pandas as pd ############################################################################################################### # GENERAL SETTINGS wf = Workflow(name='learning_predict_data_2samp_wf') wf.base_dir = os.path.join(working_dir) nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': False, 'remove_unnecessary_outputs': False, 'job_finished_timeout': 120}) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash') ds = Node(nio.DataSink(), name='ds') ds.inputs.base_directory = os.path.join(ds_dir, 'group_learning_prepare_data') ds.inputs.regexp_substitutions = [ # ('subject_id_', ''), ('_parcellation_', ''), ('_bp_freqs_', 'bp_'), ('_extraction_method_', ''), ('_subject_id_[A0-9]*/', '') ] ds_pdf = Node(nio.DataSink(), name='ds_pdf') ds_pdf.inputs.base_directory = os.path.join(ds_dir, 'pdfs') ds_pdf.inputs.parameterization = False ############################################################################################################### # ensure in_data_name_list is list of lists in_data_name_list = [i if type(i) == list else [i] for i in in_data_name_list] in_data_name_list_unique = list(set(chain.from_iterable(in_data_name_list))) ############################################################################################################### # SET ITERATORS in_data_name_infosource = Node(util.IdentityInterface(fields=['in_data_name']), name='in_data_name_infosource') in_data_name_infosource.iterables = ('in_data_name', in_data_name_list_unique) multimodal_in_data_name_infosource = Node(util.IdentityInterface(fields=['multimodal_in_data_name']), name='multimodal_in_data_name_infosource') multimodal_in_data_name_infosource.iterables = ('multimodal_in_data_name', in_data_name_list) subject_selection_infosource = Node(util.IdentityInterface(fields=['selection_criterium']), name='subject_selection_infosource') subject_selection_infosource.iterables = ('selection_criterium', subjects_selection_crit_names_list) target_infosource = Node(util.IdentityInterface(fields=['target_name']), name='target_infosource') target_infosource.iterables = ('target_name', target_list) ############################################################################################################### # COMPILE LIFE DATA ############################################################################################################### ############################################################################################################### # GET INFO AND SELECT FILES df_all_subjects_pickle_file = os.path.join(aggregated_subjects_dir, 'df_all_subjects_pickle_file/df_all.pkl') df = pd.read_pickle(df_all_subjects_pickle_file) # build lookup dict for unimodal data X_file_template = 'X_file/_in_data_name_{in_data_name}/vectorized_aggregated_data.npy' info_file_template = 'unimodal_backprojection_info_file/_in_data_name_{in_data_name}/unimodal_backprojection_info.pkl' unimodal_lookup_dict = {} for k in in_data_name_list_unique: unimodal_lookup_dict[k] = {'X_file': os.path.join(aggregated_subjects_dir, X_file_template.format( in_data_name=k)), 'unimodal_backprojection_info_file': os.path.join(aggregated_subjects_dir, info_file_template.format( in_data_name=k)) } ############################################################################################################### # AGGREGATE MULTIMODAL METRICS # stack single modality arrays horizontally aggregate_multimodal_metrics = Node(util.Function(input_names=['multimodal_list', 'unimodal_lookup_dict'], output_names=['X_multimodal_file', 'multimodal_backprojection_info', 'multimodal_name'], function=aggregate_multimodal_metrics_fct), name='aggregate_multimodal_metrics') wf.connect(multimodal_in_data_name_infosource, 'multimodal_in_data_name', aggregate_multimodal_metrics, 'multimodal_list') aggregate_multimodal_metrics.inputs.unimodal_lookup_dict = unimodal_lookup_dict ############################################################################################################### # GET INDEXER FOR SUBJECTS OF INTEREST (as defined by selection criterium) select_subjects = Node(util.Function(input_names=['df_all_subjects_pickle_file', 'subjects_selection_crit_dict', 'selection_criterium'], output_names=['df_use_file', 'df_use_pickle_file', 'subjects_selection_index'], function=select_subjects_fct), name='select_subjects') select_subjects.inputs.df_all_subjects_pickle_file = df_all_subjects_pickle_file select_subjects.inputs.subjects_selection_crit_dict = subjects_selection_crit_dict wf.connect(subject_selection_infosource, 'selection_criterium', select_subjects, 'selection_criterium') ############################################################################################################### # SELECT MULITMODAL X # select subjects (rows) from multimodal X according indexer select_multimodal_X = Node(util.Function(input_names=['X_multimodal_file', 'subjects_selection_index', 'selection_criterium'], output_names=['X_multimodal_selected_file'], function=select_multimodal_X_fct), name='select_multimodal_X') wf.connect(aggregate_multimodal_metrics, 'X_multimodal_file', select_multimodal_X, 'X_multimodal_file') wf.connect(select_subjects, 'subjects_selection_index', select_multimodal_X, 'subjects_selection_index') ############################################################################################################### # COMPILE NKI DATA ############################################################################################################### if run_2sample_training: ############################################################################################################### # GET INFO AND SELECT FILES df_all_subjects_pickle_file_nki = os.path.join(aggregated_subjects_dir_nki, 'df_all_subjects_pickle_file/df_all.pkl') df_nki = pd.read_pickle(df_all_subjects_pickle_file_nki) # build lookup dict for unimodal data X_file_template = 'X_file/_in_data_name_{in_data_name}/vectorized_aggregated_data.npy' info_file_template = 'unimodal_backprojection_info_file/_in_data_name_{in_data_name}/unimodal_backprojection_info.pkl' unimodal_lookup_dict_nki = {} for k in in_data_name_list_unique: unimodal_lookup_dict_nki[k] = {'X_file': os.path.join(aggregated_subjects_dir_nki, X_file_template.format( in_data_name=k)), 'unimodal_backprojection_info_file': os.path.join( aggregated_subjects_dir_nki, info_file_template.format( in_data_name=k)) } ############################################################################################################### # AGGREGATE MULTIMODAL METRICS # stack single modality arrays horizontally aggregate_multimodal_metrics_nki = Node(util.Function(input_names=['multimodal_list', 'unimodal_lookup_dict'], output_names=['X_multimodal_file', 'multimodal_backprojection_info', 'multimodal_name'], function=aggregate_multimodal_metrics_fct), name='aggregate_multimodal_metrics_nki') wf.connect(multimodal_in_data_name_infosource, 'multimodal_in_data_name', aggregate_multimodal_metrics_nki, 'multimodal_list') aggregate_multimodal_metrics_nki.inputs.unimodal_lookup_dict = unimodal_lookup_dict_nki ############################################################################################################### # GET INDEXER FOR SUBJECTS OF INTEREST (as defined by selection criterium) select_subjects_nki = Node(util.Function(input_names=['df_all_subjects_pickle_file', 'subjects_selection_crit_dict', 'selection_criterium'], output_names=['df_use_file', 'df_use_pickle_file', 'subjects_selection_index'], function=select_subjects_fct), name='select_subjects_nki') select_subjects_nki.inputs.df_all_subjects_pickle_file = df_all_subjects_pickle_file_nki select_subjects_nki.inputs.subjects_selection_crit_dict = subjects_selection_crit_dict_nki select_subjects_nki.inputs.selection_criterium = subjects_selection_crit_name_nki ############################################################################################################### # SELECT MULITMODAL X # select subjects (rows) from multimodal X according indexer select_multimodal_X_nki = Node(util.Function(input_names=['X_multimodal_file', 'subjects_selection_index', 'selection_criterium'], output_names=['X_multimodal_selected_file'], function=select_multimodal_X_fct), name='select_multimodal_X_nki') wf.connect(aggregate_multimodal_metrics_nki, 'X_multimodal_file', select_multimodal_X_nki, 'X_multimodal_file') wf.connect(select_subjects_nki, 'subjects_selection_index', select_multimodal_X_nki, 'subjects_selection_index') ############################################################################################################### # RUN PREDICTION # prediction_node_dict = {} backprojection_node_dict = {} prediction_split = Node(util.Function(input_names=['X_file', 'target_name', 'selection_criterium', 'df_file', 'data_str', 'regress_confounds', 'run_cv', 'n_jobs_cv', 'run_tuning', 'X_file_nki', 'df_file_nki', 'reverse_split', 'random_state_nki', 'run_learning_curve', 'life_test_size'], output_names=['scatter_file', 'brain_age_scatter_file', 'df_life_out_file', 'df_nki_out_file', 'df_big_out_file', 'model_out_file', 'df_res_out_file', 'tuning_curve_file', 'scatter_file_cv', 'learning_curve_plot_file', 'learning_curve_df_file'], function=run_prediction_split_fct), name='prediction_split') backproject_and_split_weights = Node(util.Function(input_names=['trained_model_file', 'multimodal_backprojection_info', 'data_str', 'target_name'], output_names=['out_file_list', 'out_file_render_list'], function=backproject_and_split_weights_fct), name='backproject_and_split_weights') i = 0 for reg in confound_regression: the_out_node_str = 'single_source_model_reg_%s_' % (reg) prediction_node_dict[i] = prediction_split.clone(the_out_node_str) the_in_node = prediction_node_dict[i] the_in_node.inputs.regress_confounds = reg the_in_node.inputs.run_cv = run_cv the_in_node.inputs.n_jobs_cv = n_jobs_cv the_in_node.inputs.run_tuning = run_tuning the_in_node.inputs.reverse_split = reverse_split the_in_node.inputs.random_state_nki = random_state_nki the_in_node.inputs.run_learning_curve = run_learning_curve the_in_node.inputs.life_test_size = life_test_size wf.connect(select_multimodal_X, 'X_multimodal_selected_file', the_in_node, 'X_file') wf.connect(target_infosource, 'target_name', the_in_node, 'target_name') wf.connect(subject_selection_infosource, 'selection_criterium', the_in_node, 'selection_criterium') wf.connect(select_subjects, 'df_use_pickle_file', the_in_node, 'df_file') wf.connect(aggregate_multimodal_metrics, 'multimodal_name', the_in_node, 'data_str') wf.connect(the_in_node, 'model_out_file', ds, the_out_node_str + 'trained_model') wf.connect(the_in_node, 'scatter_file', ds_pdf, the_out_node_str + 'scatter') wf.connect(the_in_node, 'brain_age_scatter_file', ds_pdf, the_out_node_str + 'brain_age_scatter') wf.connect(the_in_node, 'df_life_out_file', ds_pdf, the_out_node_str + 'predicted_life') wf.connect(the_in_node, 'df_nki_out_file', ds_pdf, the_out_node_str + 'predicted_nki') wf.connect(the_in_node, 'df_big_out_file', ds_pdf, the_out_node_str + 'predicted') wf.connect(the_in_node, 'df_res_out_file', ds_pdf, the_out_node_str + 'results_error') wf.connect(the_in_node, 'tuning_curve_file', ds_pdf, the_out_node_str + 'tuning_curve') wf.connect(the_in_node, 'scatter_file_cv', ds_pdf, the_out_node_str + 'scatter_cv') wf.connect(the_in_node, 'learning_curve_plot_file', ds_pdf, the_out_node_str + 'learning_curve_plot_file.@plot') wf.connect(the_in_node, 'learning_curve_df_file', ds_pdf, the_out_node_str + 'learning_curve_df_file.@df') # NKI if run_2sample_training: wf.connect(select_multimodal_X_nki, 'X_multimodal_selected_file', the_in_node, 'X_file_nki') wf.connect(select_subjects_nki, 'df_use_pickle_file', the_in_node, 'df_file_nki') else: the_in_node.inputs.df_file_nki = None the_in_node.inputs.X_file_nki = None # BACKPROJECT PREDICTION WEIGHTS # map weights back to single modality original format (e.g., nifti or matrix) the_out_node_str = 'backprojection_single_source_model_reg_%s_' % (reg) backprojection_node_dict[i] = backproject_and_split_weights.clone(the_out_node_str) the_from_node = prediction_node_dict[i] the_in_node = backprojection_node_dict[i] wf.connect(the_from_node, 'model_out_file', the_in_node, 'trained_model_file') wf.connect(aggregate_multimodal_metrics, 'multimodal_backprojection_info', the_in_node, 'multimodal_backprojection_info') wf.connect(aggregate_multimodal_metrics, 'multimodal_name', the_in_node, 'data_str') wf.connect(target_infosource, 'target_name', the_in_node, 'target_name') wf.connect(the_in_node, 'out_file_list', ds_pdf, the_out_node_str + '.@weights') wf.connect(the_in_node, 'out_file_render_list', ds_pdf, the_out_node_str + 'renders.@renders') i += 1 ############################################################################################################### # # RUN WF wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == 'CondorDAGMan': wf.run(plugin=plugin_name) if plugin_name == 'MultiProc': wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
# in and out similarity.base_dir = "/scr/kansas1/huntenburg/" similarity.config["execution"] = {"remove_unnecessary_outputs": "False"} out_dir = "/scr/jessica2/Schaare/LEMON/preprocessed/" data_dir = "/scr/jessica2/Schaare/LEMON/preprocessed/" # subjects=['LEMON001'] subjects = [] f = open("/scr/jessica2/Schaare/LEMON/done_freesurfer.txt", "r") for line in f: subjects.append(line.strip()) subjects.remove("LEMON027") # create inforsource to iterate over subjects infosource = Node(util.IdentityInterface(fields=["subject_id"]), name="infosource") infosource.iterables = ("subject_id", subjects) # select files templates = { "anat_brain": "{subject_id}/freesurfer_anatomy/brain_out.nii.gz", "lin_mean_coreg": "{subject_id}/coreg/lin_mean_coreg.nii.gz", "nonlin_mean_coreg": "{subject_id}/nonlin_coreg/nonlin_mean_coreg.nii.gz", "fmap_mean_coreg": "{subject_id}/fieldmap_coreg/fmap_mean_coreg.nii.gz", "topup_mean_coreg": "{subject_id}/topup_coreg/topup_mean_coreg.nii.gz", } selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="selectfiles")
preproc.connect(remove_noise, "out_file", bandpass_filter, "in_file") preproc.connect(bandpass_filter, "out_file", outputnode, "filtered_file") ################################################################################################################################### # in and out preproc.base_dir = "/scr/kansas1/huntenburg/" preproc.config["execution"] = {"remove_unnecessary_outputs": "False"} out_dir = "/scr/" data_dir = "/scr/" subjects = ["LEMON006"] # ,'LEMON001','LEMON087','LEMON030','LEMON044','LEMON071'] # infosource to iterate over subjects subject_infosource = Node(util.IdentityInterface(fields=["subject_id"]), name="subject_infosource") subject_infosource.iterables = ("subject_id", subjects) # infosource to iterate over coregistration methods cor_method_infosource = Node(util.IdentityInterface(fields=["cor_method"]), name="cor_method_infosource") cor_method_infosource.iterables = ("cor_method", ["lin_ts"]) # , 'lin_ts', 'nonlin_ts', 'fmap_ts', 'topup_ts']) # select files templates = { "timeseries": "kansas1/huntenburg/*_timeseries/_subject_id_{subject_id}/*apply*/{cor_method}.nii.gz", #'par_file':'jessica2/Schaare/LEMON/preprocessed/{subject_id}/motion_correction/rest_moco.nii.gz.par' } selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="selectfiles")
sessions = ['d0'] # directories working_dir = '/nobackup/eminem2/schmidt/MMPIRS/preprocessing/working_dir' out_dir = '/nobackup/eminem2/schmidt/MMPIRS/preprocessing/final/' # main workflow preproc_nuisance_regress = Workflow(name='func_preproc_nuisance_regress') preproc_nuisance_regress.base_dir = working_dir preproc_nuisance_regress.config['execution'][ 'crashdump_dir'] = preproc_nuisance_regress.base_dir + "/crash_files" # iterate over subjects subject_infosource = Node(util.IdentityInterface(fields=['subjectlist']), name='subject_infosource') subject_infosource.iterables = [('subjectlist', subjects)] # iterate over sessions session_infosource = Node(util.IdentityInterface(fields=['session']), name='session_infosource') session_infosource.iterables = [('session', sessions)] # select files templates = { 'unwarped_file': '/nobackup/eminem2/schmidt/MMPIRS/preprocessing/working_dir/func_preproc/_session_{session}/_subjectlist_{proband}.{subject}/fugue/corr_{subject}_{session}_S3_RS_ep2d_SMS6_TR1p1_TE22_FA40_1p2_FatSat_Echo_0_Te22_roi_unwarped.nii.gz', #'unwarped_file' : '/nobackup/eminem2/schmidt/MMPIRS/preprocessing/{subject}/fugue/corr_{subject}_{session}_S3_RS_ep2d_SMS6_TR1p1_TE22_FA40_1p2_FatSat_Echo_0_Te22_roi_unwarped.nii.gz', 'slicemoco_par_file': '/nobackup/eminem2/schmidt/MMPIRS/preprocessing/working_dir/func_preproc/_session_{session}/_subjectlist_{proband}.{subject}/spacetime_realign/{subject}_{session}_S3_RS_ep2d_SMS6_TR1p1_TE22_FA40_1p2_FatSat_Echo_0_Te22_roi.nii.gz.par', # need brain mask, csf and wm mask in functional space - from cbstools coreg pipeline
fs_skullstrip_wf = create_freesurfer_skullstrip_workflow() fs_skullstrip_wf.inputs.inputspec.subjects_dir = fs_projdir sids = [ 'sub-01', 'sub-02', 'sub-03', 'sub-04', 'sub-05', 'sub-06', 'sub-07', 'sub-09', 'sub-10', 'sub-11', 'sub-12', 'sub-13', 'sub-14', 'sub-15' ] # Set up the FreeSurfer skull stripper work flow antsreg_wf = Workflow(name='antsreg_wf') antsreg_wf.base_dir = workingdir subjID_infosource = Node( IdentityInterface(fields=['subject_id', 'subjects_dir']), name='subjID_infosource') subjID_infosource.iterables = ('subject_id', sids) antsreg_wf.connect(subjID_infosource, 'subject_id', fs_skullstrip_wf, 'inputspec.subject_id') # Use a JoinNode to aggregrate all of the outputs from the fs_skullstrip_wf reg = Node(ants.Registration(), name='antsRegister') reg.inputs.fixed_image = '/scratch/PSB6351_2017/ds008_R2.0.0/template/T1_template/study_template.nii.gz' reg.inputs.output_transform_prefix = "output_" reg.inputs.transforms = ['Rigid', 'Affine', 'SyN'] reg.inputs.transform_parameters = [(0.1, ), (0.1, ), (0.2, 3.0, 0.0)] reg.inputs.number_of_iterations = [[10000, 11110, 11110]] * 2 + [[ 100, 100, 50 ]] reg.inputs.dimension = 3 reg.inputs.write_composite_transform = True
name='apply2mean') # Initiation of the ANTS normalization workflow normflow = Workflow(name='normflow') normflow.base_dir = opj(experiment_dir, working_dir) # Connect up ANTS normalization components normflow.connect([(antsreg, apply2con, [('composite_transform', 'transforms')]), (antsreg, apply2mean, [('composite_transform', 'transforms')]) ]) # Infosource - a function free node to iterate over the list of subject names infosource = Node(IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = [('subject_id', subject_list)] # SelectFiles - to grab the data (alternativ to DataGrabber) anat_file = opj('freesurfer', '{subject_id}', 'mri/brain.mgz') func_file = opj(input_dir_1st, 'contrasts', '{subject_id}', '_mriconvert*/*_out.nii.gz') func_orig_file = opj(input_dir_1st, 'contrasts', '{subject_id}', '[ce]*.nii') mean_file = opj(input_dir_1st, 'preprocout', '{subject_id}', 'mean*.nii') templates = {'anat': anat_file, 'func': func_file, 'func_orig': func_orig_file, 'mean': mean_file, } selectfiles = Node(SelectFiles(templates,
subject_list = ['003','005','008','011','018','019','020', '059', '060','062','063','066'] session_list = ['run001', 'run002', 'run003'] output_dir = '10Hz_10s_Task_Based_OutputDir' working_dir = '10Hz_10s_Task_Based_WorkingDir' preproc_task = Workflow(name = 'preproc_task') preproc_task.base_dir = opj(experiment_dir, working_dir) #----------------------------------------------------------------------------------------------------- # In[20]: # Infosource - a function free node to iterate over the list of subject names infosource = Node(IdentityInterface(fields=['subject_id','session_id']), name="infosource") infosource.iterables = [('subject_id', subject_list), ('session_id', session_list)] #----------------------------------------------------------------------------------------------------- # In[21]: templates = { 'Anat_Bias' : '/media/amr/HDD/Work/Stimulation/Registration_Stimulation_WorkingDir/Registration_Stimulation/_subject_id_{subject_id}/BiasFieldCorrection/Anat_{subject_id}_bet_corrected.nii.gz', 'Anat_Mask' : 'Data/{subject_id}/Anat_{subject_id}_Mask.nii.gz', 'Highres2Temp_Transformations' : '/media/amr/HDD/Work/Stimulation/Registration_Stimulation_WorkingDir/Registration_Stimulation/_subject_id_{subject_id}/HighresToTemplate/transformComposite.h5', 'Stim_10Hz_10s' : 'Data/{subject_id}/Stim_{subject_id}_??_10Hz_10s_{session_id}.nii.gz', 'EPI_Mask' : 'Data/{subject_id}/EPI_{subject_id}_Mask.nii.gz' }
fmapepi.base_dir='/scr/kansas1/huntenburg/lemon_missing/working_dir/' #fmapepi.config['execution']={'remove_unnecessary_outputs': 'False'} data_dir = '/scr/jessica2/Schaare/LEMON/' fs_subjects_dir='/scr/jessica2/Schaare/LEMON/freesurfer/' out_dir = '/scr/jessica2/Schaare/LEMON/preprocessed/' #subjects=['LEMON001'] subjects=[] f = open('/scr/jessica2/Schaare/LEMON/missing_subjects.txt','r') for line in f: subjects.append(line.strip()) # create inforsource to iterate over subjects infosource = Node(util.IdentityInterface(fields=['subject_id','fs_subjects_dir']), name='infosource') infosource.inputs.fs_subjects_dir=fs_subjects_dir infosource.iterables=('subject_id', subjects) # define templates and select files templates={'epi_mean':'preprocessed/{subject_id}/motion_correction/rest_moco_mean.nii.gz', 'mag': 'raw/{subject_id}/rest/fmap_mag_1.nii.gz', 'phase': 'raw/{subject_id}/rest/fmap_phase.nii.gz', 'anat_head': 'preprocessed/{subject_id}/freesurfer_anatomy/T1_out.nii.gz', 'anat_brain': 'preprocessed/{subject_id}/freesurfer_anatomy/brain_out.nii.gz', 'wmseg':'preprocessed/{subject_id}/freesurfer_anatomy/brain_out_wmseg.nii.gz'} selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="selectfiles") #sink to store files sink = Node(nio.DataSink(base_directory=out_dir,
working_dir = 'Stimulation_Preproc_WorkingDir_CA3' stimulation_preproc = Workflow(name='stimulation_preproc_CA3') stimulation_preproc.base_dir = opj(experiment_dir, working_dir) # ===================================================================================================== # In[3]: # to prevent nipype from iterating over the anat image with each func run, you need seperate # nodes to select the files # and this will solve the problem I have for almost 6 months # but notice that in the sessions, you have to iterate also over subject_id to get the {subject_id} var # Infosource - a function free node to iterate over the list of subject names infosource_anat = Node(IdentityInterface(fields=['subject_id']), name="infosource_anat") infosource_anat.iterables = [('subject_id', subject_list)] infosource_func = Node( IdentityInterface(fields=['subject_id', 'session_id', 'frequency_id']), name="infosource_func") infosource_func.iterables = [('subject_id', subject_list), ('session_id', session_list), ('frequency_id', frequency_list)] # ======================================================================================================== # In[4]: # /home/in/aeed/poldrack_gabmling/ds000005/sub-01/anat/sub-01_T1w.nii.gz # anatomical images templates_anat = { 'anat': '/media/amr/Amr_4TB/Work/stimulation/Data_CA3/{subject_id}/Anat_{subject_id}_bet.nii.gz'
def mean_con_mat_wf(subjects_list, preprocessed_data_dir, working_dir, ds_dir, parcellations_list, extraction_methods_list, bp_freq_list, use_n_procs, plugin_name): import os from nipype import config from nipype.pipeline.engine import Node, Workflow, MapNode, JoinNode import nipype.interfaces.utility as util import nipype.interfaces.io as nio from nipype.interfaces.freesurfer.utils import ImageInfo from utils import aggregate_data ##################################### # GENERAL SETTINGS ##################################### wf = Workflow(name='mean_con_mats') wf.base_dir = os.path.join(working_dir) nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True, 'remove_unnecessary_outputs': True, 'job_finished_timeout': 120}) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash') ds = Node(nio.DataSink(), name='ds') ds.inputs.base_directory = os.path.join(ds_dir, 'group_conmats_test') ds.inputs.regexp_substitutions = [ # ('subject_id_', ''), ('_parcellation_', ''), ('_bp_freqs_', 'bp_'), ('_extraction_method_', ''), ('_subject_id_[A0-9]*/', '') ] ##################################### # SET ITERATORS ##################################### # SUBJECTS ITERATOR subjects_infosource = Node(util.IdentityInterface(fields=['subject_id']), name='subjects_infosource') subjects_infosource.iterables = ('subject_id', subjects_list) # PARCELLATION ITERATOR parcellation_infosource = Node(util.IdentityInterface(fields=['parcellation']), name='parcellation_infosource') parcellation_infosource.iterables = ('parcellation', parcellations_list) # BP FILTER ITERATOR bp_filter_infosource = Node(util.IdentityInterface(fields=['bp_freqs']), name='bp_filter_infosource') bp_filter_infosource.iterables = ('bp_freqs', bp_freq_list) # EXTRACTION METHOD ITERATOR extraction_method_infosource = Node(util.IdentityInterface(fields=['extraction_method']), name='extraction_method_infosource') extraction_method_infosource.iterables = ('extraction_method', extraction_methods_list) def create_file_list_fct(subjects_list, base_path, parcellation, bp_freqs, extraction_method): import os file_list = [] for s in subjects_list: file_list.append(os.path.join(base_path, s, 'metrics/con_mat/matrix', 'bp_%s.%s'%(bp_freqs), parcellation, extraction_method, 'matrix.pkl')) return file_list create_file_list = Node(util.Function(input_names=['subjects_list', 'base_path', 'parcellation', 'bp_freqs', 'extraction_method'], output_names=['file_list'], function=create_file_list_fct), name='create_file_list') create_file_list.inputs.subjects_list = subjects_list create_file_list.inputs.base_path = preprocessed_data_dir wf.connect(parcellation_infosource, 'parcellation', create_file_list, 'parcellation') wf.connect(bp_filter_infosource, 'bp_freqs', create_file_list, 'bp_freqs') wf.connect(extraction_method_infosource, 'extraction_method', create_file_list, 'extraction_method') aggregate = Node(util.Function(input_names=['file_list'], output_names=['merged_file'], function=aggregate_data), name='aggregate') wf.connect(create_file_list, 'file_list', aggregate, 'file_list') def plot_matrix_fct(in_file): import pickle, os import pylab as plt import numpy as np with open(in_file, 'r') as f: matrix_dict = pickle.load(f) out_file_list = [] for m_type in matrix_dict.keys(): mean_matrix = np.mean(matrix_dict[m_type], axis=0) fig = plt.imshow(mean_matrix, interpolation='nearest') plt.title(in_file) out_file = os.path.join(os.getcwd(), m_type+'.png') out_file_list.append(out_file) plt.savefig(out_file) return out_file_list plot_matrix = Node(util.Function(input_names=['in_file'], output_names=['out_file_list'], function=plot_matrix_fct), name='plot_matrix') wf.connect(aggregate, 'merged_file', plot_matrix, 'in_file') wf.connect(plot_matrix, 'out_file_list', ds, 'group_mats.@groupmats') ##################################### # RUN WF ##################################### wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == 'CondorDAGMan': wf.run(plugin=plugin_name) if plugin_name == 'MultiProc': wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
output_dir = 'DTI_TBSS_Wax' working_dir = 'DTI_TBSS_workingdir_Wax_Template' DTI_TBSS_Wax = Workflow(name='DTI_TBSS_Wax') DTI_TBSS_Wax.base_dir = opj(experiment_dir, working_dir) #----------------------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------------------- # In[3]: # Infosource - a function free node to iterate over the list of subject names infosource = Node(IdentityInterface(fields=['map_id']), name="infosource") infosource.iterables = [('map_id', map_list)] #----------------------------------------------------------------------------------------------------- # In[4]: templates = { 'all_skeleton': 'Waxholm_Template/*/{map_id}/All_*_skeletonised.nii.gz', 'skeleton_mask': 'Waxholm_Template/*/{map_id}/mean_FA_skeleton_mask.nii.gz', 'all_image': 'Waxholm_Template/*/{map_id}/All_{map_id}_WAX.nii.gz', 'mean_FA': 'Waxholm_Template/*/{map_id}/mean_FA.nii.gz', } selectfiles = Node(SelectFiles(templates, base_directory=experiment_dir), name="selectfiles") #-----------------------------------------------------------------------------------------------------
(realign, art, [('realigned_files', 'realigned_files'), ('mean_image', 'mask_file'), ('realignment_parameters', 'realignment_parameters')]), (realign, smooth, [('realigned_files', 'in_files')]), ]) ### # Input & Output Stream # Infosource - a function free node to iterate over the list of subject names infosource = Node(IdentityInterface(fields=['subject_id', 'session_id']), name="infosource") infosource.iterables = [('subject_id', subject_list), ('session_id', session_list)] # SelectFiles templates = {'func': 'data/{subject_id}/{session_id}.nii.gz'} selectfiles = Node(SelectFiles(templates, base_directory=experiment_dir), name="selectfiles") # Datasink datasink = Node(DataSink(base_directory=experiment_dir, container=output_dir), name="datasink") # Use the following DataSink output substitutions substitutions = [('_subject_id', ''), ('_session_id_', '')]
def run_workflow(undist): # ------------------ Specify variables ds_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) data_dir = ds_root output_dir = 'motion-correction' working_dir = 'workingdirs/motion-correction' # ------------------ Input Files infosource = Node(IdentityInterface(fields=[ 'subject_id', 'session_id', 'use_contours', 'smooth', 'dof', 'mcflirt_stages', ]), name="infosource") infosource.iterables = [ ('session_id', session_list), ('subject_id', subject_list), ('smooth', [1.0]), # ('dof', [6]), # ('mcflirt_stages', [3]), ] if undist: ud_flag = 'preproc_undist_PLUS' else: ud_flag = 'preproc' # SelectFiles templates = { 'funcs': 'resampled-isotropic-1mm/sub-{subject_id}/ses-{session_id}/func/' 'sub-{subject_id}_ses-{session_id}_' 'task-*run-01*_bold_res-1x1x1_' + ud_flag + '.nii.gz', 'manualweights': 'manual-masks/sub-eddy/ses-20170511/func/' 'sub-eddy_ses-20170511_task-curvetracing_run-01_frame-50_bold_' 'res-1x1x1_manualweights.nii.gz', } inputfiles = Node( nio.SelectFiles(templates, base_directory=data_dir), name="input_files") # ------------------ Output Files # Datasink outputfiles = Node(nio.DataSink( base_directory=ds_root, container=output_dir, parameterization=True), name="output_files") # Use the following DataSink output substitutions outputfiles.inputs.substitutions = [ ('subject_id_', 'sub-'), ('session_id_', 'ses-'), ('/motioncorrected/', '/'), ('_mcf.nii.gz', '.nii.gz') # BIDS Extension Proposal: BEP003 # ('_resample.nii.gz', '_res-1x1x1_preproc.nii.gz'), # remove subdirectories: # ('resampled-isotropic-1mm/isoxfm-1mm', 'resampled-isotropic-1mm'), # ('resampled-isotropic-1mm/mriconv-1mm', 'resampled-isotropic-1mm'), ] # Put result into a BIDS-like format outputfiles.inputs.regexp_substitutions = [ (r'_ses-([a-zA-Z0-9]*)_sub-([a-zA-Z0-9]*)', r'sub-\2/ses-\1'), (r'_mcflirt[0-9]+/', r'func/'), ] # -------------------------------------------- Create Pipeline workflow = Workflow( name='motion_correction', base_dir=os.path.join(ds_root, working_dir)) workflow.connect([(infosource, inputfiles, [('subject_id', 'subject_id'), ('session_id', 'session_id'), ('use_contours', 'use_contours'), ('mcflirt_stages', 'stages'), ('smooth', 'smooth'), ('dof', 'dof'), ])]) mc = create_workflow_afni() workflow.connect(inputfiles, 'funcs', mc, 'in.funcs') workflow.connect(inputfiles, 'manualweights', mc, 'in.manualweights') workflow.connect(inputfiles, 'manualweights_func_ref', mc, 'in.manualweights_func_ref') workflow.connect(mc, 'mc.out_file', outputfiles, 'motioncorrected') workflow.stop_on_first_crash = True workflow.keep_inputs = True workflow.remove_unnecessary_outputs = False workflow.write_graph() workflow.run()
# directories working_dir = '/scr/ilz3/myelinconnect/working_dir/' data_dir= '/scr/ilz3/myelinconnect/struct/' out_dir = '/scr/ilz3/myelinconnect/struct/medial_wall' # set fsl output type to nii.gz fsl.FSLCommand.set_default_output_type('NIFTI_GZ') # main workflow medwall = Workflow(name='medwall') medwall.base_dir = working_dir medwall.config['execution']['crashdump_dir'] = medwall.base_dir + "/crash_files" # iterate over subjects subject_infosource = Node(util.IdentityInterface(fields=['subject']), name='subject_infosource') subject_infosource.iterables=[('subject', subjects_db)] # select files templates={'sub_gm': 'medial_wall/input/{subject}*_sub_gm.nii.gz', 'sub_csf': 'medial_wall/input/{subject}*_sub_csf.nii.gz', 'thickness_rh' : 'thickness/{subject}*right_cortex_thick.nii.gz', 'thickness_lh' : 'thickness/{subject}*left_cortex_thick.nii.gz',} selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="selectfiles") medwall.connect([(subject_infosource, selectfiles, [('subject', 'subject')]) ]) addmasks= Node(fsl.BinaryMaths(operation='add'), name='addmasks')
working_dir = '/scr/ilz3/myelinconnect/working_dir/' data_dir= '/scr/ilz3/myelinconnect/' out_dir = '/scr/ilz3/myelinconnect/final_struct_space/rest1_1_trans' # set fsl output type to nii.gz fsl.FSLCommand.set_default_output_type('NIFTI_GZ') # main workflow smooth = Workflow(name='smooth') smooth.base_dir = working_dir smooth.config['execution']['crashdump_dir'] = smooth.base_dir + "/crash_files" # iterate over subjects subject_infosource = Node(util.IdentityInterface(fields=['subject']), name='subject_infosource') subject_infosource.iterables=[('subject', subjects_db)] # iterate over sessions session_infosource = Node(util.IdentityInterface(fields=['session']), name='session_infosource') session_infosource.iterables=[('session', sessions)] # select files templates={'rest': 'final_struct_space/rest1_1_trans/{subject}_{session}_denoised_trans.nii.gz' } selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="selectfiles") smooth.connect([(subject_infosource, selectfiles, [('subject', 'subject')]), (session_infosource, selectfiles, [('session', 'session')]) ])
def calc_local_metrics( preprocessed_data_dir, subject_id, parcellations_dict, bp_freq_list, fd_thresh, working_dir, ds_dir, use_n_procs, plugin_name, ): import os from nipype import config from nipype.pipeline.engine import Node, Workflow, MapNode import nipype.interfaces.utility as util import nipype.interfaces.io as nio import nipype.interfaces.fsl as fsl import utils as calc_metrics_utils ##################################### # GENERAL SETTINGS ##################################### fsl.FSLCommand.set_default_output_type("NIFTI_GZ") wf = Workflow(name="LeiCA_LIFE_metrics") wf.base_dir = os.path.join(working_dir) nipype_cfg = dict( logging=dict(workflow_level="DEBUG"), execution={"stop_on_first_crash": True, "remove_unnecessary_outputs": True, "job_finished_timeout": 15}, ) config.update_config(nipype_cfg) wf.config["execution"]["crashdump_dir"] = os.path.join(working_dir, "crash") ds = Node(nio.DataSink(base_directory=ds_dir), name="ds") ds.inputs.regexp_substitutions = [ ("MNI_resampled_brain_mask_calc.nii.gz", "falff.nii.gz"), ("residual_filtered_3dT.nii.gz", "alff.nii.gz"), ("_parcellation_", ""), ("_bp_freqs_", "bp_"), ] ##################### # ITERATORS ##################### # PARCELLATION ITERATOR parcellation_infosource = Node(util.IdentityInterface(fields=["parcellation"]), name="parcellation_infosource") parcellation_infosource.iterables = ("parcellation", parcellations_dict.keys()) bp_filter_infosource = Node(util.IdentityInterface(fields=["bp_freqs"]), name="bp_filter_infosource") bp_filter_infosource.iterables = ("bp_freqs", bp_freq_list) selectfiles = Node( nio.SelectFiles( { "parcellation_time_series": "{subject_id}/con_mat/parcellated_time_series/bp_{bp_freqs}/{parcellation}/parcellation_time_series.npy" }, base_directory=preprocessed_data_dir, ), name="selectfiles", ) selectfiles.inputs.subject_id = subject_id wf.connect(parcellation_infosource, "parcellation", selectfiles, "parcellation") wf.connect(bp_filter_infosource, "bp_freqs", selectfiles, "bp_freqs") fd_file = Node( nio.SelectFiles({"fd_p": "{subject_id}/QC/FD_P_ts"}, base_directory=preprocessed_data_dir), name="fd_file" ) fd_file.inputs.subject_id = subject_id ############## ## CON MATS ############## ############## ## extract ts ############## get_good_trs = Node( util.Function( input_names=["fd_file", "fd_thresh"], output_names=["good_trs", "fd_scrubbed_file"], function=calc_metrics_utils.get_good_trs, ), name="get_good_trs", ) wf.connect(fd_file, "fd_p", get_good_trs, "fd_file") get_good_trs.inputs.fd_thresh = fd_thresh parcellated_ts_scrubbed = Node( util.Function( input_names=["parcellation_time_series_file", "good_trs"], output_names=["parcellation_time_series_scrubbed"], function=calc_metrics_utils.parcellation_time_series_scrubbing, ), name="parcellated_ts_scrubbed", ) wf.connect(selectfiles, "parcellation_time_series", parcellated_ts_scrubbed, "parcellation_time_series_file") wf.connect(get_good_trs, "good_trs", parcellated_ts_scrubbed, "good_trs") ############## ## get conmat ############## con_mat = Node( util.Function( input_names=["in_data", "extraction_method"], output_names=["matrix", "matrix_file"], function=calc_metrics_utils.calculate_connectivity_matrix, ), name="con_mat", ) con_mat.inputs.extraction_method = "correlation" wf.connect(parcellated_ts_scrubbed, "parcellation_time_series_scrubbed", con_mat, "in_data") ############## ## ds ############## wf.connect(get_good_trs, "fd_scrubbed_file", ds, "QC.@fd_scrubbed_file") fd_str = ("%.1f" % fd_thresh).replace(".", "_") wf.connect(con_mat, "matrix_file", ds, "con_mat.matrix_scrubbed_%s.@mat" % fd_str) # wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') # wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') # wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == "CondorDAGMan": wf.run(plugin=plugin_name, plugin_args={"initial_specs": "request_memory = 1500"}) if plugin_name == "MultiProc": wf.run(plugin=plugin_name, plugin_args={"n_procs": use_n_procs})
Created on Tue Aug 25 11:39:05 2015 @author: craigmoodie """ from nipype.pipeline.engine import Workflow, Node, MapNode from variables import data_dir, work_dir, subject_list, plugin, plugin_args surface_workflow = Workflow(name="qc_workflow") surface_workflow.base_dir = work_dir from nipype import SelectFiles templates = dict(T1="*_{subject_id}_*/T1w_MPR_BIC_v1/*00001.nii*") file_list = Node(SelectFiles(templates), name = "EPI_and_T1_File_Selection") file_list.inputs.base_directory = data_dir file_list.iterables = [("subject_id", subject_list)] from nipype.interfaces.freesurfer import ReconAll reconall = Node(ReconAll(), name = "Recon_All") reconall.inputs.subject_id = "subject_id" reconall.inputs.directive = 'all' reconall.inputs.subjects_dir = data_dir #reconall.inputs.T1_files = "T1" #reconall.run() surface_workflow.connect(file_list,"T1", reconall, "T1_files") surface_workflow.run(plugin=plugin, plugin_args=plugin_args)
def main(): ####################### # Commandline Arguments ####################### # list of subject identifiers task_name = "Training" if training else "Test" print(project_folder, subject_list, task_name, nb_prc) ############################################################# # Extracting fMRI Params (Only works with Kamitani's Dataset) ############################################################# TR = 3.0 voxel_size = (3, 3, 3) number_of_slices = 50 json_file1 = opj(project_folder, "dataset/ds001246-download/task-imagery_bold.json") json_file2 = opj(project_folder, "dataset/ds001246-download/task-perception_bold.json") file = open(json_file1) data = json.load(file) slice_timing1 = data['SliceTiming'] file.close() file = open(json_file2) data = json.load(file) slice_timing2 = data['SliceTiming'] file.close() sorted1 = np.argsort(slice_timing1) sorted2 = np.argsort(slice_timing2) print(np.all(sorted1 == sorted2)) slice_order = list(sorted1 + 1) print("Slice order:", slice_order) ########################## # Creating essential nodes ########################## # Model Spec modelspec_node = Node(SpecifySPMModel(concatenate_runs=True, input_units='secs', output_units='secs', time_repetition=TR, high_pass_filter_cutoff=128), name='modelspec') # Level1Design - Generates a SPM design matrix level1design_node = Node(Level1Design(bases={'hrf': { 'derivs': [0, 0] }}, timing_units='secs', interscan_interval=TR, model_serial_correlations='AR(1)', mask_threshold='-Inf'), name="level1design") # EstimateModel - estimate the parameters of the model (GLM) level1estimate_node = Node( EstimateModel(estimation_method={'Classical': 1}), name="level1estimate") # Infosource - a function free node to iterate over the list of subject names infosrc_subjects = Node(IdentityInterface(fields=['subject_id']), name="infosrc_subjects") infosrc_subjects.iterables = [('subject_id', subject_list)] # SelectFiles - it select files based on template matching tsv_file = opj('dataset', 'ds001246-download', '{subject_id}', 'ses-p*' + task_name + '*', 'func', '{subject_id}_ses-p*' + task_name + '*_task-*_events.tsv') reg_file = opj('preprocess', '_subject_id_{subject_id}', '_session_id_ses-p*' + task_name + '*', 'Realign', 'rp_a{subject_id}_ses-p*' + task_name + '*_task-*_bold.txt') func_file = opj( 'preprocess', '_subject_id_{subject_id}', '_session_id_ses-p*' + task_name + '*', 'Coregister', 'rara{subject_id}_ses-p*' + task_name + '*_task-*_bold.nii') mask_file = opj('datasink', 'preprocessed_masks', '{subject_id}', '{subject_id}_full_mask.nii') templates = { 'tsv': tsv_file, 'reg': reg_file, 'func': func_file, 'mask': mask_file } selectfiles = Node(SelectFiles(templates, base_directory=project_folder), name="selectfiles") # Subject Info subject_info_node = Node(Function( input_names=['tsv_files'], output_names=['subject_info'], function=read_tsv_train if training else read_tsv_test), name='subject_info') # Datasink - creates output folder for important outputs datasink_node = Node(DataSink(base_directory=project_folder, container='datasink'), name="datasink") substitutions = [('_subject_id_', '')] datasink_node.inputs.substitutions = substitutions ##################### # Create the workflow ##################### wf_name = 'glm_train_nomod' if training else 'glm_test' glm = Workflow(name=wf_name) glm.base_dir = project_folder # connect infosource to selectfile glm.connect([(infosrc_subjects, selectfiles, [('subject_id', 'subject_id') ])]) glm.connect([(selectfiles, subject_info_node, [('tsv', 'tsv_files')])]) # connect infos to modelspec glm.connect([(subject_info_node, modelspec_node, [('subject_info', 'subject_info')])]) glm.connect([(selectfiles, modelspec_node, [('reg', 'realignment_parameters')])]) glm.connect([(selectfiles, modelspec_node, [('func', 'functional_runs')])]) # connect modelspec to level1design glm.connect([(modelspec_node, level1design_node, [('session_info', 'session_info')])]) glm.connect([(selectfiles, level1design_node, [('mask', 'mask_image')])]) # connect design to estimate glm.connect([(level1design_node, level1estimate_node, [('spm_mat_file', 'spm_mat_file')])]) # keeping estimate files params glm.connect([(level1estimate_node, datasink_node, [('mask_image', f'{wf_name}.@mask_img')])]) glm.connect([(level1estimate_node, datasink_node, [('beta_images', f'{wf_name}.@beta_imgs')])]) glm.connect([(level1estimate_node, datasink_node, [('residual_image', f'{wf_name}.@res_img')])]) glm.connect([(level1estimate_node, datasink_node, [('RPVimage', f'{wf_name}.@rpv_img')])]) glm.connect([(level1estimate_node, datasink_node, [('spm_mat_file', f'{wf_name}.@spm_mat_file')])]) glm.write_graph(graph2use='flat', format='png', simple_form=True) # from IPython.display import Image # Image(filename=opj(glm.base_dir, {wf_name}, 'graph_detailed.png')) ################## # Run the workflow ################## glm.run('MultiProc', plugin_args={'n_procs': nb_prc})
def create_volatlas_workflow(wf_name, wf_base_dir, subject_list, cnxn_names, fstr_dict, ref_file, agg_cnxn_names_dict): from nipype.pipeline import engine as pe from nipype.pipeline.engine import Node, JoinNode, MapNode, Workflow from nipype.pipeline.engine.utils import IdentityInterface from nipype.interfaces import Function from nipype.interfaces.io import DataSink """ Variables """ dpy_fstr = fstr_dict['dpy'] warp_fstr = fstr_dict['warp'] parc_fstr = fstr_dict['parc'] cnxn_mapping_fstr = fstr_dict['cnxn_mapping'] """ Node: Infosource """ # (iterates over subjects) def mirror(subject_id): return subject_id mirror_npfunc = Function(['subject_id'], ['subject_id'], mirror) node__infosource = Node(interface=mirror_npfunc, name="infosource") node__infosource.iterables = [("subject_id", subject_list)] """ Node: Get data """ # (also iterates over cnxn ids) def get_sub_files_func(subject_id, cnxn_name, dpy_fstr, warp_fstr, parc_fstr, cnxn_mapping_fstr): dpy_file = dpy_fstr % subject_id cnxn_mapping_file = cnxn_mapping_fstr % subject_id parc_file = parc_fstr % subject_id warp_file = warp_fstr % subject_id return dpy_file, parc_file, warp_file, cnxn_mapping_file, cnxn_name, subject_id get_sub_files_npfunc = Function([ 'subject_id', 'cnxn_name', 'dpy_fstr', 'warp_fstr', 'parc_fstr', 'cnxn_mapping_fstr' ], [ 'dpy_file', 'parc_file', 'warp_file', 'cnxn_mapping_file', 'cnxn_name', 'subject_id' ], get_sub_files_func) node__datasource = Node(interface=get_sub_files_npfunc, name='datasource') node__datasource.inputs.dpy_fstr = dpy_fstr node__datasource.inputs.parc_fstr = parc_fstr node__datasource.inputs.warp_fstr = warp_fstr node__datasource.inputs.cnxn_mapping_fstr = cnxn_mapping_fstr node__datasource.iterables = [('cnxn_name', cnxn_names)] """ Node: Make sub cnxn visitation map """ make_sub_vismap_npfunc = Function([ 'sub', 'dpy_file', 'parc_file', 'warp_file', 'ref_file', 'cnxn_inds_file', 'cnxn_name', 'vismap_fstr' ], ['sub_vismap_file'], make_sub_cnxn_visitation_map) node__makesubvismap = Node(interface=make_sub_vismap_npfunc, name="make_sub_vismap") node__makesubvismap.inputs.ref_file = ref_file node__makesubvismap.inputs.vismap_fstr = 'temp_vismap_%s.nii.gz' #node__makesubvismap.inputs.overwrite=True """ Node: make grp cnxn visitation map """ make_grp_vismap_npfunc = Function( ['cnxn_name', 'sub_vismaps', 'grp_vismap_fstr', 'subs_list'], ['grp_vismap_fpath', 'grp_vismap_norm_fpath', 'subs_list_file'], make_group_cnxn_visitation_map) node__makegrpvismap = JoinNode(interface=make_grp_vismap_npfunc, name='make_grp_vismap', joinsource="infosource", joinfield=["sub_vismaps", 'subs_list']) #subject_id") node__makegrpvismap.inputs.grp_vismap_fstr = 'grp_vismap_%s.nii.gz' # this needs to be changed to come from previous node in wf """ Node: aggregate group cnxn visitation map """ # (to do...) agg_grp_vismap_npfunc = Function(['in_files', 'cnxn_names', 'outfname'], ['agg_image_file', 'agg_list_file'], aggregate_grp_vismap, imports=['import os']) node__agggrpvismap = JoinNode(interface=agg_grp_vismap_npfunc, name='agg_grp_vismap', joinsource="datasource", joinfield=["in_files"]) node__agggrpvismap.iterables = [("cnxn_names", agg_cnxn_names_dict.values()), ("outfname", agg_cnxn_names_dict.keys())] node__agggrpvismap.synchronize = True """ Node: datasink """ # I want to use a mapnode for this, but can't get it to work # so have to settle with this followed by a command line copy... # (if you don't have a mapnode, just get same result as outputs of agggrpvismap node...) node__datasink = Node(DataSink(), name='datasink') node__datasink.inputs.base_directory = wf_base_dir #node__datasinkniifile = MapNode(DataSink(infields=['agg_image_file']),name='ds_nii', iterfield=['agg_image_file']) #node__datasinkniifile.inputs.base_directory=wf_base_dir #node__datasinktxtfile = MapNode(DataSink(infields=['agg_list_file']),name='ds_txt', iterfield=['agg_list_file']) #node__datasinktxtfile.inputs.base_directory=wf_base_dir """ Workflow: put it all together """ wf = pe.Workflow(name=wf_name) wf.base_dir = wf_base_dir wf.connect(node__infosource, 'subject_id', node__datasource, 'subject_id') wf.connect(node__datasource, 'subject_id', node__makesubvismap, 'sub') wf.connect(node__datasource, 'dpy_file', node__makesubvismap, 'dpy_file') wf.connect(node__datasource, 'parc_file', node__makesubvismap, 'parc_file') wf.connect(node__datasource, 'warp_file', node__makesubvismap, 'warp_file') wf.connect(node__datasource, 'cnxn_mapping_file', node__makesubvismap, 'cnxn_inds_file') wf.connect(node__datasource, 'cnxn_name', node__makesubvismap, 'cnxn_name') wf.connect(node__makesubvismap, 'sub_vismap_file', node__makegrpvismap, 'sub_vismaps') wf.connect(node__datasource, 'cnxn_name', node__makegrpvismap, 'cnxn_name') wf.connect(node__datasource, 'subject_id', node__makegrpvismap, 'subs_list') wf.connect(node__makegrpvismap, 'grp_vismap_norm_fpath', node__agggrpvismap, 'in_files') wf.connect(node__agggrpvismap, 'agg_image_file', node__datasink, '@agg_image_file') wf.connect(node__agggrpvismap, 'agg_list_file', node__datasink, '@agg_list_file') #wf.connect(node__agggrpvismap, 'agg_image_file', node__datasinkniifile, '@agg_image_file') #wf.connect(node__agggrpvismap, 'agg_list_file', node__datasinktxtfile, '@agg_list_file') return wf
def Lesion_extractor( name='Lesion_Extractor', wf_name='Test', base_dir='/homes_unix/alaurent/', input_dir=None, subjects=None, main=None, acc=None, atlas='/homes_unix/alaurent/cbstools-public-master/atlases/brain-segmentation-prior3.0/brain-atlas-quant-3.0.8.txt' ): wf = Workflow(wf_name) wf.base_dir = base_dir #file = open(subjects,"r") #subjects = file.read().split("\n") #file.close() # Subject List subjectList = Node(IdentityInterface(fields=['subject_id'], mandatory_inputs=True), name="subList") subjectList.iterables = ('subject_id', [ sub for sub in subjects if sub != '' and sub != '\n' ]) # T1w and FLAIR scanList = Node(DataGrabber(infields=['subject_id'], outfields=['T1', 'FLAIR']), name="scanList") scanList.inputs.base_directory = input_dir scanList.inputs.ignore_exception = False scanList.inputs.raise_on_empty = True scanList.inputs.sort_filelist = True #scanList.inputs.template = '%s/%s.nii' #scanList.inputs.template_args = {'T1': [['subject_id','T1*']], # 'FLAIR': [['subject_id','FLAIR*']]} scanList.inputs.template = '%s/anat/%s' scanList.inputs.template_args = { 'T1': [['subject_id', '*_T1w.nii.gz']], 'FLAIR': [['subject_id', '*_FLAIR.nii.gz']] } wf.connect(subjectList, "subject_id", scanList, "subject_id") # # T1w and FLAIR # dg = Node(DataGrabber(outfields=['T1', 'FLAIR']), name="T1wFLAIR") # dg.inputs.base_directory = "/homes_unix/alaurent/LesionPipeline" # dg.inputs.template = "%s/NIFTI/*.nii.gz" # dg.inputs.template_args['T1']=[['7']] # dg.inputs.template_args['FLAIR']=[['9']] # dg.inputs.sort_filelist=True # Reorient Volume T1Conv = Node(Reorient2Std(), name="ReorientVolume") T1Conv.inputs.ignore_exception = False T1Conv.inputs.terminal_output = 'none' T1Conv.inputs.out_file = "T1_reoriented.nii.gz" wf.connect(scanList, "T1", T1Conv, "in_file") # Reorient Volume (2) T2flairConv = Node(Reorient2Std(), name="ReorientVolume2") T2flairConv.inputs.ignore_exception = False T2flairConv.inputs.terminal_output = 'none' T2flairConv.inputs.out_file = "FLAIR_reoriented.nii.gz" wf.connect(scanList, "FLAIR", T2flairConv, "in_file") # N3 Correction T1NUC = Node(N4BiasFieldCorrection(), name="N3Correction") T1NUC.inputs.dimension = 3 T1NUC.inputs.environ = {'NSLOTS': '1'} T1NUC.inputs.ignore_exception = False T1NUC.inputs.num_threads = 1 T1NUC.inputs.save_bias = False T1NUC.inputs.terminal_output = 'none' wf.connect(T1Conv, "out_file", T1NUC, "input_image") # N3 Correction (2) T2flairNUC = Node(N4BiasFieldCorrection(), name="N3Correction2") T2flairNUC.inputs.dimension = 3 T2flairNUC.inputs.environ = {'NSLOTS': '1'} T2flairNUC.inputs.ignore_exception = False T2flairNUC.inputs.num_threads = 1 T2flairNUC.inputs.save_bias = False T2flairNUC.inputs.terminal_output = 'none' wf.connect(T2flairConv, "out_file", T2flairNUC, "input_image") ''' ##################### ### PRE-NORMALIZE ### ##################### To make sure there's no outlier values (negative, or really high) to offset the initialization steps ''' # Intensity Range Normalization getMaxT1NUC = Node(ImageStats(op_string='-r'), name="getMaxT1NUC") wf.connect(T1NUC, 'output_image', getMaxT1NUC, 'in_file') T1NUCirn = Node(AbcImageMaths(), name="IntensityNormalization") T1NUCirn.inputs.op_string = "-div" T1NUCirn.inputs.out_file = "normT1.nii.gz" wf.connect(T1NUC, 'output_image', T1NUCirn, 'in_file') wf.connect(getMaxT1NUC, ('out_stat', getElementFromList, 1), T1NUCirn, "op_value") # Intensity Range Normalization (2) getMaxT2NUC = Node(ImageStats(op_string='-r'), name="getMaxT2") wf.connect(T2flairNUC, 'output_image', getMaxT2NUC, 'in_file') T2NUCirn = Node(AbcImageMaths(), name="IntensityNormalization2") T2NUCirn.inputs.op_string = "-div" T2NUCirn.inputs.out_file = "normT2.nii.gz" wf.connect(T2flairNUC, 'output_image', T2NUCirn, 'in_file') wf.connect(getMaxT2NUC, ('out_stat', getElementFromList, 1), T2NUCirn, "op_value") ''' ######################## #### COREGISTRATION #### ######################## ''' # Optimized Automated Registration T2flairCoreg = Node(FLIRT(), name="OptimizedAutomatedRegistration") T2flairCoreg.inputs.output_type = 'NIFTI_GZ' wf.connect(T2NUCirn, "out_file", T2flairCoreg, "in_file") wf.connect(T1NUCirn, "out_file", T2flairCoreg, "reference") ''' ######################### #### SKULL-STRIPPING #### ######################### ''' # SPECTRE T1ss = Node(BET(), name="SPECTRE") T1ss.inputs.frac = 0.45 #0.4 T1ss.inputs.mask = True T1ss.inputs.outline = True T1ss.inputs.robust = True wf.connect(T1NUCirn, "out_file", T1ss, "in_file") # Image Calculator T2ss = Node(ApplyMask(), name="ImageCalculator") wf.connect(T1ss, "mask_file", T2ss, "mask_file") wf.connect(T2flairCoreg, "out_file", T2ss, "in_file") ''' #################################### #### 2nd LAYER OF N3 CORRECTION #### #################################### This time without the skull: there were some significant amounts of inhomogeneities leftover. ''' # N3 Correction (3) T1ssNUC = Node(N4BiasFieldCorrection(), name="N3Correction3") T1ssNUC.inputs.dimension = 3 T1ssNUC.inputs.environ = {'NSLOTS': '1'} T1ssNUC.inputs.ignore_exception = False T1ssNUC.inputs.num_threads = 1 T1ssNUC.inputs.save_bias = False T1ssNUC.inputs.terminal_output = 'none' wf.connect(T1ss, "out_file", T1ssNUC, "input_image") # N3 Correction (4) T2ssNUC = Node(N4BiasFieldCorrection(), name="N3Correction4") T2ssNUC.inputs.dimension = 3 T2ssNUC.inputs.environ = {'NSLOTS': '1'} T2ssNUC.inputs.ignore_exception = False T2ssNUC.inputs.num_threads = 1 T2ssNUC.inputs.save_bias = False T2ssNUC.inputs.terminal_output = 'none' wf.connect(T2ss, "out_file", T2ssNUC, "input_image") ''' #################################### #### NORMALIZE FOR MGDM #### #################################### This normalization is a bit aggressive: only useful to have a cropped dynamic range into MGDM, but possibly harmful to further processing, so the unprocessed images are passed to the subsequent steps. ''' # Intensity Range Normalization getMaxT1ssNUC = Node(ImageStats(op_string='-r'), name="getMaxT1ssNUC") wf.connect(T1ssNUC, 'output_image', getMaxT1ssNUC, 'in_file') T1ssNUCirn = Node(AbcImageMaths(), name="IntensityNormalization3") T1ssNUCirn.inputs.op_string = "-div" T1ssNUCirn.inputs.out_file = "normT1ss.nii.gz" wf.connect(T1ssNUC, 'output_image', T1ssNUCirn, 'in_file') wf.connect(getMaxT1ssNUC, ('out_stat', getElementFromList, 1), T1ssNUCirn, "op_value") # Intensity Range Normalization (2) getMaxT2ssNUC = Node(ImageStats(op_string='-r'), name="getMaxT2ssNUC") wf.connect(T2ssNUC, 'output_image', getMaxT2ssNUC, 'in_file') T2ssNUCirn = Node(AbcImageMaths(), name="IntensityNormalization4") T2ssNUCirn.inputs.op_string = "-div" T2ssNUCirn.inputs.out_file = "normT2ss.nii.gz" wf.connect(T2ssNUC, 'output_image', T2ssNUCirn, 'in_file') wf.connect(getMaxT2ssNUC, ('out_stat', getElementFromList, 1), T2ssNUCirn, "op_value") ''' #################################### #### ESTIMATE CSF PV #### #################################### Here we try to get a better handle on CSF voxels to help the segmentation step ''' # Recursive Ridge Diffusion CSF_pv = Node(RecursiveRidgeDiffusion(), name='estimate_CSF_pv') CSF_pv.plugin_args = {'sbatch_args': '--mem 6000'} CSF_pv.inputs.ridge_intensities = "dark" CSF_pv.inputs.ridge_filter = "2D" CSF_pv.inputs.orientation = "undefined" CSF_pv.inputs.ang_factor = 1.0 CSF_pv.inputs.min_scale = 0 CSF_pv.inputs.max_scale = 3 CSF_pv.inputs.propagation_model = "diffusion" CSF_pv.inputs.diffusion_factor = 0.5 CSF_pv.inputs.similarity_scale = 0.1 CSF_pv.inputs.neighborhood_size = 4 CSF_pv.inputs.max_iter = 100 CSF_pv.inputs.max_diff = 0.001 CSF_pv.inputs.save_data = True wf.connect( subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, CSF_pv.name), CSF_pv, 'output_dir') wf.connect(T1ssNUCirn, 'out_file', CSF_pv, 'input_image') ''' #################################### #### MGDM #### #################################### ''' # Multi-contrast Brain Segmentation MGDM = Node(MGDMSegmentation(), name='MGDM') MGDM.plugin_args = {'sbatch_args': '--mem 7000'} MGDM.inputs.contrast_type1 = "Mprage3T" MGDM.inputs.contrast_type2 = "FLAIR3T" MGDM.inputs.contrast_type3 = "PVDURA" MGDM.inputs.save_data = True MGDM.inputs.atlas_file = atlas wf.connect( subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, MGDM.name), MGDM, 'output_dir') wf.connect(T1ssNUCirn, 'out_file', MGDM, 'contrast_image1') wf.connect(T2ssNUCirn, 'out_file', MGDM, 'contrast_image2') wf.connect(CSF_pv, 'ridge_pv', MGDM, 'contrast_image3') # Enhance Region Contrast ERC = Node(EnhanceRegionContrast(), name='ERC') ERC.plugin_args = {'sbatch_args': '--mem 7000'} ERC.inputs.enhanced_region = "crwm" ERC.inputs.contrast_background = "crgm" ERC.inputs.partial_voluming_distance = 2.0 ERC.inputs.save_data = True ERC.inputs.atlas_file = atlas wf.connect(subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, ERC.name), ERC, 'output_dir') wf.connect(T1ssNUC, 'output_image', ERC, 'intensity_image') wf.connect(MGDM, 'segmentation', ERC, 'segmentation_image') wf.connect(MGDM, 'distance', ERC, 'levelset_boundary_image') # Enhance Region Contrast (2) ERC2 = Node(EnhanceRegionContrast(), name='ERC2') ERC2.plugin_args = {'sbatch_args': '--mem 7000'} ERC2.inputs.enhanced_region = "crwm" ERC2.inputs.contrast_background = "crgm" ERC2.inputs.partial_voluming_distance = 2.0 ERC2.inputs.save_data = True ERC2.inputs.atlas_file = atlas wf.connect( subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, ERC2.name), ERC2, 'output_dir') wf.connect(T2ssNUC, 'output_image', ERC2, 'intensity_image') wf.connect(MGDM, 'segmentation', ERC2, 'segmentation_image') wf.connect(MGDM, 'distance', ERC2, 'levelset_boundary_image') # Define Multi-Region Priors DMRP = Node(DefineMultiRegionPriors(), name='DefineMultRegPriors') DMRP.plugin_args = {'sbatch_args': '--mem 6000'} #DMRP.inputs.defined_region = "ventricle-horns" #DMRP.inputs.definition_method = "closest-distance" DMRP.inputs.distance_offset = 3.0 DMRP.inputs.save_data = True DMRP.inputs.atlas_file = atlas wf.connect( subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, DMRP.name), DMRP, 'output_dir') wf.connect(MGDM, 'segmentation', DMRP, 'segmentation_image') wf.connect(MGDM, 'distance', DMRP, 'levelset_boundary_image') ''' ############################################### #### REMOVE VENTRICLE POSTERIOR #### ############################################### Due to topology constraints, the ventricles are often not fully segmented: here add back all ventricle voxels from the posterior probability (without the topology constraints) ''' # Posterior label PostLabel = Node(Split(), name='PosteriorLabel') PostLabel.inputs.dimension = "t" wf.connect(MGDM, 'labels', PostLabel, 'in_file') # Posterior proba PostProba = Node(Split(), name='PosteriorProba') PostProba.inputs.dimension = "t" wf.connect(MGDM, 'memberships', PostProba, 'in_file') # Threshold binary mask : ventricle label part 1 VentLabel1 = Node(Threshold(), name="VentricleLabel1") VentLabel1.inputs.thresh = 10.5 VentLabel1.inputs.direction = "below" wf.connect(PostLabel, ("out_files", getFirstElement), VentLabel1, "in_file") # Threshold binary mask : ventricle label part 2 VentLabel2 = Node(Threshold(), name="VentricleLabel2") VentLabel2.inputs.thresh = 13.5 VentLabel2.inputs.direction = "above" wf.connect(VentLabel1, "out_file", VentLabel2, "in_file") # Image calculator : ventricle proba VentProba = Node(ImageMaths(), name="VentricleProba") VentProba.inputs.op_string = "-mul" VentProba.inputs.out_file = "ventproba.nii.gz" wf.connect(PostProba, ("out_files", getFirstElement), VentProba, "in_file") wf.connect(VentLabel2, "out_file", VentProba, "in_file2") # Image calculator : remove inter ventricles RmInterVent = Node(ImageMaths(), name="RemoveInterVent") RmInterVent.inputs.op_string = "-sub" RmInterVent.inputs.out_file = "rmintervent.nii.gz" wf.connect(ERC, "region_pv", RmInterVent, "in_file") wf.connect(DMRP, "inter_ventricular_pv", RmInterVent, "in_file2") # Image calculator : add horns AddHorns = Node(ImageMaths(), name="AddHorns") AddHorns.inputs.op_string = "-add" AddHorns.inputs.out_file = "rmvent.nii.gz" wf.connect(RmInterVent, "out_file", AddHorns, "in_file") wf.connect(DMRP, "ventricular_horns_pv", AddHorns, "in_file2") # Image calculator : remove ventricles RmVent = Node(ImageMaths(), name="RemoveVentricles") RmVent.inputs.op_string = "-sub" RmVent.inputs.out_file = "rmvent.nii.gz" wf.connect(AddHorns, "out_file", RmVent, "in_file") wf.connect(VentProba, "out_file", RmVent, "in_file2") # Image calculator : remove internal capsule RmIC = Node(ImageMaths(), name="RemoveInternalCap") RmIC.inputs.op_string = "-sub" RmIC.inputs.out_file = "rmic.nii.gz" wf.connect(RmVent, "out_file", RmIC, "in_file") wf.connect(DMRP, "internal_capsule_pv", RmIC, "in_file2") # Intensity Range Normalization (3) getMaxRmIC = Node(ImageStats(op_string='-r'), name="getMaxRmIC") wf.connect(RmIC, 'out_file', getMaxRmIC, 'in_file') RmICirn = Node(AbcImageMaths(), name="IntensityNormalization5") RmICirn.inputs.op_string = "-div" RmICirn.inputs.out_file = "normRmIC.nii.gz" wf.connect(RmIC, 'out_file', RmICirn, 'in_file') wf.connect(getMaxRmIC, ('out_stat', getElementFromList, 1), RmICirn, "op_value") # Probability To Levelset : WM orientation WM_Orient = Node(ProbabilityToLevelset(), name='WM_Orientation') WM_Orient.plugin_args = {'sbatch_args': '--mem 6000'} WM_Orient.inputs.save_data = True wf.connect( subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, WM_Orient.name), WM_Orient, 'output_dir') wf.connect(RmICirn, 'out_file', WM_Orient, 'probability_image') # Recursive Ridge Diffusion : PVS in WM only WM_pvs = Node(RecursiveRidgeDiffusion(), name='PVS_in_WM') WM_pvs.plugin_args = {'sbatch_args': '--mem 6000'} WM_pvs.inputs.ridge_intensities = "bright" WM_pvs.inputs.ridge_filter = "1D" WM_pvs.inputs.orientation = "orthogonal" WM_pvs.inputs.ang_factor = 1.0 WM_pvs.inputs.min_scale = 0 WM_pvs.inputs.max_scale = 3 WM_pvs.inputs.propagation_model = "diffusion" WM_pvs.inputs.diffusion_factor = 1.0 WM_pvs.inputs.similarity_scale = 1.0 WM_pvs.inputs.neighborhood_size = 2 WM_pvs.inputs.max_iter = 100 WM_pvs.inputs.max_diff = 0.001 WM_pvs.inputs.save_data = True wf.connect( subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, WM_pvs.name), WM_pvs, 'output_dir') wf.connect(ERC, 'background_proba', WM_pvs, 'input_image') wf.connect(WM_Orient, 'levelset', WM_pvs, 'surface_levelset') wf.connect(RmICirn, 'out_file', WM_pvs, 'loc_prior') # Extract Lesions : extract WM PVS extract_WM_pvs = Node(LesionExtraction(), name='ExtractPVSfromWM') extract_WM_pvs.plugin_args = {'sbatch_args': '--mem 6000'} extract_WM_pvs.inputs.gm_boundary_partial_vol_dist = 1.0 extract_WM_pvs.inputs.csf_boundary_partial_vol_dist = 3.0 extract_WM_pvs.inputs.lesion_clust_dist = 1.0 extract_WM_pvs.inputs.prob_min_thresh = 0.1 extract_WM_pvs.inputs.prob_max_thresh = 0.33 extract_WM_pvs.inputs.small_lesion_size = 4.0 extract_WM_pvs.inputs.save_data = True extract_WM_pvs.inputs.atlas_file = atlas wf.connect(subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, extract_WM_pvs.name), extract_WM_pvs, 'output_dir') wf.connect(WM_pvs, 'propagation', extract_WM_pvs, 'probability_image') wf.connect(MGDM, 'segmentation', extract_WM_pvs, 'segmentation_image') wf.connect(MGDM, 'distance', extract_WM_pvs, 'levelset_boundary_image') wf.connect(RmICirn, 'out_file', extract_WM_pvs, 'location_prior_image') ''' 2nd branch ''' # Image calculator : internal capsule witout ventricules ICwoVent = Node(ImageMaths(), name="ICWithoutVentricules") ICwoVent.inputs.op_string = "-sub" ICwoVent.inputs.out_file = "icwovent.nii.gz" wf.connect(DMRP, "internal_capsule_pv", ICwoVent, "in_file") wf.connect(DMRP, "inter_ventricular_pv", ICwoVent, "in_file2") # Image calculator : remove ventricles IC RmVentIC = Node(ImageMaths(), name="RmVentIC") RmVentIC.inputs.op_string = "-sub" RmVentIC.inputs.out_file = "RmVentIC.nii.gz" wf.connect(ICwoVent, "out_file", RmVentIC, "in_file") wf.connect(VentProba, "out_file", RmVentIC, "in_file2") # Intensity Range Normalization (4) getMaxRmVentIC = Node(ImageStats(op_string='-r'), name="getMaxRmVentIC") wf.connect(RmVentIC, 'out_file', getMaxRmVentIC, 'in_file') RmVentICirn = Node(AbcImageMaths(), name="IntensityNormalization6") RmVentICirn.inputs.op_string = "-div" RmVentICirn.inputs.out_file = "normRmVentIC.nii.gz" wf.connect(RmVentIC, 'out_file', RmVentICirn, 'in_file') wf.connect(getMaxRmVentIC, ('out_stat', getElementFromList, 1), RmVentICirn, "op_value") # Probability To Levelset : IC orientation IC_Orient = Node(ProbabilityToLevelset(), name='IC_Orientation') IC_Orient.plugin_args = {'sbatch_args': '--mem 6000'} IC_Orient.inputs.save_data = True wf.connect( subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, IC_Orient.name), IC_Orient, 'output_dir') wf.connect(RmVentICirn, 'out_file', IC_Orient, 'probability_image') # Recursive Ridge Diffusion : PVS in IC only IC_pvs = Node(RecursiveRidgeDiffusion(), name='RecursiveRidgeDiffusion2') IC_pvs.plugin_args = {'sbatch_args': '--mem 6000'} IC_pvs.inputs.ridge_intensities = "bright" IC_pvs.inputs.ridge_filter = "1D" IC_pvs.inputs.orientation = "undefined" IC_pvs.inputs.ang_factor = 1.0 IC_pvs.inputs.min_scale = 0 IC_pvs.inputs.max_scale = 3 IC_pvs.inputs.propagation_model = "diffusion" IC_pvs.inputs.diffusion_factor = 1.0 IC_pvs.inputs.similarity_scale = 1.0 IC_pvs.inputs.neighborhood_size = 2 IC_pvs.inputs.max_iter = 100 IC_pvs.inputs.max_diff = 0.001 IC_pvs.inputs.save_data = True wf.connect( subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, IC_pvs.name), IC_pvs, 'output_dir') wf.connect(ERC, 'background_proba', IC_pvs, 'input_image') wf.connect(IC_Orient, 'levelset', IC_pvs, 'surface_levelset') wf.connect(RmVentICirn, 'out_file', IC_pvs, 'loc_prior') # Extract Lesions : extract IC PVS extract_IC_pvs = Node(LesionExtraction(), name='ExtractPVSfromIC') extract_IC_pvs.plugin_args = {'sbatch_args': '--mem 6000'} extract_IC_pvs.inputs.gm_boundary_partial_vol_dist = 1.0 extract_IC_pvs.inputs.csf_boundary_partial_vol_dist = 4.0 extract_IC_pvs.inputs.lesion_clust_dist = 1.0 extract_IC_pvs.inputs.prob_min_thresh = 0.25 extract_IC_pvs.inputs.prob_max_thresh = 0.5 extract_IC_pvs.inputs.small_lesion_size = 4.0 extract_IC_pvs.inputs.save_data = True extract_IC_pvs.inputs.atlas_file = atlas wf.connect(subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, extract_IC_pvs.name), extract_IC_pvs, 'output_dir') wf.connect(IC_pvs, 'propagation', extract_IC_pvs, 'probability_image') wf.connect(MGDM, 'segmentation', extract_IC_pvs, 'segmentation_image') wf.connect(MGDM, 'distance', extract_IC_pvs, 'levelset_boundary_image') wf.connect(RmVentICirn, 'out_file', extract_IC_pvs, 'location_prior_image') ''' 3rd branch ''' # Image calculator : RmInter = Node(ImageMaths(), name="RemoveInterVentricules") RmInter.inputs.op_string = "-sub" RmInter.inputs.out_file = "rminter.nii.gz" wf.connect(ERC2, 'region_pv', RmInter, "in_file") wf.connect(DMRP, "inter_ventricular_pv", RmInter, "in_file2") # Image calculator : AddVentHorns = Node(ImageMaths(), name="AddVentHorns") AddVentHorns.inputs.op_string = "-add" AddVentHorns.inputs.out_file = "rminter.nii.gz" wf.connect(RmInter, 'out_file', AddVentHorns, "in_file") wf.connect(DMRP, "ventricular_horns_pv", AddVentHorns, "in_file2") # Intensity Range Normalization (5) getMaxAddVentHorns = Node(ImageStats(op_string='-r'), name="getMaxAddVentHorns") wf.connect(AddVentHorns, 'out_file', getMaxAddVentHorns, 'in_file') AddVentHornsirn = Node(AbcImageMaths(), name="IntensityNormalization7") AddVentHornsirn.inputs.op_string = "-div" AddVentHornsirn.inputs.out_file = "normAddVentHorns.nii.gz" wf.connect(AddVentHorns, 'out_file', AddVentHornsirn, 'in_file') wf.connect(getMaxAddVentHorns, ('out_stat', getElementFromList, 1), AddVentHornsirn, "op_value") # Extract Lesions : extract White Matter Hyperintensities extract_WMH = Node(LesionExtraction(), name='Extract_WMH') extract_WMH.plugin_args = {'sbatch_args': '--mem 6000'} extract_WMH.inputs.gm_boundary_partial_vol_dist = 1.0 extract_WMH.inputs.csf_boundary_partial_vol_dist = 2.0 extract_WMH.inputs.lesion_clust_dist = 1.0 extract_WMH.inputs.prob_min_thresh = 0.84 extract_WMH.inputs.prob_max_thresh = 0.84 extract_WMH.inputs.small_lesion_size = 4.0 extract_WMH.inputs.save_data = True extract_WMH.inputs.atlas_file = atlas wf.connect(subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, extract_WMH.name), extract_WMH, 'output_dir') wf.connect(ERC2, 'background_proba', extract_WMH, 'probability_image') wf.connect(MGDM, 'segmentation', extract_WMH, 'segmentation_image') wf.connect(MGDM, 'distance', extract_WMH, 'levelset_boundary_image') wf.connect(AddVentHornsirn, 'out_file', extract_WMH, 'location_prior_image') #=========================================================================== # extract_WMH2 = extract_WMH.clone(name='Extract_WMH2') # extract_WMH2.inputs.gm_boundary_partial_vol_dist = 2.0 # wf.connect(subjectList,('subject_id',createOutputDir,wf.base_dir,wf.name,extract_WMH2.name),extract_WMH2,'output_dir') # wf.connect(ERC2,'background_proba',extract_WMH2,'probability_image') # wf.connect(MGDM,'segmentation',extract_WMH2,'segmentation_image') # wf.connect(MGDM,'distance',extract_WMH2,'levelset_boundary_image') # wf.connect(AddVentHornsirn,'out_file',extract_WMH2,'location_prior_image') # # extract_WMH3 = extract_WMH.clone(name='Extract_WMH3') # extract_WMH3.inputs.gm_boundary_partial_vol_dist = 3.0 # wf.connect(subjectList,('subject_id',createOutputDir,wf.base_dir,wf.name,extract_WMH3.name),extract_WMH3,'output_dir') # wf.connect(ERC2,'background_proba',extract_WMH3,'probability_image') # wf.connect(MGDM,'segmentation',extract_WMH3,'segmentation_image') # wf.connect(MGDM,'distance',extract_WMH3,'levelset_boundary_image') # wf.connect(AddVentHornsirn,'out_file',extract_WMH3,'location_prior_image') #=========================================================================== ''' #################################### #### FINDING SMALL WMHs #### #################################### Small round WMHs near the cortex are often missed by the main algorithm, so we're adding this one that takes care of them. ''' # Recursive Ridge Diffusion : round WMH detection round_WMH = Node(RecursiveRidgeDiffusion(), name='round_WMH') round_WMH.plugin_args = {'sbatch_args': '--mem 6000'} round_WMH.inputs.ridge_intensities = "bright" round_WMH.inputs.ridge_filter = "0D" round_WMH.inputs.orientation = "undefined" round_WMH.inputs.ang_factor = 1.0 round_WMH.inputs.min_scale = 1 round_WMH.inputs.max_scale = 4 round_WMH.inputs.propagation_model = "none" round_WMH.inputs.diffusion_factor = 1.0 round_WMH.inputs.similarity_scale = 0.1 round_WMH.inputs.neighborhood_size = 4 round_WMH.inputs.max_iter = 100 round_WMH.inputs.max_diff = 0.001 round_WMH.inputs.save_data = True wf.connect( subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, round_WMH.name), round_WMH, 'output_dir') wf.connect(ERC2, 'background_proba', round_WMH, 'input_image') wf.connect(AddVentHornsirn, 'out_file', round_WMH, 'loc_prior') # Extract Lesions : extract round WMH extract_round_WMH = Node(LesionExtraction(), name='Extract_round_WMH') extract_round_WMH.plugin_args = {'sbatch_args': '--mem 6000'} extract_round_WMH.inputs.gm_boundary_partial_vol_dist = 1.0 extract_round_WMH.inputs.csf_boundary_partial_vol_dist = 2.0 extract_round_WMH.inputs.lesion_clust_dist = 1.0 extract_round_WMH.inputs.prob_min_thresh = 0.33 extract_round_WMH.inputs.prob_max_thresh = 0.33 extract_round_WMH.inputs.small_lesion_size = 6.0 extract_round_WMH.inputs.save_data = True extract_round_WMH.inputs.atlas_file = atlas wf.connect(subjectList, ('subject_id', createOutputDir, wf.base_dir, wf.name, extract_round_WMH.name), extract_round_WMH, 'output_dir') wf.connect(round_WMH, 'ridge_pv', extract_round_WMH, 'probability_image') wf.connect(MGDM, 'segmentation', extract_round_WMH, 'segmentation_image') wf.connect(MGDM, 'distance', extract_round_WMH, 'levelset_boundary_image') wf.connect(AddVentHornsirn, 'out_file', extract_round_WMH, 'location_prior_image') #=========================================================================== # extract_round_WMH2 = extract_round_WMH.clone(name='Extract_round_WMH2') # extract_round_WMH2.inputs.gm_boundary_partial_vol_dist = 2.0 # wf.connect(subjectList,('subject_id',createOutputDir,wf.base_dir,wf.name,extract_round_WMH2.name),extract_round_WMH2,'output_dir') # wf.connect(round_WMH,'ridge_pv',extract_round_WMH2,'probability_image') # wf.connect(MGDM,'segmentation',extract_round_WMH2,'segmentation_image') # wf.connect(MGDM,'distance',extract_round_WMH2,'levelset_boundary_image') # wf.connect(AddVentHornsirn,'out_file',extract_round_WMH2,'location_prior_image') # # extract_round_WMH3 = extract_round_WMH.clone(name='Extract_round_WMH3') # extract_round_WMH3.inputs.gm_boundary_partial_vol_dist = 2.0 # wf.connect(subjectList,('subject_id',createOutputDir,wf.base_dir,wf.name,extract_round_WMH3.name),extract_round_WMH3,'output_dir') # wf.connect(round_WMH,'ridge_pv',extract_round_WMH3,'probability_image') # wf.connect(MGDM,'segmentation',extract_round_WMH3,'segmentation_image') # wf.connect(MGDM,'distance',extract_round_WMH3,'levelset_boundary_image') # wf.connect(AddVentHornsirn,'out_file',extract_round_WMH3,'location_prior_image') #=========================================================================== ''' #################################### #### COMBINE BOTH TYPES #### #################################### Small round WMHs and regular WMH together before thresholding + PVS from white matter and internal capsule ''' # Image calculator : WM + IC DVRS DVRS = Node(ImageMaths(), name="DVRS") DVRS.inputs.op_string = "-max" DVRS.inputs.out_file = "DVRS_map.nii.gz" wf.connect(extract_WM_pvs, 'lesion_score', DVRS, "in_file") wf.connect(extract_IC_pvs, "lesion_score", DVRS, "in_file2") # Image calculator : WMH + round WMH = Node(ImageMaths(), name="WMH") WMH.inputs.op_string = "-max" WMH.inputs.out_file = "WMH_map.nii.gz" wf.connect(extract_WMH, 'lesion_score', WMH, "in_file") wf.connect(extract_round_WMH, "lesion_score", WMH, "in_file2") #=========================================================================== # WMH2 = Node(ImageMaths(), name="WMH2") # WMH2.inputs.op_string = "-max" # WMH2.inputs.out_file = "WMH2_map.nii.gz" # wf.connect(extract_WMH2,'lesion_score',WMH2,"in_file") # wf.connect(extract_round_WMH2,"lesion_score", WMH2, "in_file2") # # WMH3 = Node(ImageMaths(), name="WMH3") # WMH3.inputs.op_string = "-max" # WMH3.inputs.out_file = "WMH3_map.nii.gz" # wf.connect(extract_WMH3,'lesion_score',WMH3,"in_file") # wf.connect(extract_round_WMH3,"lesion_score", WMH3, "in_file2") #=========================================================================== # Image calculator : multiply by boundnary partial volume WMH_mul = Node(ImageMaths(), name="WMH_mul") WMH_mul.inputs.op_string = "-mul" WMH_mul.inputs.out_file = "final_mask.nii.gz" wf.connect(WMH, "out_file", WMH_mul, "in_file") wf.connect(MGDM, "distance", WMH_mul, "in_file2") #=========================================================================== # WMH2_mul = Node(ImageMaths(), name="WMH2_mul") # WMH2_mul.inputs.op_string = "-mul" # WMH2_mul.inputs.out_file = "final_mask.nii.gz" # wf.connect(WMH2,"out_file", WMH2_mul,"in_file") # wf.connect(MGDM,"distance", WMH2_mul, "in_file2") # # WMH3_mul = Node(ImageMaths(), name="WMH3_mul") # WMH3_mul.inputs.op_string = "-mul" # WMH3_mul.inputs.out_file = "final_mask.nii.gz" # wf.connect(WMH3,"out_file", WMH3_mul,"in_file") # wf.connect(MGDM,"distance", WMH3_mul, "in_file2") #=========================================================================== ''' ########################################## #### SEGMENTATION THRESHOLD #### ########################################## A threshold of 0.5 is very conservative, because the final lesion score is the product of two probabilities. This needs to be optimized to a value between 0.25 and 0.5 to balance false negatives (dominant at 0.5) and false positives (dominant at low values). ''' # Threshold binary mask : DVRS_mask = Node(Threshold(), name="DVRS_mask") DVRS_mask.inputs.thresh = 0.25 DVRS_mask.inputs.direction = "below" wf.connect(DVRS, "out_file", DVRS_mask, "in_file") # Threshold binary mask : 025 WMH1_025 = Node(Threshold(), name="WMH1_025") WMH1_025.inputs.thresh = 0.25 WMH1_025.inputs.direction = "below" wf.connect(WMH_mul, "out_file", WMH1_025, "in_file") #=========================================================================== # WMH2_025 = Node(Threshold(), name="WMH2_025") # WMH2_025.inputs.thresh = 0.25 # WMH2_025.inputs.direction = "below" # wf.connect(WMH2_mul,"out_file", WMH2_025, "in_file") # # WMH3_025 = Node(Threshold(), name="WMH3_025") # WMH3_025.inputs.thresh = 0.25 # WMH3_025.inputs.direction = "below" # wf.connect(WMH3_mul,"out_file", WMH3_025, "in_file") #=========================================================================== # Threshold binary mask : 050 WMH1_050 = Node(Threshold(), name="WMH1_050") WMH1_050.inputs.thresh = 0.50 WMH1_050.inputs.direction = "below" wf.connect(WMH_mul, "out_file", WMH1_050, "in_file") #=========================================================================== # WMH2_050 = Node(Threshold(), name="WMH2_050") # WMH2_050.inputs.thresh = 0.50 # WMH2_050.inputs.direction = "below" # wf.connect(WMH2_mul,"out_file", WMH2_050, "in_file") # # WMH3_050 = Node(Threshold(), name="WMH3_050") # WMH3_050.inputs.thresh = 0.50 # WMH3_050.inputs.direction = "below" # wf.connect(WMH3_mul,"out_file", WMH3_050, "in_file") #=========================================================================== # Threshold binary mask : 075 WMH1_075 = Node(Threshold(), name="WMH1_075") WMH1_075.inputs.thresh = 0.75 WMH1_075.inputs.direction = "below" wf.connect(WMH_mul, "out_file", WMH1_075, "in_file") #=========================================================================== # WMH2_075 = Node(Threshold(), name="WMH2_075") # WMH2_075.inputs.thresh = 0.75 # WMH2_075.inputs.direction = "below" # wf.connect(WMH2_mul,"out_file", WMH2_075, "in_file") # # WMH3_075 = Node(Threshold(), name="WMH3_075") # WMH3_075.inputs.thresh = 0.75 # WMH3_075.inputs.direction = "below" # wf.connect(WMH3_mul,"out_file", WMH3_075, "in_file") #=========================================================================== ## Outputs DVRS_Output = Node(IdentityInterface(fields=[ 'mask', 'region', 'lesion_size', 'lesion_proba', 'boundary', 'label', 'score' ]), name='DVRS_Output') wf.connect(DVRS_mask, 'out_file', DVRS_Output, 'mask') WMH_output = Node(IdentityInterface(fields=[ 'mask1025', 'mask1050', 'mask1075', 'mask2025', 'mask2050', 'mask2075', 'mask3025', 'mask3050', 'mask3075' ]), name='WMH_output') wf.connect(WMH1_025, 'out_file', WMH_output, 'mask1025') #wf.connect(WMH2_025,'out_file',WMH_output,'mask2025') #wf.connect(WMH3_025,'out_file',WMH_output,'mask3025') wf.connect(WMH1_050, 'out_file', WMH_output, 'mask1050') #wf.connect(WMH2_050,'out_file',WMH_output,'mask2050') #wf.connect(WMH3_050,'out_file',WMH_output,'mask3050') wf.connect(WMH1_075, 'out_file', WMH_output, 'mask1075') #wf.connect(WMH2_075,'out_file',WMH_output,'mask2070') #wf.connect(WMH3_075,'out_file',WMH_output,'mask3075') return wf
out_dir = os.path.abspath( '/data/pt_nmc002/other/narps/derivatives/second_lev_equal_range/') deriv_dir = os.path.join(data_dir, 'first_lev/equalRange') fwhm = [5] mask = '/data/pt_nmc002/other/narps/derivatives/fmriprep/gr_mask_tmax.nii' #template_image = '/data/pt_neunmc024/SpeechInNoise_Dyslexia_Study/MRI_Data_BIDS/derivatives/mni_template/mni1mm.nii' # list of contrast identifiers contrasts = ['con_0001', 'con_0002', 'con_0003'] # collect all the con images for each contrast. contrast_ids = list(range(1, len(contrasts) + 1)) # Infosource - a function free node to iterate over the list of subject names infosource = Node(IdentityInterface(fields=['contrast_id']), name="infosource") infosource.iterables = [('contrast_id', contrasts)] # Select files from derivatives. templates = { 'cons': '/data/pt_nmc002/other/narps/derivatives/first_lev/tmp/equalRange/*/contraste_estimate/{contrast_id}.nii' } selectderivs = Node(SelectFiles(templates, sort_filelist=True), name='selectderivs') #selectderivs.inputs.sub_id = subs # One Sample T-Test Design - creates one sample T-Test Design onesamplettestdes = Node( OneSampleTTestDesign(), #overwrite=True,
def downsampel_surfs(subject_id, working_dir, freesurfer_dir, ds_dir, plugin_name, use_n_procs): ''' Workflow resamples e.g. native thickness maps to fsaverage5 space ''' ##################################### # GENERAL SETTINGS ##################################### fsl.FSLCommand.set_default_output_type('NIFTI_GZ') fs.FSCommand.set_default_subjects_dir(freesurfer_dir) wf = Workflow(name='freesurfer_downsample') wf.base_dir = os.path.join(working_dir) nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True, 'remove_unnecessary_outputs': True, 'job_finished_timeout': 15}) config.update_config(nipype_cfg) wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash') ds = Node(nio.DataSink(base_directory=ds_dir), name='ds') ds.inputs.parameterization = False ##################### # ITERATORS ##################### # PARCELLATION ITERATOR infosource = Node(util.IdentityInterface(fields=['hemi', 'surf_measure', 'fwhm', 'target']), name='infosource') infosource.iterables = [('hemi', ['lh', 'rh']), ('surf_measure', ['thickness', 'area']), ('fwhm', [0, 5, 10, 20]), ('target', ['fsaverage3', 'fsaverage4', 'fsaverage5']), ] downsample = Node(fs.model.MRISPreproc(), name='downsample') downsample.inputs.subjects = [subject_id] wf.connect(infosource, 'target', downsample, 'target') wf.connect(infosource, 'hemi', downsample, 'hemi') wf.connect(infosource, 'surf_measure', downsample, 'surf_measure') wf.connect(infosource, 'fwhm', downsample, 'fwhm_source') rename = Node(util.Rename(format_string='%(hemi)s.%(surf_measure)s.%(target)s.%(fwhm)smm'), name='rename') rename.inputs.keep_ext = True wf.connect(infosource, 'target', rename, 'target') wf.connect(infosource, 'hemi', rename, 'hemi') wf.connect(infosource, 'surf_measure', rename, 'surf_measure') wf.connect(infosource, 'fwhm', rename, 'fwhm') wf.connect(downsample, 'out_file', rename, 'in_file') wf.connect(rename, 'out_file', ds, 'surfs.@surfs') # wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf') # 'hierarchical') wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf') wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf') if plugin_name == 'CondorDAGMan': wf.run(plugin=plugin_name) if plugin_name == 'MultiProc': wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})