'''
How this list was easily generated
'''
import datajoint as dj
import matplotlib.pyplot as plt
import networkx as nx
from scipy.spatial import Delaunay
from datasci_tools import numpy_dep as np
neuron_attributes = [
'multiplicity',
'cell_type_used',
'cell_type',
'nucleus_id',
'nuclei_distance',
'n_nuclei_in_radius',
'n_nuclei_in_bbox',
'centroid_x',
'centroid_y',
'centroid_z',
'centroid_x_nm',
'centroid_y_nm',
'centroid_z_nm',
'max_soma_n_faces',
'max_soma_volume',
'max_soma_area',
'syn_density_post_after_proof',
'syn_density_head_after_proof',
'syn_density_neck_after_proof',
'syn_density_shaft_after_proof',
'skeletal_length_processed_syn_after_proof',
'spine_density_after_proof',
'skeletal_length_processed_spine_after_proof',
'baylor_e_i_after_proof',
'baylor_e_i',
'allen_e_i',
'cell_type_used_for_axon',
'cell_type_for_axon',
'allen_e_i_n_nuc',
'allen_cell_type',
'allen_cell_type_n_nuc',
'allen_cell_type_e_i',
'axon_angle_max',
'axon_angle_min',
'n_axon_angles',
'n_vertices',
'n_faces',
'n_not_processed_soma_containing_meshes',
'n_error_limbs',
'n_same_soma_multi_touching_limbs',
'n_multi_soma_touching_limbs',
'n_somas',
'n_limbs',
'n_branches',
'max_limb_n_branches',
'skeletal_length',
'max_limb_skeletal_length',
'median_branch_length',
'width_median',
'width_no_spine_median',
'width_90_perc',
'width_no_spine_90_perc',
'n_spines',
'n_boutons',
'spine_density',
'spines_per_branch',
'skeletal_length_eligible',
'n_spine_eligible_branches',
'spine_density_eligible',
'spines_per_branch_eligible',
'total_spine_volume',
'spine_volume_median',
'spine_volume_density',
'spine_volume_density_eligible',
'spine_volume_per_branch_eligible',
'dendrite_skeletal_length',
'dendrite_area',
'dendrite_mesh_volume',
'dendrite_n_branches',
'axon_skeletal_length',
'axon_area',
'axon_mesh_volume',
'axon_n_branches',
'basal_skeletal_length',
'basal_area',
'basal_mesh_volume',
'basal_n_branches',
'apical_skeletal_length',
'apical_area',
'apical_mesh_volume',
'apical_n_branches',
'apical_tuft_skeletal_length',
'apical_tuft_area',
'apical_tuft_mesh_volume',
'apical_tuft_n_branches',
'apical_shaft_skeletal_length',
'apical_shaft_area',
'apical_shaft_mesh_volume',
'apical_shaft_n_branches',
'oblique_skeletal_length',
'oblique_area',
'oblique_mesh_volume',
'oblique_n_branches',
'apical_total_skeletal_length',
'apical_total_area',
'apical_total_mesh_volume',
'apical_total_n_branches',
'n_syn_valid',
'n_syn_valid_pre',
'n_syn_valid_post',
'n_syn_error',
'n_syn_error_pre',
'n_syn_error_post',
'n_syn_presyns_on_dendrite',
'n_syn_mesh_errored',
'n_syn_distance_errored',
'n_syn_no_label',
'n_syn_head',
'n_syn_neck',
'n_syn_shaft',
'n_syn_no_head',
'n_syn_bouton',
'n_syn_non_bouton',
'n_syn_dendrite',
'n_syn_axon',
'n_syn_basal',
'n_syn_apical',
'n_syn_apical_tuft',
'n_syn_apical_shaft',
'n_syn_oblique',
'n_syn_soma',
'n_syn_apical_total',
'n_syn_dendrite_head_postsyn',
'n_syn_dendrite_neck_postsyn',
'n_syn_dendrite_shaft_postsyn',
'n_syn_dendrite_no_head_postsyn',
'n_syn_axon_bouton_presyn',
'n_syn_axon_bouton_postsyn',
'n_syn_axon_non_bouton_presyn',
'n_syn_axon_non_bouton_postsyn',
'n_syn_basal_head_postsyn',
'n_syn_basal_neck_postsyn',
'n_syn_basal_shaft_postsyn',
'n_syn_basal_no_head_postsyn',
'n_syn_apical_head_postsyn',
'n_syn_apical_neck_postsyn',
'n_syn_apical_shaft_postsyn',
'n_syn_apical_no_head_postsyn',
'n_syn_apical_tuft_head_postsyn',
'n_syn_apical_tuft_neck_postsyn',
'n_syn_apical_tuft_shaft_postsyn',
'n_syn_apical_tuft_no_head_postsyn',
'n_syn_apical_shaft_head_postsyn',
'n_syn_apical_shaft_neck_postsyn',
'n_syn_apical_shaft_shaft_postsyn',
'n_syn_apical_shaft_no_head_postsyn',
'n_syn_oblique_head_postsyn',
'n_syn_oblique_neck_postsyn',
'n_syn_oblique_shaft_postsyn',
'n_syn_oblique_no_head_postsyn',
'n_syn_soma_no_label_presyn',
'n_syn_soma_no_label_postsyn',
'n_syn_apical_total_head_presyn',
'n_syn_apical_total_head_postsyn',
'n_syn_apical_total_neck_presyn',
'n_syn_apical_total_neck_postsyn',
'n_syn_apical_total_shaft_presyn',
'n_syn_apical_total_shaft_postsyn',
'n_syn_apical_total_no_head_presyn',
'n_syn_apical_total_no_head_postsyn',
'axon_branch_length_median',
'axon_branch_length_mean',
'axon_n_short_branches',
'axon_n_long_branches',
'axon_n_medium_branches',
'axon_bbox_volume',
'axon_bbox_x_min',
'axon_bbox_y_min',
'axon_bbox_z_min',
'axon_bbox_x_max',
'axon_bbox_y_max',
'axon_bbox_z_max',
'axon_bbox_x_min_soma_relative',
'axon_bbox_y_min_soma_relative',
'axon_bbox_z_min_soma_relative',
'axon_bbox_x_max_soma_relative',
'axon_bbox_y_max_soma_relative',
'axon_bbox_z_max_soma_relative',
'apical_branch_length_median',
'apical_branch_length_mean',
'apical_n_short_branches',
'apical_n_long_branches',
'apical_n_medium_branches',
'apical_bbox_volume',
'apical_bbox_x_min',
'apical_bbox_y_min',
'apical_bbox_z_min',
'apical_bbox_x_max',
'apical_bbox_y_max',
'apical_bbox_z_max',
'apical_bbox_x_min_soma_relative',
'apical_bbox_y_min_soma_relative',
'apical_bbox_z_min_soma_relative',
'apical_bbox_x_max_soma_relative',
'apical_bbox_y_max_soma_relative',
'apical_bbox_z_max_soma_relative',
'basal_branch_length_median',
'basal_branch_length_mean',
'basal_n_short_branches',
'basal_n_long_branches',
'basal_n_medium_branches',
'basal_bbox_volume',
'basal_bbox_x_min',
'basal_bbox_y_min',
'basal_bbox_z_min',
'basal_bbox_x_max',
'basal_bbox_y_max',
'basal_bbox_z_max',
'basal_bbox_x_min_soma_relative',
'basal_bbox_y_min_soma_relative',
'basal_bbox_z_min_soma_relative',
'basal_bbox_x_max_soma_relative',
'basal_bbox_y_max_soma_relative',
'basal_bbox_z_max_soma_relative',
'dendrite_branch_length_median',
'dendrite_branch_length_mean',
'dendrite_n_short_branches',
'dendrite_n_long_branches',
'dendrite_n_medium_branches',
'dendrite_bbox_volume',
'dendrite_bbox_x_min',
'dendrite_bbox_y_min',
'dendrite_bbox_z_min',
'dendrite_bbox_x_max',
'dendrite_bbox_y_max',
'dendrite_bbox_z_max',
'dendrite_bbox_x_min_soma_relative',
'dendrite_bbox_y_min_soma_relative',
'dendrite_bbox_z_min_soma_relative',
'dendrite_bbox_x_max_soma_relative',
'dendrite_bbox_y_max_soma_relative',
'dendrite_bbox_z_max_soma_relative',
]
V1_bounds = [
(280053, 322718, 14850),
(230308, 322718, 27858),
(52770, 322718, 27858),
(52770, 322718, 14896),
(230308, 60616, 27858),
(52771, 60616, 27858),
(280053, 60616, 14850),
(52771, 60616, 14850),
(266380, 60616, 18837),
(266380, 322718, 18837),
(252036, 60616, 23240),
(252036, 322718, 23240),
(239706, 60616, 26108),
(239706, 322718, 26108)
]
RL_bounds1 = [
(280053, 322718, 14850),
(280053, 60616, 14850),
(291053, 60616, 14850),
(291053, 322718, 14850),
(304555, 60616, 16084),
(304555, 322718, 16084),
(314280, 60616, 18176),
(314280, 322718, 18176),
(325895, 60616, 19816),
(325895, 322718, 19816),
(341016, 60616, 21822),
(341016, 322718, 21822),
(375347, 60616, 27904),
(375347, 322718, 27904),
(230308, 60616, 27858),
(230308, 322718, 27858),
(266380, 60616, 18837),
(266380, 322718, 18837),
(252036, 60616, 23240),
(252036, 322718, 23240),
(239706, 60616, 26108),
(239706, 322718, 26108)
]
RL_bounds2= [
(341016, 60616, 21822),
(341016, 322718, 21822),
(375347, 60616, 27904),
(375347, 322718, 27904),
(358451, 60616, 22439),
(358451, 322718, 22439),
(375347, 60616, 22722),
(375347, 322718, 22722),
]
AL_bounds = [
(307453, 60616, 16516),
(307453, 322718, 16516),
(315126, 60616, 14816),
(315126, 322718, 14816),
(375347, 60616, 14816),
(375347, 322718, 14816),
(314280, 60616, 18176),
(314280, 322718, 18176),
(325895, 60616, 19816),
(325895, 322718, 19816),
(341016, 60616, 21822),
(341016, 322718, 21822),
(358451, 60616, 22439),
(358451, 322718, 22439),
(375347, 60616, 22722),
(375347, 322718, 22722)
]
volume_bound_coordinates = np.vstack([V1_bounds,RL_bounds1,RL_bounds2,AL_bounds])
layer_axis = 1 #the lower the number the higher the cell is in the volume
top_of_layer_vector = np.array([0,-1,0])
[docs]def coordinates_to_layer_height(coordinates,turn_negative=True):
if coordinates.ndim == 1:
new_coords = coordinates[layer_axis]
elif coordinates.ndim == 2:
new_coords = coordinates[:,layer_axis]
else:
raise Exception(f"coordinates.ndim == {coordinates.ndim}")
if turn_negative:
new_coords = -1*new_coords
return new_coords
[docs]def plot_visual_area_xz_projection(
region_names = ["V1","RL","AL"],
region_colors = ["Blues","Greens","Reds"],
verbose=False,):
"""
Purpose: To plot the triangulation used for the regions of the visual areas
Example:
import microns_utils as mru
mru.plot_visual_area_xz_projection(verbose=True)
"""
if verbose:
for rn,rc in zip(region_names,region_colors):
print(f"{rn}= {rc}")
region_names = np.array(region_names)
V1_Tri = Delaunay(V1_bounds)
RL_a_Tri = Delaunay(RL_bounds1)
RL_b_Tri = Delaunay(RL_bounds2)
AL_Tri = Delaunay(AL_bounds)
triangulation_list = [V1_Tri,RL_a_Tri,RL_b_Tri,AL_Tri]
triangulation_points = [np.array(k) for k in [V1_bounds,RL_bounds1,RL_bounds2,AL_bounds]]
triangulation_color_list = []
for r_n in ["V1","RL","AL"]:
curr_color = region_colors[np.where(region_names==r_n)[0][0]]
if r_n == "RL":
curr_color = [curr_color]*2
else:
curr_color = [curr_color]
triangulation_color_list += curr_color
if verbose:
print(f"triangulation_color_list = {triangulation_color_list}")
fig,ax = plt.subplots()
for tri_points,tri_col in zip(triangulation_points,triangulation_color_list):
tri = Delaunay(np.array(tri_points)[:,[0,2]])
tri_x = tri.points[:,0]
tri_y = tri.points[:,1]
facecolors = np.zeros(len(tri.simplices))
ax.tripcolor(tri_x,
tri_y,
tri.simplices,
facecolors=facecolors,
cmap=tri_col,
edgecolors='k')
plt.show()
[docs]def EM_coordinates_to_visual_areas(coordinates):
"""
Purpose: To use the boundary points to classify
a list of points (usually representing soma centroids)
in visual area classification (V1,AL,RL)
Ex:
centroid_x,centroid_y,centroid_z = minnie.AutoProofreadNeurons3.fetch("centroid_x","centroid_y","centroid_z")
soma_centers = np.vstack([centroid_x,centroid_y,centroid_z ]).T
mru.EM_coordinates_to_visual_areas(soma_centers)
"""
point = coordinates
V1_contains = Delaunay(V1_bounds).find_simplex(point) >= 0 # V1
RL_contains = np.logical_or(
Delaunay(RL_bounds1).find_simplex(point)>=0,
Delaunay(RL_bounds2).find_simplex(point)>= 0) # RL
AL_contains = Delaunay(AL_bounds).find_simplex(point) >= 0 # AL
visual_areas = np.array(["V1","RL","AL"])
contains_mask = np.vstack([V1_contains,RL_contains,AL_contains]).T
point_visual_areas = visual_areas[np.argmax(contains_mask,axis=1)]
return point_visual_areas
layer_by_max_height_voxel = {
"LAYER_1":0,
"LAYER_2/3": 100000,
"LAYER_4":147000,
"LAYER_5": 168500,
"LAYER_6": 224000,
"WHITE_MATTER": 265000
}
layer_by_max_height_nm = {k:v*4 for k,v in layer_by_max_height_voxel.items()}
[docs]def EM_coordinates_to_layer(coordinates):
"""
Purpose: To convert the y value of the EM coordinate(s)
to the layer in the volume it is located
"""
layer_names = np.array(["LAYER_1","LAYER_2/3","LAYER_4","LAYER_5","LAYER_6","WHITE_MATTER"])
bins = [100000,147000,168500,224000,265000]
coordinates = coordinates.reshape(-1,3)
return layer_names[np.digitize(coordinates[:,1],bins)]
[docs]def add_node_attributes_to_proofread_graph(
G,
neuron_data_df,
attributes=None,
add_visual_area=True,
debug=False
):
"""
Pseudocode:
1) Download all of the attributes want to store in the nodes
2) Create a dictionar mapping the nuclei to a dict of attribute values
3) set the attributes of the original graph
"""
if attributes is None:
attributes = [
"spine_category",
"cell_type_predicted",
"n_axons",
"axon_length",
"n_apicals",
"n_spines",
"n_boutons",
"n_nuclei_in_radius",
"skeletal_length",
]
if "nucleus_id" not in attributes:
attributes.append("nucleus_id")
if add_visual_area:
for s_t in ["centroid_x","centroid_y","centroid_z"]:
if s_t not in attributes:
attributes.append(s_t)
#neuron_data = du.proofreading_neurons_table().fetch(*attributes,as_dict=True)
neuron_data = neuron_data_df[attributes]
if add_visual_area:
soma_points = np.array([[k["centroid_x"],k["centroid_y"],k["centroid_z"]] for k in neuron_data])
visual_area_labels = mru.EM_coordinates_to_visual_areas(soma_points)
layer_labels = mru.EM_coordinates_to_layer(soma_points)
if debug:
print(f"soma_points.shape = {soma_points.shape}")
print(f"visual_area_labels.shape = {visual_area_labels.shape}")
attr_dict = dict()
for j,k in enumerate(neuron_data):
curr_dict = {k1:v for k1,v in k.items() if k != "nucleus_id"}
if add_visual_area:
curr_dict["visual_area"] = visual_area_labels[j]
curr_dict["layer"] = layer_labels[j]
attr_dict[k["nucleus_id"]] = curr_dict
nx.set_node_attributes(G, attr_dict)
return G
[docs]def neuron_soma_layer_height(neuron_obj,soma_name="S0"):
return mru.coordinates_to_layer_height(neuron_obj["S0"].mesh_center)
voxel_to_nm_scaling = np.array([4,4,40])
[docs]def em_voxels_to_nm(data):
return np.array(data)*voxel_to_nm_scaling
[docs]def nm_to_em_voxels(data):
return np.array(data)/voxel_to_nm_scaling
[docs]def visual_area_from_em_centroid_xyz(row):
soma_points = np.array([row["centroid_x"],row["centroid_y"],row["centroid_z"]])
visual_area_labels = mru.EM_coordinates_to_visual_areas(soma_points)[0]
return visual_area_labels
[docs]def layer_from_em_centroid_xyz(row):
soma_points = np.array([row["centroid_x"],row["centroid_y"],row["centroid_z"]])
layer_labels = mru.EM_coordinates_to_layer(soma_points)[0]
return layer_labels
microns_volume_coordinates = np.array(V1_bounds +
RL_bounds1 +
RL_bounds2 +
AL_bounds)
[docs]def microns_volume_bbox_corners(return_nm=True):
bbox_corners = nu.bouning_box_corners(microns_volume_coordinates)
if return_nm:
return em_voxels_to_nm(bbox_corners)
return bbox_corners
[docs]def microns_volume_bbox_midpoint(return_nm=True):
bbox_corners = nu.bouning_box_midpoint(microns_volume_coordinates,)
if return_nm:
return em_voxels_to_nm(bbox_corners)
return bbox_corners
[docs]def distance_from_microns_volume_bbox_midpoint(coordinates):
coordinates = np.array(coordinates)
orig_dim = np.array(coordinates).ndim
coordinates = coordinates.reshape(-1,3)
dist_returned = np.linalg.norm(coordinates-microns_volume_bbox_midpoint(),axis=1)
if orig_dim == 1:
return dist_returned[0]
return dist_returned
[docs]def soma_distances_from_microns_volume_bbox_midpoint(neuron_obj,
return_dict = True):
"""
Purpose: To return the distances of each some from the middle of the volume
Ex:
mru.soma_distances_from_microns_volume_bbox_midpoint(neuron_obj,
return_dict=False)
"""
soma_names = neuron_obj.get_soma_node_names()
soma_distances = {k:mru.distance_from_microns_volume_bbox_midpoint(neuron_obj[k].mesh_center)
for k in soma_names}
if return_dict:
return soma_distances
else:
return list(soma_distances.values())
[docs]def em_alignment_data_raw(
return_dict = True,
):
"""
"""
m65em = dj.create_virtual_module('minnie_em', 'microns_minnie_em_v2')
max_alignment = np.max(m65em.EM().fetch("alignment"))
curr_em_table = m65em.EM() & dict(alignment = max_alignment)
if return_dict:
return curr_em_table.fetch1()
else:
return curr_em
[docs]def em_alignment_coordinates_info(
return_nm = True):
'''
Purpose: To get the center points and max points
and all the labels associated
Pseudocode:
1) Get the center,max,min,min anat and max anat
'''
align_dict = em_alignment_data_raw(return_dict = True)
center_pt = np.array([align_dict[f"ctr_pt_{ax}"] for ax in ['x','y','z']])
min_pt = np.array([align_dict[f"min_pt_{ax}"] for ax in ['x','y','z']])
min_labels = np.array([align_dict[f"min_pt_{ax}_anat"] for ax in ['x','y','z']])
max_pt = np.array([align_dict[f"max_pt_{ax}"] for ax in ['x','y','z']])
max_labels = np.array([align_dict[f"max_pt_{ax}_anat"] for ax in ['x','y','z']])
curr_dict = dict(
center_pt=center_pt,
min_pt=min_pt,
max_pt=max_pt,
min_labels=min_labels,
max_labels=max_labels,
)
if return_nm:
for k,v in curr_dict.items():
if "pt" in k:
curr_dict[k] = v*voxel_to_nm_scaling
return curr_dict
[docs]def align_mesh(
mesh,
soma_center=None,
verbose = False):
return mesh
[docs]def align_skeleton(
skeleton,
soma_center=None,
verbose = False):
return skeleton
[docs]def align_array(
array,
soma_center=None,
verbose = False):
return array
[docs]def align_neuron_obj(neuron_obj,**kwargs):
return neuron_obj
[docs]def unalign_neuron_obj(neuron_obj,**kwargs):
return neuron_obj
from . import volume_utils
[docs]class DataInterface(volume_utils.DataInterface):
[docs] def __init__(self,**kwargs):
super().__init__(
**kwargs
)
[docs] def align_array(self,*args,**kwargs):
return align_array(*args,**kwargs)
[docs] def align_mesh(self,*args,**kwargs):
return align_mesh(*args,**kwargs)
[docs] def align_skeleton(self,*args,**kwargs):
return align_skeleton(*args,**kwargs)
[docs] def align_neuron_obj(self,*args,**kwargs):
return align_neuron_obj(*args,**kwargs)
[docs] def unalign_neuron_obj(self,*args,**kwargs):
return unalign_neuron_obj(*args,**kwargs)
[docs] def segment_id_to_synapse_dict(
self,
segment_id = None,
synapse_filepath=None,
**kwargs
):
return super().segment_id_to_synapse_dict(
synapse_filepath=synapse_filepath,
segment_id = segment_id,
**kwargs
)
# if synapse_filepath is None:
# raise Exception("")
# return syu.synapse_dict_from_synapse_csv(
# synapse_filepath=synapse_filepath,
# segment_id = segment_id,
# **kwargs
# )
data_interface = DataInterface(
source = "microns",
voxel_to_nm_scaling = voxel_to_nm_scaling
)
#--- from neurd_packages ---
from . import volume_utils
#--- from datasci_tools ---
from datasci_tools import numpy_dep as np
from datasci_tools import numpy_utils as nu
from . import microns_volume_utils as mru