def mask_CTBrain(CT_dir, T1_dir, frac): # nav to dir with T1 images os.chdir(T1_dir) # run BET to extract brain from T1 bet = BET() bet.inputs.in_file = T1_dir + '/T1.nii' bet.inputs.frac = frac bet.inputs.robust = True bet.inputs.mask = True print "::: Extracting Brain mask from T1 using BET :::" bet.run() # use flrit to correg CT to T1 flirt = FLIRT() flirt.inputs.in_file = CT_dir + '/CT.nii' flirt.inputs.reference = T1_dir + '/T1.nii' flirt.inputs.cost_func = 'mutualinfo' print "::: Estimating corregistration from CT to T1 using FLIRT :::" flirt.run() # get inverse of estimated coreg of CT tp T1 print "::: Estimating inverse affine for Brain mask of CT :::" os.system('convert_xfm -omat inv_CT_flirt.mat -inverse CT_flirt.mat') os.system('mv inv_CT_flirt.mat %s' % (CT_dir)) # apply inverse affine coreg to get brain mask in CT space applyxfm = ApplyXfm() applyxfm.inputs.in_file = T1_dir + '/T1_brain_mask.nii.gz' applyxfm.inputs.in_matrix_file = CT_dir + '/inv_CT_flirt.mat' applyxfm.inputs.out_file = CT_dir + '/CT_mask.nii.gz' applyxfm.inputs.reference = CT_dir + '/CT.nii' applyxfm.inputs.apply_xfm = True print "::: Applying inverse affine to Brain mask to get CT mask :::" applyxfm.run() # dilate brain mask to make sure all elecs are in final masked img CT_mask = nib.load(CT_dir + '/CT_mask.nii.gz') CT_mask_dat = CT_mask.get_data() kernel = np.ones((5, 5), np.uint8) print "::: Dilating CT mask :::" dilated = cv2.dilate(CT_mask_dat, kernel, iterations=1) hdr = CT_mask.get_header() affine = CT_mask.get_affine() N = nib.Nifti1Image(dilated, affine, hdr) new_fname = CT_dir + '/dilated_CT_mask.nii' N.to_filename(new_fname) # apply mask to CT os.chdir(CT_dir) print "::: masking CT with dilated brain mask :::" os.system( "fslmaths 'CT.nii' -mas 'dilated_CT_mask.nii.gz' 'masked_CT.nii'") os.system('gunzip masked_CT.nii.gz')
def func_register(img_original,img_template, img_registered): # img_original : original T2 or FLAIR image file # img_template : isovoxel T1C file used for registration template # img_registered :file name that stores registered (isovoxel) T2 or FLAIR file coregi_iso = FLIRT(bins=640, cost_func='mutualinfo', dof=12, output_type="NIFTI_GZ", verbose=0, datatype = 'float', interp = 'trilinear', in_file = img_original, reference = img_template, out_file = img_registered) coregi_iso.run()
def mask_CTBrain(CT_dir, T1_dir, frac): # nav to dir with T1 images os.chdir(T1_dir) # run BET to extract brain from T1 bet = BET() bet.inputs.in_file = T1_dir + "/T1.nii" bet.inputs.frac = frac bet.inputs.robust = True bet.inputs.mask = True print "::: Extracting Brain mask from T1 using BET :::" bet.run() # use flrit to correg CT to T1 flirt = FLIRT() flirt.inputs.in_file = CT_dir + "/CT.nii" flirt.inputs.reference = T1_dir + "/T1.nii" flirt.inputs.cost_func = "mutualinfo" print "::: Estimating corregistration from CT to T1 using FLIRT :::" flirt.run() # get inverse of estimated coreg of CT tp T1 print "::: Estimating inverse affine for Brain mask of CT :::" os.system("convert_xfm -omat inv_CT_flirt.mat -inverse CT_flirt.mat") os.system("mv inv_CT_flirt.mat %s" % (CT_dir)) # apply inverse affine coreg to get brain mask in CT space applyxfm = ApplyXfm() applyxfm.inputs.in_file = T1_dir + "/T1_brain_mask.nii.gz" applyxfm.inputs.in_matrix_file = CT_dir + "/inv_CT_flirt.mat" applyxfm.inputs.out_file = CT_dir + "/CT_mask.nii.gz" applyxfm.inputs.reference = CT_dir + "/CT.nii" applyxfm.inputs.apply_xfm = True print "::: Applying inverse affine to Brain mask to get CT mask :::" applyxfm.run() # dilate brain mask to make sure all elecs are in final masked img CT_mask = nib.load(CT_dir + "/CT_mask.nii.gz") CT_mask_dat = CT_mask.get_data() kernel = np.ones((5, 5), np.uint8) print "::: Dilating CT mask :::" dilated = cv2.dilate(CT_mask_dat, kernel, iterations=1) hdr = CT_mask.get_header() affine = CT_mask.get_affine() N = nib.Nifti1Image(dilated, affine, hdr) new_fname = CT_dir + "/dilated_CT_mask.nii" N.to_filename(new_fname) # apply mask to CT os.chdir(CT_dir) print "::: masking CT with dilated brain mask :::" os.system("fslmaths 'CT.nii' -mas 'dilated_CT_mask.nii.gz' 'masked_CT.nii'") os.system("gunzip masked_CT.nii.gz")
def isotropic_voxels(): if verbose: print('Resampling to isotropic voxels') orig = nib.load('%s/opposedphase.nii.gz' % tmpdir) for f in ['opposedphase', 'inphase']: iso = FLIRT() iso.inputs.in_file = '%s/%s.nii.gz' % (tmpdir, f) iso.inputs.reference = '%s/%s.nii.gz' % (tmpdir, f) iso.inputs.out_file = '%s/%s_iso.nii.gz' % (tmpdir, f) iso.inputs.apply_isoxfm = orig.header.get_zooms()[0] iso.run()
def calculate_realignment_cost(target_id: str, cost_function: str, serialize: bool = True): realigned_subject_dirs = generate_subject_dirs("realigned", target_id, cost_function) target_scan = get_target_scan(target_id) costs = {} for subject_dir in realigned_subject_dirs: subject_id = subject_dir.split("/")[-2] registered, mat_file = get_realigned_subject_data(subject_id) print(f"Calculating cost function value...", end="\t") flirt = FLIRT() flirt.inputs.in_file = registered flirt.inputs.reference = target_scan flirt.inputs.schedule = "/usr/local/fsl/etc/flirtsch/measurecost1.sch" flirt.inputs.in_matrix_file = mat_file tmp = os.path.join(subject_dir, "tmp") flirt.inputs.out_file = os.path.join(tmp, "cost.nii.gz") flirt.inputs.out_matrix_file = os.path.join(tmp, "cost.mat") os.makedirs(tmp, exist_ok=True) f = flirt.run() result = float(f.runtime.stdout.split()[0]) print(f"done! [{result}]") shutil.rmtree(tmp) costs[subject_id] = result if serialize: serialize_results(target_id, cost_function, costs) return costs
def flirt_t1_epi(subject_id, data_dir, run, sink_dir): def get_niftis(subject_id, data_dir, run, sink_dir): from os.path import join, exists t1 = join( data_dir, subject_id, "session-1", "anatomical", "anatomical-0", "anatomical.nii.gz", ) # t1_brain_mask = join(data_dir, subject, 'session-1', 'anatomical', 'anatomical-0', 'fsl', 'anatomical-bet.nii.gz') ex_func = join( sink_dir, subject_id, "{0}-{1}_retr-example_func.nii.gz".format(subject_id, run), ) assert exists(t1), "t1 does not exist" assert exists(ex_func), "example func does not exist" standard = "/home/applications/fsl/5.0.8/data/standard/MNI152_T1_2mm.nii.gz" return t1, ex_func, standard coreg = join(sink_dir, "qa", "{0}-{1}_t1_flirt.png".format(subject, run)) data = Function( function=get_niftis, input_names=["subject_id", "data_dir", "run", "sink_dir"], output_names=["t1", "ex_func", "standard"], ) data.inputs.data_dir = data_dir data.inputs.sink_dir = sink_dir data.inputs.subject_id = subject data.inputs.run = run grabber = data.run() re_flit = FLIRT( cost_func="normmi", dof=12, searchr_x=[-90, 90], searchr_y=[-90, 90], searchr_z=[-90, 90], interp="trilinear", bins=256, ) re_flit.inputs.reference = grabber.outputs.ex_func re_flit.inputs.in_file = grabber.outputs.t1 re_flit.inputs.out_file = join( sink_dir, subject, "{0}-{1}_t1-flirt-retr.nii.gz".format(subject, run)) re_flit.inputs.out_matrix_file = join( sink_dir, subject, "{0}-{1}_t1-flirt-retr.mat".format(subject, run)) reg_func = re_flit.run() display = plotting.plot_anat(grabber.outputs.ex_func, dim=0) display.add_edges(reg_func.outputs.out_file) display.savefig(coreg, dpi=300) return
def func_regi2mni(path_T1C_isovoxel, path_mask_isovoxel): matrix_2mni = 'matrix_2mni.mat' mni_reference = 'MNI152_T1_1mm_brain.nii.gz' coregi_t1gd2mni= FLIRT(bins=640, cost_func='mutualinfo', dof=12, output_type="NIFTI_GZ", verbose=0, datatype = 'float', interp = 'trilinear', in_file = path_T1C_isovoxel, reference = mni_reference, out_file = 'img_2mni.nii.gz', out_matrix_file = matrix_2mni) coregi_t1gd2mni.run() coregi_mask2MNI = ApplyXFM(in_file = path_mask_isovoxel, in_matrix_file = matrix_2mni, out_file = 'mask_2mni.nii.gz', reference= mni_reference) coregi_mask2MNI.run()
def resample_to_umap(DeepX, reference): if verbose: print('Resampling to umap resolution') # Rehape to in-phase resolution DeepX = np.swapaxes(np.flipud(np.fliplr(DeepX)), 2, 0) DeepX_padded = np.zeros(reference.shape) DeepX_padded[96:288, 6:198, :192] = DeepX DeepX_nii = nib.Nifti1Image(DeepX_padded, reference.affine, reference.header) nib.save(DeepX_nii, '%s/DeepDixon.nii.gz' % tmpdir) # Resample to UMAP resolution DeepX_rsl = FLIRT() DeepX_rsl.inputs.in_file = '%s/DeepDixon.nii.gz' % tmpdir DeepX_rsl.inputs.reference = '%s/umap.nii.gz' % tmpdir DeepX_rsl.inputs.out_file = '%s/DeepDixon_rsl.nii.gz' % tmpdir DeepX_rsl.run() DeepX = nib.load('%s/DeepDixon_rsl.nii.gz' % tmpdir).get_fdata() DeepX = DeepX.astype(np.uint16) DeepX = np.fliplr(np.flipud(np.swapaxes(np.swapaxes(DeepX, 0, 1), 1, 2))) return DeepX
os.path.join(path_t1[i], "mask.nii"), niter_mask, sigma_mask, file_cmap) """ flirt """ os.chdir(path_flirt) flirt = FLIRT() flirt.inputs.cost_func = "corratio" flirt.inputs.dof = 6 flirt.inputs.interp = "trilinear" # trilinear, nearestneighbour, sinc or spline flirt.inputs.in_file = os.path.join(path_epi_target, "pbepi.nii") flirt.inputs.reference = os.path.join(path_epi_source, "pbepi.nii") flirt.inputs.output_type = "NIFTI" flirt.inputs.out_file = os.path.join(path_flirt, "flirt.nii") flirt.inputs.out_matrix_file = os.path.join(path_flirt, "flirt_matrix.mat") flirt.run() """ invert matrix """ invt = ConvertXFM() invt.inputs.in_file = os.path.join(path_flirt, "flirt_matrix.mat") invt.inputs.invert_xfm = True invt.inputs.out_file = os.path.join(path_flirt, "flirt_inv_matrix.mat") invt.run() """ get cmap """ generate_coordinate_mapping(os.path.join(path_epi_target, "bepi.nii"), pad=0, path_output=path_flirt, suffix="target",
def preproc(data_dir, sink_dir, subject, task, session, run, masks, motion_thresh, moco): from nipype.interfaces.fsl import MCFLIRT, FLIRT, FNIRT, ExtractROI, ApplyWarp, MotionOutliers, InvWarp, FAST #from nipype.interfaces.afni import AlignEpiAnatPy from nipype.interfaces.utility import Function from nilearn.plotting import plot_anat from nilearn import input_data #WRITE A DARA GRABBER def get_niftis(subject_id, data_dir, task, run, session): from os.path import join, exists t1 = join(data_dir, subject_id, 'session-{0}'.format(session), 'anatomical', 'anatomical-0', 'anatomical.nii.gz') #t1_brain_mask = join(data_dir, subject_id, 'session-1', 'anatomical', 'anatomical-0', 'fsl', 'anatomical-bet.nii.gz') epi = join(data_dir, subject_id, 'session-{0}'.format(session), task, '{0}-{1}'.format(task, run), '{0}.nii.gz'.format(task)) assert exists(t1), "t1 does not exist at {0}".format(t1) assert exists(epi), "epi does not exist at {0}".format(epi) standard = '/home/applications/fsl/5.0.8/data/standard/MNI152_T1_2mm.nii.gz' return t1, epi, standard data = Function( function=get_niftis, input_names=["subject_id", "data_dir", "task", "run", "session"], output_names=["t1", "epi", "standard"]) data.inputs.data_dir = data_dir data.inputs.subject_id = subject data.inputs.run = run data.inputs.session = session data.inputs.task = task grabber = data.run() if session == 0: sesh = 'pre' if session == 1: sesh = 'post' #reg_dir = '/home/data/nbc/physics-learning/data/first-level/{0}/session-1/retr/retr-{1}/retr-5mm.feat/reg'.format(subject, run) #set output paths for quality assurance pngs qa1 = join( sink_dir, 'qa', '{0}-session-{1}_{2}-{3}_t1_flirt.png'.format(subject, session, task, run)) qa2 = join( sink_dir, 'qa', '{0}-session-{1}_{2}-{3}_mni_flirt.png'.format(subject, session, task, run)) qa3 = join( sink_dir, 'qa', '{0}-session-{1}_{2}-{3}_mni_fnirt.png'.format(subject, session, task, run)) confound_file = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_confounds.txt'.format(subject, session, task, run)) #run motion correction if indicated if moco == True: mcflirt = MCFLIRT(ref_vol=144, save_plots=True, output_type='NIFTI_GZ') mcflirt.inputs.in_file = grabber.outputs.epi #mcflirt.inputs.in_file = join(data_dir, subject, 'session-1', 'retr', 'retr-{0}'.format(run), 'retr.nii.gz') mcflirt.inputs.out_file = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_mcf.nii.gz'.format( subject, session, task, run)) flirty = mcflirt.run() motion = np.genfromtxt(flirty.outputs.par_file) else: print "no moco needed" motion = 0 #calculate motion outliers try: mout = MotionOutliers(metric='fd', threshold=motion_thresh) mout.inputs.in_file = grabber.outputs.epi mout.inputs.out_file = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_fd-gt-{3}mm'.format( subject, session, task, run, motion_thresh)) mout.inputs.out_metric_plot = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_metrics.png'.format( subject, session, task, run)) mout.inputs.out_metric_values = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_fd.txt'.format(subject, session, task, run)) moutliers = mout.run() outliers = np.genfromtxt(moutliers.outputs.out_file) e = 'no errors in motion outliers, yay' except Exception as e: print(e) outliers = np.genfromtxt(mout.inputs.out_metric_values) #set everything above the threshold to 1 and everything below to 0 outliers[outliers > motion_thresh] = 1 outliers[outliers < motion_thresh] = 0 #concatenate motion parameters and motion outliers to form confounds file #outliers = outliers.reshape((outliers.shape[0],1)) conf = outliers np.savetxt(confound_file, conf, delimiter=',') #extract an example volume for normalization ex_fun = ExtractROI(t_min=144, t_size=1) ex_fun.inputs.in_file = flirty.outputs.out_file ex_fun.inputs.roi_file = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}-example_func.nii.gz'.format( subject, session, task, run)) fun = ex_fun.run() warp = ApplyWarp(interp="nn", abswarp=True) if not exists( '/home/data/nbc/physics-learning/data/first-level/{0}/session-{1}/{2}/{2}-{3}/{2}-5mm.feat/reg/example_func2standard_warp.nii.gz' .format(subject, session, task, run)): #two-step normalization using flirt and fnirt, outputting qa pix flit = FLIRT(cost_func="corratio", dof=12) reg_func = flit.run( reference=fun.outputs.roi_file, in_file=grabber.outputs.t1, searchr_x=[-180, 180], searchr_y=[-180, 180], out_file=join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_t1-flirt.nii.gz'.format( subject, session, task, run)), out_matrix_file=join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_t1-flirt.mat'.format( subject, session, task, run))) reg_mni = flit.run( reference=grabber.outputs.t1, in_file=grabber.outputs.standard, searchr_y=[-180, 180], searchr_z=[-180, 180], out_file=join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_mni-flirt-t1.nii.gz'.format( subject, session, task, run)), out_matrix_file=join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_mni-flirt-t1.mat'.format( subject, session, task, run))) #plot_stat_map(aligner.outputs.out_file, bg_img=fun.outputs.roi_file, colorbar=True, draw_cross=False, threshold=1000, output_file=qa1a, dim=-2) display = plot_anat(fun.outputs.roi_file, dim=-1) display.add_edges(reg_func.outputs.out_file) display.savefig(qa1, dpi=300) display.close() display = plot_anat(grabber.outputs.t1, dim=-1) display.add_edges(reg_mni.outputs.out_file) display.savefig(qa2, dpi=300) display.close() perf = FNIRT(output_type='NIFTI_GZ') perf.inputs.warped_file = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_mni-fnirt-t1.nii.gz'.format( subject, session, task, run)) perf.inputs.affine_file = reg_mni.outputs.out_matrix_file perf.inputs.in_file = grabber.outputs.standard perf.inputs.subsampling_scheme = [8, 4, 2, 2] perf.inputs.fieldcoeff_file = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_mni-fnirt-t1-warpcoeff.nii.gz'.format( subject, session, task, run)) perf.inputs.field_file = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_mni-fnirt-t1-warp.nii.gz'.format( subject, session, task, run)) perf.inputs.ref_file = grabber.outputs.t1 reg2 = perf.run() warp.inputs.field_file = reg2.outputs.field_file #plot fnirted MNI overlaid on example func display = plot_anat(grabber.outputs.t1, dim=-1) display.add_edges(reg2.outputs.warped_file) display.savefig(qa3, dpi=300) display.close() else: warpspeed = InvWarp(output_type='NIFTI_GZ') warpspeed.inputs.warp = '/home/data/nbc/physics-learning/data/first-level/{0}/session-{1}/{2}/{2}-{3}/{2}-5mm.feat/reg/example_func2standard_warp.nii.gz'.format( subject, session, task, run) warpspeed.inputs.reference = fun.outputs.roi_file warpspeed.inputs.inverse_warp = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_mni-fnirt-t1-warp.nii.gz'.format( subject, session, task, run)) mni2epiwarp = warpspeed.run() warp.inputs.field_file = mni2epiwarp.outputs.inverse_warp for key in masks.keys(): #warp takes us from mni to epi warp.inputs.in_file = masks[key] warp.inputs.ref_file = fun.outputs.roi_file warp.inputs.out_file = join( sink_dir, sesh, subject, '{0}-session-{1}_{2}-{3}_{4}.nii.gz'.format( subject, session, task, run, key)) net_warp = warp.run() qa_file = join( sink_dir, 'qa', '{0}-session-{1}_{2}-{3}_qa_{4}.png'.format( subject, session, task, run, key)) display = plotting.plot_roi(net_warp.outputs.out_file, bg_img=fun.outputs.roi_file, colorbar=True, vmin=0, vmax=18, draw_cross=False) display.savefig(qa_file, dpi=300) display.close() return flirty.outputs.out_file, confound_file, e
def get_flash2orig(file_flash, file_inv2, file_orig, path_output, cleanup=False): """ This function computes the deformation field for the registration between a partial coverage GRE image and the freesurfer orig file. The following steps are performed: (1) set output folder structure, (2) get scanner transform GRE <-> inv2 and inv2 -> orig, (3) generate flash cmap, (4) apply scanner transform inv2 -> GRE, (5) get flirt registration GRE -> inv2, (6) apply flirt to GRE cmap, (7) apply scanner transform to GRE cmap, (8) apply final deformation to GRE. The function needs the FSL environment set. Inputs: *file_flash: input path for GRE image. *file_inv2: input path for MP2RAGE INV2 image. *file_orig: input path for freesurfer orig image. *path_output: path where output is saved. *cleanup: delete intermediate files (boolean). created by Daniel Haenelt Date created: 18-04-2019 Last modified: 16-05-2019 """ import os import shutil as sh from nipype.interfaces.fsl import FLIRT from nipype.interfaces.fsl.preprocess import ApplyXFM from nipype.interfaces.freesurfer.preprocess import MRIConvert from nighres.registration import apply_coordinate_mappings from lib.cmap import generate_coordinate_mapping from lib.registration.get_scanner_transform import get_scanner_transform """ set folder structure """ path_temp = os.path.join(path_output, "temp") if not os.path.exists(path_output): os.makedirs(path_output) if not os.path.exists(path_temp): os.makedirs(path_temp) # copy input files sh.copyfile(file_inv2, os.path.join(path_temp, "inv2.nii")) sh.copyfile(file_flash, os.path.join(path_temp, "flash.nii")) """ convert orig to nifti """ mc = MRIConvert() mc.inputs.in_file = file_orig mc.inputs.out_file = os.path.join(path_temp, "orig.nii") mc.inputs.in_type = "mgz" mc.inputs.out_type = "nii" mc.run() """ scanner transformation """ get_scanner_transform(os.path.join(path_temp, "inv2.nii"), os.path.join(path_temp, "flash.nii"), path_temp, False) get_scanner_transform(os.path.join(path_temp, "flash.nii"), os.path.join(path_temp, "inv2.nii"), path_temp, False) get_scanner_transform(os.path.join(path_temp, "inv2.nii"), os.path.join(path_temp, "orig.nii"), path_temp, False) """ generate coordinate mapping """ generate_coordinate_mapping(os.path.join(path_temp, "flash.nii"), 0, path_temp, "flash", False, True) """ scanner transform inv2 to flash """ apply_coordinate_mappings( os.path.join(path_temp, "inv2.nii"), # input os.path.join(path_temp, "inv2_2_flash_scanner.nii"), # cmap interpolation="linear", # nearest or linear padding="zero", # closest, zero or max save_data=True, # save output data to file (boolean) overwrite=True, # overwrite existing results (boolean) output_dir=path_temp, # output directory file_name= "inv2_apply_scanner" # base name with file extension for output ) """ flirt flash to inv2 """ os.chdir(path_temp) flirt = FLIRT() flirt.inputs.cost_func = "mutualinfo" flirt.inputs.dof = 6 flirt.inputs.interp = "trilinear" # trilinear, nearestneighbour, sinc or spline flirt.inputs.in_file = os.path.join(path_temp, "flash.nii") flirt.inputs.reference = os.path.join(path_temp, "inv2_apply_scanner_def-img.nii.gz") flirt.inputs.output_type = "NIFTI_GZ" flirt.inputs.out_file = os.path.join(path_temp, "flash_apply_flirt_def-img.nii.gz") flirt.inputs.out_matrix_file = os.path.join(path_temp, "flirt_matrix.txt") flirt.run() """ apply flirt to flash cmap """ applyxfm = ApplyXFM() applyxfm.inputs.in_file = os.path.join(path_temp, "cmap_flash.nii") applyxfm.inputs.reference = os.path.join(path_temp, "flash.nii") applyxfm.inputs.in_matrix_file = os.path.join(path_temp, "flirt_matrix.txt") applyxfm.inputs.interp = "trilinear" applyxfm.inputs.padding_size = 0 applyxfm.inputs.output_type = "NIFTI_GZ" applyxfm.inputs.out_file = os.path.join(path_temp, "cmap_apply_flirt_def-img.nii.gz") applyxfm.inputs.apply_xfm = True applyxfm.run() """ apply scanner transform to flash cmap """ apply_coordinate_mappings( os.path.join(path_temp, "cmap_apply_flirt_def-img.nii.gz"), os.path.join(path_temp, "flash_2_inv2_scanner.nii"), # cmap 1 os.path.join(path_temp, "inv2_2_orig_scanner.nii"), # cmap 2 interpolation="linear", # nearest or linear padding="zero", # closest, zero or max save_data=True, # save output data to file (boolean) overwrite=True, # overwrite existing results (boolean) output_dir=path_temp, # output directory file_name= "cmap_apply_scanner" # base name with file extension for output ) """ apply deformation to source image """ apply_coordinate_mappings( os.path.join(path_temp, "flash.nii"), # input os.path.join(path_temp, "cmap_apply_scanner_def-img.nii.gz"), interpolation="linear", # nearest or linear padding="zero", # closest, zero or max save_data=True, # save output data to file (boolean) overwrite=True, # overwrite existing results (boolean) output_dir=path_temp, # output directory file_name= "flash_apply_deformation" # base name with file extension for output ) # rename final deformation examples os.rename(os.path.join(path_temp, "cmap_apply_scanner_def-img.nii.gz"), os.path.join(path_output, "flash2orig.nii.gz")) os.rename( os.path.join(path_temp, "flash_apply_deformation_def-img.nii.gz"), os.path.join(path_output, "flash2orig_example.nii.gz")) # clean intermediate files if cleanup: sh.rmtree(path_temp, ignore_errors=True)
def elecDetect(CT_dir, fs_dir, img, thresh_f, thresh_c, frac, num_gridStrips, n_elects): # run CT_electhresh print "::: Thresholding CT at %f stdv :::" % (thresh) CT_img = CT_dir + img electhresh(CT_img, thresh_f, thresh_c) # run im_filt to gaussian smooth thresholded image fname = CT_dir + "thresh_" + img print "::: Applying guassian smooth of 2.5mm to thresh-CT :::" img_filt(fname) # compute cv alg to find electrode center coordinates mlab = matlab.MatlabCommand() mlab.inputs.script = "" % (CT_dir, CT_dir, CT_dir, CT_dir) print "::: Applying 3D cv alg to smoothed thresh-CT :::" out = mlab.run() # run the hough and get errors if any ocur # save txt version of hough putputs coords = scipy.io.loadmat(CT_dir + '/' + '3dcv_coords.mat').get('coords') np.savetxt('dirty_elecsAll.txt', coords, delimiter=' ', fmt='%-7.1f') # run fsl FLIRT to compute CT-MRI registration flirt = FLIRT() flirt.inputs.in_file = CT_dir + '/CT.nii' flirt.inputs.reference = fs_dir + '/orig.nii' flirt.inputs.cost_func = 'mutualinfo' print "::: Computing corregistration between CT and MRI using FLIRT :::" flirt.run() # use fsl to calc voxel coords for elec centers in CT registered to orig # in RAS voxel coordinates using affine from FLIRT print "::: Applying FLIRT transformation to 3d cv ouput :::" orig_brain = fs_dir + '/orig.nii' os.system( 'cat %s/dirty_elecsAll.txt | img2imgcoord -src %s/CT.nii -dest %s \ -xfm %s/CT_flirt.mat -vox > %s/dirty_elecsAll_RAS.txt' % (CT_dir, CT_dir, orig_brain, fs_dir, CT_dir)) # remove outliers caused by staples in the most superior portion of the img print "::: Removing outliers from detected electrode coordinates :::" elecs_dirty_RAS = scipy.loadtxt('dirty_elecsAll_RAS.txt', skiprows=1) clean_elecs_RAS = [] for i in elecs_dirty_RAS: if i[1] > (0.3 * np.max(elecs_dirty_RAS[:, 2])): clean_elecs_RAS.append(i) clean_elecs_RAS = np.array(clean_elecs_RAS) # save surface RAS coords for cleaned coords # first apply vox2Ras affine for all fs orig volumes print "::: Applying freesurfer vox2RAS transformation :::" affine = np.array([[-1., 0., 0., 128.], [0., 0., 1., -128.], [0., -1., 0., 128.], [0., 0., 0., 1.]]) intercept = np.ones(len(clean_elecs_RAS)) vox_elecs = np.column_stack((clean_elecs_RAS, intercept)) vox_elecs = np.transpose(vox_elecs) sRAS_coords = np.matrix.dot(affine, vox_elecs) sRAS_coords = np.transpose(sRAS_coords) sRAS_coords = sRAS_coords[:, 0:3] # apply difference coord (lh_pial.asc - lh.pial) to shift all elecmatrix coords c_RAS = get_cRAS(fs_dir, subj) sRAS_coords = coords - c_RAS # shifted to correct back to lh.pial coords scipy.io.savemat('elecs_all_cleaned.mat', {'elecmatrix': sRAS_coords}) # run K means to find grid and strip clusters n_clusts = num_gridStrips # number of cluster to find = number of electrodes iters = 1000 init_clusts = n_clusts print "::: Performing K-means cluster to find %d grid-strip and noise clusters :::" % ( n_clusts) [clust_coords, clust_labels] = clust(sRAS_coords, n_clusts, iters, init_clusts) # save cluster results as individual arrays grid_strip_iter = np.linspace(0, num_gridStrips - 1, num_gridStrips) sRAS_coords_list = [list(b) for b in sRAS_coords] clust_labels_list = list(clust_labels) for i in grid_strip_iter: coords = [] for d in sRAS_coords_list: if clust_labels_list[sRAS_coords_list.index(d)] == int(i): coords.append(d) coords = np.array(coords) scipy.io.savemat('clust%s.mat' % (i), {'elecmatrix': coords})
def elecDetect(CT_dir, fs_dir,img, thresh_f, thresh_c, frac, num_gridStrips, n_elects): # run CT_electhresh print "::: Thresholding CT at %f stdv :::" %(thresh); CT_img = CT_dir + img; electhresh(CT_img,thresh_f, thresh_c); # run im_filt to gaussian smooth thresholded image fname = CT_dir + "thresh_" + img; print "::: Applying guassian smooth of 2.5mm to thresh-CT :::"; img_filt(fname); # compute hough transform to find electrode center coordinates mlab = matlab.MatlabCommand(); mlab.inputs.script = "addpath(genpath('/Volumes/Thunderbolt_Duo/Scripts/Matlab/SphericalHough')); \ img = readFileNifti('%s/smoothed_thresh_CT.nii');img = img.data(); \ fltr4LM_R = 3; obj_cint = 0.0; radrange = [0.1, 3]; multirad = 0.3; \ grdthres = 0.33;\ [center_img,sphere_img,sphcen2,sphrad]=SphericalHough(img,radrange,grdthres, \ fltr4LM_R, multirad, obj_cint); save('%s/elec_spheres.mat', 'sphere_img'); \ save('%s/elec_centers.mat', 'center_img'); \ save('%s/3d_hough_elect_coords.mat', 'sphcen2');" %(CT_dir, CT_dir , CT_dir, CT_dir); print "::: Applying 3D hough transform to smoothed thresh-CT :::"; out = mlab.run(); # run the hough and get errors if any ocur # save txt version of hough putputs coords = scipy.io.loadmat(CT_dir + '/'+ '3dHough_coords.mat').get('coords') np.savetxt('dirty_elecsAll.txt', coords, delimiter=' ', fmt='%-7.1f'); # run fsl FLIRT to compute CT-MRI registration flirt = FLIRT(); flirt.inputs.in_file = CT_dir + '/CT.nii'; flirt.inputs.reference = fs_dir + '/orig.nii'; flirt.inputs.cost_func = 'mutualinfo'; print "::: Computing corregistration between CT and MRI using FLIRT :::"; flirt.run(); # use fsl to calc voxel coords for elec centers in CT registered to orig # in RAS voxel coordinates using affine from FLIRT print "::: Applying FLIRT transformation to 3d Hough ouput :::"; orig_brain = fs_dir + '/orig.nii'; os.system('cat %s/dirty_elecsAll.txt | img2imgcoord -src %s/CT.nii -dest %s \ -xfm %s/CT_flirt.mat -vox > %s/dirty_elecsAll_RAS.txt' %(CT_dir, CT_dir, orig_brain, fs_dir, CT_dir)); # remove outliers caused by staples in the most superior portion of the img print "::: Removing outliers from detected electrode coordinates :::"; elecs_dirty_RAS = scipy.loadtxt('dirty_elecsAll_RAS.txt', skiprows=1); clean_elecs_RAS = []; for i in elecs_dirty_RAS: if i[1] > (0.3*np.max(elecs_dirty_RAS[:,2])): clean_elecs_RAS.append(i); clean_elecs_RAS = np.array(clean_elecs_RAS); # save surface RAS coords for cleaned coords # first apply vox2Ras affine for all fs orig volumes print "::: Applying freesurfer vox2RAS transformation :::"; affine = np.array([[ -1., 0., 0., 128.], [ 0., 0., 1., -128.], [ 0., -1., 0., 128.], [ 0., 0., 0., 1.]]); intercept = np.ones(len(clean_elecs_RAS)); vox_elecs = np.column_stack((clean_elecs_RAS,intercept)); vox_elecs = np.transpose(vox_elecs); sRAS_coords = np.matrix.dot(affine,vox_elecs); sRAS_coords = np.transpose(sRAS_coords); sRAS_coords = sRAS_coords[:,0:3]; # apply difference coord (lh_pial.asc - lh.pial) to shift all elecmatrix coords c_RAS = get_cRAS(fs_dir,subj); sRAS_coords = coords - c_RAS; # shifted to correct back to lh.pial coords scipy.io.savemat('elecs_all_cleaned.mat', {'elecmatrix':sRAS_coords}); # run K means to find grid and strip clusters n_clusts = num_gridStrips; # number of cluster to find = number of electrodes iters = 1000; init_clusts = n_clusts; print "::: Performing K-means cluster to find %d grid-strip and noise clusters :::" %(n_clusts); [clust_coords, clust_labels] = clust(sRAS_coords, n_clusts, iters, init_clusts); # save cluster results as individual arrays grid_strip_iter = np.linspace(0,num_gridStrips-1, num_gridStrips); sRAS_coords_list = [list(b) for b in sRAS_coords]; clust_labels_list = list(clust_labels); for i in grid_strip_iter: coords = []; for d in sRAS_coords_list: if clust_labels_list[sRAS_coords_list.index(d)] == int(i): coords.append(d); coords = np.array(coords); scipy.io.savemat('clust%s.mat' %(i), {'elecmatrix':coords});