wholemask=opj(path_root, 'fmriprep', 'fmriprep', '{subject_id}', '*', 'func', '*highspeed*space-T1w*brain_mask.nii.gz'), ) # define the selectfiles node: selectfiles = Node(SelectFiles(templates, sort_filelist=True), name='selectfiles') # set expected thread and memory usage for the node: selectfiles.interface.num_threads = 1 selectfiles.interface.mem_gb = 0.1 # selectfiles.inputs.subject_id = 'sub-20' # selectfiles_results = selectfiles.run() # ====================================================================== # DEFINE CREATE_SUSAN_SMOOTH WORKFLOW NODE # ====================================================================== # define the susan smoothing node and specify the smoothing fwhm: susan = create_susan_smooth() # set the smoothing kernel: susan.inputs.inputnode.fwhm = fwhm # set expected thread and memory usage for the nodes: susan.get_node('inputnode').interface.num_threads = 1 susan.get_node('inputnode').interface.mem_gb = 0.1 susan.get_node('median').interface.num_threads = 1 susan.get_node('median').interface.mem_gb = 3 susan.get_node('mask').interface.num_threads = 1 susan.get_node('mask').interface.mem_gb = 3 susan.get_node('meanfunc2').interface.num_threads = 1 susan.get_node('meanfunc2').interface.mem_gb = 3 susan.get_node('merge').interface.num_threads = 1 susan.get_node('merge').interface.mem_gb = 3 susan.get_node('multi_inputs').interface.num_threads = 1 susan.get_node('multi_inputs').interface.mem_gb = 3
def create_preprocessing_workflow(name="preproc", exp_info=None): """Return a Nipype workflow for fMRI preprocessing. This mostly follows the preprocessing in FSL, although some of the processing has been moved into pure Python. Parameters ---------- name : string workflow object name exp_info : dict dictionary with experimental information """ preproc = Workflow(name) if exp_info is None: exp_info = lyman.default_experiment_parameters() # Define the inputs for the preprocessing workflow in_fields = ["timeseries", "subject_id"] if exp_info["whole_brain_template"]: in_fields.append("whole_brain") if exp_info["fieldmap_template"]: in_fields.append("fieldmap") inputnode = Node(IdentityInterface(in_fields), "inputs") # Remove equilibrium frames and convert to float prepare = MapNode(PrepTimeseries(), "in_file", "prep_timeseries") prepare.inputs.frames_to_toss = exp_info["frames_to_toss"] # Unwarp using fieldmap images if exp_info["fieldmap_template"]: unwarp = create_unwarp_workflow(fieldmap_pe=exp_info["fieldmap_pe"]) # Spatial realignment realign = create_realignment_workflow() # Temporal interpolation if exp_info["temporal_interp"]: slicetime = create_slicetime_workflow( TR=exp_info["TR"], slice_order=exp_info["slice_order"], interleaved=exp_info["interleaved"], ) # Estimate a registration from funtional to anatomical space coregister = create_bbregister_workflow(partial_brain=bool( exp_info["whole_brain_template"]), init_with=exp_info["coreg_init"]) # Skullstrip the brain using the Freesurfer segmentation skullstrip = create_skullstrip_workflow() # Smooth intelligently in the volume susan = create_susan_smooth() susan.inputs.inputnode.fwhm = exp_info["smooth_fwhm"] # Scale and filter the timeseries filter_smooth = create_filtering_workflow("filter_smooth", exp_info["hpf_cutoff"], exp_info["TR"], "smoothed_timeseries") filter_rough = create_filtering_workflow("filter_rough", exp_info["hpf_cutoff"], exp_info["TR"], "unsmoothed_timeseries") # Automatically detect motion and intensity outliers artifacts = MapNode(ArtifactDetection(), ["timeseries", "mask_file", "motion_file"], "artifacts") artifacts.inputs.intensity_thresh = exp_info["intensity_threshold"] artifacts.inputs.motion_thresh = exp_info["motion_threshold"] artifacts.inputs.spike_thresh = exp_info["spike_threshold"] # Extract nuisance variables from anatomical sources confounds = create_confound_extraction_workflow("confounds", exp_info["wm_components"]) # Save the experiment info for this run saveparams = MapNode(SaveParameters(exp_info=exp_info), "in_file", "saveparams") preproc.connect([ (inputnode, prepare, [("timeseries", "in_file")]), (realign, artifacts, [("outputs.motion_file", "motion_file")]), (realign, coregister, [("outputs.timeseries", "inputs.timeseries")]), (inputnode, coregister, [("subject_id", "inputs.subject_id")]), (inputnode, skullstrip, [("subject_id", "inputs.subject_id")]), (coregister, skullstrip, [("outputs.tkreg_mat", "inputs.reg_file")]), (skullstrip, artifacts, [("outputs.mask_file", "mask_file")]), (skullstrip, susan, [("outputs.mask_file", "inputnode.mask_file"), ("outputs.timeseries", "inputnode.in_files")]), (susan, filter_smooth, [("outputnode.smoothed_files", "inputs.timeseries")]), (skullstrip, filter_smooth, [("outputs.mask_file", "inputs.mask_file") ]), (skullstrip, filter_rough, [("outputs.timeseries", "inputs.timeseries") ]), (skullstrip, filter_rough, [("outputs.mask_file", "inputs.mask_file") ]), (filter_rough, artifacts, [("outputs.timeseries", "timeseries")]), (filter_rough, confounds, [("outputs.timeseries", "inputs.timeseries") ]), (inputnode, confounds, [("subject_id", "inputs.subject_id")]), (skullstrip, confounds, [("outputs.mask_file", "inputs.brain_mask")]), (coregister, confounds, [("outputs.tkreg_mat", "inputs.reg_file")]), (inputnode, saveparams, [("timeseries", "in_file")]), ]) # Optionally add a connection for unwarping if bool(exp_info["fieldmap_template"]): preproc.connect([ (inputnode, unwarp, [("fieldmap", "inputs.fieldmap")]), (prepare, unwarp, [("out_file", "inputs.timeseries")]), (unwarp, realign, [("outputs.timeseries", "inputs.timeseries")]) ]) else: preproc.connect([ (prepare, realign, [("out_file", "inputs.timeseries")]), ]) # Optionally add a connection for slice time correction if exp_info["temporal_interp"]: preproc.connect([ (realign, slicetime, [("outputs.timeseries", "inputs.timeseries") ]), (slicetime, skullstrip, [("outputs.timeseries", "inputs.timeseries")]), ]) else: preproc.connect([ (realign, skullstrip, [("outputs.timeseries", "inputs.timeseries") ]), ]) # Optionally connect the whole brain template if bool(exp_info["whole_brain_template"]): preproc.connect([(inputnode, coregister, [ ("whole_brain_template", "inputs.whole_brain_template") ])]) # Define the outputs of the top-level workflow output_fields = [ "smoothed_timeseries", "unsmoothed_timeseries", "example_func", "mean_func", "functional_mask", "realign_report", "mask_report", "artifact_report", "confound_file", "flirt_affine", "tkreg_affine", "coreg_report", "json_file" ] if bool(exp_info["fieldmap_template"]): output_fields.append("unwarp_report") outputnode = Node(IdentityInterface(output_fields), "outputs") preproc.connect([ (realign, outputnode, [("outputs.example_func", "example_func"), ("outputs.report", "realign_report")]), (skullstrip, outputnode, [("outputs.mask_file", "functional_mask"), ("outputs.report", "mask_report")]), (artifacts, outputnode, [("out_files", "artifact_report")]), (coregister, outputnode, [("outputs.tkreg_mat", "tkreg_affine"), ("outputs.flirt_mat", "flirt_affine"), ("outputs.report", "coreg_report")]), (filter_smooth, outputnode, [("outputs.timeseries", "smoothed_timeseries")]), (filter_rough, outputnode, [("outputs.timeseries", "unsmoothed_timeseries"), ("outputs.mean_file", "mean_func")]), (confounds, outputnode, [("outputs.confound_file", "confound_file")]), (saveparams, outputnode, [("json_file", "json_file")]), ]) if bool(exp_info["fieldmap_template"]): preproc.connect([ (unwarp, outputnode, [("outputs.report", "unwarp_report")]), ]) return preproc, inputnode, outputnode
'isotropic_voxel', 'anisotropic_voxel', 'isotropic_surface' ])] realign = pe.Node(interface=spm.Realign(), name="realign") realign.inputs.register_to_mean = True isotropic_voxel_smooth = pe.Node( interface=spm.Smooth(), name="isotropic_voxel_smooth") preprocessing.connect(realign, "realigned_files", isotropic_voxel_smooth, "in_files") preprocessing.connect(iter_fwhm, "fwhm", isotropic_voxel_smooth, "fwhm") compute_mask = pe.Node(interface=nipy.ComputeMask(), name="compute_mask") preprocessing.connect(realign, "mean_image", compute_mask, "mean_volume") anisotropic_voxel_smooth = fsl_wf.create_susan_smooth( name="anisotropic_voxel_smooth", separate_masks=False) anisotropic_voxel_smooth.inputs.smooth.output_type = 'NIFTI' preprocessing.connect(realign, "realigned_files", anisotropic_voxel_smooth, "inputnode.in_files") preprocessing.connect(iter_fwhm, "fwhm", anisotropic_voxel_smooth, "inputnode.fwhm") preprocessing.connect(compute_mask, "brain_mask", anisotropic_voxel_smooth, 'inputnode.mask_file') recon_all = pe.Node(interface=fs.ReconAll(), name="recon_all") surfregister = pe.Node(interface=fs.BBRegister(), name='surfregister') surfregister.inputs.init = 'fsl' surfregister.inputs.contrast_type = 't2' preprocessing.connect(realign, 'mean_image', surfregister, 'source_file') preprocessing.connect(recon_all, 'subject_id', surfregister, 'subject_id')
iterfield = ['in_file'], name = 'dilatemask') maskfunc2 = pe.MapNode( interface=fsl.ImageMaths( suffix = '_mask', op_string = '-mas'), iterfield = ['in_file', 'in_file2'], name = 'maskfunc2') susansmooth = create_susan_smooth() susansmooth.inputs.inputnode.fwhm = study_FWHM art = pe.MapNode( interface=ra.ArtifactDetect( norm_threshold = 1, zintensity_threshold = 3, mask_type = 'file', parameter_source = 'SPM', use_differences = [True,False], use_norm = True), iterfield = ['realigned_files', 'realignment_parameters'],
def create_preprocessing_workflow(name="preproc", exp_info=None): """Return a Nipype workflow for fMRI preprocessing. This mostly follows the preprocessing in FSL, although some of the processing has been moved into pure Python. Parameters ---------- name : string workflow object name exp_info : dict dictionary with experimental information """ preproc = Workflow(name) if exp_info is None: exp_info = lyman.default_experiment_parameters() # Define the inputs for the preprocessing workflow in_fields = ["timeseries", "subject_id"] if exp_info["whole_brain_template"]: in_fields.append("whole_brain_template") inputnode = Node(IdentityInterface(in_fields), "inputs") # Remove equilibrium frames and convert to float prepare = MapNode(Function(["in_file", "frames_to_toss"], ["out_file"], prep_timeseries, imports), "in_file", "prep_timeseries") prepare.inputs.frames_to_toss = exp_info["frames_to_toss"] # Motion and slice time correct realign = create_realignment_workflow( temporal_interp=exp_info["temporal_interp"], TR=exp_info["TR"], slice_order=exp_info["slice_order"], interleaved=exp_info["interleaved"]) # Run a conservative skull strip and get a brain mask skullstrip = create_skullstrip_workflow() # Estimate a registration from funtional to anatomical space coregister = create_bbregister_workflow( partial_brain=bool(exp_info["whole_brain_template"])) # Smooth intelligently in the volume susan = create_susan_smooth() susan.inputs.inputnode.fwhm = exp_info["smooth_fwhm"] # Scale and filter the timeseries filter_smooth = create_filtering_workflow("filter_smooth", exp_info["hpf_cutoff"], exp_info["TR"], "smoothed_timeseries") filter_rough = create_filtering_workflow("filter_rough", exp_info["hpf_cutoff"], exp_info["TR"], "unsmoothed_timeseries") # Automatically detect motion and intensity outliers artifacts = MapNode(Function(["timeseries", "mask_file", "motion_file", "intensity_thresh", "motion_thresh"], ["artifact_report"], detect_artifacts, imports), ["timeseries", "mask_file", "motion_file"], "artifacts") artifacts.inputs.intensity_thresh = exp_info["intensity_threshold"] artifacts.inputs.motion_thresh = exp_info["motion_threshold"] # Save the experiment info for this run dumpjson = MapNode(Function(["exp_info", "timeseries"], ["json_file"], dump_exp_info, imports), "timeseries", "dumpjson") dumpjson.inputs.exp_info = exp_info preproc.connect([ (inputnode, prepare, [("timeseries", "in_file")]), (prepare, realign, [("out_file", "inputs.timeseries")]), (realign, skullstrip, [("outputs.timeseries", "inputs.timeseries")]), (realign, artifacts, [("outputs.motion_file", "motion_file")]), (skullstrip, artifacts, [("outputs.mask_file", "mask_file")]), (skullstrip, coregister, [("outputs.mean_file", "inputs.source_file")]), (inputnode, coregister, [("subject_id", "inputs.subject_id")]), (skullstrip, susan, [("outputs.mask_file", "inputnode.mask_file"), ("outputs.timeseries", "inputnode.in_files")]), (susan, filter_smooth, [("outputnode.smoothed_files", "inputs.timeseries")]), (skullstrip, filter_smooth, [("outputs.mask_file", "inputs.mask_file")]), (skullstrip, filter_rough, [("outputs.timeseries", "inputs.timeseries")]), (skullstrip, filter_rough, [("outputs.mask_file", "inputs.mask_file")]), (filter_rough, artifacts, [("outputs.timeseries", "timeseries")]), (inputnode, dumpjson, [("timeseries", "timeseries")]), ]) if bool(exp_info["whole_brain_template"]): preproc.connect([ (inputnode, coregister, [("whole_brain_template", "inputs.whole_brain_template")]) ]) # Define the outputs of the top-level workflow output_fields = ["smoothed_timeseries", "unsmoothed_timeseries", "example_func", "mean_func", "functional_mask", "realign_report", "mask_report", "artifact_report", "flirt_affine", "tkreg_affine", "coreg_report", "json_file"] outputnode = Node(IdentityInterface(output_fields), "outputs") preproc.connect([ (realign, outputnode, [("outputs.example_func", "example_func"), ("outputs.report", "realign_report")]), (skullstrip, outputnode, [("outputs.mean_file", "mean_func"), ("outputs.mask_file", "functional_mask"), ("outputs.report", "mask_report")]), (artifacts, outputnode, [("artifact_report", "artifact_report")]), (coregister, outputnode, [("outputs.tkreg_mat", "tkreg_affine"), ("outputs.flirt_mat", "flirt_affine"), ("outputs.report", "coreg_report")]), (filter_smooth, outputnode, [("outputs.timeseries", "smoothed_timeseries")]), (filter_rough, outputnode, [("outputs.timeseries", "unsmoothed_timeseries")]), (dumpjson, outputnode, [("json_file", "json_file")]), ]) return preproc, inputnode, outputnode
def create_prep(name='preproc'): """ Base preprocessing workflow for task and resting state fMRI Parameters ---------- name : name of workflow. Default = 'preproc' Inputs ------ inputspec.fssubject_id : inputspec.fssubject_dir : inputspec.func : inputspec.highpass : inputspec.num_noise_components : inputspec.ad_normthresh : inputspec.ad_zthresh : inputspec.tr : inputspec.interleaved : inputspec.sliceorder : inputspec.compcor_select : inputspec.highpass_sigma : inputspec.lowpass_sigma : inputspec.reg_params : inputspec.FM_TEdiff : inputspec.FM_Echo_spacing : inputspec.FM_sigma : Outputs ------- outputspec.reference : outputspec.motion_parameters : outputspec.realigned_files : outputspec.mask : outputspec.smoothed_files : outputspec.highpassed_files : outputspec.mean : outputspec.combined_motion : outputspec.outlier_files : outputspec.mask : outputspec.reg_cost : outputspec.reg_file : outputspec.noise_components : outputspec.tsnr_file : outputspec.stddev_file : outputspec.filter_file : outputspec.scaled_files : outputspec.z_img : outputspec.motion_plots : outputspec.FM_unwarped_mean : outputspec.FM_unwarped_epi : Returns ------- workflow : preprocessing workflow """ preproc = pe.Workflow(name=name) # Compcorr node compcor = create_compcorr() # Input node inputnode = pe.Node(util.IdentityInterface(fields=['fssubject_id', 'fssubject_dir', 'func', 'highpass', 'num_noise_components', 'ad_normthresh', 'ad_zthresh', 'tr', 'interleaved', 'sliceorder', 'compcor_select', 'highpass_sigma', 'lowpass_sigma', 'reg_params', 'FM_TEdiff', 'FM_Echo_spacing', 'FM_sigma']), name='inputspec') # Separate input node for FWHM inputnode_fwhm = pe.Node(util.IdentityInterface(fields=['fwhm']), name='fwhm_input') # convert BOLD images to float img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float', op_string='', suffix='_dtype'), iterfield=['in_file'], name='img2float') # define the motion correction node motion_correct = pe.Node(interface=FmriRealign4d(), name='realign') # construct motion plots plot_motion = pe.MapNode(interface=fsl.PlotMotionParams(in_source='fsl'), name='plot_motion', iterfield=['in_file']) # rapidArt for artifactual timepoint detection ad = pe.Node(ra.ArtifactDetect(), name='artifactdetect') # extract the mean volume if the first functional run meanfunc = art_mean_workflow() # generate a freesurfer workflow that will return the mask getmask = create_getmask_flow() # create a SUSAN smoothing workflow, and smooth each run with # 75% of the median value for each run as the brightness # threshold. smooth = create_susan_smooth(name="smooth_with_susan", separate_masks=False) # choose susan function """ The following node selects smooth or unsmoothed data depending on the fwhm. This is because SUSAN defaults to smoothing the data with about the voxel size of the input data if the fwhm parameter is less than 1/3 of the voxel size. """ choosesusan = pe.Node(util.Function(input_names=['fwhm', 'motion_files', 'smoothed_files'], output_names=['cor_smoothed_files'], function=choose_susan), name='select_smooth') # scale the median value of each run to 10,000 meanscale = pe.MapNode(interface=fsl.ImageMaths(suffix='_gms'), iterfield=['in_file', 'op_string'], name='scale_median') # determine the median value of the MASKED functional runs medianval = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'), iterfield=['in_file'], name='compute_median_val') # temporal highpass filtering highpass = pe.MapNode(interface=fsl.ImageMaths(suffix='_tempfilt'), iterfield=['in_file'], name='highpass') # Calculate the z-score of output zscore = pe.MapNode(interface=util.Function(input_names=['image','outliers'], output_names=['z_img'], function=z_image), name='z_score', iterfield=['image','outliers']) # declare some node inputs... plot_motion.iterables = ('plot_type', ['rotations', 'translations']) ad.inputs.parameter_source = 'FSL' meanfunc.inputs.inputspec.parameter_source = 'FSL' ad.inputs.mask_type = 'file' ad.inputs.use_differences = [True, False] getmask.inputs.inputspec.contrast_type = 't2' getmask.inputs.register.out_fsl_file = True fssource = getmask.get_node('fssource') # make connections... preproc.connect(inputnode, 'fssubject_id', getmask, 'inputspec.subject_id') preproc.connect(inputnode, 'ad_normthresh', ad, 'norm_threshold') preproc.connect(inputnode, 'ad_zthresh', ad, 'zintensity_threshold') preproc.connect(inputnode, 'tr', motion_correct, 'tr') preproc.connect(inputnode, 'interleaved', motion_correct, 'interleaved') preproc.connect(inputnode, 'sliceorder', motion_correct, 'slice_order') preproc.connect(inputnode, 'compcor_select', compcor, 'inputspec.selector') preproc.connect(inputnode, 'fssubject_dir', getmask, 'inputspec.subjects_dir') preproc.connect(inputnode, 'func', img2float, 'in_file') preproc.connect(img2float, 'out_file', motion_correct, 'in_file') preproc.connect(motion_correct, 'par_file', plot_motion, 'in_file') preproc.connect(motion_correct, 'out_file', meanfunc, 'inputspec.realigned_files') preproc.connect(motion_correct, 'par_file', meanfunc, 'inputspec.realignment_parameters') preproc.connect(meanfunc, 'outputspec.mean_image', getmask, 'inputspec.source_file') preproc.connect(inputnode, 'num_noise_components', compcor, 'inputspec.num_components') preproc.connect(motion_correct, 'out_file', compcor, 'inputspec.realigned_file') preproc.connect(meanfunc, 'outputspec.mean_image', compcor, 'inputspec.mean_file') preproc.connect(fssource, 'aseg', compcor, 'inputspec.fsaseg_file') preproc.connect(getmask, ('outputspec.reg_file', pickfirst), compcor, 'inputspec.reg_file') preproc.connect(motion_correct, 'out_file', ad, 'realigned_files') preproc.connect(motion_correct, 'par_file', ad, 'realignment_parameters') preproc.connect(getmask, ('outputspec.mask_file', pickfirst), ad, 'mask_file') preproc.connect(getmask, ('outputspec.mask_file', pickfirst), medianval, 'mask_file') preproc.connect(inputnode_fwhm, 'fwhm', smooth, 'inputnode.fwhm') preproc.connect(motion_correct, 'out_file', smooth, 'inputnode.in_files') preproc.connect(getmask, ('outputspec.mask_file',pickfirst), smooth, 'inputnode.mask_file') preproc.connect(smooth, 'outputnode.smoothed_files', choosesusan, 'smoothed_files') preproc.connect(motion_correct, 'out_file', choosesusan, 'motion_files') preproc.connect(inputnode_fwhm, 'fwhm', choosesusan, 'fwhm') preproc.connect(choosesusan, 'cor_smoothed_files', meanscale, 'in_file') preproc.connect(choosesusan, 'cor_smoothed_files', medianval, 'in_file') preproc.connect(medianval, ('out_stat', getmeanscale), meanscale, 'op_string') preproc.connect(inputnode, ('highpass', highpass_operand), highpass, 'op_string') preproc.connect(meanscale, 'out_file', highpass, 'in_file') preproc.connect(highpass, 'out_file', zscore, 'image') preproc.connect(ad, 'outlier_files', zscore, 'outliers') # create output node outputnode = pe.Node(interface=util.IdentityInterface( fields=['mean', 'motion_parameters', 'realigned_files', 'smoothed_files', 'highpassed_files', 'combined_motion', 'outlier_files', 'outlier_stat_files', 'mask', 'reg_cost', 'reg_file', 'reg_fsl_file', 'noise_components', 'tsnr_file', 'stddev_file', 'tsnr_detrended', 'filter_file', 'scaled_files', 'z_img', 'motion_plots', 'FM_unwarped_epi', 'FM_unwarped_mean', 'vsm_file', 'bandpassed_file']), name='outputspec') # make output connection preproc.connect(meanfunc, 'outputspec.mean_image', outputnode, 'mean') preproc.connect(motion_correct, 'par_file', outputnode, 'motion_parameters') preproc.connect(motion_correct, 'out_file', outputnode, 'realigned_files') preproc.connect(highpass, 'out_file', outputnode, 'highpassed_files') preproc.connect(ad, 'norm_files', outputnode, 'combined_motion') preproc.connect(ad, 'outlier_files', outputnode, 'outlier_files') preproc.connect(ad, 'statistic_files', outputnode, 'outlier_stat_files') preproc.connect(compcor, 'outputspec.noise_components', outputnode, 'noise_components') preproc.connect(getmask, 'outputspec.mask_file', outputnode, 'mask') preproc.connect(getmask, 'register.out_fsl_file', outputnode, 'reg_fsl_file') preproc.connect(getmask, 'outputspec.reg_file', outputnode, 'reg_file') preproc.connect(getmask, 'outputspec.reg_cost', outputnode, 'reg_cost') preproc.connect(choosesusan, 'cor_smoothed_files', outputnode, 'smoothed_files') preproc.connect(compcor, 'outputspec.tsnr_file', outputnode, 'tsnr_file') preproc.connect(compcor, 'outputspec.stddev_file', outputnode, 'stddev_file') preproc.connect(compcor, 'outputspec.tsnr_detrended', outputnode, 'tsnr_detrended') preproc.connect(zscore,'z_img', outputnode,'z_img') preproc.connect(plot_motion,'out_file', outputnode,'motion_plots') return preproc
def anatPipeline(resultsDir, workDir, subDir, subid): pnf = join(subDir,subid+".ipynb") pnb = getIPythonNB(pnf, True) text= "# Anatomic Pipeline results for subject " + subid code= "" addCell(pnb, text,code) print("\n ** PIPELINE : starting anatomic pipeline.\n") ANAT_DIR = abspath(join(subDir, 'anat')) ANAT_T1W = abspath(join(ANAT_DIR, subid + '_T1w.nii.gz')) ANAT_BET_T1W=abspath(join(resultsDir, subid + '_T1w_bet.nii.gz')) text="Anatomic T1W image" code=("%pylab inline\nimport nibabel as nb;img = nb.load('" +ANAT_T1W+"');data = img.get_data();" "plt.imshow(np.rot90(data[...,100]),cmap='gray');" "plt.gca().set_axis_off()") addCell(pnb, text,code) #A. PREPROCESSING PIPELINE #1. SKULL STRIPPING WITH BET betNodeInputs={} betNodeInputs['in_file']=ANAT_T1W #betNodeInputs['out_file']=ANAT_BET_T1W #very strange that this stops it working in workflow mode betNodeInputs['mask']=True betNodeInputs['frac']=0.5 betNode = createNiPypeNode(BET(),'betNode',betNodeInputs) #n_file=ANAT_T1W #betNode = Node(BET(in_file=in_file,mask=True), name="betNode") #print(betNode.inputs) #print(betNode._interface.cmdline) #print(betNode.outputs) #betResults = betNode.run() #print('** debug ** command line output') #print(betNode._interface.cmdline) #print('** debug ** inputs') #print(betNode.inputs) #print('** debug ** outputs') #print(tempresult.outputs) #2. SMOOTH ORIGINAL IMAGE WITH ISOTROPIC SMOOTH smoothNodeInputs = {} smoothNodeInputs['in_file']=ANAT_T1W smoothNodeInputs['fwhm']=4 smoothNode = createNiPypeNode(IsotropicSmooth(),'smoothNode',smoothNodeInputs) #smoothResults =smoothNode.run() #3. MASK SMOOTHED IMAGE WITH APPLYMASK maskNodeInputs = {} maskNode = createNiPypeNode(ApplyMask(),'maskNode',maskNodeInputs) # ILLUSTRATING USING WORKFLOW WITH APPLYMASK #4. create workflow wfName='smoothflow' wfGraph='smoothWorkflow_graph.dot' wfGraphDetailed='smoothWorkflow_graph_detailed.dot' wf = Workflow(name=wfName,base_dir=workDir) WF_DIR=abspath(join(workDir, wfName)) wf.connect(betNode, "mask_file",maskNode, "mask_file") wf.connect([(smoothNode,maskNode,[("out_file", "in_file")])]) wf.write_graph(wfGraph, graph2use='colored') wfImg = plt.imread(WF_DIR + '/' + wfGraph+'.png') plt.imshow(wfImg) #plt.show(block=False) #set to true if you want to see this graph wf.write_graph(wfGraph, graph2use='flat') wfImgDetailed = plt.imread(WF_DIR + '/' + wfGraphDetailed+'.png') #plt.imshow(wfImgDetailed) #plt.show(block=False) # run the workflow wf.run() print(wf.inputs) print(wf.outputs) #print(betNode.inputs) #print(betNode.outputs) #print(wf.get_node('betNode').inputs) #print(wf.get_node('betNode').outputs) pnames=[] wfInputs = getWorkFlowInputs(wf,True) if len(wfInputs)> 0: for node in wf.list_node_names(): for key in wfInputs[node]: filename = wfInputs[node][key] filecomps = filename.split('.') if filecomps[-1]=='nii' or (filecomps[-1]=='gz' and filecomps[-2]=='nii'): pnames.append(filename) wfOutputs = getWorkFlowOutputs(wf,True) if len(wfOutputs)> 0: for node in wf.list_node_names(): for key in wfOutputs[node]: filename = wfOutputs[node][key] filecomps = filename.split('.') if filecomps[-1]=='nii' or (filecomps[-1]=='gz' and filecomps[-2]=='nii'): pnames.append(filename) pnames = set(pnames) # #%pylab inline #from nilearn import plotting #niplot.plot_anat(betNode.inputs.in_file,title='T1W in-file', cut_coords=(10,10,10), display_mode='ortho', dim=-1, draw_cross=False, annotate=False) #niplot.show() #need a better way to display #plt.show(block=False) #niplot.plot_anat(smoothResults.outputs.out_file,title='T1W in-file', cut_coords=(10,10,10), display_mode='ortho', dim=-1, draw_cross=False, annotate=False) #niplot.show() #need a better way to display #niplot.plot_anat(betResults.outputs.out_file,title='T1W skull-stripped out-file', cut_coords=(10,10,10), display_mode='ortho', dim=-1, draw_cross=False, annotate=False) #niplot.show() #need a better way to display that doesn't hold up process #niplot.show() #for now just do this at the end. #plt.show(block=False) #plot images vertically #fnames=[] #fnames.append(betResults.outputs.out_file) #fnames.append(smoothResults.outputs.out_file) ranges = [30, 138, 180] plot_slices(pnames,ranges, 'v') plt.show() #plot images horizontally #fnames=[] #fnames.append(betResults.outputs.out_file) #fnames.append(smoothResults.outputs.out_file) ranges=range(130,136) plot_slices(pnames,ranges, 'h') plt.show() # ILLUSTRATING USING NESTED WORKFLOW WITH PROVIDED SUSAN FLOW for Non-linear smoothing # 5. Create Susan workflow and display # Note that to specify specific location for susan to work then you will need to embed it into another workflow!!! wfName='susan_smooth' wfGraph='susan_smooth_graph.dot' WF_DIR=abspath(join(workDir, wfName)) susanWf = create_susan_smooth(name='susan_smooth', separate_masks=False) #print(susanWf.inputs) #print(susanWf.outputs) #print(susanWf.inputs.inputnode) # this specifies the visible inputs/outputs to external #print(susanWf.outputs.outputnode) graphLoc=join(WF_DIR,wfGraph) susanWf.write_graph(graphLoc,graph2use='colored') susanWfImg = plt.imread(join(WF_DIR,wfGraph+'.png')) plt.imshow(susanWfImg) plt.gca().set_axis_off() plt.show() # 6. Create new Workflow and use Susan as the smoothing step # Initiate workflow with name and base directory wfName='smoothSusanFlow' wfGraph='smoothSusanFlow_graph.dot' WF_DIR=abspath(join(workDir, wfName)) wf2 = Workflow(name=wfName, base_dir=workDir) # Create new skullstrip and mask nodes betNodeInputs={} betNodeInputs['in_file']=ANAT_T1W betNodeInputs['mask']=True betNodeInputs['frac']=0.5 betNode2 = createNiPypeNode(BET(),'betNode2',betNodeInputs) maskNodeInputs = {} maskNode2 = createNiPypeNode(ApplyMask(),'maskNode2',maskNodeInputs) # Connect the nodes to each other and to the susan workflow wf2.connect([(betNode2, maskNode2, [("mask_file", "mask_file")]), (betNode2, susanWf, [("mask_file", "inputnode.mask_file")]), (susanWf, list_extract, [("outputnode.smoothed_files", "list_out")]), (list_extract, maskNode2, [("out_file", "in_file")]) ]) # Specify the remaining input variables for the susan workflow susanWf.inputs.inputnode.in_files = abspath(ANAT_T1W) susanWf.inputs.inputnode.fwhm = 4 #detailed graph showing workflow details embedded in overall workflow graphLoc=join(WF_DIR,wfGraph) wf2.write_graph(graphLoc, graph2use='colored') graphImgLoc=join(WF_DIR,wfGraph+'.png') wf2Img = plt.imread(graphImgLoc) plt.imshow(wf2Img) plt.gca().set_axis_off() plt.show() text="Demonstrating Nilearn plotting" plotTitle = 'dynamic title' code=("%pylab inline\nfrom nilearn import plotting;plotting.plot_anat('"+ ANAT_T1W + "',title='" + plotTitle +"', cut_coords=(" + "10,10,10"+"), display_mode='ortho', dim=-1, draw_cross=False, annotate=False)") addCell(pnb, text,code) #niplot.plot_anat(betNode.inputs.in_file,title='T1W in-file', cut_coords=(10,10,10), display_mode='ortho', dim=-1, draw_cross=False, annotate=False) #niplot.show() #need a better way to display #plt.show(block=False) text="Anatomic Workflow" code=("%pylab inline\nimg=matplotlib.image.imread('"+ graphImgLoc + "');imgplot = plt.imshow(img)") addCell(pnb, text,code) closeIPythonNB(pnf, pnb, True) #graph showing summary of embedded workflow wf2.write_graph(join(WF_DIR,wfGraph), graph2use='orig') wf2Img = plt.imread(join(WF_DIR,wfGraph+'.png')) plt.imshow(wf2Img) plt.gca().set_axis_off() plt.show() #run the new workflow with embedded susan wf2.run() print(wf2.inputs) print(wf2.outputs) print(str(wf2.list_node_names())) print(str(susanWf.list_node_names())) #LOrdie there has to be an easier way than this to get the outputs and input files generically from a workflow? pnames=[] wfInputs = getWorkFlowInputs(wf2,True) if len(wfInputs)> 0: for node in wf2.list_node_names(): if node in wfInputs: for key in wfInputs[node]: filename = wfInputs[node][key] filecomps = filename.split('.') if filecomps[-1]=='nii' or (filecomps[-1]=='gz' and filecomps[-2]=='nii'): pnames.append(filename) wfOutputs = getWorkFlowOutputs(wf2,True) if len(wfOutputs)> 0: for node in wf2.list_node_names(): if node in wfOutputs: for key in wfOutputs[node]: filename = wfOutputs[node][key] filecomps = filename.split('.') if filecomps[-1]=='nii' or (filecomps[-1]=='gz' and filecomps[-2]=='nii'): pnames.append(filename) pnames = set(pnames) ranges = [30, 138, 180] plot_slices(pnames,ranges, 'v') plt.show() #plot images horizontally #fnames=[] #fnames.append(betResults.outputs.out_file) #fnames.append(smoothResults.outputs.out_file) ranges=range(130,136) plot_slices(pnames,ranges, 'h') plt.show() # 6 Demonstrate efficient recomputing of workflows - only dependent steps need to be recomputed #original workflow wf.inputs.smoothNode.fwhm = 1 wf.run() pnames=[] wfOutputs = getWorkFlowOutputs(wf,True) if len(wfOutputs)> 0: for node in wf.list_node_names(): for key in wfOutputs[node]: filename = wfOutputs[node][key] filecomps = filename.split('.') if filecomps[-1]=='nii' or (filecomps[-1]=='gz' and filecomps[-2]=='nii'): pnames.append(filename) pnames = set(pnames) ranges = [30, 138] plot_slices(pnames,ranges, 'h') plt.show() #susan workflow wf2.inputs.susan_smooth.inputnode.fwhm = 1 wf2.run() pnames=[] wfOutputs = getWorkFlowOutputs(wf2,True) if len(wfOutputs)> 0: for node in wf2.list_node_names(): if node in wfOutputs: for key in wfOutputs[node]: filename = wfOutputs[node][key] filecomps = filename.split('.') if filecomps[-1]=='nii' or (filecomps[-1]=='gz' and filecomps[-2]=='nii'): pnames.append(filename) pnames = set(pnames) ranges = [30, 138] plot_slices(pnames,ranges, 'h') plt.show()
def create_preprocessing_workflow(name="preproc", exp_info=None): """Return a Nipype workflow for fMRI preprocessing. This mostly follows the preprocessing in FSL, although some of the processing has been moved into pure Python. Parameters ---------- name : string workflow object name exp_info : dict dictionary with experimental information """ preproc = Workflow(name) if exp_info is None: exp_info = lyman.default_experiment_parameters() # Define the inputs for the preprocessing workflow in_fields = ["timeseries", "subject_id"] if exp_info["whole_brain_template"]: in_fields.append("whole_brain") if exp_info["fieldmap_template"]: in_fields.append("fieldmap") inputnode = Node(IdentityInterface(in_fields), "inputs") # Remove equilibrium frames and convert to float prepare = MapNode(PrepTimeseries(), "in_file", "prep_timeseries") prepare.inputs.frames_to_toss = exp_info["frames_to_toss"] # Unwarp using fieldmap images if exp_info["fieldmap_template"]: unwarp = create_unwarp_workflow(fieldmap_pe=exp_info["fieldmap_pe"]) # Motion and slice time correct realign = create_realignment_workflow( temporal_interp=exp_info["temporal_interp"], TR=exp_info["TR"], slice_order=exp_info["slice_order"], interleaved=exp_info["interleaved"], ) # Estimate a registration from funtional to anatomical space coregister = create_bbregister_workflow( partial_brain=bool(exp_info["whole_brain_template"]), init_with=exp_info["coreg_init"] ) # Skullstrip the brain using the Freesurfer segmentation skullstrip = create_skullstrip_workflow() # Smooth intelligently in the volume susan = create_susan_smooth() susan.inputs.inputnode.fwhm = exp_info["smooth_fwhm"] # Scale and filter the timeseries filter_smooth = create_filtering_workflow( "filter_smooth", exp_info["hpf_cutoff"], exp_info["TR"], "smoothed_timeseries" ) filter_rough = create_filtering_workflow( "filter_rough", exp_info["hpf_cutoff"], exp_info["TR"], "unsmoothed_timeseries" ) # Automatically detect motion and intensity outliers artifacts = MapNode(ArtifactDetection(), ["timeseries", "mask_file", "motion_file"], "artifacts") artifacts.inputs.intensity_thresh = exp_info["intensity_threshold"] artifacts.inputs.motion_thresh = exp_info["motion_threshold"] artifacts.inputs.spike_thresh = exp_info["spike_threshold"] # Extract nuisance variables from anatomical sources confounds = create_confound_extraction_workflow("confounds", exp_info["wm_components"]) # Save the experiment info for this run saveparams = MapNode(SaveParameters(exp_info=exp_info), "in_file", "saveparams") preproc.connect( [ (inputnode, prepare, [("timeseries", "in_file")]), (realign, artifacts, [("outputs.motion_file", "motion_file")]), (realign, coregister, [("outputs.timeseries", "inputs.timeseries")]), (inputnode, coregister, [("subject_id", "inputs.subject_id")]), (realign, skullstrip, [("outputs.timeseries", "inputs.timeseries")]), (inputnode, skullstrip, [("subject_id", "inputs.subject_id")]), (coregister, skullstrip, [("outputs.tkreg_mat", "inputs.reg_file")]), (skullstrip, artifacts, [("outputs.mask_file", "mask_file")]), ( skullstrip, susan, [("outputs.mask_file", "inputnode.mask_file"), ("outputs.timeseries", "inputnode.in_files")], ), (susan, filter_smooth, [("outputnode.smoothed_files", "inputs.timeseries")]), (skullstrip, filter_smooth, [("outputs.mask_file", "inputs.mask_file")]), (skullstrip, filter_rough, [("outputs.timeseries", "inputs.timeseries")]), (skullstrip, filter_rough, [("outputs.mask_file", "inputs.mask_file")]), (filter_rough, artifacts, [("outputs.timeseries", "timeseries")]), (filter_rough, confounds, [("outputs.timeseries", "inputs.timeseries")]), (inputnode, confounds, [("subject_id", "inputs.subject_id")]), (skullstrip, confounds, [("outputs.mask_file", "inputs.brain_mask")]), (coregister, confounds, [("outputs.tkreg_mat", "inputs.reg_file")]), (inputnode, saveparams, [("timeseries", "in_file")]), ] ) # Optionally add a connection for unwarping if bool(exp_info["fieldmap_template"]): preproc.connect( [ (inputnode, unwarp, [("fieldmap", "inputs.fieldmap")]), (prepare, unwarp, [("out_file", "inputs.timeseries")]), (unwarp, realign, [("outputs.timeseries", "inputs.timeseries")]), ] ) else: preproc.connect([(prepare, realign, [("out_file", "inputs.timeseries")])]) # Optionally connect the whole brain template if bool(exp_info["whole_brain_template"]): preproc.connect([(inputnode, coregister, [("whole_brain_template", "inputs.whole_brain_template")])]) # Define the outputs of the top-level workflow output_fields = [ "smoothed_timeseries", "unsmoothed_timeseries", "example_func", "mean_func", "functional_mask", "realign_report", "mask_report", "artifact_report", "confound_file", "flirt_affine", "tkreg_affine", "coreg_report", "json_file", ] if bool(exp_info["fieldmap_template"]): output_fields.append("unwarp_report") outputnode = Node(IdentityInterface(output_fields), "outputs") preproc.connect( [ (realign, outputnode, [("outputs.example_func", "example_func"), ("outputs.report", "realign_report")]), (skullstrip, outputnode, [("outputs.mask_file", "functional_mask"), ("outputs.report", "mask_report")]), (artifacts, outputnode, [("out_files", "artifact_report")]), ( coregister, outputnode, [ ("outputs.tkreg_mat", "tkreg_affine"), ("outputs.flirt_mat", "flirt_affine"), ("outputs.report", "coreg_report"), ], ), (filter_smooth, outputnode, [("outputs.timeseries", "smoothed_timeseries")]), ( filter_rough, outputnode, [("outputs.timeseries", "unsmoothed_timeseries"), ("outputs.mean_file", "mean_func")], ), (confounds, outputnode, [("outputs.confound_file", "confound_file")]), (saveparams, outputnode, [("json_file", "json_file")]), ] ) if bool(exp_info["fieldmap_template"]): preproc.connect([(unwarp, outputnode, [("outputs.report", "unwarp_report")])]) return preproc, inputnode, outputnode