Skip to content
Snippets Groups Projects
Commit 7ef6f0a4 authored by polarbean's avatar polarbean
Browse files

add support for brainglobe atlases

parent 7cb5f75d
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,8 @@ from .counting_and_load import label_points, pixel_count_per_region ...@@ -5,6 +5,8 @@ from .counting_and_load import label_points, pixel_count_per_region
import json import json
import pandas as pd import pandas as pd
from datetime import datetime from datetime import datetime
import numpy as np
import brainglobe_atlasapi
import os import os
...@@ -19,8 +21,8 @@ class PyNutil: ...@@ -19,8 +21,8 @@ class PyNutil:
The path to the alignment JSON file. The path to the alignment JSON file.
colour : int colour : int
The colour of the segmentation data to extract. The colour of the segmentation data to extract.
volume_path : str atlas_name : str
The name of the atlas volume to use. The name of the atlas volume to use. Uses BrainGlobe API name
settings_file : str, optional settings_file : str, optional
The path to a JSON file containing the above parameters. The path to a JSON file containing the above parameters.
...@@ -76,7 +78,8 @@ class PyNutil: ...@@ -76,7 +78,8 @@ class PyNutil:
segmentation_folder=None, segmentation_folder=None,
alignment_json=None, alignment_json=None,
colour=None, colour=None,
volume_path=None, atlas_name=None,
atlas_resolution_micron=None,
settings_file=None, settings_file=None,
) -> None: ) -> None:
self.config, self.metadata_path = metadata_loader.load_config() self.config, self.metadata_path = metadata_loader.load_config()
...@@ -87,28 +90,29 @@ class PyNutil: ...@@ -87,28 +90,29 @@ class PyNutil:
segmentation_folder = settings["segmentation_folder"] segmentation_folder = settings["segmentation_folder"]
alignment_json = settings["alignment_json"] alignment_json = settings["alignment_json"]
colour = settings["colour"] colour = settings["colour"]
volume_path = settings["volume_path"] atlas_name = settings["atlas_name"]
except KeyError as exc: except KeyError as exc:
raise KeyError( raise KeyError(
"settings file must contain segmentation_folder, alignment_json, colour, and volume_path" "settings file must contain segmentation_folder, alignment_json, colour, and atlas_name"
) from exc ) from exc
# check if any values are None # check if any values are None
if None in [segmentation_folder, alignment_json, colour, volume_path]: if None in [segmentation_folder, alignment_json, colour, atlas_name]:
raise ValueError( raise ValueError(
"segmentation_folder, alignment_json, colour, and volume_path must all be specified and not be None" "segmentation_folder, alignment_json, colour, and volume_path must all be specified and not be None"
) )
if volume_path not in self.config["annotation_volumes"]: # if atlas_name not in self.config["annotation_volumes"]:
raise ValueError( # raise ValueError(
f"Atlas {volume_path} not found in config file, valid atlases are: \n{' , '.join(list(self.config['annotation_volumes'].keys()))}" # f"Atlas {atlas_name} not found in config file, valid atlases are: \n{' , '.join(list(self.config['annotation_volumes'].keys()))}"
) # )
self.segmentation_folder = segmentation_folder self.segmentation_folder = segmentation_folder
self.alignment_json = alignment_json self.alignment_json = alignment_json
self.colour = colour self.colour = colour
self.atlas = volume_path self.atlas_name = atlas_name
self.atlas_volume, self.atlas_labels = self.load_atlas_data() self.atlas_volume, self.atlas_labels = self.load_atlas_data(atlas_name=atlas_name)
###This is just because of the migration to BrainGlobe
def load_atlas_data(self): def load_atlas_data(self, atlas_name):
"""Loads the atlas volume and labels from disk. """Loads the atlas volume and labels from disk.
Returns Returns
...@@ -119,16 +123,26 @@ class PyNutil: ...@@ -119,16 +123,26 @@ class PyNutil:
""" """
# load the metadata json as well as the path to stored data files # load the metadata json as well as the path to stored data files
# this could potentially be moved into init # this could potentially be moved into init
atlas_root_path = self.config["annotation_volume_directory"]
current_atlas_path = self.config["annotation_volumes"][self.atlas]["volume"]
print("loading atlas volume") print("loading atlas volume")
start_time = datetime.now() atlas = brainglobe_atlasapi.BrainGlobeAtlas(atlas_name=atlas_name)
atlas_volume = read_atlas_volume(f"{atlas_root_path}{current_atlas_path}") atlas_structures = {'idx':[i['id'] for i in atlas.structures_list],
time_taken = datetime.now() - start_time 'name':[i['name'] for i in atlas.structures_list],
print(f"atlas volume loaded in: {time_taken}") 'r':[i['rgb_triplet'][0] for i in atlas.structures_list],
atlas_label_path = self.config["annotation_volumes"][self.atlas]["labels"] 'g':[i['rgb_triplet'][1] for i in atlas.structures_list],
print("loading atlas labels") 'b':[i['rgb_triplet'][2] for i in atlas.structures_list]
atlas_labels = pd.read_csv(f"{atlas_root_path}{atlas_label_path}") }
atlas_structures['idx'].insert(0,0)
atlas_structures['name'].insert(0,'Clear Label')
atlas_structures['r'].insert(0,0)
atlas_structures['g'].insert(0,0)
atlas_structures['b'].insert(0,0)
atlas_labels = pd.DataFrame(atlas_structures)
if "allen_mouse_" in atlas_name:
print("reorienting allen atlas into quicknii space...")
atlas_volume = np.transpose(atlas.annotation,[2,0,1])[:,::-1,::-1]
else:
atlas_volume = atlas.annotation
print("atlas labels loaded ✅") print("atlas labels loaded ✅")
return atlas_volume, atlas_labels return atlas_volume, atlas_labels
...@@ -249,7 +263,7 @@ class PyNutil: ...@@ -249,7 +263,7 @@ class PyNutil:
all_region_df = self.atlas_labels.merge(ra, on="idx", how="left") all_region_df = self.atlas_labels.merge(ra, on="idx", how="left")
current_df_new = all_region_df.merge( current_df_new = all_region_df.merge(
current_df, on="idx", how="left", suffixes=(None, "_y") current_df, on="idx", how="left", suffixes=(None, "_y")
).drop(columns=["a", "VIS", "MSH", "name_y", "r_y", "g_y", "b_y"]) ).drop(columns=["name_y", "r_y", "g_y", "b_y"])
current_df_new["area_fraction"] = ( current_df_new["area_fraction"] = (
current_df_new["pixel_count"] / current_df_new["region_area"] current_df_new["pixel_count"] / current_df_new["region_area"]
) )
......
import brainglobe_atlasapi
import pandas as pd
import nrrd
import matplotlib.pyplot as plt
import numpy as np
brainglobe_atlasapi.list_atlases.show_atlases()
allen = brainglobe_atlasapi.BrainGlobeAtlas('allen_mouse_25um')
keys = allen.structures.keys()
##current structure format
labels = pd.read_csv(r'/home/harryc/github/PyNutil/PyNutil/metadata/annotation_volumes/allen2017_colours.csv')
labels
orig_vol = nrrd.read(r"/home/harryc/github/PyNutil/PyNutil/metadata/annotation_volumes/annotation_25_reoriented_2017.nrrd")
plt.imshow(orig_vol[0][200]>0)
{ "volume_path": "allen2017", { "atlas_name": "allen_mouse_25um",
"label_path": "annotation_volumes/allen2017_colours.csv",
"segmentation_folder": "test_data/ttA_2877_NOP_segmentations", "segmentation_folder": "test_data/ttA_2877_NOP_segmentations",
"alignment_json": "test_data/ttA_2877_NOP_horizontal_final_2017.json", "alignment_json": "test_data/ttA_2877_NOP_horizontal_final_2017.json",
"nonlinear": true, "nonlinear": true,
......
{ {
"volume_path": "allen2017", "atlas_name": "allen_mouse_25um",
"label_path": "PyNutil/annotation_volumes/allen2017_colours.csv", "label_path": "PyNutil/annotation_volumes/allen2017_colours.csv",
"segmentation_folder": "PyNutil/test_data/PyTest_web", "segmentation_folder": "PyNutil/test_data/PyTest_web",
"alignment_json": "PyNutil/test_data/PyNutil_test.waln", "alignment_json": "PyNutil/test_data/PyNutil_test.waln",
......
{ "volume_path": "../annotation_volumes/annotation_10_reoriented_2022.nrrd", { "atlas_name": "allen_mouse_25um",
"label_path": "../annotation_volumes/allen2022_colours_updated.csv",
"segmentation_folder": "../test_data/oneSection15", "segmentation_folder": "../test_data/oneSection15",
"alignment_json": "../test_data/C68_nonlinear_no_markers.json", "alignment_json": "../test_data/C68_nonlinear_no_markers.json",
"nonlinear": true, "nonlinear": true,
......
{ "volume_path": "allen2017", { "atlas_name": "allen_mouse_25um",
"label_path": "annotation_volumes/allen2017_colours.csv",
"segmentation_folder": "test_data/oneSection15", "segmentation_folder": "test_data/oneSection15",
"alignment_json": "test_data/C68_nonlinear.json", "alignment_json": "test_data/C68_nonlinear.json",
"nonlinear": true, "nonlinear": true,
......
{ "volume_path": "allen2017", { "atlas_name": "allen_mouse_25um",
"label_path": "annotation_volumes/allen2017_colours.csv",
"segmentation_folder": "test_data/oneSection15", "segmentation_folder": "test_data/oneSection15",
"alignment_json": "test_data/C68_nonlinear_no_markers.json", "alignment_json": "test_data/C68_nonlinear_no_markers.json",
"nonlinear": true, "nonlinear": true,
......
{ "volume_path": "allen2017", { "atlas_name": "allen_mouse_25um",
"label_path": "annotation_volumes/allen2017_colours.csv",
"segmentation_folder": "test_data/ttA_2877_NOP_s037_seg", "segmentation_folder": "test_data/ttA_2877_NOP_s037_seg",
"alignment_json": "test_data/ttA_2877_NOP_horizontal_final_2017.json", "alignment_json": "test_data/ttA_2877_NOP_horizontal_final_2017.json",
"nonlinear": false, "nonlinear": false,
......
{ "volume_path": "../annotation_volumes/annotation_10_reoriented_2017.nrrd", { "atlas_name": "allen_mouse_25um",
"label_path": "../annotation_volumes/allen2017_colours.csv", "label_path": "../annotation_volumes/allen2017_colours.csv",
"segmentation_folder": "../test_data/ttA_2877_NOP_segmentations", "segmentation_folder": "../test_data/ttA_2877_NOP_segmentations",
"alignment_json": "../test_data/ttA_2877_NOP_horizontal_final_2017.json", "alignment_json": "../test_data/ttA_2877_NOP_horizontal_final_2017.json",
......
{ "volume_path": "allen2017", { "atlas_name": "allen_mouse_25um",
"label_path": "annotation_volumes/allen2017_colours.csv", "label_path": "annotation_volumes/allen2017_colours.csv",
"segmentation_folder": "test_data/PyTest_seg", "segmentation_folder": "test_data/PyTest_seg",
"alignment_json": "test_data/PyNutil_testdataset_Nonlin_SY.json", "alignment_json": "test_data/PyNutil_testdataset_Nonlin_SY.json",
......
{ {
"volume_path": "allen2017", "atlas_name": "allen_mouse_25um",
"label_path": "PyNutil/annotation_volumes/allen2017_colours.csv", "label_path": "PyNutil/annotation_volumes/allen2017_colours.csv",
"segmentation_folder": "PyNutil/test_data/PyTest_bigcaudoputamen_seg", "segmentation_folder": "PyNutil/test_data/PyTest_bigcaudoputamen_seg",
"alignment_json": "PyNutil/test_data/PyNutil_testdataset_Nonlin_SY_fixed_bigcaudoputamen.json", "alignment_json": "PyNutil/test_data/PyNutil_testdataset_Nonlin_SY_fixed_bigcaudoputamen.json",
......
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import cv2 import cv2
from skimage import measure from skimage import measure
......
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from PyNutil import PyNutil from PyNutil import PyNutil
import os import os
os.chdir("..") pnt = PyNutil(settings_file=r"test/test8_PyNutil_bigcaudoputamen.json")
pnt = PyNutil(settings_file=r"PyNutil/test/test10_PyNutil_web.json")
##use_flat can be set to True if you want to use the flat file ##use_flat can be set to True if you want to use the flat file
## for method select between "all", "per_pixel" and "per_object" ## for method select between "all", "per_pixel" and "per_object"
...@@ -12,7 +12,7 @@ pnt.get_coordinates(object_cutoff=0, method="all", use_flat=False) ...@@ -12,7 +12,7 @@ pnt.get_coordinates(object_cutoff=0, method="all", use_flat=False)
pnt.quantify_coordinates() pnt.quantify_coordinates()
pnt.save_analysis("PyNutil/outputs/test10_PyNutil_web_all") pnt.save_analysis("../PyNutil/outputs/test9_PyNutil_bigcaudoputamen_new")
# remove name, r, g, b, from pixel_ # remove name, r, g, b, from pixel_
# add to region_areas df # add to region_areas df
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment