def orientation_crop_check(src, axes=("0", "1", "2"), crop=False, dst=False): """Function to check orientation and cropping. MaxIPs along 0 axis. "crop": #use to crop volume, values below assume horizontal imaging and sagittal atlas False cerebellum: "[:,390:,:]" caudal midbrain: "[:,300:415,:]" midbrain: "[:,215:415,:]" thalamus: "[:,215:345,:]" anterior cortex: "[:,:250,:]" "dst": (optional) path+extension to save image Returns --------------- cropped image """ fig = plt.figure() plt.axis("off") ax = fig.add_subplot(1, 2, 1) if type(src) == str: src = tifffile.imread(src) plt.imshow(np.max(src, axis=0)) plt.title("Before reorientation") ax = fig.add_subplot(1, 2, 2) if crop: src = eval("src{}".format(crop)) src = fix_orientation(src, axes=axes) plt.imshow(np.max(src, axis=0)) plt.title("After reorientation") if dst: plt.savefig(dst, dpi=300) return src
def orientation_crop_check(src, axes = ('0','1','2'), crop = False, dst=False): '''Function to check orientation and cropping. MaxIPs along 0 axis. 'crop': #use to crop volume, values below assume horizontal imaging and sagittal atlas False cerebellum: '[:,390:,:]' caudal midbrain: '[:,300:415,:]' midbrain: '[:,215:415,:]' thalamus: '[:,215:345,:]' anterior cortex: '[:,:250,:]' 'dst': (optional) path+extension to save image Returns --------------- cropped image ''' fig = plt.figure() plt.axis('off') ax = fig.add_subplot(1,2,1) if type(src) == str: src = tifffile.imread(src) plt.imshow(np.max(src, axis=0)) plt.title('Before reorientation') ax = fig.add_subplot(1,2,2) if crop: src = eval('src{}'.format(crop)) src = fix_orientation(src, axes=axes) plt.imshow(np.max(src, axis=0)) plt.title('After reorientation') if dst: plt.savefig(dst, dpi=300) return src
def export_to_tiff(pth, dst, z_step=10, final_res=25): """ function to take downsized 2D planes and make them into a 3D isotropic volumes AKA downsize in Z and export to tif params: pth = lightsheet processed directory dst = secondary location to save iso volumes for registration z_step = z-steps used during imaging final_res = resolution of isotropic volume you want your atlas to be """ fld = os.path.join(pth, "downsized_for_atlas") print(os.path.basename(pth)) plns = [os.path.join(fld, xx) for xx in os.listdir(fld)] plns.sort() arr = np.zeros((len(plns), tifffile.imread(plns[0]).shape[0], tifffile.imread(plns[0]).shape[1])) for i, pln in enumerate(plns): arr[i] = tifffile.imread(pln) if i % 100 == 0: print(i) tifffile.imsave(os.path.join(pth, "downsized_for_atlas.tif"), arr.astype("uint16")) #remove folder with indiviudal tifs shutil.rmtree(fld) #make iso volume factor = z_step / final_res #e.g. downsizing z by 10um (z step) / 25 um (desired resolution) arr_dwnsz = zoom(arr, (factor, 1, 1), order=1) #horizontal image arr_dwnsz_sag = fix_orientation(arr_dwnsz, axes=("2", "1", "0")) tifffile.imsave(os.path.join(dst, os.path.basename(pth) + ".tif"), arr_dwnsz_sag.astype("uint16")) return
nzs = [ str(x) for xx in nonzeros for x in xx ] #this list has duplicates if two brains had the same voxel w label c = Counter(nzs) array = np.zeros_like(atlas) print('Collecting nonzero pixels for pooled image...') tick = 0 #generating pooled array where voxel value = total number of brains with that voxel as positive for k, v in c.items(): k = [int(xx) for xx in k.replace('(', '').replace(')', '').split(',')] array[k[0], k[1], k[2]] = int(v) tick += 1 if tick % 50000 == 0: print(' {}'.format(tick)) #reslice atlas = fix_orientation(atlas, axes=kwargs["reorientation"]) arr = fix_orientation(array, axes=kwargs["reorientation"]) my_cmap = eval('plt.cm.{}(np.arange(plt.cm.RdBu.N))'.format("plasma")) my_cmap[:1, :4] = 0.0 my_cmap = mpl.colors.ListedColormap(my_cmap) my_cmap.set_under('w') plt.figure() plt.imshow(np.max(atlas, axis=0), cmap='gray') plt.imshow(np.max(arr, axis=0), alpha=0.99, cmap=my_cmap) plt.colorbar() plt.axis('off') plt.savefig('/home/wanglab/Desktop/test/heatmap.pdf', dpi=300, transparent=True) plt.close()
# outpth = run_transformix(invol, outpth, transformfile) # # #fix the negative #'s around the site, and overwrite the tif onto the resampled version # #this was checked and is consistent w the transform # img = tifffile.imread(outpth+"/result.tif") # img[img < 0] = 0 # assert np.sum(img < 0) == 0 #make sure there are no negative values # tifffile.imsave(invol, img.astype("uint16")) # shutil.rmtree(outpth) #delete original transformed file #inspect injection sites for the brains i currently have imgs = [os.path.join(dct["dst"], xx + ".tif") for xx in brains] imgs.sort() #the y-axis cutoff for visualization sites = np.array([ fix_orientation(tifffile.imread(xx)[:, 450:, :], dct["reorientation"]) for xx in imgs ]) #check # for i,site in enumerate(sites): # tifffile.imsave("/home/wanglab/Desktop/{}.tif".format(brains[i]), np.max(site, axis = 0)) atl = fix_orientation( tifffile.imread(dct["atlas"])[:, 450:, :], dct["reorientation"]) #make counter nonzeros = [list(zip(*np.nonzero(site))) for site in sites] #<-for pooled image # #cell counts to csv # allen_id_table=pd.read_excel(dct["id_table"]).drop(columns = ["Unnamed: 0"]) # ann = fix_orientation(tifffile.imread(dct["annotation"])[:, 450:, :], dct["reorientation"]) # for i,site in enumerate(sites):
def pool_injections_inversetransform(**kwargs): """Function to pool several injection sites. Assumes that the basic registration AND inverse transform using elastix has been run. If not, runs inverse transform. Additions to analyze_injection.py and pool_injections_for_analysis(). Inputs ----------- kwargs: "inputlist": inputlist, #list of folders generated previously from software "channel": "01", "channel_type": "injch", "filter_kernel": (5,5,5), #gaussian blur in pixels (if registered to ABA then 1px likely is 25um) "threshold": 10 (int, value to use for thresholding, this value represents the number of stand devs above the mean of the gblurred image) "num_sites_to_keep": #int, number of injection sites to keep, useful if multiple distinct sites "injectionscale": 45000, #use to increase intensity of injection site visualizations generated - DOES NOT AFFECT DATA "imagescale": 2, #use to increase intensity of background site visualizations generated - DOES NOT AFFECT DATA "reorientation": ("2","0","1"), #use to change image orientation for visualization only "crop": #use to crop volume, values below assume horizontal imaging and sagittal atlas False cerebellum: "[:,390:,:]" caudal midbrain: "[:,300:415,:]" midbrain: "[:,215:415,:]" thalamus: "[:,215:345,:]" anterior cortex: "[:,:250,:]" "dst": "/home/wanglab/Downloads/test", #save location "save_individual": True, #optional to save individual images, useful to inspect brains, which you can then remove bad brains from list and rerun function "colormap": "plasma", "atlas": "/jukebox/LightSheetTransfer/atlas/sagittal_atlas_20um_iso.tif", #whole brain atlas Optional: ---------- "save_array": path to folder to save out numpy array per brain of binarized detected site "save_tif": saves out tif volume per brain of binarized detected site "dpi": dots per square inch to save at Returns ----------------count_threshold a pooled image consisting of max IP of reorientations provide in kwargs. a list of structures (csv file) with pixel counts, pooling across brains. if save individual will save individual images, useful for inspection and/or visualization """ inputlist = kwargs["inputlist"] dst = kwargs["dst"] makedir(dst) injscale = kwargs["injectionscale"] if "injectionscale" in kwargs else 1 imagescale = kwargs["imagescale"] if "imagescale" in kwargs else 1 axes = kwargs["reorientation"] if "reorientation" in kwargs else ("0", "1", "2") cmap = kwargs["colormap"] if "colormap" in kwargs else "plasma" save_array = kwargs["save_array"] if "save_array" in kwargs else False save_tif = kwargs["save_tif"] if "save_tif" in kwargs else False num_sites_to_keep = kwargs[ "num_sites_to_keep"] if "num_sites_to_keep" in kwargs else 1 ann = sitk.GetArrayFromImage(sitk.ReadImage(kwargs["annotation"])) #if kwargs["crop"]: (from original analyze injection function, no functionality here if points file exist) # ann = eval("ann{}".format(kwargs["crop"])) nonzeros = [] #not needed as mapped points from point_transformix used #id_table = kwargs["id_table"] if "id_table" in kwargs else "/jukebox/temp_wang/pisano/Python/lightsheet/supp_files/allen_id_table.xlsx" #allen_id_table = pd.read_excel(id_table) for i in range(len(inputlist)): #to iteratre through brains pth = inputlist[i] #path of each processed brain print(" loading:\n {}".format(pth)) dct = load_kwargs(pth) #load kwargs of brain as dct try: inj_vol = [xx for xx in dct["volumes"] if xx.ch_type == "injch" ][0] #set injection channel volume im = tifffile.imread(inj_vol.resampled_for_elastix_vol ) #load inj_vol as numpy array if kwargs["crop"]: im = eval("im{}".format(kwargs["crop"])) #; print im.shape #run find site function to segment inj site using non-registered resampled for elastix volume - pulled directly from tools.registration.register.py and tools.analysis.analyze_injection.py array = find_site(im, thresh=kwargs["threshold"], filter_kernel=kwargs["filter_kernel"], num_sites_to_keep=num_sites_to_keep) * injscale if save_array: np.save( os.path.join(dst, "{}".format(os.path.basename(pth)) + ".npy"), array.astype("uint16")) if save_tif: tifffile.imsave( os.path.join(dst, "{}".format(os.path.basename(pth)) + ".tif"), array.astype("uint16")) #optional "save_individual" if kwargs["save_individual"]: im = im * imagescale a = np.concatenate((np.max( im, axis=0), np.max(array.astype("uint16"), axis=0)), axis=1) b = np.concatenate((np.fliplr( np.rot90(np.max(fix_orientation(im, axes=axes), axis=0), k=3)), np.fliplr( np.rot90(np.max(fix_orientation( array.astype("uint16"), axes=axes), axis=0), k=3))), axis=1) plt.figure() plt.imshow(np.concatenate((b, a), axis=0), cmap=cmap, alpha=1) plt.axis("off") plt.savefig(os.path.join( dst, "{}".format(os.path.basename(pth)) + ".pdf"), dpi=300, transparent=True) plt.close() #find all nonzero pixels in resampled for elastix volume print(" finding nonzero pixels for voxel counts...\n") nz = np.nonzero(array) nonzeros.append(zip(*nz)) #<-for pooled image #find transform file inverse_fld = inj_vol.inverse_elastixfld inj_fld = listdirfull(inverse_fld, "inj")[0] atlas2reg2sig_fld = listdirfull(inj_fld, "atlas2reg2sig")[0] transformfile = os.path.join(atlas2reg2sig_fld, "reg2sig_TransformParameters.1.txt") if not os.path.exists(transformfile): #if transformed points exist print( "Transform file file not found. Running elastix inverse transform... \n" ) transformfile = make_inverse_transform( [xx for xx in dct["volumes"] if xx.ch_type == "injch"][0], cores=6, **dct) else: print("Inverse transform exists. \n") #apply resizing point transform txtflnm = point_transform_due_to_resizing(array, chtype="injch", **dct) #run transformix on points points_file = point_transformix(txtflnm, transformfile) tdf = transformed_pnts_to_allen(points_file, ann, ch_type="injch", point_or_index=None, **dct) #map to allen atlas if i == 0: df = tdf.copy() countcol = "count" if "count" in df.columns else "cell_count" df.drop([countcol], axis=1, inplace=True) df[os.path.basename(pth)] = tdf[countcol] except: print( "could not recover injection site, inspect manually for parameter dictionary errors or missing inj channel \n\n" ) #cell counts to csv df.to_csv(os.path.join(dst, "voxel_counts.csv")) print("\n\nCSV file of cell counts, saved as {}\n\n\n".format( os.path.join(dst, "voxel_counts.csv"))) #condense nonzero pixels nzs = [ str(x) for xx in nonzeros for x in xx ] #this list has duplicates if two brains had the same voxel w label c = Counter(nzs) arr = np.zeros(im.shape) print("Collecting nonzero pixels for pooled image...") tick = 0 #generating pooled array where voxel value = total number of brains with that voxel as positive for k, v in c.items(): k = [int(xx) for xx in k.replace("(", "").replace(")", "").split(",")] arr[k[0], k[1], k[2]] = int(v) tick += 1 if tick % 50000 == 0: print(" {}".format(tick)) #load atlas and generate final figure print("Generating final figure...") atlas = tifffile.imread(kwargs["atlas"]) #reads atlas print( "Zooming in atlas..." ) #necessary to have a representative heat map as these segmentations are done from the resized volume, diff dimensions than atlas zoomed_atlas = zoom( atlas, 1.3) #zooms atlas; different than original analyze_injection.py sites = fix_orientation(arr, axes=axes) #cropping if kwargs["crop"]: zoomed_atlas = eval("zoomed_atlas{}".format(kwargs["crop"])) zoomed_atlas = fix_orientation(zoomed_atlas, axes=axes) my_cmap = eval("plt.cm.{}(np.arange(plt.cm.RdBu.N))".format(cmap)) my_cmap[:1, :4] = 0.0 my_cmap = mpl.colors.ListedColormap(my_cmap) my_cmap.set_under("w") plt.figure() plt.imshow(np.max(zoomed_atlas, axis=0), cmap="gray") plt.imshow(np.max(sites, axis=0), alpha=0.99, cmap=my_cmap) plt.colorbar() plt.axis("off") dpi = int(kwargs["dpi"]) if "dpi" in kwargs else 300 plt.savefig(os.path.join(dst, "heatmap.pdf"), dpi=dpi, transparent=True) plt.close() print("Saved as {}".format(os.path.join(dst, "heatmap.pdf"))) return df
def pool_injections_for_analysis(**kwargs): """Function to pool several injection sites. Assumes that the basic registration using this software has been run. Inputs ----------- kwargs: "inputlist": inputlist, #list of folders generated previously from software "inputtype": "main_folder", "tiff" #specify the type of input. main_folder is the lightsheetpackage"s folder, tiff is the file to use for injection site segmentation "channel": "01", "channel_type": "injch", "filter_kernel": (3,3,3), #gaussian blur in pixels (if registered to ABA then 1px likely is 25um) "threshold": 3 (int, value to use for thresholding, this value represents the number of stand devs above the mean of the gblurred image) "num_sites_to_keep": int, number of injection sites to keep, useful if multiple distinct sites "injectionscale": 45000, #use to increase intensity of injection site visualizations generated - DOES NOT AFFECT DATA "imagescale": 2, #use to increase intensity of background site visualizations generated - DOES NOT AFFECT DATA "reorientation": ("2","0","1"), #use to change image orientation for visualization only "crop": #use to crop volume, values below assume horizontal imaging and sagittal atlas False cerebellum: "[:,390:,:]" caudal midbrain: "[:,300:415,:]" midbrain: "[:,215:415,:]" thalamus: "[:,215:345,:]" anterior cortex: "[:,:250,:]" "dst": "/home/wanglab/Downloads/test", #save location "save_individual": True, #optional to save individual images, useful to inspect brains, which you can then remove bad brains from list and rerun function "colormap": "plasma", "atlas": "/jukebox/wang/pisano/Python/allenatlas/average_template_25_sagittal_forDVscans.tif", "annotation":"/jukebox/wang/pisano/Python/allenatlas/annotation_25_ccf2015_forDVscans.nrrd", "id_table": "/jukebox/temp_wang/pisano/Python/lightsheet/supp_files/allen_id_table.xlsx", Optional: ---------- "save_array": path to folder to save out numpy array per brain of binarized detected site "save_tif": saves out tif volume per brain of binarized detected site "dpi": dots per square inch to save at "crop_atlas":(notfunctional) similiar to crop. Use when you would like to greatly restrain the cropping for injsite detection, but you want to display a larger area of overlay. this will 0 pad the injection sites to accomodate the difference in size. Note this MUST be LARGER THAN crop. Returns ----------------count_threshold a pooled image consisting of max IP of reorientations provide in kwargs. a list of structures (csv file) with pixel counts, pooling across brains. if save individual will save individual images, useful for inspection and/or visualization """ inputlist = kwargs["inputlist"] inputtype = kwargs["inputtype"] if "inputtype" in kwargs else "main_folder" dst = kwargs["dst"] makedir(dst) injscale = kwargs["injectionscale"] if "injectionscale" in kwargs else 1 imagescale = kwargs["imagescale"] if "imagescale" in kwargs else 1 axes = kwargs["reorientation"] if "reorientation" in kwargs else ("0", "1", "2") cmap = kwargs["colormap"] if "colormap" in kwargs else "plasma" id_table = kwargs[ "id_table"] if "id_table" in kwargs else "/jukebox/LightSheetTransfer/atlas/ls_id_table_w_voxelcounts.xlsx" save_array = kwargs["save_array"] if "save_array" in kwargs else False save_tif = kwargs["save_tif"] if "save_tif" in kwargs else False num_sites_to_keep = kwargs[ "num_sites_to_keep"] if "num_sites_to_keep" in kwargs else 1 nonzeros = [] ann = sitk.GetArrayFromImage(sitk.ReadImage(kwargs["annotation"])) if kwargs["crop"]: ann = eval("ann{}".format(kwargs["crop"])) allen_id_table = pd.read_excel(id_table) for i in range(len(inputlist)): pth = inputlist[i] print("\n\n_______\n{}".format(os.path.basename(pth))) #find the volume by loading the param dictionary generated using the light-sheet package if inputtype == "main_folder": dct = load_kwargs(pth) #print dct["AtlasFile"] try: vol = [ xx for xx in dct["volumes"] if xx.ch_type in kwargs["channel_type"] and xx.channel == kwargs["channel"] ][0] except: vol = [xx for xx in dct["volumes"] if xx.ch_type != "regch"][0] #risky for 3 channel images, but needed if param dict initially is mislabelled #done to account for different versions if os.path.exists(vol.ch_to_reg_to_atlas + "/result.1.tif"): impth = vol.ch_to_reg_to_atlas + "/result.1.tif" elif os.path.exists(vol.ch_to_reg_to_atlas ) and vol.ch_to_reg_to_atlas[-4:] == ".tif": impth = vol.ch_to_reg_to_atlas elif os.path.exists( os.path.dirname(vol.ch_to_reg_to_atlas) + "/result.1.tif"): impth = os.path.dirname( vol.ch_to_reg_to_atlas) + "/result.1.tif" elif os.path.exists( os.path.dirname(vol.ch_to_reg_to_atlas) + "/result.tif"): impth = os.path.dirname(vol.ch_to_reg_to_atlas) + "/result.tif" else: #"tiff", use the file given impth = pth print(" loading:\n {}".format(pth)) im = tifffile.imread(impth) if kwargs["crop"]: im = eval("im{}".format(kwargs["crop"])) #; print im.shape #segment arr = find_site(im, thresh=kwargs["threshold"], filter_kernel=kwargs["filter_kernel"], num_sites_to_keep=num_sites_to_keep) * injscale if save_array: np.save( os.path.join(save_array, "{}".format(os.path.basename(pth)) + ".npy"), arr.astype("float32")) if save_tif: tifffile.imsave( os.path.join(save_tif, "{}".format(os.path.basename(pth)) + ".tif"), arr.astype("float32")) #optional "save_individual" if kwargs["save_individual"]: im = im * imagescale a = np.concatenate( (np.max(im, axis=0), np.max(arr.astype("uint16"), axis=0)), axis=1) b = np.concatenate((np.fliplr( np.rot90(np.max(fix_orientation(im, axes=axes), axis=0), k=3)), np.fliplr( np.rot90(np.max(fix_orientation( arr.astype("uint16"), axes=axes), axis=0), k=3))), axis=1) plt.figure() plt.imshow(np.concatenate((b, a), axis=0), cmap=cmap, alpha=1) plt.axis("off") plt.savefig(os.path.join( dst, "{}".format(os.path.basename(pth)) + ".pdf"), dpi=300, transparent=True) plt.close() #cell counts to csv print(" finding nonzero pixels for voxel counts...") nz = np.nonzero(arr) nonzeros.append(list(zip(*nz))) #<-for pooled image pos = transformed_pnts_to_allen_helper_func( np.asarray(list(zip(*[nz[2], nz[1], nz[0]]))), ann) tdf = count_structure_lister(allen_id_table, *pos) if i == 0: df = tdf.copy() countcol = "count" if "count" in df.columns else "cell_count" df.drop([countcol], axis=1, inplace=True) df[os.path.basename(pth)] = tdf[countcol] df.to_csv(os.path.join(dst, "voxel_counts.csv"), index=False) print("\n\nCSV file of cell counts, saved as {}\n\n\n".format( os.path.join(dst, "voxel_counts.csv"))) #condense nonzero pixels nzs = [ str(x) for xx in nonzeros for x in xx ] #this list has duplicates if two brains had the same voxel w label c = Counter(nzs) array = np.zeros(im.shape) print("Collecting nonzero pixels for pooled image...") tick = 0 #generating pooled array where voxel value = total number of brains with that voxel as positive for k, v in c.items(): k = [int(xx) for xx in k.replace("(", "").replace(")", "").split(",")] array[k[0], k[1], k[2]] = int(v) tick += 1 if tick % 50000 == 0: print(" {}".format(tick)) #load atlas and generate final figure print("Generating final figure...") atlas = tifffile.imread(kwargs["atlas"]) arr = fix_orientation(array, axes=axes) #cropping if kwargs["crop"]: atlas = eval("atlas{}".format(kwargs["crop"])) atlas = fix_orientation(atlas, axes=axes) my_cmap = eval("plt.cm.{}(np.arange(plt.cm.RdBu.N))".format(cmap)) my_cmap[:1, :4] = 0.0 my_cmap = mpl.colors.ListedColormap(my_cmap) my_cmap.set_under("w") plt.figure() plt.imshow(np.max(atlas, axis=0), cmap="gray") plt.imshow(np.max(arr, axis=0), alpha=0.99, cmap=my_cmap) plt.colorbar() plt.axis("off") dpi = int(kwargs["dpi"]) if "dpi" in kwargs else 300 plt.savefig(os.path.join(dst, "heatmap.pdf"), dpi=dpi, transparent=True) plt.close() print("Saved as {}".format(os.path.join(dst, "heatmap.pdf"))) return df
xx for xx in os.listdir(os.path.join(brain, "full_sizedatafld")) if "647" in xx ][0]) ydim, xdim = tifffile.imread( os.path.join(fszfld, os.listdir(fszfld)[0])).shape zdim = len(os.listdir(fszfld)) cell_map = np.zeros((zdim, ydim, xdim), dtype="bool") for x, y, z in arr: try: cell_map[z, y, x] = True except Exception as e: print(e) #flip the z axis in cells cells_flip = fix_orientation(cell_map, axes=("0", "1", "-2")) arr_flip = np.where(cells_flip == True) #convert to x,y,z 3d array arr_flip = np.array([ np.array([arr_flip[2][i], arr_flip[1][i], arr_flip[0][i]]) for i in range(len(arr_flip[0])) ]) #save out/overwrite np.save(cells_pth, arr_flip) #re-run step 6 to threshold and transform points params = load_kwargs(brain) output_analysis(threshold=(750, 8000), row=(2, 2), check_cell_detection=False, **params)
"Auditory areas", "Ectorhinal area", "Perirhinal area"] primary_iid = [] for soi in sois: progeny = [soi] get_progeny(ontology_dict, soi, progeny) iids = [df.loc[df.name == progen, "id"].values[0] for progen in progeny] for iid in iids[1:]: z,y,x = np.where(ann == iid) ann[z,y,x] = iids[0] primary_iid.append(iids[0]) #reslice coronal ann = fix_orientation(ann, ("2","0","1")) ap_dim = [] for iid in primary_iid: ann_mask = ann.copy() ann_mask[ann_mask != iid] = 0 ap, dv, ml = center_of_mass(ann_mask) ap_dim.append(ap) ap_dim = np.array(ap_dim) ap_dim_sort = np.sort(ap_dim) sois = np.array(sois)[np.argsort(ap_dim)] #now use this ordering so it is truly ordered by A-P dimension #%% #THALAMUS brains = ["20170410_tp_bl6_lob6a_ml_repro_01", "20160823_tp_bl6_cri_500r_02", "20180417_jg59_bl6_cri_03",
"annotation": "/jukebox/LightSheetTransfer/atlas/allen_atlas/annotation_template_25_sagittal_forDVscans.tif", "id_table": "/jukebox/LightSheetTransfer/atlas/allen_atlas/allen_id_table_w_voxel_counts.xlsx" } #segment injection site # for brain in inputlist: # vol = os.path.join(os.path.join(src, brain), "transformix_on_inj/result.tif") # arr = find_site(vol, dct["threshold"], dct["filter_kernel"]) # tifffile.imsave(os.path.join(dct["dst"], os.path.basename(brain)+".tif"), # arr.astype("uint16")*65535) #save to inj site destination #inspect injection sites for the brains i currently have imgs = [os.path.join(dct["dst"], xx+".tif") for xx in brains]; imgs.sort() #the y-axis cutoff for visualization sites = np.array([fix_orientation(tifffile.imread(xx)[:, 420:, :], dct["reorientation"]) for xx in imgs]) atl = fix_orientation(tifffile.imread(dct["atlas"])[:, 420:, :], dct["reorientation"]) #cut at 423 for HSV?? #make counter nonzeros = [list(zip(*np.nonzero(site))) for site in sites] #<-for pooled image #condense nonzero pixels nzs = [str(x) for xx in nonzeros for x in xx] #this list has duplicates if two brains had the same voxel w label c = Counter(nzs) array = np.zeros(atl.shape) print("Collecting nonzero pixels for pooled image...") tick = 0 #generating pooled array where voxel value = total number of brains with that voxel as positive for k,v in c.items(): k = [int(xx) for xx in k.replace("(","").replace(")","").split(",")] array[k[0], k[1], k[2]] = int(v) tick+=1
def pool_injections_for_analysis(**kwargs): '''Function to pool several injection sites. Assumes that the basic registration using this software has been run. Inputs ----------- kwargs: 'inputlist': inputlist, #list of folders generated previously from software 'channel': '01', 'channel_type': 'injch', 'filter_kernel': (3,3,3), #gaussian blur in pixels (if registered to ABA then 1px likely is 25um) 'threshold': 3 (int, value to use for thresholding, this value represents the number of stand devs above the mean of the gblurred image) 'num_sites_to_keep': int, number of injection sites to keep, useful if multiple distinct sites 'injectionscale': 45000, #use to increase intensity of injection site visualizations generated - DOES NOT AFFECT DATA 'imagescale': 2, #use to increase intensity of background site visualizations generated - DOES NOT AFFECT DATA 'reorientation': ('2','0','1'), #use to change image orientation for visualization only 'crop': #use to crop volume, values below assume horizontal imaging and sagittal atlas False cerebellum: '[:,390:,:]' caudal midbrain: '[:,300:415,:]' midbrain: '[:,215:415,:]' thalamus: '[:,215:345,:]' anterior cortex: '[:,:250,:]' 'dst': '/home/wanglab/Downloads/test', #save location 'save_individual': True, #optional to save individual images, useful to inspect brains, which you can then remove bad brains from list and rerun function 'colormap': 'plasma', 'atlas': '/jukebox/wang/pisano/Python/allenatlas/average_template_25_sagittal_forDVscans.tif', 'annotation':'/jukebox/wang/pisano/Python/allenatlas/annotation_25_ccf2015_forDVscans.nrrd', 'id_table': '/jukebox/temp_wang/pisano/Python/lightsheet/supp_files/allen_id_table.xlsx', Optional: ---------- 'save_array': path to folder to save out numpy array per brain of binarized detected site 'save_tif': saves out tif volume per brain of binarized detected site 'dpi': dots per square inch to save at 'crop_atlas':(notfunctional) similiar to crop. Use when you would like to greatly restrain the cropping for injsite detection, but you want to display a larger area of overlay. this will 0 pad the injection sites to accomodate the difference in size. Note this MUST be LARGER THAN crop. Returns ----------------count_threshold a pooled image consisting of max IP of reorientations provide in kwargs. a list of structures (csv file) with pixel counts, pooling across brains. if save individual will save individual images, useful for inspection and/or visualization ''' inputlist = kwargs['inputlist'] dst = kwargs['dst'] makedir(dst) injscale = kwargs['injectionscale'] if 'injectionscale' in kwargs else 1 imagescale = kwargs['imagescale'] if 'imagescale' in kwargs else 1 axes = kwargs['reorientation'] if 'reorientation' in kwargs else ('0', '1', '2') cmap = kwargs['colormap'] if 'colormap' in kwargs else 'plasma' id_table = kwargs[ 'id_table'] if 'id_table' in kwargs else '/jukebox/temp_wang/pisano/Python/lightsheet/supp_files/allen_id_table.xlsx' count_threshold = kwargs[ 'count_threshold'] if 'count_threshold' in kwargs else 10 save_array = kwargs['save_array'] if 'save_array' in kwargs else False save_tif = kwargs['save_tif'] if 'save_tif' in kwargs else False num_sites_to_keep = kwargs[ 'num_sites_to_keep'] if 'num_sites_to_keep' in kwargs else 1 nonzeros = [] ann = sitk.GetArrayFromImage(sitk.ReadImage(kwargs['annotation'])) if kwargs['crop']: ann = eval('ann{}'.format(kwargs['crop'])) allen_id_table = pd.read_excel(id_table) for i in range(len(inputlist)): pth = inputlist[i] print('\n\n_______\n{}'.format(os.path.basename(pth))) dct = load_kwargs(pth) #print dct['AtlasFile'] try: vol = [ xx for xx in dct['volumes'] if xx.ch_type == kwargs['channel_type'] and xx.channel == kwargs['channel'] ][0] except: vol = [ xx for xx in dct['volumes'] if xx.ch_type == "cellch" and xx.channel == kwargs['channel'] ][0] #done to account for different versions if os.path.exists(vol.ch_to_reg_to_atlas + '/result.1.tif'): impth = vol.ch_to_reg_to_atlas + '/result.1.tif' elif os.path.exists(vol.ch_to_reg_to_atlas ) and vol.ch_to_reg_to_atlas[-4:] == '.tif': impth = vol.ch_to_reg_to_atlas elif os.path.exists( os.path.dirname(vol.ch_to_reg_to_atlas) + '/result.1.tif'): impth = os.path.dirname(vol.ch_to_reg_to_atlas) + '/result.1.tif' elif os.path.exists( os.path.dirname(vol.ch_to_reg_to_atlas) + '/result.tif'): impth = os.path.dirname(vol.ch_to_reg_to_atlas) + '/result.tif' print(' loading:\n {}'.format(pth)) im = tifffile.imread(impth) if kwargs['crop']: im = eval('im{}'.format(kwargs['crop'])) #; print im.shape #segment arr = find_site(im, thresh=kwargs['threshold'], filter_kernel=kwargs['filter_kernel'], num_sites_to_keep=num_sites_to_keep) * injscale if save_array: np.save( os.path.join(dst, '{}'.format(os.path.basename(pth)) + '.npy'), arr.astype('float32')) if save_tif: tifffile.imsave( os.path.join(dst, '{}'.format(os.path.basename(pth)) + '.tif'), arr.astype('float32')) #optional 'save_individual' if kwargs['save_individual']: im = im * imagescale a = np.concatenate( (np.max(im, axis=0), np.max(arr.astype('uint16'), axis=0)), axis=1) b = np.concatenate((np.fliplr( np.rot90(np.max(fix_orientation(im, axes=axes), axis=0), k=3)), np.fliplr( np.rot90(np.max(fix_orientation( arr.astype('uint16'), axes=axes), axis=0), k=3))), axis=1) plt.figure() plt.imshow(np.concatenate((b, a), axis=0), cmap=cmap, alpha=1) plt.axis('off') plt.savefig(os.path.join( dst, '{}'.format(os.path.basename(pth)) + '.pdf'), dpi=300, transparent=True) plt.close() #cell counts to csv print(' finding nonzero pixels for voxel counts...') nz = np.nonzero(arr) nonzeros.append(zip(*nz)) #<-for pooled image pos = transformed_pnts_to_allen_helper_func( np.asarray(zip(*[nz[2], nz[1], nz[0]])), ann) tdf = count_structure_lister(allen_id_table, *pos) if i == 0: df = tdf.copy() countcol = 'count' if 'count' in df.columns else 'cell_count' df.drop([countcol], axis=1, inplace=True) df[os.path.basename(pth)] = tdf[countcol] df.to_csv(os.path.join(dst, 'voxel_counts.csv')) print('\n\nCSV file of cell counts, saved as {}\n\n\n'.format( os.path.join(dst, 'voxel_counts.csv'))) #condense nonzero pixels nzs = [ str(x) for xx in nonzeros for x in xx ] #this list has duplicates if two brains had the same voxel w label c = Counter(nzs) array = np.zeros(im.shape) print('Collecting nonzero pixels for pooled image...') tick = 0 #generating pooled array where voxel value = total number of brains with that voxel as positive for k, v in c.iteritems(): k = [int(xx) for xx in k.replace('(', '').replace(')', '').split(',')] array[k[0], k[1], k[2]] = int(v) tick += 1 if tick % 50000 == 0: print(' {}'.format(tick)) #load atlas and generate final figure print('Generating final figure...') atlas = tifffile.imread(kwargs['atlas']) arr = fix_orientation(array, axes=axes) #cropping #if 'crop_atlas' not in kwargs: if kwargs['crop']: atlas = eval('atlas{}'.format(kwargs['crop'])) atlas = fix_orientation(atlas, axes=axes) #elif 'crop_atlas' in kwargs: #if kwargs['crop_atlas']: atlas = eval('atlas{}'.format(kwargs['crop_atlas'])) #atlas = fix_orientation(atlas, axes=axes) #accomodate for size difference #d0,d1,d2 = [(x-y)/2 for x,y in zip(atlas.shape, arr.shape)] #arr = np.pad(arr,((d0,d0),(d1,d1),(d2,d2)), mode='constant') ##allows for a single pixel shift - if needed #d0,d1,d2 = [(x-y) for x,y in zip(atlas.shape, arr.shape)] #arr = np.pad(arr,((d0,0),(d1,0),(d2,0)), mode='constant') my_cmap = eval('plt.cm.{}(np.arange(plt.cm.RdBu.N))'.format(cmap)) my_cmap[:1, :4] = 0.0 my_cmap = mpl.colors.ListedColormap(my_cmap) my_cmap.set_under('w') plt.figure() plt.imshow(np.max(atlas, axis=0), cmap='gray') plt.imshow(np.max(arr, axis=0), alpha=0.99, cmap=my_cmap) plt.colorbar() plt.axis('off') dpi = int(kwargs['dpi']) if 'dpi' in kwargs else 300 plt.savefig(os.path.join(dst, 'heatmap.pdf'), dpi=dpi, transparent=True) plt.close() print('Saved as {}'.format(os.path.join(dst, 'heatmap.pdf'))) return df
#find only cerbellum cb_roi = np.zeros_like(ann_raw) for nm, iid in iids.items(): z, y, x = np.where(ann_raw == iid) #find where structure is represented cb_roi[z, y, x] = 1 #make a mask of structure in annotation space cb_roi = cb_roi.astype(bool) #add mask of structure to dictionary #mask all the regions that are not cerebellum in the segmentation for site in sites: site[~cb_roi] = 0 #%% #visualization atl = fix_orientation(tifffile.imread(atl_pth)[:, 450:, :], ("2", "0", "1")) #masked_sites = np.array([fix_orientation(site[:, 450:, :], ("2", "0", "1")) for site in sites]) for i, site in enumerate(sites): masked_site = fix_orientation(site[:, 450:, :], ("2", "0", "1")) kwargs = load_kwargs(os.path.join(data, os.path.basename(imgs[i])[:-15])) cellvol = [ vol for vol in kwargs["volumes"] if vol.ch_type == "cellch" or vol.ch_type == "injch" ][0] regvol = fix_orientation( tifffile.imread(cellvol.ch_to_reg_to_atlas)[:, 450:, :], ("2", "0", "1")) tifffile.imsave( os.path.join(dst, os.path.basename(imgs[i])[:-15] + "maxproj_.tif"),
rois = np.array([[int(yy) for yy in xx[0].replace(".roi", "").split("-")] for xx in read_roi_zip(roipth, include_roi_name=True)]) pnts = np.array([[xx[0] - 1, xx[1], xx[2]] for xx in rois]) #correct for fijis 1-based z numbering pnts_sag = np.array([[xx[2], xx[0], xx[1]] for xx in pnts]) kwargs = load_kwargs(brain) impth = [ vol for vol in kwargs["volumes"] if vol.ch_type == "injch" or vol.ch_type == "cellch" ][0].ch_to_reg_to_atlas im = tifffile.imread(impth) imcor = fix_orientation(im, ("2", "0", "1")) #points clicked in coronal vol track = np.zeros_like(imcor) size = (1, 20, 1) #size of dilatation in zyx otsu_factor = 1 for pnt in pnts: vol = np.copy(imcor[np.max((pnt[0] - size[0], 0)):pnt[0] + size[0], np.max((pnt[1] - size[1], 0)):pnt[1] + size[1], np.max((pnt[2] - size[2], 0)):pnt[2] + size[2]]) * 1.0 v = filters.threshold_otsu(vol) / float(otsu_factor) vol[vol < v] = 0 vol[vol >= v] = 1 nvol = np.maximum( track[np.max((pnt[0] - size[0], 0)):pnt[0] + size[0], np.max((pnt[1] - size[1], 0)):pnt[1] + size[1],
def pool_injections_for_analysis(**kwargs): inputlist = kwargs['inputlist'] dst = kwargs['dst']; makedir(dst) injscale = kwargs['injectionscale'] if 'injectionscale' in kwargs else 1 imagescale = kwargs['imagescale'] if 'imagescale' in kwargs else 1 axes = kwargs['reorientation'] if 'reorientation' in kwargs else ('0','1','2') cmap = kwargs['colormap'] if 'colormap' in kwargs else 'plasma' id_table = kwargs['id_table'] if 'id_table' in kwargs else '/jukebox/temp_wang/pisano/Python/lightsheet/supp_files/allen_id_table.xlsx' save_tif = kwargs['save_tif'] if 'save_tif' in kwargs else False num_sites_to_keep = kwargs['num_sites_to_keep'] if 'num_sites_to_keep' in kwargs else 1 nonzeros = [] ann = sitk.GetArrayFromImage(sitk.ReadImage(kwargs['annotation'])) if kwargs['crop']: ann = eval('ann{}'.format(kwargs['crop'])) allen_id_table=pd.read_excel(id_table) for i in range(len(inputlist)): impth = inputlist[i] animal = os.path.basename(os.path.dirname(os.path.dirname(os.path.dirname(impth)))) print('\n\n_______\n{}'.format(animal)) print(' loading:\n {}'.format(animal)) im = tifffile.imread(impth) if kwargs['crop']: im = eval('im{}'.format(kwargs['crop']))#; print im.shape #reorient to coronal? #segment arr = find_site(im, thresh=kwargs['threshold'], filter_kernel=kwargs['filter_kernel'], num_sites_to_keep=num_sites_to_keep)*injscale if save_tif: tifffile.imsave(os.path.join(dst,'{}'.format(os.path.dirname(impth))+'_inj.tif'), arr.astype('float32')) #optional 'save_individual' if kwargs['save_individual']: im = im*imagescale a=np.concatenate((np.max(im, axis=0), np.max(arr.astype('uint16'), axis=0)), axis=1) b=np.concatenate((np.fliplr(np.rot90(np.max(fix_orientation(im, axes=axes), axis=0),k=3)), np.fliplr(np.rot90(np.max(fix_orientation(arr.astype('uint16'), axes=axes), axis=0),k=3))), axis=1) plt.figure() plt.imshow(np.concatenate((b,a), axis=0), cmap=cmap, alpha=1); plt.axis('off') plt.savefig(os.path.join(dst,'{}'.format(animal)+'.pdf'), dpi=300, transparent=True) plt.close() #cell counts to csv print(' finding nonzero pixels for voxel counts...') nz = np.nonzero(arr) nonzeros.append(zip(*nz)) #<-for pooled image pos = transformed_pnts_to_allen_helper_func(np.asarray(zip(*[nz[2], nz[1], nz[0]])), ann) tdf = count_structure_lister(allen_id_table, *pos) if i == 0: df = tdf.copy() countcol = 'count' if 'count' in df.columns else 'cell_count' df.drop([countcol], axis=1, inplace=True) df[animal] = tdf[countcol] df.to_csv(os.path.join(dst,'voxel_counts.csv')) print('\n\nCSV file of cell counts, saved as {}\n\n\n'.format(os.path.join(dst,'voxel_counts.csv'))) #condense nonzero pixels nzs = [str(x) for xx in nonzeros for x in xx] #this list has duplicates if two brains had the same voxel w label c = Counter(nzs) array = np.zeros(im.shape) print('Collecting nonzero pixels for pooled image...') tick = 0 #generating pooled array where voxel value = total number of brains with that voxel as positive for k,v in c.iteritems(): k = [int(xx) for xx in k.replace('(','').replace(')','').split(',')] array[k[0], k[1], k[2]] = int(v) tick+=1 if tick % 50000 == 0: print(' {}'.format(tick)) #load atlas and generate final figure print('Generating final figure...') atlas = tifffile.imread(kwargs['atlas']) arr = fix_orientation(array, axes=axes) #cropping #if 'crop_atlas' not in kwargs: if kwargs['crop']: atlas = eval('atlas{}'.format(kwargs['crop'])) atlas = fix_orientation(atlas, axes=axes) my_cmap = eval('plt.cm.{}(np.arange(plt.cm.RdBu.N))'.format(cmap)) my_cmap[:1,:4] = 0.0 my_cmap = mpl.colors.ListedColormap(my_cmap) my_cmap.set_under('w') plt.figure() plt.imshow(np.max(atlas, axis=0), cmap='gray') plt.imshow(np.max(arr, axis=0), alpha=0.99, cmap=my_cmap); plt.colorbar(); plt.axis('off') dpi = int(kwargs['dpi']) if 'dpi' in kwargs else 300 plt.savefig(os.path.join(dst,'heatmap.pdf'), dpi=dpi, transparent=True); plt.close() print('Saved as {}'.format(os.path.join(dst,'heatmap.pdf'))) return df
from skimage.external import tifffile import SimpleITK as sitk, numpy as np, matplotlib.pyplot as plt vol = tifffile.imread('/home/wanglab/wang/pisano/tracing_output/cfos/201701_cfos/clearmap_analysis/bkgd5_cell105_analysis/stim_vs_ctl/pvalues.tif') ann = tifffile.imread('/home/wanglab/LightSheetTransfer/atlas/allen_atlas/annotation_template_25_sagittal_forDVscans.tif') atl = tifffile.imread('/home/wanglab/LightSheetTransfer/atlas/allen_atlas/average_template_25_sagittal_forDVscans.tif') import os import scipy import scipy.stats os.chdir('/home/wanglab/wang/pisano/Python/lightsheet') from tools.imageprocessing.orientation import fix_orientation from tools.utils.io import * #pvol = fix_orientation(vol[:,:,:,1], axes=('2','0','1')) #nvol = fix_orientation(vol[:,:,:,0], axes=('2','0','1')) pvol = vol[:,:,:,1] nvol = vol[:,:,:,0] atl = fix_orientation(atl, axes=('2','0','1')) ann = fix_orientation(ann, axes=('2','0','1')) assert vol.shape[:-1] == ann.shape print ann.shape print nvol.shape assert pvol.shape == ann.shape #anterior is 0 index; 100-250 is good in z from tools.registration.allen_structure_json_to_pandas import annotation_value_to_structure, isolate_structures_return_list, consolidate_parents_structures, annotation_location_to_structure allen_id_table = '/home/wanglab/wang/pisano/Python/lightsheet/supp_files/allen_id_table.xlsx' #ann = '/home/wanglab/wang/pisano/Python/allenatlas/annotation_25_ccf2015.nrrd' #find all pixel IDs present in structures #pix_values=list(np.unique(ann[100:175].ravel().astype('float64')))
arr_fullsz = np.zeros((len(imgs), im.shape[0], im.shape[1])) print(arr_fullsz.shape) print(arr.shape) ################################################################################################################################################################# arr_fullsz[:, 1700:, :] = arr #plt.imshow(arr_fullsz[300]) zf, yf, xf = 1, (1 / 3), (1 / 3) dim = (int(im.shape[1] * xf), int(im.shape[0] * yf)) arr_resz = np.array([cv2.resize(img, dim) for img in arr_fullsz]) print(arr_resz.shape) #to sagittal arr_resz_sag = fix_orientation(arr_resz, axes=("2", "1", "0")) #now downsample again resmpl = tif.imread(cellvol.resampled_for_elastix_vol) zrsm, yrsm, xrsm = resmpl.shape zresz, yresz, xresz = arr_resz_sag.shape arr_resmpl_sag = zoom(arr_resz_sag, (zrsm / zresz, yrsm / yresz, xrsm / xresz), order=1) resz_dst = os.path.join(dst, "downsized_segmentations") makedir(resz_dst) tif.imsave(os.path.join(resz_dst, "%s.tif" % os.path.basename(brain)),
def pool_injections_for_analysis(**kwargs): """ Parameters ---------- **kwargs : parameter dictionary consisting of 'inputlist' --> list of strings; path to image to be segmented 'filter_kernel' --> tuple; 3D kernel used for segmentation in (https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.gaussian_filter.html) 'threshold' --> int; threshold for making final segmentation volume in find_site() function 'num_sites_to_keep' --> int; number of segmentation sites to keep, depends on injection sites in volume 'injectionscale' --> int; used for visualization, typically can be 45000 'imagescale' --> int; used for visualization, typically can be 3 'reorientation' --> tuple of strings; reorientation for visualization, sagittal to coronal=('2','0','1'), sagittal to horizontal=('2','1','0') default maintains current orientation 'crop' --> string; if volume needs to be cropped before segmentation; for cerebellum, you can typically crop in y as such = '[:, 450, :]' default does not crop 'crop_atlas' --> string; if atlas needs to be cropped the same way for final 2D visualization default does not crop 'dst' --> destination directory 'save_individual' --> boolean; if you want to save 2D image of segmentation for each brain 'save_tif' --> boolean; if you want to save the segmented volume for each brain for later use 'colormap' --> string; matplotlib colormap used for visualization, default is plasma 'atlas' --> string; path to atlas file the volumes are registered to 'annotation' --> string; path to annotation file corresponding to the atlas 'id_table' --> annotation look-up table corresponding to the annotation volume default is '/jukebox/LightSheetTransfer/atlas/allen_atlas/allen_id_table.xlsx' Returns ------- df : pandas dataframe pandas dataframe of brain (column) x structures (row) of injection voxels detected """ inputlist = kwargs["inputlist"] dst = kwargs["dst"] makedir(dst) injscale = kwargs["injectionscale"] if "injectionscale" in kwargs else 1 imagescale = kwargs["imagescale"] if "imagescale" in kwargs else 1 axes = kwargs["reorientation"] if "reorientation" in kwargs else ("0", "1", "2") cmap = kwargs["colormap"] if "colormap" in kwargs else "plasma" id_table = kwargs[ "id_table"] if "id_table" in kwargs else "/jukebox/LightSheetTransfer/atlas/allen_atlas/allen_id_table.xlsx" save_tif = kwargs["save_tif"] if "save_tif" in kwargs else False num_sites_to_keep = kwargs[ "num_sites_to_keep"] if "num_sites_to_keep" in kwargs else 1 nonzeros = [] ann = sitk.GetArrayFromImage(sitk.ReadImage(kwargs["annotation"])) if kwargs["crop"]: ann = eval("ann{}".format(kwargs["crop"])) allen_id_table = pd.read_excel(id_table) for i in range(len(inputlist)): impth = inputlist[i] animal = os.path.basename( os.path.dirname(os.path.dirname(os.path.dirname(impth)))) print("\n\n_______\n{}".format(animal)) print(" loading:\n {}".format(animal)) im = tifffile.imread(impth) if kwargs["crop"]: im = eval("im{}".format(kwargs["crop"])) #; print im.shape #segment arr = find_site(im, thresh=kwargs["threshold"], filter_kernel=kwargs["filter_kernel"], num_sites_to_keep=num_sites_to_keep) * injscale if save_tif: tifffile.imsave( os.path.join(dst, "{}".format(animal) + "_inj.tif"), arr.astype("float32")) #optional "save_individual" if kwargs["save_individual"]: im = im * imagescale a = np.concatenate( (np.max(im, axis=0), np.max(arr.astype("uint16"), axis=0)), axis=1) b = np.concatenate((np.fliplr( np.rot90(np.max(fix_orientation(im, axes=axes), axis=0), k=3)), np.fliplr( np.rot90(np.max(fix_orientation( arr.astype("uint16"), axes=axes), axis=0), k=3))), axis=1) plt.figure() plt.imshow(np.concatenate((b, a), axis=0), cmap=cmap, alpha=1) plt.axis("off") plt.savefig(os.path.join(dst, "{}".format(animal) + ".pdf"), dpi=300, transparent=True) plt.close() #cell counts to csv print(" finding nonzero pixels for voxel counts...") nz = np.nonzero(arr) nonzeros.append(list(zip(*nz))) #<-for pooled image pos = transformed_pnts_to_allen_helper_func( np.asarray(list(zip(*[nz[2], nz[1], nz[0]]))), ann) tdf = count_structure_lister(allen_id_table, *pos) if i == 0: df = tdf.copy() countcol = "count" if "count" in df.columns else "cell_count" df.drop([countcol], axis=1, inplace=True) df[animal] = tdf[countcol] df.to_csv(os.path.join(dst, "voxel_counts.csv")) print("\n\nCSV file of cell counts, saved as {}\n\n\n".format( os.path.join(dst, "voxel_counts.csv"))) #load atlas and generate final figure print("Generating final figure...") atlas = tifffile.imread(kwargs["atlas"]) #cropping #if "crop_atlas" not in kwargs: if kwargs["crop_atlas"]: atlas = eval("atlas{}".format(kwargs["crop_atlas"])) #condense nonzero pixels nzs = [ str(x) for xx in nonzeros for x in xx ] #this list has duplicates if two brains had the same voxel w label c = Counter(nzs) array = np.zeros_like(atlas) print("Collecting nonzero pixels for pooled image...") tick = 0 #generating pooled array where voxel value = total number of brains with that voxel as positive for k, v in c.items(): k = [int(xx) for xx in k.replace("(", "").replace(")", "").split(",")] array[k[0], k[1], k[2]] = int(v) tick += 1 if tick % 50000 == 0: print(" {}".format(tick)) #reslice atlas = fix_orientation(atlas, axes=axes) arr = fix_orientation(array, axes=axes) my_cmap = eval("plt.cm.{}(np.arange(plt.cm.RdBu.N))".format(cmap)) my_cmap[:1, :4] = 0.0 my_cmap = mpl.colors.ListedColormap(my_cmap) my_cmap.set_under("w") plt.figure() plt.imshow(np.max(atlas, axis=0), cmap="gray") plt.imshow(np.max(arr, axis=0), alpha=0.99, cmap=my_cmap) cb = plt.colorbar() cb.set_label("# Brains expressing", fontsize="small", labelpad=3) cb.ax.tick_params(labelsize="x-small") cb.ax.set_visible(True) plt.axis("off") plt.savefig(os.path.join(dst, "heatmap.pdf"), dpi=300, transparent=True) plt.close() print("Saved as {}".format(os.path.join(dst, "heatmap.pdf"))) return df