def do_pipe3_projection(subject_ID, freesurfer_dir, workflow_dir, output_dir, tract_number, use_sample=False): """ Packages and Data Setup ======================= Import necessary modules from nipype. """ import nipype.interfaces.io as io # Data i/o import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pipeline engine import nipype.interfaces.fsl as fsl import nipype.interfaces.freesurfer as fsurf # freesurfer import nipype.interfaces.ants as ants import os.path as op # system functions from nipype.interfaces.utility import Function from dmri_pipe_aux import get_connectivity_matrix from dmri_pipe_aux import surf2file from dmri_pipe_aux import voxels2nii from dmri_pipe_aux import normalize_matrix from dmri_pipe_aux import interface2surf from dmri_pipe_aux import read_voxels from dmri_pipe_aux import downsample_matrix from dmri_pipe_aux import merge_matrices """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """ Point to the freesurfer subjects directory (Recon-all must have been run on the subjects) """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" subjects_dir = op.abspath(freesurfer_dir) fsurf.FSCommand.set_default_subjects_dir(subjects_dir) fsl.FSLCommand.set_default_output_type('NIFTI') """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """ define the workflow """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" dmripipeline = pe.Workflow(name='pipe3_projection') """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """ Use datasource node to perform the actual data grabbing. Templates for the associated images are used to obtain the correct images. """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" data_template = subject_ID + "/%s/" + "%s" + "%s" info = dict( wm=[['fa_masking', subject_ID, '_mask_wm.nii']], seeds_left=[['fa_masking', subject_ID, '_interface_left_voxels.txt']], seeds_right=[['fa_masking', subject_ID, '_interface_right_voxels.txt']], index_left=[['fa_masking', subject_ID, '_interface_left_index.nii']], index_right=[['fa_masking', subject_ID, '_interface_right_index.nii']], fa=[['fa_masking', subject_ID, '_fa_masked.nii']], t1=[['anatomy', subject_ID, '_t1_masked.nii']], inv_flirt_mat=[['anatomy', '', 'flirt_t1_2_fa_inv.mat']], warp=[['anatomy', '', 'ants_fa_2_regt1_Warp.nii.gz']]) datasource = pe.Node(interface=io.DataGrabber(outfields=info.keys()), name='datasource') datasource.inputs.template = data_template datasource.inputs.base_directory = output_dir datasource.inputs.template_args = info datasource.inputs.sort_filelist = True datasource.run_without_submitting = True tracts_left_source = pe.Node( interface=io.DataGrabber(outfields=['tracts_left']), name='tracts_left_source') tracts_left_source.inputs.template = subject_ID + '/raw_tracts/lh/probtract_*.nii' tracts_left_source.inputs.base_directory = output_dir tracts_left_source.inputs.sort_filelist = True tracts_left_source.run_without_submitting = True tracts_right_source = pe.Node( interface=io.DataGrabber(outfields=['tracts_right']), name='tracts_right_source') tracts_right_source.inputs.template = subject_ID + '/raw_tracts/rh/probtract_*.nii' tracts_right_source.inputs.base_directory = output_dir tracts_right_source.inputs.sort_filelist = True tracts_right_source.run_without_submitting = True """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """ The input node declared here will be the main conduits for the raw data to the rest of the processing pipeline. """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" inputnode = pe.Node(interface=util.IdentityInterface(fields=[ "wm", "seeds_left", "seeds_right", "index_left", "index_right", "fa", "t1", "inv_flirt_mat", "warp", "tracts_left", "tracts_right" ]), name="inputnode") """ read seed coordinates """ interface_voxels_left = pe.Node(interface=Function( input_names=["seed_file", "use_sample"], output_names=["seed_list"], function=read_voxels), name='70_interface_voxels_left') interface_voxels_left.inputs.use_sample = use_sample dmripipeline.connect(inputnode, "seeds_left", interface_voxels_left, "seed_file") interface_voxels_right = interface_voxels_left.clone( name='70_interface_voxels_right') dmripipeline.connect(inputnode, "seeds_right", interface_voxels_right, "seed_file") """ Get the direct connectivity matrix """ connectivity_matrix = pe.Node(interface=Function( input_names=[ "tract_list_left", "tract_list_right", "voxel_list_left", "voxel_list_right", "max_value" ], output_names=[ "submatrix_left_left", "submatrix_left_right", "submatrix_right_left", "submatrix_right_right", "exclusion_list" ], function=get_connectivity_matrix), name='71_direct_connect_array') connectivity_matrix.inputs.max_value = tract_number connectivity_matrix.run_without_submitting = True # connectivity_matrix.plugin_args={'override_specs': 'requirements = Machine == "kalifornien.cbs.mpg.de"'} dmripipeline.connect(inputnode, "tracts_left", connectivity_matrix, "tract_list_left") dmripipeline.connect(inputnode, "tracts_right", connectivity_matrix, "tract_list_right") dmripipeline.connect(interface_voxels_left, "seed_list", connectivity_matrix, "voxel_list_left") dmripipeline.connect(interface_voxels_right, "seed_list", connectivity_matrix, "voxel_list_right") tract_exclusion_mask = pe.Node(interface=Function( input_names=["voxel_list", "ref_image", "outfile"], output_names=["outfile"], function=voxels2nii), name='72_tract_exclusion_mask') tract_exclusion_mask.inputs.outfile = subject_ID + '_tractseed_exclusion_mask.nii' dmripipeline.connect(inputnode, "wm", tract_exclusion_mask, "ref_image") dmripipeline.connect(connectivity_matrix, "exclusion_list", tract_exclusion_mask, "voxel_list") submatrix_left_left = pe.Node(interface=Function( input_names=["in_array", "max_value", "outfile_prefix"], output_names=[ "mat_matrix_nat", "mat_matrix_log", "nii_matrix_nat", "nii_matrix_log" ], function=normalize_matrix), name='73_submatrix_left_left') submatrix_left_left.run_without_submitting = True submatrix_left_left.inputs.max_value = tract_number submatrix_left_left.inputs.outfile_prefix = 'directconnect_left_left' dmripipeline.connect(connectivity_matrix, "submatrix_left_left", submatrix_left_left, "in_array") submatrix_left_right = submatrix_left_left.clone( name='73_submatrix_left_right') submatrix_left_right.inputs.outfile_prefix = 'directconnect_left_right' dmripipeline.connect(connectivity_matrix, "submatrix_left_right", submatrix_left_right, "in_array") submatrix_right_left = submatrix_left_left.clone( name='73_submatrix_right_left') submatrix_right_left.inputs.outfile_prefix = 'directconnect_right_left' dmripipeline.connect(connectivity_matrix, "submatrix_right_left", submatrix_right_left, "in_array") submatrix_right_right = submatrix_left_left.clone( name='73_submatrix_right_right') submatrix_right_right.inputs.outfile_prefix = 'directconnect_right_right' dmripipeline.connect(connectivity_matrix, "submatrix_right_right", submatrix_right_right, "in_array") # full_matrix_nat = pe.Node(interface=Function(input_names=["sm_left_left", "sm_left_right","sm_right_left", "sm_right_right", "out_filename"], output_names=["out_file"], function=merge_matrices), name='73_full_matrix_nat') # full_matrix_nat.inputs.out_filename = 'directconnect_full_nat.mat' # full_matrix_nat.run_without_submitting = True # dmripipeline.connect(submatrix_left_left, "nii_matrix_nat", full_matrix_nat, "sm_left_left") # dmripipeline.connect(submatrix_left_right, "nii_matrix_nat", full_matrix_nat, "sm_left_right") # dmripipeline.connect(submatrix_right_left, "nii_matrix_nat", full_matrix_nat, "sm_right_left") # dmripipeline.connect(submatrix_right_right, "nii_matrix_nat", full_matrix_nat, "sm_right_right") # # full_matrix_log = full_matrix_nat.clone(name='73_full_matrix_log') # full_matrix_log.inputs.out_filename = 'directconnect_full_log.mat' # full_matrix_log.run_without_submitting = True # dmripipeline.connect(submatrix_left_left, "nii_matrix_log", full_matrix_log, "sm_left_left") # dmripipeline.connect(submatrix_left_right, "nii_matrix_log", full_matrix_log, "sm_left_right") # dmripipeline.connect(submatrix_right_left, "nii_matrix_log", full_matrix_log, "sm_right_left") # dmripipeline.connect(submatrix_right_right, "nii_matrix_log", full_matrix_log, "sm_right_right") """ # invert and binarize tract exclusion mask and remove those voxels from the index interfaces """ tract_denoise_mask = pe.Node(interface=fsl.maths.MathsCommand(), name='74_tract_denoise_mask') tract_denoise_mask.inputs.args = '-binv' tract_denoise_mask.run_without_submitting = True dmripipeline.connect(tract_exclusion_mask, "outfile", tract_denoise_mask, "in_file") index_pruned_left = pe.Node(interface=fsl.maths.ApplyMask(), name='75_interface_pruned_left') index_pruned_left.inputs.out_file = subject_ID + '_interface_pruned_left.nii' index_pruned_left.run_without_submitting = True dmripipeline.connect(inputnode, "index_left", index_pruned_left, "in_file") dmripipeline.connect(tract_denoise_mask, "out_file", index_pruned_left, "mask_file") index_pruned_right = index_pruned_left.clone( name='75_interface_pruned_right') index_pruned_right.inputs.out_file = subject_ID + '_interface_pruned_right.nii' dmripipeline.connect(inputnode, "index_right", index_pruned_right, "in_file") dmripipeline.connect(tract_denoise_mask, "out_file", index_pruned_right, "mask_file") """ # warp index image to t1 space """ index_warped_2_t1_left = pe.Node(interface=ants.WarpImageMultiTransform(), name='76_index_warped_2_t1_left') index_warped_2_t1_left.inputs.use_nearest = True index_warped_2_t1_left.run_without_submitting = True dmripipeline.connect([(index_pruned_left, index_warped_2_t1_left, [('out_file', 'input_image')])]) dmripipeline.connect([(inputnode, index_warped_2_t1_left, [('fa', 'reference_image')])]) dmripipeline.connect([(inputnode, index_warped_2_t1_left, [('warp', 'transformation_series')])]) index_warped_2_t1_right = index_warped_2_t1_left.clone( name='76_index_warped_2_t1_right') dmripipeline.connect([(index_pruned_right, index_warped_2_t1_right, [('out_file', 'input_image')])]) dmripipeline.connect([(inputnode, index_warped_2_t1_right, [('fa', 'reference_image')])]) dmripipeline.connect([(inputnode, index_warped_2_t1_right, [('warp', 'transformation_series')])]) index_final_2_t1_left = pe.Node(interface=fsl.ApplyXfm(), name='77_index_final_2_t1_left') index_final_2_t1_left.inputs.apply_xfm = True index_final_2_t1_left.run_without_submitting = True index_final_2_t1_left.inputs.interp = 'nearestneighbour' index_final_2_t1_left.inputs.out_file = subject_ID + '_index_seedt1_left.nii' dmripipeline.connect([(index_warped_2_t1_left, index_final_2_t1_left, [("output_image", "in_file")])]) dmripipeline.connect([(inputnode, index_final_2_t1_left, [("inv_flirt_mat", "in_matrix_file")])]) dmripipeline.connect([(inputnode, index_final_2_t1_left, [("t1", "reference")])]) index_final_2_t1_right = index_final_2_t1_left.clone( name='77_index_final_2_t1_right') index_final_2_t1_right.inputs.out_file = subject_ID + '_index_seedt1_right.nii' dmripipeline.connect([(index_warped_2_t1_right, index_final_2_t1_right, [("output_image", "in_file")])]) dmripipeline.connect([(inputnode, index_final_2_t1_right, [("inv_flirt_mat", "in_matrix_file")])]) dmripipeline.connect([(inputnode, index_final_2_t1_right, [("t1", "reference")])]) """ extra processing """ index_vol2surf_left = pe.Node(interface=fsurf.SampleToSurface(), name='78_index_vol2surf_left') index_vol2surf_left.inputs.hemi = 'lh' index_vol2surf_left.inputs.subject_id = subject_ID index_vol2surf_left.inputs.reg_header = True index_vol2surf_left.inputs.interp_method = 'nearest' index_vol2surf_left.inputs.sampling_method = 'point' index_vol2surf_left.inputs.sampling_range = 0 index_vol2surf_left.inputs.sampling_units = 'frac' index_vol2surf_left.inputs.surface = 'orig' #index_vol2surf_left.inputs.cortex_mask = True index_vol2surf_left.inputs.terminal_output = 'file' index_vol2surf_left.inputs.out_file = subject_ID + '_index_seedt1_2surf_left.mgz' index_vol2surf_left.run_without_submitting = True dmripipeline.connect([(index_final_2_t1_left, index_vol2surf_left, [('out_file', 'source_file')])]) index_vol2surf_right = index_vol2surf_left.clone( name='78_index_vol2surf_right') index_vol2surf_right.inputs.hemi = 'rh' index_vol2surf_right.inputs.out_file = subject_ID + '_index_seedt1_2surf_right.mgz' dmripipeline.connect([(index_final_2_t1_right, index_vol2surf_right, [('out_file', 'source_file')])]) index_2_t1_reorient_left = pe.Node(interface=fsl.Reorient2Std(), name='79_next_2_t1_reorient_left') index_2_t1_reorient_left.inputs.out_file = subject_ID + '_index_seedt1_reorient_left.nii' index_2_t1_reorient_left.run_without_submitting = True dmripipeline.connect(index_final_2_t1_left, 'out_file', index_2_t1_reorient_left, 'in_file') index_2_t1_reorient_right = index_2_t1_reorient_left.clone( name='79_next_2_t1_reorient_right') index_2_t1_reorient_right.inputs.out_file = subject_ID + '_index_seedt1_reorient_right.nii' dmripipeline.connect(index_final_2_t1_right, 'out_file', index_2_t1_reorient_right, 'in_file') index_interface2surf_left = pe.Node(interface=Function( input_names=[ "interface_image", "surface_file", "cortex_label", "ref_mgz", "out_file" ], output_names=["out_file"], function=interface2surf), name='80_index_interface2surf_left') index_interface2surf_left.inputs.surface_file = subjects_dir + '/' + subject_ID + '/surf/lh.orig' index_interface2surf_left.inputs.cortex_label = subjects_dir + '/' + subject_ID + '/label/lh.cortex.label' index_interface2surf_left.inputs.out_file = subject_ID + '_index_seedt1_2surf_left.mgz' dmripipeline.connect(index_2_t1_reorient_left, 'out_file', index_interface2surf_left, 'interface_image') dmripipeline.connect(index_vol2surf_left, 'out_file', index_interface2surf_left, 'ref_mgz') index_interface2surf_right = index_interface2surf_left.clone( name='80_index_interface2surf_right') index_interface2surf_right.inputs.surface_file = subjects_dir + '/' + subject_ID + '/surf/rh.orig' index_interface2surf_right.inputs.cortex_label = subjects_dir + '/' + subject_ID + '/label/rh.cortex.label' index_interface2surf_right.inputs.out_file = subject_ID + '_index_seedt1_2surf_right.mgz' dmripipeline.connect(index_2_t1_reorient_right, 'out_file', index_interface2surf_right, 'interface_image') dmripipeline.connect(index_vol2surf_right, 'out_file', index_interface2surf_right, 'ref_mgz') fs_indexlist_left = pe.Node(interface=Function( input_names=["in_surface_values", "cortex_label", "out_file"], output_names=["out_file"], function=surf2file), name='81_index_fsnative_left') fs_indexlist_left.inputs.cortex_label = op.join( freesurfer_dir, subject_ID + '/label/lh.cortex.label') fs_indexlist_left.inputs.out_file = subject_ID + '_seed_index_fsnative_left.txt' fs_indexlist_left.run_without_submitting = True dmripipeline.connect([(index_interface2surf_left, fs_indexlist_left, [("out_file", "in_surface_values")])]) fs_indexlist_right = fs_indexlist_left.clone( name='81_index_fsnative_right') fs_indexlist_right.inputs.cortex_label = op.join( freesurfer_dir, subject_ID + '/label/rh.cortex.label') fs_indexlist_right.inputs.out_file = subject_ID + '_seed_index_fsnative_right.txt' dmripipeline.connect([(index_interface2surf_right, fs_indexlist_right, [("out_file", "in_surface_values")])]) """""" """""" """""" """""" """ """ """""" """""" """""" """""" index_fsaverage5_left = pe.Node(interface=fsurf.SurfaceTransform(), name='81_index_fsaverage5_left') index_fsaverage5_left.inputs.hemi = 'lh' index_fsaverage5_left.inputs.source_subject = subject_ID index_fsaverage5_left.inputs.target_subject = 'fsaverage5' index_fsaverage5_left.inputs.args = '--mapmethod nnf --label-src lh.cortex.label --label-trg lh.cortex.label' index_fsaverage5_left.inputs.out_file = subject_ID + '_index_seedt1_fsaverage5_left.mgz' #index_fsaverage5_left.run_without_submitting = True dmripipeline.connect([(index_interface2surf_left, index_fsaverage5_left, [('out_file', 'source_file')])]) index_fsaverage5_right = index_fsaverage5_left.clone( name='81_index_fsaverage5_right') index_fsaverage5_right.inputs.hemi = 'rh' index_fsaverage5_left.inputs.args = '--mapmethod nnf --label-src rh.cortex.label --label-trg rh.cortex.label' index_fsaverage5_right.inputs.out_file = subject_ID + '_index_seedt1_fsaverage5_right.mgz' dmripipeline.connect([(index_interface2surf_right, index_fsaverage5_right, [('out_file', 'source_file')])]) fs5_indexlist_left = pe.Node(interface=Function( input_names=["in_surface_values", "cortex_label", "out_file"], output_names=["out_file"], function=surf2file), name='82_index_fsav5_left') fs5_indexlist_left.inputs.cortex_label = op.join( freesurfer_dir, 'fsaverage5/label/lh.cortex.label') fs5_indexlist_left.inputs.out_file = subject_ID + '_seed_index_fs5_left.txt' #fs5_indexlist_left.run_without_submitting = True dmripipeline.connect([(index_fsaverage5_left, fs5_indexlist_left, [("out_file", "in_surface_values")])]) fs5_indexlist_right = fs5_indexlist_left.clone(name='82_index_fsav5_right') fs5_indexlist_right.inputs.cortex_label = op.join( freesurfer_dir, 'fsaverage5/label/rh.cortex.label') fs5_indexlist_right.inputs.out_file = subject_ID + '_seed_index_fs5_right.txt' dmripipeline.connect([(index_fsaverage5_right, fs5_indexlist_right, [("out_file", "in_surface_values")])]) index_fsaverage4_left = pe.Node(interface=fsurf.SurfaceTransform(), name='81_index_fsaverage4_left') index_fsaverage4_left.inputs.hemi = 'lh' index_fsaverage4_left.inputs.source_subject = subject_ID index_fsaverage4_left.inputs.target_subject = 'fsaverage4' index_fsaverage4_left.inputs.args = '--mapmethod nnf --label-src lh.cortex.label --label-trg lh.cortex.label' index_fsaverage4_left.inputs.out_file = subject_ID + '_index_seedt1_fsaverage4_left.mgz' #index_fsaverage4_left.run_without_submitting = True dmripipeline.connect([(index_interface2surf_left, index_fsaverage4_left, [('out_file', 'source_file')])]) index_fsaverage4_right = index_fsaverage4_left.clone( name='81_index_fsaverage4_right') index_fsaverage4_right.inputs.hemi = 'rh' index_fsaverage4_left.inputs.args = '--mapmethod nnf --label-src rh.cortex.label --label-trg rh.cortex.label' index_fsaverage4_right.inputs.out_file = subject_ID + '_index_seedt1_fsaverage4_right.mgz' dmripipeline.connect([(index_interface2surf_right, index_fsaverage4_right, [('out_file', 'source_file')])]) fs4_indexlist_left = pe.Node(interface=Function( input_names=["in_surface_values", "cortex_label", "out_file"], output_names=["out_file"], function=surf2file), name='82_index_fsav4_left') fs4_indexlist_left.inputs.cortex_label = op.join( freesurfer_dir, 'fsaverage4/label/lh.cortex.label') fs4_indexlist_left.inputs.out_file = subject_ID + '_seed_index_fs4_left.txt' #fs4_indexlist_left.run_without_submitting = True dmripipeline.connect([(index_fsaverage4_left, fs4_indexlist_left, [("out_file", "in_surface_values")])]) fs4_indexlist_right = fs4_indexlist_left.clone(name='82_index_fsav4_right') fs4_indexlist_right.inputs.cortex_label = op.join( freesurfer_dir, 'fsaverage4/label/rh.cortex.label') fs4_indexlist_right.inputs.out_file = subject_ID + '_seed_index_fs4_right.txt' dmripipeline.connect([(index_fsaverage4_right, fs4_indexlist_right, [("out_file", "in_surface_values")])]) """ downsample matrices according to fsaverage projections """ if (not use_sample): connect_mat_fs4_nat_left_left = pe.Node( interface=Function(input_names=[ "index_row_file", "index_col_file", "matrix_file", "out_prefix", "dist2sim" ], output_names=["out_mat", "out_nii"], function=downsample_matrix), name='83_connect_mat_fs4_nat_left_left') connect_mat_fs4_nat_left_left.inputs.out_prefix = subject_ID + '_connect_fs4_nat_left_left' connect_mat_fs4_nat_left_left.inputs.dist2sim = False dmripipeline.connect(fs4_indexlist_left, "out_file", connect_mat_fs4_nat_left_left, "index_row_file") dmripipeline.connect(fs4_indexlist_left, "out_file", connect_mat_fs4_nat_left_left, "index_col_file") dmripipeline.connect(submatrix_left_left, "mat_matrix_nat", connect_mat_fs4_nat_left_left, "matrix_file") connect_mat_fs4_nat_left_right = connect_mat_fs4_nat_left_left.clone( name='83_connect_mat_fs4_nat_left_right') connect_mat_fs4_nat_left_right.inputs.out_prefix = subject_ID + '_connect_fs4_nat_left_right' dmripipeline.connect(fs4_indexlist_left, "out_file", connect_mat_fs4_nat_left_right, "index_row_file") dmripipeline.connect(fs4_indexlist_right, "out_file", connect_mat_fs4_nat_left_right, "index_col_file") dmripipeline.connect(submatrix_left_right, "mat_matrix_nat", connect_mat_fs4_nat_left_right, "matrix_file") connect_mat_fs4_nat_right_left = connect_mat_fs4_nat_left_left.clone( name='83_connect_mat_fs4_nat_right_left') connect_mat_fs4_nat_right_left.inputs.out_prefix = subject_ID + '_connect_fs4_nat_right_left' dmripipeline.connect(fs4_indexlist_right, "out_file", connect_mat_fs4_nat_right_left, "index_row_file") dmripipeline.connect(fs4_indexlist_left, "out_file", connect_mat_fs4_nat_right_left, "index_col_file") dmripipeline.connect(submatrix_right_left, "mat_matrix_nat", connect_mat_fs4_nat_right_left, "matrix_file") connect_mat_fs4_nat_right_right = connect_mat_fs4_nat_left_left.clone( name='83_connect_mat_fs4_nat_right_right') connect_mat_fs4_nat_right_right.inputs.out_prefix = subject_ID + '_connect_fs4_nat_right_right' dmripipeline.connect(fs4_indexlist_right, "out_file", connect_mat_fs4_nat_right_right, "index_row_file") dmripipeline.connect(fs4_indexlist_right, "out_file", connect_mat_fs4_nat_right_right, "index_col_file") dmripipeline.connect(submatrix_right_right, "mat_matrix_nat", connect_mat_fs4_nat_right_right, "matrix_file") connect_mat_fs4_log_left_left = connect_mat_fs4_nat_left_left.clone( name='83_connect_mat_fs4_log_left_left') connect_mat_fs4_log_left_left.inputs.out_prefix = subject_ID + '_connect_fs4_log_left_left' dmripipeline.connect(fs4_indexlist_left, "out_file", connect_mat_fs4_log_left_left, "index_row_file") dmripipeline.connect(fs4_indexlist_left, "out_file", connect_mat_fs4_log_left_left, "index_col_file") dmripipeline.connect(submatrix_left_left, "mat_matrix_log", connect_mat_fs4_log_left_left, "matrix_file") connect_mat_fs4_log_left_right = connect_mat_fs4_log_left_left.clone( name='83_connect_mat_fs4_log_left_right') connect_mat_fs4_log_left_right.inputs.out_prefix = subject_ID + '_connect_fs4_log_left_right' dmripipeline.connect(fs4_indexlist_left, "out_file", connect_mat_fs4_log_left_right, "index_row_file") dmripipeline.connect(fs4_indexlist_right, "out_file", connect_mat_fs4_log_left_right, "index_col_file") dmripipeline.connect(submatrix_left_right, "mat_matrix_log", connect_mat_fs4_log_left_right, "matrix_file") connect_mat_fs4_log_right_left = connect_mat_fs4_log_left_left.clone( name='83_connect_mat_fs4_log_right_left') connect_mat_fs4_log_right_left.inputs.out_prefix = subject_ID + '_connect_fs4_log_right_left' dmripipeline.connect(fs4_indexlist_right, "out_file", connect_mat_fs4_log_right_left, "index_row_file") dmripipeline.connect(fs4_indexlist_left, "out_file", connect_mat_fs4_log_right_left, "index_col_file") dmripipeline.connect(submatrix_right_left, "mat_matrix_log", connect_mat_fs4_log_right_left, "matrix_file") connect_mat_fs4_log_right_right = connect_mat_fs4_log_left_left.clone( name='83_connect_mat_fs4_log_right_right') connect_mat_fs4_log_right_right.inputs.out_prefix = subject_ID + '_connect_fs4_log_right_right' dmripipeline.connect(fs4_indexlist_right, "out_file", connect_mat_fs4_log_right_right, "index_row_file") dmripipeline.connect(fs4_indexlist_right, "out_file", connect_mat_fs4_log_right_right, "index_col_file") dmripipeline.connect(submatrix_right_right, "mat_matrix_log", connect_mat_fs4_log_right_right, "matrix_file") # connect_mat_fs4_nat_full = pe.Node(interface=Function(input_names=["sm_left_left", "sm_left_right","sm_right_left", "sm_right_right", "out_filename"], output_names=["out_file"], function=merge_matrices), name='83_connect_mat_fs4_nat_full') # connect_mat_fs4_nat_full.inputs.out_filename = subject_ID + '_connect_fs4_nat_full.mat' # connect_mat_fs4_nat_full.run_without_submitting = True # dmripipeline.connect(connect_mat_fs4_nat_left_left, "out_nii", connect_mat_fs4_nat_full, "sm_left_left") # dmripipeline.connect(connect_mat_fs4_nat_left_right, "out_nii", connect_mat_fs4_nat_full, "sm_left_right") # dmripipeline.connect(connect_mat_fs4_nat_right_left, "out_nii", connect_mat_fs4_nat_full, "sm_right_left") # dmripipeline.connect(connect_mat_fs4_nat_right_right, "out_nii", connect_mat_fs4_nat_full, "sm_right_right") # # connect_mat_fs4_log_full = connect_mat_fs4_nat_full.clone(name='83_connect_mat_fs4_log_full') # connect_mat_fs4_log_full.inputs.outfile_prefix = subject_ID + '_connect_fs4_log_full.mat' # connect_mat_fs4_log_full.run_without_submitting = True # dmripipeline.connect(connect_mat_fs4_log_left_left, "out_nii", connect_mat_fs4_log_full, "sm_left_left") # dmripipeline.connect(connect_mat_fs4_log_left_right, "out_nii", connect_mat_fs4_log_full, "sm_left_right") # dmripipeline.connect(connect_mat_fs4_log_right_left, "out_nii", connect_mat_fs4_log_full, "sm_right_left") # dmripipeline.connect(connect_mat_fs4_log_right_right, "out_nii", connect_mat_fs4_log_full, "sm_right_right") connect_mat_fs5_nat_left_left = connect_mat_fs4_nat_left_left.clone( name='83_connect_mat_fs5_nat_left_left') connect_mat_fs5_nat_left_left.inputs.out_prefix = subject_ID + '_connect_fs5_nat_left_left' dmripipeline.connect(fs5_indexlist_left, "out_file", connect_mat_fs5_nat_left_left, "index_row_file") dmripipeline.connect(fs5_indexlist_left, "out_file", connect_mat_fs5_nat_left_left, "index_col_file") dmripipeline.connect(submatrix_left_left, "mat_matrix_nat", connect_mat_fs5_nat_left_left, "matrix_file") connect_mat_fs5_nat_left_right = connect_mat_fs5_nat_left_left.clone( name='83_connect_mat_fs5_nat_left_right') connect_mat_fs5_nat_left_right.inputs.out_prefix = subject_ID + '_connect_fs5_nat_left_right' dmripipeline.connect(fs5_indexlist_left, "out_file", connect_mat_fs5_nat_left_right, "index_row_file") dmripipeline.connect(fs5_indexlist_right, "out_file", connect_mat_fs5_nat_left_right, "index_col_file") dmripipeline.connect(submatrix_left_right, "mat_matrix_nat", connect_mat_fs5_nat_left_right, "matrix_file") connect_mat_fs5_nat_right_left = connect_mat_fs5_nat_left_left.clone( name='83_connect_mat_fs5_nat_right_left') connect_mat_fs5_nat_right_left.inputs.out_prefix = subject_ID + '_connect_fs5_nat_right_left' dmripipeline.connect(fs5_indexlist_right, "out_file", connect_mat_fs5_nat_right_left, "index_row_file") dmripipeline.connect(fs5_indexlist_left, "out_file", connect_mat_fs5_nat_right_left, "index_col_file") dmripipeline.connect(submatrix_right_left, "mat_matrix_nat", connect_mat_fs5_nat_right_left, "matrix_file") connect_mat_fs5_nat_right_right = connect_mat_fs5_nat_left_left.clone( name='83_connect_mat_fs5_nat_right_right') connect_mat_fs5_nat_right_right.inputs.out_prefix = subject_ID + '_connect_fs5_nat_right_right' dmripipeline.connect(fs5_indexlist_right, "out_file", connect_mat_fs5_nat_right_right, "index_row_file") dmripipeline.connect(fs5_indexlist_right, "out_file", connect_mat_fs5_nat_right_right, "index_col_file") dmripipeline.connect(submatrix_right_right, "mat_matrix_nat", connect_mat_fs5_nat_right_right, "matrix_file") connect_mat_fs5_log_left_left = connect_mat_fs5_nat_left_left.clone( name='83_connect_mat_fs5_log_left_left') connect_mat_fs5_log_left_left.inputs.out_prefix = subject_ID + '_connect_fs5_log_left_left' dmripipeline.connect(fs5_indexlist_left, "out_file", connect_mat_fs5_log_left_left, "index_row_file") dmripipeline.connect(fs5_indexlist_left, "out_file", connect_mat_fs5_log_left_left, "index_col_file") dmripipeline.connect(submatrix_left_left, "mat_matrix_log", connect_mat_fs5_log_left_left, "matrix_file") connect_mat_fs5_log_left_right = connect_mat_fs5_log_left_left.clone( name='83_connect_mat_fs5_log_left_right') connect_mat_fs5_log_left_right.inputs.out_prefix = subject_ID + '_connect_fs5_log_left_right' dmripipeline.connect(fs5_indexlist_left, "out_file", connect_mat_fs5_log_left_right, "index_row_file") dmripipeline.connect(fs5_indexlist_right, "out_file", connect_mat_fs5_log_left_right, "index_col_file") dmripipeline.connect(submatrix_left_right, "mat_matrix_log", connect_mat_fs5_log_left_right, "matrix_file") connect_mat_fs5_log_right_left = connect_mat_fs5_log_left_left.clone( name='83_connect_mat_fs5_log_right_left') connect_mat_fs5_log_right_left.inputs.out_prefix = subject_ID + '_connect_fs5_log_right_left' dmripipeline.connect(fs5_indexlist_right, "out_file", connect_mat_fs5_log_right_left, "index_row_file") dmripipeline.connect(fs5_indexlist_left, "out_file", connect_mat_fs5_log_right_left, "index_col_file") dmripipeline.connect(submatrix_right_left, "mat_matrix_log", connect_mat_fs5_log_right_left, "matrix_file") connect_mat_fs5_log_right_right = connect_mat_fs5_log_left_left.clone( name='83_connect_mat_fs5_log_right_right') connect_mat_fs5_log_right_right.inputs.out_prefix = subject_ID + '_connect_fs5_log_right_right' dmripipeline.connect(fs5_indexlist_right, "out_file", connect_mat_fs5_log_right_right, "index_row_file") dmripipeline.connect(fs5_indexlist_right, "out_file", connect_mat_fs5_log_right_right, "index_col_file") dmripipeline.connect(submatrix_right_right, "mat_matrix_log", connect_mat_fs5_log_right_right, "matrix_file") # connect_mat_fs5_nat_full = connect_mat_fs4_nat_full.clone(name='83_connect_mat_fs5_nat_full') # connect_mat_fs5_nat_full.inputs.outfile_prefix = subject_ID + '_connect_fs5_nat_full.mat' # connect_mat_fs5_nat_full.run_without_submitting = True # dmripipeline.connect(connect_mat_fs5_nat_left_left, "out_nii", connect_mat_fs5_nat_full, "sm_left_left") # dmripipeline.connect(connect_mat_fs5_nat_left_right, "out_nii", connect_mat_fs5_nat_full, "sm_left_right") # dmripipeline.connect(connect_mat_fs5_nat_right_left, "out_nii", connect_mat_fs5_nat_full, "sm_right_left") # dmripipeline.connect(connect_mat_fs5_nat_right_right, "out_nii", connect_mat_fs5_nat_full, "sm_right_right") # # connect_mat_fs5_log_full = connect_mat_fs5_nat_full.clone(name='83_connect_mat_fs5_log_full') # connect_mat_fs5_log_full.inputs.out_filename = subject_ID + '_connect_fs5_log_full.mat' # connect_mat_fs5_log_full.run_without_submitting = True # dmripipeline.connect(connect_mat_fs5_log_left_left, "out_nii", connect_mat_fs5_log_full, "sm_left_left") # dmripipeline.connect(connect_mat_fs5_log_left_right, "out_nii", connect_mat_fs5_log_full, "sm_left_right") # dmripipeline.connect(connect_mat_fs5_log_right_left, "out_nii", connect_mat_fs5_log_full, "sm_right_left") # dmripipeline.connect(connect_mat_fs5_log_right_right, "out_nii", connect_mat_fs5_log_full, "sm_right_right") # """ use a sink to save outputs """ datasink = pe.Node(io.DataSink(), name='99_datasink') datasink.inputs.base_directory = output_dir datasink.inputs.container = subject_ID datasink.inputs.parameterization = True #datasink.run_without_submitting = True dmripipeline.connect(index_pruned_left, 'out_file', datasink, 'interface_index.@3') dmripipeline.connect(index_pruned_right, 'out_file', datasink, 'interface_index.@4') dmripipeline.connect(index_final_2_t1_left, 'out_file', datasink, 'interface_index.@5') dmripipeline.connect(index_final_2_t1_right, 'out_file', datasink, 'interface_index.@6') dmripipeline.connect(index_interface2surf_left, 'out_file', datasink, 'interface_index.@7') dmripipeline.connect(index_interface2surf_right, 'out_file', datasink, 'interface_index.@8') dmripipeline.connect(index_fsaverage5_left, 'out_file', datasink, 'interface_index.@9') dmripipeline.connect(index_fsaverage5_right, 'out_file', datasink, 'interface_index.@10') dmripipeline.connect(fs5_indexlist_left, 'out_file', datasink, 'interface_index.@11') dmripipeline.connect(fs5_indexlist_right, 'out_file', datasink, 'interface_index.@12') dmripipeline.connect(index_fsaverage4_left, 'out_file', datasink, 'interface_index.@13') dmripipeline.connect(index_fsaverage4_right, 'out_file', datasink, 'interface_index.@14') dmripipeline.connect(fs4_indexlist_left, 'out_file', datasink, 'interface_index.@15') dmripipeline.connect(fs4_indexlist_right, 'out_file', datasink, 'interface_index.@16') dmripipeline.connect(fs_indexlist_left, 'out_file', datasink, 'interface_index.@17') dmripipeline.connect(fs_indexlist_right, 'out_file', datasink, 'interface_index.@18') dmripipeline.connect(tract_exclusion_mask, 'outfile', datasink, 'interface_index.@19') # dmripipeline.connect(submatrix_left_left, 'mat_matrix_nat', datasink, 'connect_matrix.native.mat') # dmripipeline.connect(submatrix_left_left, 'mat_matrix_log', datasink, 'connect_matrix.native.mat.@2') dmripipeline.connect(submatrix_left_left, 'nii_matrix_nat', datasink, 'connect_matrix.native.@3') dmripipeline.connect(submatrix_left_left, 'nii_matrix_log', datasink, 'connect_matrix.native.@4') # dmripipeline.connect(submatrix_right_right, 'mat_matrix_nat', datasink, 'connect_matrix.native.mat.@5') # dmripipeline.connect(submatrix_right_right, 'mat_matrix_log', datasink, 'connect_matrix.native.mat.@6') dmripipeline.connect(submatrix_right_right, 'nii_matrix_nat', datasink, 'connect_matrix.native.@7') dmripipeline.connect(submatrix_right_right, 'nii_matrix_log', datasink, 'connect_matrix.native.@8') # dmripipeline.connect(submatrix_left_right, 'mat_matrix_nat', datasink, 'connect_matrix.native.mat') # dmripipeline.connect(submatrix_left_right, 'mat_matrix_log', datasink, 'connect_matrix.native.mat.@2') dmripipeline.connect(submatrix_left_right, 'nii_matrix_nat', datasink, 'connect_matrix.native.@9') dmripipeline.connect(submatrix_left_right, 'nii_matrix_log', datasink, 'connect_matrix.native.@10') # dmripipeline.connect(submatrix_right_left, 'mat_matrix_nat', datasink, 'connect_matrix.native.mat') # dmripipeline.connect(submatrix_right_left, 'mat_matrix_log', datasink, 'connect_matrix.native.mat.@2') dmripipeline.connect(submatrix_right_left, 'nii_matrix_nat', datasink, 'connect_matrix.native.@11') dmripipeline.connect(submatrix_right_left, 'nii_matrix_log', datasink, 'connect_matrix.native.@12') # dmripipeline.connect(full_matrix_nat, 'out_file', datasink, 'connect_matrix.native.@9') # dmripipeline.connect(full_matrix_log, 'out_file', datasink, 'connect_matrix.native.@11') if (not use_sample): # dmripipeline.connect(connect_mat_fs4_nat_left_left, 'out_mat', datasink, 'connect_matrix.fs4.mat.@1') # dmripipeline.connect(connect_mat_fs4_log_left_left, 'out_mat', datasink, 'connect_matrix.fs4.mat.@2') # dmripipeline.connect(connect_mat_fs4_nat_right_right, 'out_mat', datasink, 'connect_matrix.fs4.mat.@3') # dmripipeline.connect(connect_mat_fs4_log_right_right, 'out_mat', datasink, 'connect_matrix.fs4.mat.@4') # dmripipeline.connect(connect_mat_fs4_nat_left_right, 'out_mat', datasink, 'connect_matrix.fs4.mat.@5') # dmripipeline.connect(connect_mat_fs4_log_left_right, 'out_mat', datasink, 'connect_matrix.fs4.mat.@6') # dmripipeline.connect(connect_mat_fs4_nat_right_left, 'out_mat', datasink, 'connect_matrix.fs4.mat.@7') # dmripipeline.connect(connect_mat_fs4_log_right_left, 'out_mat', datasink, 'connect_matrix.fs4.mat.@8') dmripipeline.connect(connect_mat_fs4_nat_left_left, 'out_nii', datasink, 'connect_matrix.fs4.@1') dmripipeline.connect(connect_mat_fs4_log_left_left, 'out_nii', datasink, 'connect_matrix.fs4.@2') dmripipeline.connect(connect_mat_fs4_nat_right_right, 'out_nii', datasink, 'connect_matrix.fs4.@3') dmripipeline.connect(connect_mat_fs4_log_right_right, 'out_nii', datasink, 'connect_matrix.fs4.@4') dmripipeline.connect(connect_mat_fs4_nat_left_right, 'out_nii', datasink, 'connect_matrix.fs4.@5') dmripipeline.connect(connect_mat_fs4_log_left_right, 'out_nii', datasink, 'connect_matrix.fs4.@6') dmripipeline.connect(connect_mat_fs4_nat_right_left, 'out_nii', datasink, 'connect_matrix.fs4.@7') dmripipeline.connect(connect_mat_fs4_log_right_left, 'out_nii', datasink, 'connect_matrix.fs4.@8') # dmripipeline.connect(connect_mat_fs4_nat_full, 'out_file', datasink, 'connect_matrix.@28') # dmripipeline.connect(connect_mat_fs4_log_full, 'out_file', datasink, 'connect_matrix.@30') # dmripipeline.connect(connect_mat_fs5_nat_left_left, 'out_mat', datasink, 'connect_matrix.fs5.mat.@1') # dmripipeline.connect(connect_mat_fs5_log_left_left, 'out_mat', datasink, 'connect_matrix.fs5.mat.@2') # dmripipeline.connect(connect_mat_fs5_nat_right_right, 'out_mat', datasink, 'connect_matrix.fs5.mat.@3') # dmripipeline.connect(connect_mat_fs5_log_right_right, 'out_mat', datasink, 'connect_matrix.fs5.mat.@4') # dmripipeline.connect(connect_mat_fs5_nat_left_right, 'out_mat', datasink, 'connect_matrix.fs5.mat.@5') # dmripipeline.connect(connect_mat_fs5_log_left_right, 'out_mat', datasink, 'connect_matrix.fs5.mat.@6') # dmripipeline.connect(connect_mat_fs5_nat_right_left, 'out_mat', datasink, 'connect_matrix.fs5.mat.@7') # dmripipeline.connect(connect_mat_fs5_log_right_left, 'out_mat', datasink, 'connect_matrix.fs5.mat.@8') dmripipeline.connect(connect_mat_fs5_nat_left_left, 'out_nii', datasink, 'connect_matrix.fs5.@1') dmripipeline.connect(connect_mat_fs5_log_left_left, 'out_nii', datasink, 'connect_matrix.fs5.@2') dmripipeline.connect(connect_mat_fs5_nat_right_right, 'out_nii', datasink, 'connect_matrix.fs5.@3') dmripipeline.connect(connect_mat_fs5_log_right_right, 'out_nii', datasink, 'connect_matrix.fs5.@4') dmripipeline.connect(connect_mat_fs5_nat_left_right, 'out_nii', datasink, 'connect_matrix.fs5.@5') dmripipeline.connect(connect_mat_fs5_log_left_right, 'out_nii', datasink, 'connect_matrix.fs5.@6') dmripipeline.connect(connect_mat_fs5_nat_right_left, 'out_nii', datasink, 'connect_matrix.fs5.@7') dmripipeline.connect(connect_mat_fs5_log_right_left, 'out_nii', datasink, 'connect_matrix.fs5.@8') # dmripipeline.connect(connect_mat_fs5_nat_full, 'out_file', datasink, 'connect_matrix.@40') # dmripipeline.connect(connect_mat_fs5_log_full, 'out_file', datasink, 'connect_matrix.@42') """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """ =============================================================================== Connecting the workflow =============================================================================== """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """ Create a higher-level workflow ------------------------------ Finally, we create another higher-level workflow to connect our dmripipeline workflow with the info and datagrabbing nodes declared at the beginning. Our tutorial is now extensible to any arbitrary number of subjects by simply adding their names to the subject list and their data to the proper folders. """ connectprepro = pe.Workflow(name="dmri_pipe3_projection") connectprepro.base_dir = op.abspath(workflow_dir + "/workflow_" + subject_ID) connectprepro.connect([(datasource, dmripipeline, [('wm', 'inputnode.wm'), ('seeds_left', 'inputnode.seeds_left'), ('seeds_right', 'inputnode.seeds_right'), ('t1', 'inputnode.t1'), ('warp', 'inputnode.warp'), ('inv_flirt_mat', 'inputnode.inv_flirt_mat'), ('fa', 'inputnode.fa'), ('index_left', 'inputnode.index_left'), ('index_right', 'inputnode.index_right')]), (tracts_left_source, dmripipeline, [('tracts_left', 'inputnode.tracts_left')]), (tracts_right_source, dmripipeline, [('tracts_right', 'inputnode.tracts_right')])]) return connectprepro
def create_apply_ants_xfm(dimension, mapnode, name='apply_ants_xfm'): """ Takes in the results of the FSL-based functional-to-anatomical registration, and the results of the ANTS-based anatomical-to-template registration, and applies these transformations to register functional to template. The FSL-based functional-to-anatomical registration output transformations are first converted from FSL format to ITK format - this step can and should be separated into their own workflows in the future. NOTE: The dimension of the input image (3 or 4) must be specified in the function call, as well as whether or not the apply warp must be treated as a mapnode (0 - no, 1 - yes). Parameters ---------- name : string, optional Name of the workflow. Returns ------- apply_ants_xfm : nipype.pipeline.engine.Workflow Notes ----- Workflow Inputs:: inputspec.in_file : string (nifti file) File of functional brain data to be registered inputspec.warp_reference : string (nifti file) File of template to be used inputspec.use_nearest : boolean (True or False) Whether or not to use nearest neighbor interpolation inputspec.func_anat_affine : .mat file (affine matrix) Output matrix of FSL-based functional to anatomical registration inputspec.conversion_reference : string (nifti file) File of skull-stripped anatomical brain to be used in affine conversion inputspec.conversion_source : string (nifti file) Should match the input of the apply warp (in_file) unless you are applying the warp to a 4-d file, in which case this file should be a mean_functional file inputspec.nonlinear_field : string (nifti file) Output field file of the anatomical to template ANTS registration inputspec.ants_affine : text file Output matrix of the anatomical to template ANTS registration Workflow Outputs:: outputspec.out_file : string (nifti file) Normalizion of input functional file Registration Procedure: 1. Convert the FSL-based functional-to-anatomical output affine matrix into ANTS (ITK) format. 2. Collect this converted affine, and the ants_affine.txt and nonlinear field file from the anatomical-to-template ANTS registration into one transformation series string. 3. Apply the warp to the input file using WarpImageMultiTransform (for 3d files) or WarpTimeSeriesImageMultiTransform (for 4d files with timeseries). Workflow Graph: .. image:: :width: 500 Detailed Workflow Graph: .. image:: :width: 500 """ apply_ants_xfm = pe.Workflow(name=name) inputspec = pe.Node(util.IdentityInterface(fields=[ 'warp_reference', 'in_file', 'use_nearest', 'func_anat_affine', 'conversion_reference', 'conversion_source', 'nonlinear_field', 'ants_affine' ]), name='inputspec') outputspec = pe.Node(util.IdentityInterface(fields=['out_file']), name='outputspec') if dimension == 4: if mapnode == 0: # converts FSL-format .mat affine xfm into ANTS-format .txt # .mat affine comes from Func->Anat registration fsl_reg_2_itk = create_fsl_to_itk_conversion( mapnode, 'fsl_reg_2_itk') #collects series of transformations to be applied to the moving images collect_transforms = pe.Node(util.Merge(3), name='collect_transforms') # performs series of transformations on moving images warp_images = pe.Node( interface=ants.WarpTimeSeriesImageMultiTransform(), name='ants_apply_4d_warp') warp_images.inputs.dimension = 4 apply_ants_xfm.connect(inputspec, 'warp_reference', warp_images, 'reference_image') apply_ants_xfm.connect(inputspec, 'use_nearest', warp_images, 'use_nearest') elif mapnode == 1: # in this case with 4-d images (timeseries), fsl_reg_2_itk and collect_transforms are not # map nodes due to the fact that the affine conversion (fsl_reg_2_itk) cannot take in a # 4-d image as its conversion_source (ordinarily the input image and the conversion source # are the same image, however with timeseries, mean_functional should be used as the # conversion source and the 4-d image used as the input image to the apply warp. # (this is why in_file and conversion_source are separated into two inputs) # converts FSL-format .mat affine xfm into ANTS-format .txt # .mat affine comes from Func->Anat registration fsl_reg_2_itk = create_fsl_to_itk_conversion( mapnode, 'fsl_reg_2_itk') #collects series of transformations to be applied to the moving images collect_transforms = pe.Node(util.Merge(3), name='collect_transforms') # performs series of transformations on moving images warp_images = pe.MapNode( interface=ants.WarpTimeSeriesImageMultiTransform(), name='ants_apply_4d_warp', iterfield=['in_file']) warp_images.inputs.dimension = 4 apply_ants_xfm.connect(inputspec, 'warp_reference', warp_images, 'reference_image') apply_ants_xfm.connect(inputspec, 'use_nearest', warp_images, 'use_nearest') elif dimension == 3: if mapnode == 0: # converts FSL-format .mat affine xfm into ANTS-format .txt # .mat affine comes from Func->Anat registration fsl_reg_2_itk = create_fsl_to_itk_conversion( mapnode, 'fsl_reg_2_itk') #collects series of transformations to be applied to the moving images collect_transforms = pe.Node(util.Merge(3), name='collect_transforms') # performs series of transformations on moving images warp_images = pe.Node(interface=ants.WarpImageMultiTransform(), name='apply_ants_3d_warp') warp_images.inputs.dimension = 3 apply_ants_xfm.connect(inputspec, 'warp_reference', warp_images, 'reference_image') apply_ants_xfm.connect(inputspec, 'use_nearest', warp_images, 'use_nearest') elif mapnode == 1: # converts FSL-format .mat affine xfm into ANTS-format .txt # .mat affine comes from Func->Anat registration fsl_reg_2_itk = create_fsl_to_itk_conversion( mapnode, 'fsl_reg_2_itk') #collects series of transformations to be applied to the moving images collect_transforms = pe.MapNode(util.Merge(3), name='collect_transforms', iterfield=['in3']) # performs series of transformations on moving images warp_images = pe.MapNode( interface=ants.WarpImageMultiTransform(), name='apply_ants_3d_warp', iterfield=['input_image', 'transformation_series']) warp_images.inputs.dimension = 3 apply_ants_xfm.connect(inputspec, 'warp_reference', warp_images, 'reference_image') apply_ants_xfm.connect(inputspec, 'use_nearest', warp_images, 'use_nearest') # convert the .mat from linear Func->Anat to ANTS format apply_ants_xfm.connect(inputspec, 'func_anat_affine', fsl_reg_2_itk, 'inputspec.transform_file') apply_ants_xfm.connect(inputspec, 'conversion_reference', fsl_reg_2_itk, 'inputspec.reference_file') apply_ants_xfm.connect(inputspec, 'conversion_source', fsl_reg_2_itk, 'inputspec.source_file') # Premat from Func->Anat linear reg and bbreg (if bbreg is enabled) apply_ants_xfm.connect(fsl_reg_2_itk, 'outputspec.itk_transform', collect_transforms, 'in3') # Field file from anatomical nonlinear registration apply_ants_xfm.connect(inputspec, 'nonlinear_field', collect_transforms, 'in1') # affine transformation from anatomical registration apply_ants_xfm.connect(inputspec, 'ants_affine', collect_transforms, 'in2') apply_ants_xfm.connect(inputspec, 'in_file', warp_images, 'input_image') apply_ants_xfm.connect(collect_transforms, 'out', warp_images, 'transformation_series') apply_ants_xfm.connect(warp_images, 'output_image', outputspec, 'out_file') return apply_ants_xfm
def get_post_struct_norm_WIMT_workflow(name='normalize_post_struct'): """ Base post-structural workflow for normalization Parameters ---------- name : name of workflow. Default = 'normalize_post_struct' Inputs ------ inputspec.template_file : inputspec.unwarped_brain : inputspec.warp_field : inputspec.affine_transformation : inputspec.out_fsl_file : inputspec.moving_image : inputspec.mean_func : inputspec.use_nearest: Outputs ------- outputspec.warped_image : Returns ------- workflow : post-structural normalization workflow """ #inputs to workflow import nipype.interfaces.freesurfer as fs import nipype.interfaces.ants as ants import nipype.pipeline.engine as pe import nipype.interfaces.utility as util inputspec = pe.Node(util.IdentityInterface(fields=[ 'template_file', 'unwarped_brain', 'warp_field', 'affine_transformation', 'out_fsl_file', 'moving_image', 'mean_func', "use_nearest" ]), name='inputspec') #makes fsl-style coregistration ANTS compatible fsl_reg_2_itk = pe.Node(c3.C3dAffineTool(fsl2ras=True), name='fsl_reg_2_itk') #collects series of transformations to be applied to the moving images collect_transforms = pe.Node(util.Merge(3), name='collect_transforms') #performs series of transformations on moving images warp_images = pe.MapNode(ants.WarpImageMultiTransform(), name='warp_images', iterfield=['input_image', 'dimension']) #collects workflow outputs outputspec = pe.Node(util.IdentityInterface(fields=['warped_image']), name='outputspec') #initializes and connects workflow nodes normalize_post_struct = pe.Workflow(name=name) normalize_post_struct.connect([ (inputspec, fsl_reg_2_itk, [('unwarped_brain', 'reference_file')]), (inputspec, fsl_reg_2_itk, [('out_fsl_file', 'transform_file')]), (inputspec, fsl_reg_2_itk, [('mean_func', 'source_file')]), (fsl_reg_2_itk, collect_transforms, [('itk_transform', 'in3')]), (inputspec, collect_transforms, [('warp_field', 'in1'), ('affine_transformation', 'in2')]), (inputspec, warp_images, [('moving_image', 'input_image')]), (inputspec, warp_images, [(('moving_image', get_image_dimensions), 'dimension')]), (inputspec, warp_images, [('template_file', 'reference_image'), ('use_nearest', 'use_nearest')]), (collect_transforms, warp_images, [('out', 'transformation_series')]), (warp_images, outputspec, [('output_image', 'warped_image')]) ]) return normalize_post_struct
sep_tfms = pe.Node(interface=Function(input_names=['in_list'], output_names=['out_list'], function=get_sec_tfm),name='sep_tfms') preproc.connect(ants_mbRef_to_t2_output, 'forward_transforms', sep_tfms, 'in_list') # combine transformations for (func to atlas) cmb_tfm_func_to_ds_atlas = pe.MapNode(interface=util.Merge(4, axis='vstack'), name='cmb_tfm_func_to_ds_atlas', iterfield=['in4']) # from atlas in struct resolution to func resolution preproc.connect(fsl2ras_downsample_atlas_from_struct_to_func, 'itk_transform', cmb_tfm_func_to_ds_atlas, 'in1') # from structural to atlas (with struct resolution) preproc.connect(structs_to_atlas_coreg_output, ('forward_transforms', get_sec), cmb_tfm_func_to_ds_atlas, 'in2') preproc.connect(structs_to_atlas_coreg_output, ('forward_transforms', get_first), cmb_tfm_func_to_ds_atlas, 'in3') # transform from functional to structural #preproc.connect(ants_mbRef_to_t2_output, ('forward_transforms', get_sec), cmb_tfm_func_to_ds_atlas, 'in4') preproc.connect(sep_tfms, 'out_list', cmb_tfm_func_to_ds_atlas, 'in4') # apply transformation from mbRef all the way to caltech atlas (in func resolution) mbRef_to_ds_atlas = pe.MapNode(interface=ants.WarpImageMultiTransform(use_nearest = True), name = 'mbRef_to_ds_atlas', iterfield=['input_image', 'transformation_series']) preproc.connect(mask_mbRef, 'out_file', mbRef_to_ds_atlas, 'input_image') preproc.connect(downsample_atlas_t2_to_func, 'out_file', mbRef_to_ds_atlas, 'reference_image') preproc.connect(cmb_tfm_func_to_ds_atlas, 'out', mbRef_to_ds_atlas, 'transformation_series') # apply transformation to 4D func func_to_ds_atlas = pe.MapNode(interface=ants.WarpTimeSeriesImageMultiTransform(use_nearest = True), name = 'func_to_ds_atlas', iterfield=['transformation_series','input_image']) preproc.connect(unwarp_func, 'unwarped_file', func_to_ds_atlas, 'input_image') preproc.connect(downsample_atlas_t2_to_func, 'out_file', func_to_ds_atlas, 'reference_image') preproc.connect(cmb_tfm_func_to_ds_atlas, 'out', func_to_ds_atlas, 'transformation_series') # combine transformations (t2 to atlas) cmb_tfm_t2_to_ds_atlas = pe.Node(interface=util.Merge(3, axis='hstack'), name='cmb_tfm_t2_to_ds_atlas') # from structural to atlas (with struct resolution) preproc.connect(structs_to_atlas_coreg_output, ('forward_transforms', get_sec), cmb_tfm_t2_to_ds_atlas, 'in1') preproc.connect(structs_to_atlas_coreg_output, ('forward_transforms', get_first), cmb_tfm_t2_to_ds_atlas, 'in2')
def process_segment_map(wf_name, use_ants): """ This is a sub workflow used inside segmentation workflow to process probability maps obtained in segmententation. Steps include overlapping of the prior tissue with probability maps, thresholding and binarizing it and creating a mask thst is used in further analysis. Parameters ---------- wf_name : string Workflow Name Returns ------- preproc : workflow Workflow Object for process_segment_map Workflow Notes ----- `Source <https://github.com/FCP-INDI/C-PAC/blob/master/CPAC/seg_preproc/seg_preproc.py>`_ Workflow Inputs:: inputspec.brain : string (existing nifti file) Anatomical image(without skull) inputspec.standard2highres_mat : string (existing affine transformation .mat file) path to transformation matrix from mni space to anatomical space inputspec.tissue_prior : string (existing nifti file) path to FSL Standard Tissue prior image inputspec.threshold : string (float) threshold of Segmentation Probaility Maps inputspec.probability_map : string (nifti file) tissue Probability map obtained from fsl FAST Workflow Outputs:: outputspec.segment_mni2t1 : string (nifti file) path to output CSF prior template(in MNI space) registered to anatomical space outputspec.segment_combo : string (nifti file) path to output image containing overlap between csf probability map and segment_mni2t1 outputspec.segment_bin : string (nifti file) path to output image after Thresholding and binarizing segment_combo outputspec.segment_mask : string (nifti file) path to output image after masking segment_combo with its tissue prior in t1 space Order of commands: - Register tissue prior in MNI space to t1 space. - Find overlap between segment probability map and tissue prior in t1 native space. - Threshold and binarize segment probability map - Generate segment mask, by applying tissue prior in t1 space to thresholded binarized segment probability map High Level Graph: .. image:: ../images/process_segment_map.dot.png :width: 1100 :height: 480 Detailed Graph: .. image:: ../images/process_segment_map_detailed.dot.png :width: 1100 :height: 480 """ preproc = pe.Workflow(name=wf_name) inputNode = pe.Node(util.IdentityInterface(fields=[ 'tissue_prior', 'threshold', 'brain', 'probability_map', 'standard2highres_mat' ]), name='inputspec') outputNode = pe.Node(util.IdentityInterface(fields=[ 'tissueprior_mni2t1', 'segment_combo', 'segment_bin', 'segment_mask' ]), name='outputspec') def form_threshold_string(threshold): return '-thr %f -bin ' % (threshold) if use_ants == True: tissueprior_mni_to_t1 = pe.Node( interface=ants.WarpImageMultiTransform(), name='%s_prior_mni_to_t1' % (wf_name)) tissueprior_mni_to_t1.inputs.invert_affine = [1] tissueprior_mni_to_t1.inputs.use_nearest = True overlap_segmentmap_with_prior = pe.Node( interface=fsl.MultiImageMaths(), name='overlap_%s_map_with_prior' % (wf_name)) overlap_segmentmap_with_prior.inputs.op_string = '-mas %s ' binarize_threshold_segmentmap = pe.Node(interface=fsl.ImageMaths(), name='binarize_threshold_%s' % (wf_name)) segment_mask = pe.Node(interface=fsl.MultiImageMaths(), name='%s_mask' % (wf_name)) segment_mask.inputs.op_string = '-mas %s ' #mni to t1 preproc.connect(inputNode, 'tissue_prior', tissueprior_mni_to_t1, 'input_image') preproc.connect(inputNode, 'brain', tissueprior_mni_to_t1, 'reference_image') preproc.connect(inputNode, 'standard2highres_mat', tissueprior_mni_to_t1, 'transformation_series') #overlapping preproc.connect(inputNode, 'probability_map', overlap_segmentmap_with_prior, 'in_file') preproc.connect(tissueprior_mni_to_t1, 'output_image', overlap_segmentmap_with_prior, 'operand_files') #binarize preproc.connect(overlap_segmentmap_with_prior, 'out_file', binarize_threshold_segmentmap, 'in_file') preproc.connect(inputNode, ('threshold', form_threshold_string), binarize_threshold_segmentmap, 'op_string') #create segment mask preproc.connect(binarize_threshold_segmentmap, 'out_file', segment_mask, 'in_file') preproc.connect(tissueprior_mni_to_t1, 'output_image', segment_mask, 'operand_files') #connect to output nodes preproc.connect(tissueprior_mni_to_t1, 'output_image', outputNode, 'tissueprior_mni2t1') preproc.connect(overlap_segmentmap_with_prior, 'out_file', outputNode, 'segment_combo') preproc.connect(binarize_threshold_segmentmap, 'out_file', outputNode, 'segment_bin') preproc.connect(segment_mask, 'out_file', outputNode, 'segment_mask') else: tissueprior_mni_to_t1 = pe.Node(interface=fsl.FLIRT(), name='%s_prior_mni_to_t1' % (wf_name)) tissueprior_mni_to_t1.inputs.apply_xfm = True tissueprior_mni_to_t1.inputs.interp = 'nearestneighbour' overlap_segmentmap_with_prior = pe.Node( interface=fsl.MultiImageMaths(), name='overlap_%s_map_with_prior' % (wf_name)) overlap_segmentmap_with_prior.inputs.op_string = '-mas %s ' binarize_threshold_segmentmap = pe.Node(interface=fsl.ImageMaths(), name='binarize_threshold_%s' % (wf_name)) segment_mask = pe.Node(interface=fsl.MultiImageMaths(), name='%s_mask' % (wf_name)) segment_mask.inputs.op_string = '-mas %s ' #mni to t1 preproc.connect(inputNode, 'tissue_prior', tissueprior_mni_to_t1, 'in_file') preproc.connect(inputNode, 'brain', tissueprior_mni_to_t1, 'reference') preproc.connect(inputNode, 'standard2highres_mat', tissueprior_mni_to_t1, 'in_matrix_file') #overlapping preproc.connect(inputNode, 'probability_map', overlap_segmentmap_with_prior, 'in_file') preproc.connect(tissueprior_mni_to_t1, 'out_file', overlap_segmentmap_with_prior, 'operand_files') #binarize preproc.connect(overlap_segmentmap_with_prior, 'out_file', binarize_threshold_segmentmap, 'in_file') preproc.connect(inputNode, ('threshold', form_threshold_string), binarize_threshold_segmentmap, 'op_string') #create segment mask preproc.connect(binarize_threshold_segmentmap, 'out_file', segment_mask, 'in_file') preproc.connect(tissueprior_mni_to_t1, 'out_file', segment_mask, 'operand_files') #connect to output nodes preproc.connect(tissueprior_mni_to_t1, 'out_file', outputNode, 'tissueprior_mni2t1') preproc.connect(overlap_segmentmap_with_prior, 'out_file', outputNode, 'segment_combo') preproc.connect(binarize_threshold_segmentmap, 'out_file', outputNode, 'segment_bin') preproc.connect(segment_mask, 'out_file', outputNode, 'segment_mask') return preproc
func2anat_fsl2itk.inputs.itk_transform = True func2anat_fsl2itk.inputs.fsl2ras = True wf.connect(datagrabber, "func2anat_transform", func2anat_fsl2itk, "transform_file") wf.connect(datagrabber, "epi_mask", func2anat_fsl2itk, "source_file") wf.connect(ants_normalize, "brain_2nii.out_file", func2anat_fsl2itk, "reference_file") collect_transforms = pe.Node(util.Merge(3), name='collect_transforms') wf.connect(func2anat_fsl2itk, "itk_transform", collect_transforms, "in1") wf.connect(ants_normalize, "outputspec.affine_transformation", collect_transforms, "in2") wf.connect(ants_normalize, "outputspec.inverse_warp", collect_transforms, "in3") mask2func = pe.Node(ants.WarpImageMultiTransform(dimension=3), name="mask2func") mask2func.inputs.invert_affine = [1, 2] wf.connect(datagrabber, "epi_mask", mask2func, "reference_image") wf.connect(sphere, "out_file", mask2func, "input_image") wf.connect(collect_transforms, "out", mask2func, "transformation_series") threshold = pe.Node(fs.Binarize(min=0.5, out_type='nii'), name="threshold") wf.connect(mask2func, "output_image", threshold, "in_file") restrict_to_brain = pe.Node(fsl.ApplyMask(), name="restrict_to_brain") wf.connect(threshold, "binary_file", restrict_to_brain, "in_file") wf.connect(datagrabber, "epi_mask", restrict_to_brain, "mask_file") extract_timeseries = pe.Node(afni.Maskave(), name="extract_timeseries") correlation_map = pe.Node(afni.Fim(), name="correlation_map")
def create_nuisance(use_ants, name='nuisance'): """ Workflow for the removal of various signals considered to be noise in resting state fMRI data. The residual signals for linear regression denoising is performed in a single model. Therefore the residual time-series will be orthogonal to all signals. Parameters ---------- name : string, optional Name of the workflow. Returns ------- nuisance : nipype.pipeline.engine.Workflow Nuisance workflow. Notes ----- Workflow Inputs:: inputspec.subject : string (nifti file) Path of the subject's realigned nifti file. inputspec.wm_mask : string (nifti file) Corresponding white matter mask. inputspec.csf_mask : string (nifti file) Corresponding cerebral spinal fluid mask. inputspec.gm_mask : string (nifti file) Corresponding grey matter mask. inputspec.mni_to_anat_linear_xfm : string (nifti file) Corresponding MNI to anatomical linear transformation inputspec.func_to_anat_linear_xfm : string (nifti file) Corresponding EPI to anatomical linear transformation inputspec.harvard_oxford_mask : string (nifti file) Harvard Oxford parcellation for ventrical locations inputspec.motion_components : string (text file) Corresponding rigid-body motion parameters. Matrix in the file should be of shape (`T`, `R`), `T` timepoints and `R` motion parameters. inputspec.selector : dictionary inputspec.compcor_ncomponents : integer Workflow Outputs:: outputspec.subject : string (nifti file) Path of residual file in nifti format outputspec.regressors : string (mat file) Path of csv file of regressors used. Filename corresponds to the name of each regressor in each column. Nuisance Procedure: 1. Compute nuisance regressors based on input selections. 2. Calculate residuals with respect to these nuisance regressors in a single model for every voxel. Workflow Graph: .. image:: ../images/nuisance.dot.png :width: 500 Detailed Workflow Graph: .. image:: ../images/nuisance_detailed.dot.png :width: 500 """ nuisance = pe.Workflow(name=name) inputspec = pe.Node(util.IdentityInterface(fields=['subject', 'wm_mask', 'csf_mask', 'gm_mask', 'mni_to_anat_linear_xfm', 'func_to_anat_linear_xfm', 'harvard_oxford_mask', 'motion_components', 'selector', 'compcor_ncomponents', 'template_brain']), name='inputspec') outputspec = pe.Node(util.IdentityInterface(fields=['subject', 'regressors']), name='outputspec') # Resampling the masks from 1mm to 2mm wm_anat_to_2mm = pe.Node(interface=fsl.FLIRT(), name='wm_anat_to_2mm_flirt_applyxfm') wm_anat_to_2mm.inputs.args = '-applyisoxfm 2' wm_anat_to_2mm.inputs.interp = 'nearestneighbour' nuisance.connect(inputspec, 'wm_mask', wm_anat_to_2mm, 'in_file') nuisance.connect(inputspec, 'wm_mask', wm_anat_to_2mm, 'reference') # Resampling the masks from 1mm to 2mm csf_anat_to_2mm = pe.Node(interface=fsl.FLIRT(), name='csf_anat_to_2mm_flirt_applyxfm') csf_anat_to_2mm.inputs.args = '-applyisoxfm 2' csf_anat_to_2mm.inputs.interp = 'nearestneighbour' nuisance.connect(inputspec, 'csf_mask', csf_anat_to_2mm, 'in_file') nuisance.connect(inputspec, 'csf_mask', csf_anat_to_2mm, 'reference') # Resampling the masks from 1mm to 2mm gm_anat_to_2mm = pe.Node(interface=fsl.FLIRT(), name='gm_anat_to_2mm_flirt_applyxfm') gm_anat_to_2mm.inputs.args = '-applyisoxfm 2' gm_anat_to_2mm.inputs.interp = 'nearestneighbour' nuisance.connect(inputspec, 'gm_mask', gm_anat_to_2mm, 'in_file') nuisance.connect(inputspec, 'gm_mask', gm_anat_to_2mm, 'reference') func_to_2mm = pe.Node(interface=fsl.FLIRT(), name='func_to_2mm_flirt_applyxfm') func_to_2mm.inputs.args = '-applyisoxfm 2' nuisance.connect(inputspec, 'subject', func_to_2mm, 'in_file') nuisance.connect(inputspec, 'csf_mask', func_to_2mm, 'reference') nuisance.connect(inputspec, 'func_to_anat_linear_xfm', func_to_2mm, 'in_matrix_file') if use_ants == True: ho_mni_to_2mm = pe.Node(interface=ants.WarpImageMultiTransform(), name='ho_mni_to_2mm_ants_applyxfm') ho_mni_to_2mm.inputs.invert_affine = [1] ho_mni_to_2mm.inputs.use_nearest = True ho_mni_to_2mm.inputs.dimension = 3 nuisance.connect(inputspec, 'mni_to_anat_linear_xfm', ho_mni_to_2mm, 'transformation_series') nuisance.connect(inputspec, 'harvard_oxford_mask', ho_mni_to_2mm, 'input_image') nuisance.connect(csf_anat_to_2mm, 'out_file', ho_mni_to_2mm, 'reference_image') #resample_to_2mm = pe.Node(interface=afni.Resample(), name='resample_to_2mm_ants_output' else: ho_mni_to_2mm = pe.Node(interface=fsl.FLIRT(), name='ho_mni_to_2mm_flirt_applyxfm') ho_mni_to_2mm.inputs.args = '-applyisoxfm 2' ho_mni_to_2mm.inputs.interp = 'nearestneighbour' nuisance.connect(inputspec, 'mni_to_anat_linear_xfm', ho_mni_to_2mm, 'in_matrix_file') nuisance.connect(inputspec, 'harvard_oxford_mask', ho_mni_to_2mm, 'in_file') nuisance.connect(inputspec, 'csf_mask', ho_mni_to_2mm, 'reference') tissue_masks = pe.Node(util.Function(input_names=['data_file', 'ho_mask_file', 'wm_seg_file', 'csf_seg_file', 'gm_seg_file', 'wm_threshold', 'csf_threshold', 'gm_threshold'], output_names=['file_wm', 'file_csf', 'file_gm'], function=extract_tissue_data), name='tissue_masks') nuisance.connect(func_to_2mm, 'out_file', tissue_masks, 'data_file') nuisance.connect(wm_anat_to_2mm, 'out_file', tissue_masks, 'wm_seg_file') nuisance.connect(csf_anat_to_2mm, 'out_file', tissue_masks, 'csf_seg_file') nuisance.connect(gm_anat_to_2mm, 'out_file', tissue_masks, 'gm_seg_file') if use_ants == True: nuisance.connect(ho_mni_to_2mm, 'output_image', tissue_masks, 'ho_mask_file') else: nuisance.connect(ho_mni_to_2mm, 'out_file', tissue_masks, 'ho_mask_file') calc_r = pe.Node(util.Function(input_names=['subject', 'selector', 'wm_sig_file', 'csf_sig_file', 'gm_sig_file', 'motion_file', 'compcor_ncomponents'], output_names=['residual_file', 'regressors_file'], function=calc_residuals), name='residuals') nuisance.connect(inputspec, 'subject', calc_r, 'subject') nuisance.connect(tissue_masks, 'file_wm', calc_r, 'wm_sig_file') nuisance.connect(tissue_masks, 'file_csf', calc_r, 'csf_sig_file') nuisance.connect(tissue_masks, 'file_gm', calc_r, 'gm_sig_file') nuisance.connect(inputspec, 'motion_components', calc_r, 'motion_file') nuisance.connect(inputspec, 'selector', calc_r, 'selector') nuisance.connect(inputspec, 'compcor_ncomponents', calc_r, 'compcor_ncomponents') nuisance.connect(calc_r, 'residual_file', outputspec, 'subject') nuisance.connect(calc_r, 'regressors_file', outputspec, 'regressors') return nuisance