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
Exemple #2
0
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
Exemple #3
0
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()
Exemple #5
0
    #        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)
Exemple #9
0
            "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
Exemple #12
0
#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"),
Exemple #13
0
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],
Exemple #14
0
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
Exemple #15
0
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