Source code for neurd.synapse_utils

'''




How to adjust the features on synapses
based on the closest skeleton point

# to calculate the closest skeleton point
syn_coord_sk = sk.closest_skeleton_coordinate(curr_branch.skeleton,
                            face_coord)
#after have closest skeleton coordinate
syu.calculate_endpoints_dist()
syu.calculate_upstream_downstream_dist_from_down_idx(syn,down_idx)






'''
import copy
import operator
import pandas as pd
import time
from datasci_tools import numpy_dep as np
from datasci_tools import module_utils as modu
from datasci_tools import general_utils as gu
from . import microns_volume_utils as mvu
from . import h01_volume_utils as hvu


[docs]class Synapse: """ Classs that will hold information about the synapses that will be attributes of a neuron object Attributes ---------- synapse_id: synapse volume upstream_dist: skeletal distance from the closest upstream branch point downstream_dist: skeletal distance from the closest downstream branch point or endpoint coordinate: 3D location in space: closest_sk_coordinate: 3D location in space of closest skeletal point on branch for which synapse is located closest_face_coordinate: center coordinate of closest mesh face on branch for which synapse is located closest_face_dist: distance from synapse coordinate to closest_face_coordinate soma_distance: skeletal walk distance from synapse to soma soma_distance_euclidean: straight path distance from synapse to soma center head_neck_shaft: whether the synapse is located on a spine head, spine neck or neurite shaft (decoding of integer label is in spine_utils) compartment: the compartment of the branch that the synapse is located on limb_idx: the limb identifier that the synapse is located on branch_idx: the branch identifier that the synapse is located on Note: features like head_neck_shaft, compartment are not populated until later stages (cell typing, autoproofreading) when that information is available for the branches """
[docs] def __init__(self,synapse_obj=None,**kwargs): for a in synapse_attributes: setattr(self,a,None) if synapse_obj is not None: kwargs.update(synapse_obj.export()) #if synapse_dict is not None: for k,v in kwargs.items(): if k in synapse_attributes: setattr(self,k,v)
[docs] def export(self): return syu.export(self)
synapse_attributes = ["syn_type", "syn_id", "volume", "endpoints_dist", "upstream_dist", "downstream_dist", "coordinate", "closest_sk_coordinate", "closest_face_idx", "closest_branch_face_idx", "closest_face_dist", "closest_face_coordinate", "soma_distance", "soma_distance_euclidean", "head_neck_shaft", "compartment", "limb_idx", "branch_idx" ] synapse_coordinate_system_dependent_attributes = [ "closest_sk_coordinate", "coordinate", "closest_face_coordinate" ] #soma_synapse_offset = nru.soma_face_offset synapse_error_types = ["distance_errored","mesh_errored"] synapse_type_names = dict(presyn=dict(valid="valid_syn_centers_presyn", error="errored_syn_centers_presyn"), postsyn = dict(valid="valid_syn_centers_postsyn", error = "errored_syn_centers_postsyn")) valid_pre_color = "yellow" valid_post_color = "blue" error_pre_color = "black" error_post_color = "orange" distance_errored_synapses_pre_color = "tan" distance_errored_synapses_post_color = "pink" mesh_errored_synapses_pre_color = "brown" mesh_errored_synapses_post_color = "lime" soma_pre_color = "aqua" soma_post_color = "purple" default_synapse_size = 0.3 synapse_types = dict( soma="synapses_somas", limb_branch="synapses", mesh_errored="mesh_errored_synapses", distance_errored="distance_errored_synapses" )
[docs]def get_synapse_types(): return list(synapse_types.values())
# ------ different queries for synapses ------- # presyns_on_dendrite_as_errors = True
[docs]def set_presyns_on_dendrite_as_errors_default(): print(f"set_presyns_on_dendrite_as_errors to default of True") presyns_on_dendrite_as_errors = True
[docs]def set_presyns_on_dendrite_as_errors(value): print(f"set_presyns_on_dendrite_as_errors to {value}") presyns_on_dendrite_as_errors = value
[docs]def error_query(): #query = f"(compartment=='error')" query = f"(soma_distance == -1) or (compartment == 'error') or (label in ['mesh_errored','distance_errored'])" if presyns_on_dendrite_as_errors: query += f" or {presyns_on_dendrite_query}" return query
[docs]def valid_query(): #query = f"(compartment !='error')" query = f"not ({error_query()})" if presyns_on_dendrite_as_errors: query += f" and not({presyns_on_dendrite_query})" return query
# ------- Synapse Plotting ------------- #
[docs]def plot_valid_error_synpases(neuron_obj = None, synapse_dict=None, mesh = None, original_mesh = None, synapses_type_to_plot = None, synapses_type_to_not_plot = None, keyword_to_plot = None, verbose=False, TP_color="yellow", TN_color="aqua", FP_color="black", FN_color="orange", synapse_scatter_size = 0.3, #for plotting the actual mesh parts to go along plot_only_axon_skeleton = True, error_mesh_color = "red", valid_mesh_color = "green", valid_skeleton_color = "black", mesh_alpha = 0.3, print_color_key = True, # mapping = dict(TP= "valid_syn_centers_presyn", # FP = "errored_syn_centers_presyn", # TN = "valid_syn_centers_postsyn", # FN = "errored_syn_centers_postsyn",), mapping = None, **kwargs): """ Purpose: Will plot the synapse centers against a proofread neuron Ex: output_syn_dict = syu.synapse_dict_mesh_labels_to_synapse_coordinate_dict(synapse_mesh_labels_dict=mesh_label_dict, synapse_dict=synapse_dict) syu.plot_valid_error_synpases( synapse_dict=output_syn_dict, neuron_obj = None, mesh = mesh, original_mesh = original_mesh, keyword_to_plot = "error", synapse_scatter_size=2, ) """ if synapse_dict is None: synapse_dict = syu.synapse_pre_post_valid_errror_coordinates_dict(neuron_obj) if synapses_type_to_plot is not None: new_dict = dict(synapse_dict) for k in synapse_dict.keys(): if k not in synapses_type_to_plot: del new_dict[k] synapse_dict = new_dict if synapses_type_to_not_plot is not None: new_dict = dict(synapse_dict) for k in synapse_dict.keys(): if k in synapses_type_to_not_plot: del new_dict[k] synapse_dict = new_dict if keyword_to_plot is not None: new_dict = dict(synapse_dict) for k in synapse_dict.keys(): if keyword_to_plot not in k: del new_dict[k] synapse_dict = new_dict if mapping is not None: synapse_types = ["valid_syn_centers_presyn","errored_syn_centers_presyn", "valid_syn_centers_postsyn","errored_syn_centers_postsyn"] synapse_dict_pre = {k:np.array([]) for k in synapse_types} for k,v in synapse_dict.items(): synapse_dict_pre[mapping[k]] = v synapse_dict = synapse_dict_pre color_dict = dict(TP_color=TP_color, TN_color=TN_color, FP_color=FP_color, FN_color=FN_color,) # ---- Part B: Prepares the Mesh Part of the Visual --------# """ Purpose: Plot the valid faces and the invalid faces of neuron (including maybe the axon skeleton of the valid portion), and then to plot the synapses Pseudocode: 1) Get the error mesh from the original mesh and then the mesh after proofreading 2) Get the valid skeleton """ if neuron_obj is not None: print(f"Using the mesh from the neuron object") import validation_utils as vu error_mesh, valid_mesh = vu.mesh_errored_after_neuron_proofreading(neuron_obj,return_valid_mesh=True) if plot_only_axon_skeleton: valid_skeleton = neuron_obj.axon_skeleton else: valid_skeleton = neuron_obj.skeleton skeletons = [valid_skeleton] else: valid_mesh = mesh if original_mesh is not None: error_mesh = tu.subtract_mesh(original_mesh,valid_mesh) skeletons = [] meshes = [error_mesh,valid_mesh] meshes_colors = [error_mesh_color,valid_mesh_color] skeletons_colors = [valid_skeleton_color] #print(f"synapse_dict = {synapse_dict}") nviz.plot_valid_error_synapses(neuron_obj=None, synapse_dict =synapse_dict, meshes=meshes, meshes_colors=meshes_colors, synapse_scatter_size=synapse_scatter_size, # scatters=scatters, # scatter_size=scatter_size, # scatters_colors=scatters_colors, valid_presyn_color=TP_color, valid_postsyn_color=TN_color, error_presyn_color=FP_color, error_postsyn_color=FN_color, plot_error_synapses=True, skeletons=skeletons, skeletons_colors=skeletons_colors, mesh_alpha=mesh_alpha, **kwargs ) if print_color_key: curr_colors = [TP_color,TN_color,FP_color,FN_color] curr_types = ["valid_presyn_color","valid_postsyn_color","error_presyn_color","error_postsyn_color"] #print(f"\nColor Key:") for c_type,col in zip(curr_types,curr_colors): print(f"{c_type}:{col}")
[docs]def soma_synapses_to_scatter_info(neuron_obj, pre_color=soma_pre_color, post_color = soma_post_color, scatter_size = default_synapse_size): """ Purpose: To Turn the soma synapses into plottable scatters Ex: syu.soma_synapses_to_scatter_info(neuron_obj) """ scatters = [] scatters_colors = [] scatter_size_list = [] for soma_name in neuron_obj.get_soma_node_names(): soma_syns_pre = neuron_obj[soma_name].synapses_pre soma_syns_post = neuron_obj[soma_name].synapses_post scatters.append(syu.synapses_to_coordinates(soma_syns_pre)) scatters.append(syu.synapses_to_coordinates(soma_syns_post)) scatters_colors += [pre_color,post_color] scatter_size_list += [scatter_size,scatter_size] return scatters,scatters_colors,scatter_size_list
[docs]def error_synapses_to_scatter_info(neuron_obj, error_synapses_names = None, pre_color=error_pre_color, post_color = error_post_color, color_mapping=dict(distance_errored_synapses_pre = distance_errored_synapses_pre_color, distance_errored_synapses_post = distance_errored_synapses_post_color, mesh_errored_synapses_pre = mesh_errored_synapses_pre_color, mesh_errored_synapses_post = mesh_errored_synapses_post_color,), scatter_size = default_synapse_size): """ To turn the error synapses into plottable scatters Ex: syu.error_synapses_to_scatter_info(neuron_obj) """ scatters = [] scatters_colors = [] scatter_size_list = [] default_color_mapping = dict(pre=pre_color, post=post_color) if error_synapses_names is None: error_synapses_names = syu.get_errored_synapses_names(neuron_obj) for err_syn in error_synapses_names: for syn_type in ["pre","post"]: err_syn_type = f"{err_syn}_{syn_type}" if err_syn_type in color_mapping.keys(): curr_color = color_mapping[err_syn_type] else: curr_color = default_color_mapping[syn_type] curr_synapses = getattr(neuron_obj,err_syn_type) scatters.append(syu.synapses_to_coordinates(curr_synapses)) scatters_colors.append(curr_color) scatter_size_list.append(scatter_size) return scatters,scatters_colors,scatter_size_list
[docs]def limb_branch_synapses_to_scatter_info(neuron_obj, limb_branch_dict="all", pre_color = valid_pre_color, post_color = valid_post_color, scatter_size = default_synapse_size, synapse_type = "synapses"): """ Purpose: To make the synapses on the limb and branches plottable Ex: limb_branch_synapses_to_scatter_info(neuron_obj) """ if limb_branch_dict == "all": limb_branch_dict = neuron_obj.limb_branch_dict pre_syn = nru.concatenate_feature_over_limb_branch_dict(neuron_obj, limb_branch_dict=limb_branch_dict, feature="synapses_pre") post_syn = nru.concatenate_feature_over_limb_branch_dict(neuron_obj, limb_branch_dict=limb_branch_dict, feature="synapses_post") if synapse_type == "synapses": scatters = [syu.synapses_to_coordinates(pre_syn), syu.synapses_to_coordinates(post_syn)] scatters_colors = [pre_color,post_color] scatter_size_list = [scatter_size,scatter_size] elif synapse_type == "synapses_pre": scatters = [syu.synapses_to_coordinates(pre_syn)] scatters_colors = [pre_color] scatter_size_list = [scatter_size] elif synapse_type == "synapses_post": scatters = [syu.synapses_to_coordinates(post_syn)] scatters_colors = [post_color] scatter_size_list = [scatter_size] else: raise Exception(f"Unknown synapse type = {synapse_type}") return scatters,scatters_colors,scatter_size_list
[docs]def append_synapses_to_plot( neuron_obj, total_synapses = False, total_synapses_size = default_synapse_size, limb_branch_dict = "all", limb_branch_synapses = False, limb_branch_size = default_synapse_size, limb_branch_synapse_type = "synapses", distance_errored_synapses = False, distance_errored_size = default_synapse_size, mesh_errored_synapses = False, mesh_errored_size = default_synapse_size, soma_synapses = False, soma_size = default_synapse_size, return_plottable = False, append_figure = True, show_at_end = False, verbose = False): """ Purpose: To add synapse scatter plots to an existing plot """ scatters = [] scatters_colors = [] scatter_size_list = [] if total_synapses: limb_branch_size = total_synapses_size distance_errored_size = total_synapses_size mesh_errored_size = total_synapses_size soma_size = total_synapses_size limb_branch_synapses = True distance_errored_size = True mesh_errored_synapses = True soma_synapses = True limb_branch_dict = "all" if limb_branch_synapses: curr_sc,curr_c,curr_sz = syu.limb_branch_synapses_to_scatter_info(neuron_obj, scatter_size = limb_branch_size, limb_branch_dict=limb_branch_dict, synapse_type=limb_branch_synapse_type) scatters+= curr_sc scatters_colors+=curr_c scatter_size_list += curr_sz if mesh_errored_synapses: curr_sc,curr_c,curr_sz = syu.error_synapses_to_scatter_info(neuron_obj, error_synapses_names=["mesh_errored_synapses"], scatter_size = mesh_errored_size) scatters+= curr_sc scatters_colors+=curr_c scatter_size_list += curr_sz if distance_errored_synapses: curr_sc,curr_c,curr_sz = syu.error_synapses_to_scatter_info(neuron_obj, error_synapses_names=["distance_errored_synapses"], scatter_size = distance_errored_size) scatters+= curr_sc scatters_colors+=curr_c scatter_size_list += curr_sz if soma_synapses: curr_sc,curr_c,curr_sz = syu.soma_synapses_to_scatter_info(neuron_obj, scatter_size = soma_size) scatters+= curr_sc scatters_colors+=curr_c scatter_size_list += curr_sz scatters = [np.array(k).reshape(-1,3) for k in scatters] if verbose: print(f"scatters = {scatters}") print(f"scatters_colors= {scatters_colors}") print(f"scatter_size_list = {scatter_size_list}") if len(scatters) == 0 or len(np.vstack(scatters)) == 0: if verbose: print(f"No Synapses to plot") else: nviz.plot_objects(scatters=scatters, scatters_colors=scatters_colors, scatter_size=scatter_size_list, append_figure=append_figure, show_at_end=show_at_end) if return_plottable: return [scatters,scatter_size_list,scatter_size_list]
[docs]def plot_synapses( neuron_obj, synapse_type = "synapses", total_synapses=False, limb_branch_size = default_synapse_size, distance_errored_size = default_synapse_size, mesh_errored_size = default_synapse_size, soma_size = default_synapse_size, **kwargs ): """ The synapse types """ nviz.visualize_neuron( neuron_obj, limb_branch_dict="all",#dict(L2="all"), limb_branch_synapses=True, limb_branch_synapse_type = synapse_type, total_synapses=total_synapses, limb_branch_size = limb_branch_size, distance_errored_size = distance_errored_size, mesh_errored_size = mesh_errored_size, soma_size = soma_size, **kwargs )
# --------- End of Synapse Plotting -------#
[docs]def export(synapse_obj): return {k:getattr(synapse_obj,k,None) for k in synapse_attributes}
[docs]def combine_synapse_dict_into_presyn_postsyn_valid_error_dict(synapse_dict, verbose = False): """ Purpose: To concatenate all of the valid and error synapses into one synapse dict (application: which can eventually be plotted) Pseudocode: 1) iterate through presyn,postsyn 2) iterate through error valid Find all the keys that have the following in the name Concatenate the lists Store """ output_dict = dict() for k in ["presyn","postsyn"]: synapse_info = synapse_dict[k] synapse_info_keys = list(synapse_info.keys()) for t in ["valid","error"]: curr_name = synapse_type_names[k][t] curr_keys = [j for j in synapse_info_keys if t in j] if verbose: print(f"\nFor {curr_name} using keys {curr_keys}") if len(curr_keys) > 0: curr_arrays = np.vstack([np.array(synapse_info[h]) for h in curr_keys]) else: curr_arrays = np.array([]) if verbose: print(f"# of coordinates = {len(curr_arrays)}") output_dict[curr_name] = curr_arrays return output_dict
[docs]def synapse_dict_mesh_labels_to_synapse_attribute_dict(synapse_mesh_labels_dict, synapse_dict, attribute, return_presyn_postsyn_valid_error_dict = False ): coord_dict = dict() for synapse_type,syn_info in synapse_mesh_labels_dict.items(): coord_dict[synapse_type] = dict() for l,l_ids in syn_info.items(): current_indices = nu.intersect_indices(synapse_dict[synapse_type]["synapse_ids"],l_ids) coord_dict[synapse_type][l] = synapse_dict[synapse_type][attribute][current_indices] if return_presyn_postsyn_valid_error_dict: coord_dict = syu.combine_synapse_dict_into_presyn_postsyn_valid_error_dict(coord_dict, verbose = False) return coord_dict
[docs]def synapse_dict_mesh_labels_to_synapse_coordinate_dict(synapse_mesh_labels_dict, synapse_dict, return_presyn_postsyn_valid_error_dict = True ): return synapse_dict_mesh_labels_to_synapse_attribute_dict(synapse_mesh_labels_dict, synapse_dict, attribute = "synapse_coordinates", return_presyn_postsyn_valid_error_dict = return_presyn_postsyn_valid_error_dict )
[docs]def synapse_dict_mesh_labels_to_synapse_volume_dict(synapse_mesh_labels_dict, synapse_dict, return_presyn_postsyn_valid_error_dict = True ): return synapse_dict_mesh_labels_to_synapse_attribute_dict(synapse_mesh_labels_dict, synapse_dict, attribute = "synapse_sizes", return_presyn_postsyn_valid_error_dict = return_presyn_postsyn_valid_error_dict )
[docs]def n_synapses(neuron_obj): if type(neuron_obj) != list: synapses = neuron_obj.synapses else: synapses = neuron_obj return len(synapses)
[docs]def synapse_density(neuron_obj,synapses=None,density_type = "skeletal_length"): if synapses is None: synapses = neuron_obj.synapses skeletal_length = getattr(neuron_obj,density_type) if skeletal_length > 0: spine_density = len(synapses)/skeletal_length else: spine_density = 0 return spine_density
[docs]def synapses_pre(neuron_obj): if type(neuron_obj) != list: curr_synapses = neuron_obj.synapses else: curr_synapses = neuron_obj return syu.synapses_with_feature(curr_synapses, feature_name="syn_type", comparison_value="presyn")
[docs]def synapses(neuron_obj): if type(neuron_obj) != list: curr_synapses = neuron_obj.synapses else: curr_synapses = neuron_obj return curr_synapses
[docs]def synapses_post(neuron_obj=None): if type(neuron_obj) != list: curr_synapses = neuron_obj.synapses else: curr_synapses = neuron_obj return syu.synapses_with_feature(curr_synapses, feature_name="syn_type", comparison_value="postsyn")
[docs]def n_synapses_pre(neuron_obj): return len(syu.synapses_pre(neuron_obj))
[docs]def n_synapses_post(neuron_obj): return len(syu.synapses_post(neuron_obj))
[docs]def synapse_density_pre(neuron_obj,density_type = "skeletal_length"): return synapse_density(neuron_obj, synapses=syu.synapses_pre(neuron_obj), density_type=density_type)
[docs]def synapse_density_post(neuron_obj,density_type = "skeletal_length"): return synapse_density(neuron_obj, synapses=syu.synapses_post(neuron_obj), density_type=density_type)
[docs]def synapse_pre_perc(neuron_obj): total_synapses = syu.n_synapses(neuron_obj) if total_synapses > 0: return syu.n_synapses_pre(neuron_obj)/total_synapses else: return 0
[docs]def synapse_post_perc(neuron_obj): total_synapses = syu.n_synapses(neuron_obj) if total_synapses > 0: return syu.n_synapses_post(neuron_obj)/total_synapses else: return 0
# -------- 7/19: Has all of the head_neck_shaft classifications ----- #
[docs]def synapses_head(neuron_obj): if type(neuron_obj) != list: curr_synapses = neuron_obj.synapses else: curr_synapses = neuron_obj return syu.synapses_with_feature(curr_synapses, feature_name="head_neck_shaft", comparison_value=spu.head_neck_shaft_dict["head"])
[docs]def synapses_neck(neuron_obj): if type(neuron_obj) != list: curr_synapses = neuron_obj.synapses else: curr_synapses = neuron_obj return syu.synapses_with_feature(curr_synapses, feature_name="head_neck_shaft", comparison_value=spu.head_neck_shaft_dict["neck"])
[docs]def synapses_shaft(neuron_obj): if type(neuron_obj) != list: curr_synapses = neuron_obj.synapses else: curr_synapses = neuron_obj return syu.synapses_with_feature(curr_synapses, feature_name="head_neck_shaft", comparison_value=spu.head_neck_shaft_dict["shaft"])
[docs]def synapses_no_head(neuron_obj): if type(neuron_obj) != list: curr_synapses = neuron_obj.synapses else: curr_synapses = neuron_obj return syu.synapses_with_feature(curr_synapses, feature_name="head_neck_shaft", comparison_value=spu.head_neck_shaft_dict["no_head"])
[docs]def synapses_non_bouton(neuron_obj): if type(neuron_obj) != list: curr_synapses = neuron_obj.synapses else: curr_synapses = neuron_obj return syu.synapses_with_feature(curr_synapses, feature_name="head_neck_shaft", comparison_value=spu.head_neck_shaft_dict["non_bouton"])
[docs]def synapses_bouton(neuron_obj): if type(neuron_obj) != list: curr_synapses = neuron_obj.synapses else: curr_synapses = neuron_obj return syu.synapses_with_feature(curr_synapses, feature_name="head_neck_shaft", comparison_value=spu.head_neck_shaft_dict["bouton"])
[docs]def synapses_type_and_head_neck_shaft(neuron_obj, syn_type, head_neck_shaft_type): if type(neuron_obj) != list: curr_synapses = neuron_obj.synapses else: curr_synapses = neuron_obj if len(curr_synapses) == 0: return [] return syu.query_synapses(curr_synapses, query=(f"(syn_type == '{syn_type}') and " f"(head_neck_shaft == {spu.head_neck_shaft_dict[head_neck_shaft_type]})"), return_synapses=True )
[docs]def synapses_post_head(neuron_obj): return synapses_type_and_head_neck_shaft(neuron_obj,"postsyn","head")
[docs]def synapses_post_neck(neuron_obj): return synapses_type_and_head_neck_shaft(neuron_obj,"postsyn","neck")
[docs]def synapses_post_shaft(neuron_obj): return synapses_type_and_head_neck_shaft(neuron_obj,"postsyn","shaft")
[docs]def synapses_post_no_head(neuron_obj): return synapses_type_and_head_neck_shaft(neuron_obj,"postsyn","no_head")
[docs]def synapses_post_spine(neuron_obj): return synapses_post_neck(neuron_obj) + synapses_post_head(neuron_obj) + synapses_post_no_head(neuron_obj)
[docs]def synapses_pre_shaft(neuron_obj): return synapses_type_and_head_neck_shaft(neuron_obj,"presyn","shaft")
[docs]def synapses_spine(neuron_obj): return syu.synapses_head(neuron_obj) + syu.synapses_neck(neuron_obj) + syu.synapses_no_head(neuron_obj)
[docs]def n_synapses_head(neuron_obj): return len(syu.synapses_head(neuron_obj))
[docs]def n_synapses_neck(neuron_obj): return len(syu.synapses_neck(neuron_obj))
[docs]def n_synapses_shaft(neuron_obj): return len(syu.synapses_shaft(neuron_obj))
[docs]def n_synapses_no_head(neuron_obj): return len(syu.synapses_no_head(neuron_obj))
[docs]def n_synapses_spine(neuron_obj): return len(syu.synapses_spine(neuron_obj))
[docs]def n_synapses_post_head(neuron_obj): return len(syu.synapses_post_head(neuron_obj))
[docs]def n_synapses_post_neck(neuron_obj): return len(syu.synapses_post_head(neuron_obj))
[docs]def n_synapses_post_no_head(neuron_obj): return len(syu.synapses_post_no_head(neuron_obj))
[docs]def n_synapses_post_spine(neuron_obj): return len(syu.synapses_post_spine(neuron_obj))
[docs]def n_synapses_post_shaft(neuron_obj): return len(syu.synapses_post_shaft(neuron_obj))
[docs]def n_synapses_pre_shaft(neuron_obj): return len(syu.synapses_pre_shaft(neuron_obj))
[docs]def synapse_density_head(neuron_obj,density_type = "skeletal_length"): return synapse_density(neuron_obj, synapses=syu.synapses_head(neuron_obj),density_type=density_type)
[docs]def synapse_density_neck(neuron_obj,density_type = "skeletal_length"): return synapse_density(neuron_obj, synapses=syu.synapses_neck(neuron_obj),density_type=density_type)
[docs]def synapse_density_shaft(neuron_obj,density_type = "skeletal_length"): return synapse_density(neuron_obj, synapses=syu.synapses_shaft(neuron_obj))
[docs]def synapse_density_no_head(neuron_obj,density_type = "skeletal_length"): return synapse_density(neuron_obj, synapses=syu.synapses_no_head(neuron_obj),density_type=density_type)
[docs]def synapse_density_spine(neuron_obj,density_type = "skeletal_length"): return synapse_density(neuron_obj, synapses=syu.synapses_spine(neuron_obj),density_type=density_type)
[docs]def synapse_head_perc(neuron_obj): total_synapses = syu.n_synapses(neuron_obj) if total_synapses > 0: return syu.n_synapses_head(neuron_obj)/total_synapses else: return 0
[docs]def synapse_spine_perc(neuron_obj): total_synapses = syu.n_synapses(neuron_obj) if total_synapses > 0: return syu.n_synapses_spine(neuron_obj)/total_synapses else: return 0
# --------- End of head neck shaft --------------
[docs]def synapses_with_feature(synapses, feature_name, comparison_value, operator_func=operator.eq, verbose = False ): """ Purpose: Will find synapses with a certain feature Possible operators: operator.eq operator.gt operator.ge operator.lt operator.le Ex: synapses_with_feature(neuron_obj.synapses, feature_name="syn_type", comparison_value="postsyn", verbose=True) Ex: import operator syu.calculate_neuron_soma_distance(neuron_obj) syn_from_soma = syu.synapses_with_feature(neuron_obj.synapses, feature_name = "soma_distance", comparison_value = 4000, operator_func=operator.le, verbose = True) syn_coords = syu.synapses_to_coordinates(syn_from_soma) nviz.plot_objects(neuron_obj.mesh, scatters=[syn_coords]) """ if not nu.is_array_like(feature_name): feature_name = [feature_name] if not nu.is_array_like(comparison_value): comparison_value = [comparison_value] if not nu.is_array_like(operator_func): operator_func = [operator_func] match_synapses = synapses for feat,cv,of in zip(feature_name,comparison_value,operator_func): match_synapses = [k for k in match_synapses if of(getattr(k,feat),cv)] if verbose: print(f"# of match_synapses with {feature_name} {operator_func} to value {comparison_value} = {len(match_synapses)}") return match_synapses
[docs]def exports_to_synapses(exports): if exports is None: return None return_list = [] for j in exports: if type(j) == dict: return_list.append(syu.Synapse(**j)) elif j.__class__ == syu.Synapse().__class__: return_list.append(j) else: raise Exception(f"Unknown type: {type(j)}") return return_list
[docs]def synapses_to_exports(synapses): return [k.export() for k in synapses]
[docs]def calculate_limb_synapse_soma_distances( limb_obj, calculate_endpoints_dist_if_empty=False, verbose=False): """ Purpose: To store the distances to the soma for all of the synapses Computing the upstream soma distance for each branch 1) calculate the upstream distance 2) Calcualte the upstream endpoint For each synapse: 3) Soma distance = endpoint_dist Ex: calculate_limb_synapse_soma_distances(limb_obj = neuron_obj[2], verbose = True) """ for branch_idx in limb_obj.get_branch_names(): branch_obj = limb_obj[branch_idx] #1) Calculate the upstream distance upstream_dist = nst.total_upstream_skeletal_length(limb_obj,branch_idx) upstream_endpoint_idx = nru.upstream_endpoint(limb_obj,branch_idx,return_endpoint_index=True) for syn in branch_obj.synapses: endpoint_dist = syn.endpoints_dist[upstream_endpoint_idx] if endpoint_dist == -1: if calculate_endpoints_dist_if_empty: syu.calculate_endpoints_dist(branch_obj,syn) syu.calculate_upstream_downstream_dist(limb_obj,branch_idx,syn) #endpoint_dist = syn.endpoints_dist[upstream_endpoint_idx] endpoint_dist = syn.upstream_dist else: raise Exception("Endpoint distance was not calculated yet and calculate_endpoint_dist_if_empty not set") syn.soma_distance = endpoint_dist + upstream_dist
[docs]def calculate_endpoints_dist(branch_obj,syn): """ Purpose: Will calculate the endpoint distance for a synapse """ bau.calculate_endpoints_dist(branch_obj,syn)
[docs]def calculate_upstream_downstream_dist(limb_obj, branch_idx, syn): bau.calculate_upstream_downstream_dist(limb_ob,branch_idx,syn)
[docs]def calculate_upstream_downstream_dist_from_down_idx( syn,down_idx): bau.calculate_upstream_downstream_dist_from_down_idx(syn,down_idx)
[docs]def calculate_upstream_downstream_dist_from_up_idx( syn,up_idx): bau.calculate_upstream_downstream_dist_from_up_idx(syn,up_idx)
[docs]def calculate_neuron_soma_distance(neuron_obj, verbose =False, store_soma_placeholder = True, store_error_placeholder = True): """ Purpose: To calculate all of the soma distances for all the valid synapses on limbs Ex: calculate_neuron_soma_distance(neuron_obj, verbose = True) """ st = time.time() for limb_name in neuron_obj.get_limb_names(): st_loc = time.time() limb_obj = neuron_obj[limb_name] syu.calculate_limb_synapse_soma_distances(limb_obj = limb_obj, verbose = False) if verbose: print(f"\n--- Limb {limb_name} soma calculation time = {np.round(time.time() - st_loc,3)}") if store_soma_placeholder: if verbose: print(f"Putting Soma Placeholders") for s_idx in neuron_obj.get_soma_indexes(): st_loc = time.time() soma_synapses = neuron_obj[f"S{s_idx}"].synapses for syn in soma_synapses: syn.soma_distance = -1*(nru.soma_face_offset + s_idx) if verbose: print(f"\n--- Soma {s_idx} soma calculation time = {np.round(time.time() - st_loc,3)}") if store_error_placeholder: st_loc = time.time() if verbose: print(f"Putting Error Placeholders") for syn in neuron_obj.synapses_error: syn.soma_distance = -1 if verbose: print(f"\n--- Error soma calculation time = {np.round(time.time() - st_loc,3)}") if verbose: print(f"Total soma distance calculation time = {time.time() - st}")
# -------------- 6/9 For Applying the synapses ------------ #
[docs]def add_valid_soma_synapses_to_neuron_obj(neuron_obj, verbose=False, validation=False, **kwargs): return syu.add_valid_synapses_to_neuron_obj(neuron_obj, verbose=verbose, validation=validation, add_only_soma_synapses = True, **kwargs )
[docs]def add_valid_synapses_to_neuron_obj(neuron_obj, synapse_dict=None, mesh_label_dict=None, validation = False, verbose = False, debug_time = True, calualate_endpoints_dist = True, limb_branch_dict_to_add_synapses = None, #set_head_neck_shaft = False, original_mesh = None, add_only_soma_synapses = False, **kwargs): """ Purpose: To add valid synapses to a neuron object """ # ----- Phase 0: Getting the Synapse Info ------ # if synapse_dict is None: synapse_dict = vdi.segment_id_to_synapse_dict(neuron_obj.segment_id, validation=validation, verbose=verbose) if mesh_label_dict is None: mesh_label_dict = syu.fetch_synapse_dict_by_mesh_labels( mesh = nru.neuron_mesh_from_branches(neuron_obj), segment_id=neuron_obj.segment_id, synapse_dict = synapse_dict, original_mesh = original_mesh, #original_mesh_kd=original_mesh_kd, validation=validation, plot_synapses=False, verbose = verbose) # ----- Phase 1: Computing the features of the Synapses ------ # st = time.time() valid_synapse_dict = dict(presyn=dict(valid=mesh_label_dict["presyn"]["valid"]), postsyn=dict(valid=mesh_label_dict["postsyn"]["valid"])) valid_synapse_dict_coord = syu.synapse_dict_mesh_labels_to_synapse_coordinate_dict(valid_synapse_dict, synapse_dict, return_presyn_postsyn_valid_error_dict = False) valid_synapse_dict_volume = syu.synapse_dict_mesh_labels_to_synapse_volume_dict(valid_synapse_dict, synapse_dict, return_presyn_postsyn_valid_error_dict = False) if debug_time: print(f"Synapse dict: {np.round(time.time() - st,4)}") st = time.time() original_mesh_proof = neuron_obj.mesh_from_branches original_mesh_kdtree_proof = tu.mesh_to_kdtree(original_mesh_proof) if debug_time: print(f"Original Mesh: {np.round(time.time() - st,4)}") st = time.time() limb_branch_info = dict() for k in ["presyn","postsyn"]: limb_branch_info[k] = dict() limb_branch_idx,dist,closest_faces = nru.coordinates_to_closest_limb_branch(neuron_obj, coordinates=valid_synapse_dict_coord[k]["valid"], original_mesh = original_mesh_proof, original_mesh_kdtree = original_mesh_kdtree_proof, return_distances_to_limb_branch = True, return_closest_faces=True) if add_only_soma_synapses: if verbose: print(f"Restricting to only soma synapses") keep_map = limb_branch_idx[:,0] < -1 valid_synapse_dict[k]["valid"] = valid_synapse_dict[k]["valid"][keep_map] valid_synapse_dict_coord[k]["valid"] = valid_synapse_dict_coord[k]["valid"][keep_map] valid_synapse_dict_volume[k]["valid"] = valid_synapse_dict_volume[k]["valid"][keep_map] limb_branch_idx = np.array(limb_branch_idx)[keep_map] dist = np.array(dist)[keep_map] closest_faces = np.array(closest_faces)[keep_map] limb_branch_info[k]["limb_idx"] = limb_branch_idx[:,0].astype("int") limb_branch_info[k]["branch_idx"] = limb_branch_idx[:,1].astype("int") limb_branch_info[k]["closest_face_dist"] = dist limb_branch_info[k]["closest_face_idx"] = closest_faces limb_branch_info[k]["closest_face_coordinate"] = original_mesh_proof.triangles_center[closest_faces] if debug_time: print(f"Closest Branch: {np.round(time.time() - st,4)}") st = time.time() #computing the closest skeleton vertex and endpoint distance limb_branch_info[k]["closest_sk_coordinate"] = np.zeros(limb_branch_info[k]["closest_face_coordinate"].shape) limb_branch_info[k]["endpoints_dist"] = np.ones((limb_branch_info[k]["closest_face_coordinate"].shape[0],2))*-1 limb_branch_info[k]["upstream_dist"] = np.ones((limb_branch_info[k]["closest_face_coordinate"].shape[0]))*-1 limb_branch_info[k]["downstream_dist"] = np.ones((limb_branch_info[k]["closest_face_coordinate"].shape[0]))*-1 downstream_endpoint_idx_dict = dict() for j,(limb_idx,branch_idx,face_coord,curr_face_idx) in enumerate(zip(limb_branch_info[k]["limb_idx"], limb_branch_info[k]["branch_idx"], limb_branch_info[k]["closest_face_coordinate"], limb_branch_info[k]["closest_face_idx"])): if limb_idx < 0 or branch_idx < 0: syn_coord_sk = face_coord endpoints_dist = [0,0] upstream_dist = 0 downstream_dist = 0 # if set_head_neck_shaft: # head_neck_shaft_val = spu.head_neck_shaft_dict["no_label"] else: if limb_branch_dict_to_add_synapses is not None: if not nru.in_limb_branch_dict(limb_branch_dict_to_add_synapses,limb_idx,branch_idx): continue curr_branch = neuron_obj[limb_idx][branch_idx] # if set_head_neck_shaft: # head_neck_shaft_val = curr_branch.head_neck_shaft_idx[curr_face_idx] syn_coord_sk = sk.closest_skeleton_coordinate(curr_branch.skeleton, face_coord) #getting the distances to endpoint1 and endpoint2 if calualate_endpoints_dist: endpoints_dist = [sk.skeleton_path_between_skeleton_coordinates( starting_coordinate = syn_coord_sk, destination_node=j, skeleton_graph = curr_branch.skeleton_graph, only_skeleton_distance = True,) for j in curr_branch.endpoints_nodes] # if debug_time: # print(f"endpoints_dist {limb_idx},{branch_idx}: {np.round(time.time() - st,4)}") # st = time.time() """ Need to figure out which index is upstream and which is downstream """ if limb_idx not in downstream_endpoint_idx_dict.keys(): downstream_endpoint_idx_dict[limb_idx] = dict() if branch_idx not in downstream_endpoint_idx_dict[limb_idx].keys(): downstream_endpoint_idx_dict[limb_idx][branch_idx] = nru.downstream_endpoint(neuron_obj[limb_idx],branch_idx,return_endpoint_index=True) down_idx = downstream_endpoint_idx_dict[limb_idx][branch_idx] downstream_dist = endpoints_dist[down_idx] upstream_dist = endpoints_dist[1-down_idx] else: upstream_dist = -1 downstream_dist = -1 endpoints_dist = [upstream_dist,downstream_dist] limb_branch_info[k]["endpoints_dist"][j] = endpoints_dist limb_branch_info[k]["upstream_dist"][j] = upstream_dist limb_branch_info[k]["downstream_dist"][j] = downstream_dist limb_branch_info[k]["closest_sk_coordinate"][j] = syn_coord_sk # limb_branch_info[k]["head_neck_shaft"][j] = head_neck_shaft_val # THIS IS VERY LONG STEP IN THE KUBERNETES VERSION if debug_time: print(f"Closest Skeleton Branch and distance from endpoint: {np.round(time.time() - st,4)}") st = time.time() # ----- Phase 2: Creating the Synapse Objects ------ # st = time.time() #print(f"limb_branch_dict_to_add_synapses = {limb_branch_dict_to_add_synapses}") limb_branch_to_synapse_list = dict() for syn_type,valid_dict in valid_synapse_dict.items(): syn_ids = valid_dict["valid"] for syn_idx,syn_id in enumerate(syn_ids): limb_idx = limb_branch_info[syn_type]["limb_idx"][syn_idx] branch_idx = limb_branch_info[syn_type]["branch_idx"][syn_idx] if limb_branch_dict_to_add_synapses is not None: if not nru.in_limb_branch_dict(limb_branch_dict_to_add_synapses,limb_idx,branch_idx): continue syn_coord = valid_synapse_dict_coord[syn_type]["valid"][syn_idx] syn_volume = valid_synapse_dict_volume[syn_type]["valid"][syn_idx] syn_obj_dict = dict(syn_type=syn_type, syn_id = syn_id, volume = syn_volume, coordinate = syn_coord, ) syn_obj_dict.update({k:v[syn_idx] for k,v in limb_branch_info[syn_type].items() if k not in ["limb_idx","branch_idx"]}) # curr_branch = neuron_obj[limb_idx][branch_idx] # nviz.plot_objects(curr_branch.mesh, # scatters=[curr_branch.endpoints[0], # curr_branch.endpoints[1], # syn_obj_dict["coordinate"]], # scatters_colors=["red","blue","orange"], # scatter_size=0.5) if limb_idx not in limb_branch_to_synapse_list.keys(): limb_branch_to_synapse_list[limb_idx] = dict() if branch_idx not in limb_branch_to_synapse_list[limb_idx].keys(): limb_branch_to_synapse_list[limb_idx][branch_idx] = [] limb_branch_to_synapse_list[limb_idx][branch_idx].append(syu.Synapse(**syn_obj_dict)) #return limb_branch_to_synapse_list #----- Phase 2: Adding the Synapse Objects ------ # soma_synapses = {k:[] for k in neuron_obj.get_soma_indexes()} for l,limb_data in limb_branch_to_synapse_list.items(): limb_name = nru.get_limb_string_name(l) if limb_branch_dict_to_add_synapses is not None: if limb_name not in limb_branch_dict_to_add_synapses.keys(): continue for b,branch_synapses in limb_data.items(): if limb_branch_dict_to_add_synapses is not None: if b not in limb_branch_dict_to_add_synapses[limb_name]: continue if l < 0 or b < 0: soma_synapses[-l - nru.soma_face_offset]+= branch_synapses else: neuron_obj[l][b].synapses = branch_synapses # storing the soma synapses if limb_branch_dict_to_add_synapses is None: for k,v in soma_synapses.items(): # for v_syn in v: # v.compartment = "soma" neuron_obj[f"S{k}"].synapses = v # print(f"soma_synapses= {soma_synapses}") # print(f"neuron_obj.syanspes_somas = {neuron_obj.synapses_somas}") if verbose: print(f"Total time for valid synapse objects = {time.time() - st}")
[docs]def add_error_synapses_to_neuron_obj( neuron_obj, synapse_dict=None, mesh_label_dict=None, validation = False, verbose = False, original_mesh = None, ): """ Pseudocode: 0) Get the coordinates and volumes of each For each error type a) Create a list for storage For presyn/postsyn: c) Build the synapses from the information d) store in the list """ st = time.time() # ----- Phase 0: Getting the Synapse Info ------ # if synapse_dict is None: synapse_dict = vdi.segment_id_to_synapse_dict(neuron_obj.segment_id, validation=validation, verbose=verbose) if mesh_label_dict is None: mesh_label_dict = syu.fetch_synapse_dict_by_mesh_labels( mesh = nru.neuron_mesh_from_branches(neuron_obj), segment_id=neuron_obj.segment_id, synapse_dict = synapse_dict, original_mesh = original_mesh, #original_mesh_kd=original_mesh_kd, validation=validation, plot_synapses=False, verbose = verbose) # ------ Phase 1: Getting the Error Dictionaries set Up ------- error_synapse_dict = dict() for t in ["presyn","postsyn"]: error_synapse_dict[t] = {k:v for k,v in mesh_label_dict[t].items() if "error" in k} error_synapse_dict_coord = syu.synapse_dict_mesh_labels_to_synapse_coordinate_dict(error_synapse_dict, synapse_dict, return_presyn_postsyn_valid_error_dict = False) error_synapse_dict_volume = syu.synapse_dict_mesh_labels_to_synapse_volume_dict(error_synapse_dict, synapse_dict, return_presyn_postsyn_valid_error_dict = False) # ------ Phase 2: Creating the Error Synapses From the Dictionary Info ------- syn_error_lists = {k:[] for k in syu.synapse_error_types} for error_type in syu.synapse_error_types: if verbose: print(f"Working on error_type = {error_type}") for syn_type,valid_dict in error_synapse_dict.items(): syn_ids = valid_dict[error_type] for syn_idx,syn_id in enumerate(syn_ids): syn_coord = error_synapse_dict_coord[syn_type][error_type][syn_idx] syn_volume = error_synapse_dict_volume[syn_type][error_type][syn_idx] syn_obj_dict = dict(syn_type=syn_type, syn_id = syn_id, volume = syn_volume, coordinate = syn_coord, soma_distance = -1, ) syn_error_lists[error_type].append(syu.Synapse(**syn_obj_dict)) setattr(neuron_obj,f"{error_type}_synapses",syn_error_lists[error_type]) if verbose: print(f"Total time for valid synapse objects = {time.time() - st}")
[docs]def add_synapses_to_neuron_obj( neuron_obj, segment_id = None, validation = False, verbose = False, original_mesh = None, plot_valid_error_synapses = False, calculate_synapse_soma_distance = False, add_valid_synapses = True, add_error_synapses = True, limb_branch_dict_to_add_synapses = None, **kwargs #set_head_neck_shaft=True ): """ Purpose: To add the synapse information to the neuron object Pseudocode: 0) Get the KDTree of the original mesh 1) Get """ if verbose: print(f"\n---Step 1: Computing synapse_dict---") if segment_id is None: segment_id = neuron_obj.segment_id synapse_dict = vdi.segment_id_to_synapse_dict( segment_id = segment_id, validation=validation, verbose=verbose, **kwargs ) #original_mesh_kd = tu.mesh_to_kdtree(original_mesh) if verbose: print(f"\n---Step 2: Computing mesh_label_dict---") mesh_label_dict = syu.fetch_synapse_dict_by_mesh_labels( mesh = nru.neuron_mesh_from_branches(neuron_obj), segment_id=segment_id, synapse_dict = synapse_dict, original_mesh = original_mesh, #original_mesh_kd=original_mesh_kd, validation=validation, plot_synapses=plot_valid_error_synapses, verbose = verbose) # Apply the Valid Synapses if add_valid_synapses: if verbose: print(f"\n---Step 3: add_valid_synapses_to_neuron_obj---") syu.add_valid_synapses_to_neuron_obj(neuron_obj, synapse_dict=synapse_dict, mesh_label_dict=mesh_label_dict, validation = validation, verbose = verbose, debug_time = verbose, calualate_endpoints_dist = True, limb_branch_dict_to_add_synapses = limb_branch_dict_to_add_synapses #set_head_neck_shaft=set_head_neck_shaft ) if add_error_synapses: if verbose: print(f"\n---Step 4: add_error_synapses_to_neuron_obj---") syu.add_error_synapses_to_neuron_obj(neuron_obj, synapse_dict=synapse_dict, mesh_label_dict=mesh_label_dict, validation = validation, verbose = verbose) if calculate_synapse_soma_distance: if verbose: print(f"\n---Step 5: Adding Soma distances to synapse objects---") syu.calculate_neuron_soma_distance(neuron_obj) syu.set_limb_branch_idx_to_synapses(neuron_obj) return neuron_obj
def synapses_to_coordinates(synapses, coordinate_type = "coordinate"): """ Will export the coordinates of a list of synapse Other coordinate types: 1) coordinate 2) closest_sk_coordinate 3) closest_face_coordinate """ return np.array([getattr(k,coordinate_type) for k in synapses]).reshape(-1,3) def synapses_over_limb_branch_dict(neuron_obj, limb_branch_dict, synapse_type = "synapses"): """ To gather all of the synapses over a limb branch dict restriction Ex: syu.synapses_over_limb_branch_dict(neuron_obj, limb_branch_dict=dict(L2=[5,6,7]), synapse_type = "synapses") """ return nru.concatenate_feature_over_limb_branch_dict(neuron_obj, limb_branch_dict=limb_branch_dict, feature=synapse_type)
[docs]def n_synapses_over_limb_branch_dict(neuron_obj, limb_branch_dict, synapse_type = "synapses"): """ To gather all of the synapses over a limb branch dict restriction Ex: syu.synapses_over_limb_branch_dict(neuron_obj, limb_branch_dict=dict(L2=[5,6,7]), synapse_type = "synapses") """ return nru.sum_feature_over_limb_branch_dict(neuron_obj, limb_branch_dict=limb_branch_dict, feature=f"n_{synapse_type}")
[docs]def n_synapses_pre_over_limb_branch_dict(neuron_obj, limb_branch_dict,): """ To gather all of the synapses over a limb branch dict restriction Ex: syu.synapses_over_limb_branch_dict(neuron_obj, limb_branch_dict=dict(L2=[5,6,7]), synapse_type = "synapses") """ return nru.sum_feature_over_limb_branch_dict(neuron_obj, limb_branch_dict=limb_branch_dict, feature=f"n_synapses_pre")
[docs]def n_synapses_post_over_limb_branch_dict(neuron_obj, limb_branch_dict,): """ To gather all of the synapses over a limb branch dict restriction Ex: syu.synapses_over_limb_branch_dict(neuron_obj, limb_branch_dict=dict(L2=[5,6,7]), synapse_type = "synapses") """ return nru.sum_feature_over_limb_branch_dict(neuron_obj, limb_branch_dict=limb_branch_dict, feature=f"n_synapses_post")
[docs]def synapse_pre_perc_over_limb_branch_dict(neuron_obj, limb_branch_dict ): """ Purpose: Will compute the percentage of synapses that are presyn over a limb branch dict Ex: branches = [0,5,6,7] lb = dict(L0=branches) syn_pre_perc = syu.synapse_pre_perc_over_limb_branch_dict(neuron_obj_exc_syn_sp, lb) """ curr_syns = syu.synapses_over_limb_branch_dict(neuron_obj, limb_branch_dict) return syu.synapse_pre_perc(curr_syns)
[docs]def synapse_post_perc_over_limb_branch_dict(neuron_obj, limb_branch_dict ): """ Purpose: Will compute the percentage of synapses that are postsyn over a limb branch dict Ex: lb = dict(L0=branches) syn_post_perc = syu.synapse_post_perc_over_limb_branch_dict(neuron_obj_exc_syn_sp, lb) """ curr_syns = syu.synapses_over_limb_branch_dict(neuron_obj, limb_branch_dict) return syu.synapse_post_perc(curr_syns)
[docs]def get_errored_synapses_names(neuron_obj): return [k for k in neuron_obj.__dict__.keys() if "errored_synapses" in k]
[docs]def synapses_somas(neuron_obj): total_synapses = [] for s in neuron_obj.get_soma_node_names(): total_synapses += neuron_obj[s].synapses return total_synapses
soma_synapses = synapses_somas
[docs]def synapses_somas_postsyn( neuron_obj, verbose = False, plot= False, **kwargs): return syu.query_synapses( neuron_obj, query = "(compartment == 'soma') and (syn_type == 'postsyn') ", plot = plot, verbose = verbose )
[docs]def n_synapses_somas_postsyn(neuron_obj,**kwargs): return len(syu.synapses_somas_postsyn(neuron_obj,**kwargs))
[docs]def synapses_valid_old(neuron_obj,include_soma=True): """ Will return all valid synapses and somas """ valid_synapses = neuron_obj.synapses if include_soma: valid_synapses += neuron_obj.synapses_somas return valid_synapses
[docs]def synapses_valid(neuron_obj,include_soma=True): """ Will return all valid synapses and somas """ valid_syns = syu.query_synapses(neuron_obj, query = valid_query(), return_synapses=True, verbose = False) return valid_syns
[docs]def n_synapses_valid(neuron_obj,include_soma=True): return len(syu.synapses_valid(neuron_obj))
[docs]def synapses_valid_pre(neuron_obj): return syu.synapses_pre(syu.synapses_valid(neuron_obj))
[docs]def synapses_valid_post(neuron_obj): return syu.synapses_post(syu.synapses_valid(neuron_obj))
[docs]def n_synapses_valid_pre(neuron_obj): return len(syu.synapses_valid_pre(neuron_obj))
[docs]def n_synapses_valid_post(neuron_obj): return len(syu.synapses_valid_post(neuron_obj))
[docs]def synapses_error_old(neuron_obj, error_synapses_names=None, presyns_on_dendrite_as_errors = presyns_on_dendrite_as_errors, verbose=False): """ Will get all of the errored synapses stored in the object syu.error_synpases(neuron_obj, verbose = True) """ total_error_synapses = [] if error_synapses_names is None: error_synapses_names = syu.get_errored_synapses_names(neuron_obj) if verbose: print(f"error_synapses_names = {error_synapses_names}") for err_syn in error_synapses_names: total_error_synapses += getattr(neuron_obj,err_syn) return total_error_synapses
[docs]def synapses_error(neuron_obj, error_synapses_names=None, presyns_on_dendrite_as_errors = presyns_on_dendrite_as_errors, verbose=False): """ Will get all of the errored synapses stored in the object syu.error_synpases(neuron_obj, verbose = True) """ error_syns = syu.query_synapses(neuron_obj, query = error_query(), return_synapses=True, verbose = False) return error_syns
[docs]def n_synapses_error(neuron_obj, error_synapses_names=None, presyns_on_dendrite_as_errors = presyns_on_dendrite_as_errors, verbose=False): return len(syu.synapses_error(neuron_obj, error_synapses_names=error_synapses_names, presyns_on_dendrite_as_errors = presyns_on_dendrite_as_errors, verbose=verbose))
[docs]def synapses_error_pre(neuron_obj): return syu.synapses_pre(syu.synapses_error(neuron_obj))
[docs]def synapses_error_post(neuron_obj): return syu.synapses_post(syu.synapses_error(neuron_obj))
[docs]def n_synapses_error_pre(neuron_obj): return len(syu.synapses_error_pre(neuron_obj))
[docs]def n_synapses_error_post(neuron_obj): return len(syu.synapses_error_post(neuron_obj))
[docs]def synapses_total(neuron_obj): """ Purpose: to find the total number of synapses stored in the neuron object Pseducode: 1) get all of the soma synapses 2) get all of the errored synapses 3) get all of the limb_branch synapses """ # # old way of compiling # soma_synapses = neuron_obj.synapses_somas # errored_synapses = neuron_obj.synapses_error # limb_branch_synapses = neuron_obj.synapses # soma_synapses + errored_synapses + limb_branch_synapses total_synapses = [] for s_type,s_type_att in syu.synapse_types.items(): curr_syns = getattr(neuron_obj,s_type_att) total_synapses += curr_syns return total_synapses
[docs]def synapses_to_synapses_df( synapses, label="no_label", add_compartment_coarse_fine = False, decode_head_neck_shaft_idx = False,): synapse_dicts = [dict(k.export(), label=label, ) for k in synapses] df = pu.dicts_to_dataframe(synapse_dicts) df = annotate_synapse_df( df, add_compartment_coarse_fine=add_compartment_coarse_fine, decode_head_neck_shaft_idx = decode_head_neck_shaft_idx, ) return df
[docs]def synapses_df( neuron_obj, synapse_types_to_process = None, verbose = False, add_compartment_coarse_fine = False, decode_head_neck_shaft_idx = False, **kwargs): """ Purpose: To create a dataframe with all of the features of the synapses so the synapses can be queried """ if isinstance(neuron_obj,neuron.Limb) or (isinstance(neuron_obj,neuron.Branch)): neuron_obj = neuron_obj.synapses if type(neuron_obj) == list: return syu.synapses_to_synapses_df( neuron_obj, add_compartment_coarse_fine=add_compartment_coarse_fine, decode_head_neck_shaft_idx=decode_head_neck_shaft_idx, **kwargs) if synapse_types_to_process is not None: curr_synapse_types = {k:v for k,v in syu.synapse_types.items() if k in synapse_types_to_process} else: curr_synapse_types = syu.synapse_types synapse_dicts = [] for s_type,s_type_att in curr_synapse_types.items(): if s_type != "limb_branch": if s_type == "soma": compartment = "soma" elif "error" in s_type: compartment = "error" else: raise Exception(f"Unknown stype = {s_type}") curr_syns = getattr(neuron_obj,s_type_att) curr_synapse_dicts = [] for ss in curr_syns: curr_dict = dict(label=s_type, limb_idx = -1, branch_idx = -1, compartment = compartment,) curr_dict.update({j:b for j,b in ss.export().items() if (b is not None or j not in ["label","limb_idx","brnach_idx","compartment"])}) curr_synapse_dicts.append(curr_dict) # curr_synapse_dicts = [dict(k.export(), # label=s_type, # limb_idx = -1, # branch_idx = -1, # compartment = compartment, # ) # for k in curr_syns] synapse_dicts += curr_synapse_dicts else: for limb_idx in neuron_obj.get_limb_names(return_int=True): limb_obj = neuron_obj[limb_idx] for branch_idx in limb_obj.get_branch_names(): curr_synapse_dicts = [] branch_obj = limb_obj[branch_idx] for ss in branch_obj.synapses: curr_dict = dict(label=s_type, limb_idx = limb_idx, branch_idx = branch_idx, compartment = limb_obj[branch_idx].axon_compartment, #width = ) curr_dict.update({j:b for j,b in ss.export().items() if (b is not None or j not in ["label","limb_idx","brnach_idx","compartment"])}) curr_synapse_dicts.append(curr_dict) # curr_synapse_dicts = [dict(k.export(), # label=s_type, # limb_idx = limb_idx, # branch_idx = branch_idx, # compartment = limb_obj[branch_idx].axon_compartment, # ) # for k in limb_obj[branch_idx].synapses] synapse_dicts += curr_synapse_dicts if verbose: print(f"# of synapses processed = {len(synapse_dicts)}") df = pu.dicts_to_dataframe(synapse_dicts) df = nru.add_limb_branch_combined_name_to_df( df, ) df = annotate_synapse_df( df, add_compartment_coarse_fine=add_compartment_coarse_fine, decode_head_neck_shaft_idx = decode_head_neck_shaft_idx, ) return df
[docs]def annotate_synapse_df( df, add_compartment_coarse_fine=False, decode_head_neck_shaft_idx = False, ): if add_compartment_coarse_fine: df = apu.add_compartment_coarse_fine_to_df( df ) if decode_head_neck_shaft_idx: df["head_neck_shaft"] = spu.decode_head_neck_shaft_idx( df.head_neck_shaft ) return df
synapse_df = synapses_df
[docs]def restrict_synapses_df_by_limb_branch_dict( df, limb_branch_dict, ): return df.query(f"limb_branch in {list(nru.limb_branch_str_names_from_limb_branch_dict(limb_branch_dict))}")
[docs]def query_synapses(neuron_obj, query, return_df=False, return_index=False, return_synapses=False, return_column = "syn_id", local_dict = dict(), limb_branch_dict = None, verbose = False, plot = False, synapse_size = 1, **kwargs): """ Purpose: To return a dataframe Pseudocode: 1) Create synapse dataframe 2) Use the query function to reduce the dataframe 3) Return the desired output Note: YOU CAN SEND THIS FUNCTION A LIST OF SYNAPSES NOW EX: syn_type = "presyn" head_neck_shaft_type = "shaft" syu.query_synapses(neuron_obj_exc_syn_sp[0][0].synapses, query=(f"(syn_type == '{syn_type}') and " f"(head_neck_shaft == {spu.head_neck_shaft_dict[head_neck_shaft_type]})"), return_synapses=True ) """ synapse_df = syu.synapses_df(neuron_obj,**kwargs) query_df = synapse_df.query(query, local_dict=local_dict) if limb_branch_dict is not None and len(query_df)>0: if len(limb_branch_dict) > 0: query_df = syu.restrict_synapses_df_by_limb_branch_dict( query_df, limb_branch_dict ) if verbose: print(f"# of synapses in query = {len(query_df)}") if plot: syn_indexes = query_df.index.to_numpy() synapse_objs = syu.synapse_indexes_to_synapses(neuron_obj, syn_indexes) syu.plot_synapses_objs(neuron_obj, synapse_objs, synapse_size=synapse_size) if return_synapses: syn_indexes = query_df.index.to_numpy() if nu.is_array_like(neuron_obj): return [neuron_obj[k] for k in syn_indexes] else: return synapse_indexes_to_synapses(neuron_obj, syn_indexes) elif return_df: return query_df elif return_index: return query_df.index.to_numpy() else: return query_df[return_column].to_numpy()
# ---------- 6:11 For creating datajoint entries ----------
[docs]def synapses_dj_export_dict_valid(synapse, output_spine_str=True,): syn=synapse spine_label = syn.head_neck_shaft compartment_coarse,compartment_fine = apu.coarse_fine_compartment_from_label(syn.compartment) return_dict = dict(synapse_id=syn.syn_id, synapse_type=syn.syn_type, skeletal_distance_to_soma = np.round(syn.soma_distance,2), limb_idx = syn.limb_idx, branch_idx = syn.branch_idx, compartment_coarse=compartment_coarse, compartment_fine=compartment_fine) if output_spine_str: spine_label = spu.spine_str_label(spine_label) return_dict["spine_bouton"] = spine_label return return_dict
[docs]def synapses_dj_export_dict_error(synapse,**kwargs): syn=synapse return dict(synapse_id=syn.syn_id, synapse_type=syn.syn_type,)
[docs]def synapses_to_dj_keys_old( neuron_obj, valid_synapses = True, verbose = False, nucleus_id = None, split_index = None, output_spine_str=True, ver=None): """ Pseudocode: 1) Get either the valid of invalid synapses 2) For each synapses export the following as dict synapse_id=syn, synapse_type=synapse_type, nucleus_id = nucleus_id, segment_id = segment_id, split_index = split_index, skeletal_distance_to_soma=np.round(syn_dist[syn_i],2), return the list Ex: from datasci_tools import numpy_dep as np dj_keys = syu.synapses_to_dj_keys(neuron_obj, verbose = True, nucleus_id=12345, split_index=0) np.unique([k["compartment"] for k in dj_keys],return_counts=True) Ex: How to get error keys with version: dj_keys = syu.synapses_to_dj_keys(neuron_obj, valid_synapses = False, verbose = True, nucleus_id=12345, split_index=0, ver=158) """ segment_id = neuron_obj.segment_id if nucleus_id is not None: neuron_obj.nucleus_id = nucleus_id if split_index is not None: neuron_obj.split_index = split_index if valid_synapses: synapses = neuron_obj.synapses_valid export_func = syu.synapses_dj_export_dict_valid else: synapses = neuron_obj.synapses_error export_func = syu.synapses_dj_export_dict_error for att in ["nucleus_id","segment_id","split_index"]: # globs = globals() # locs = locals() if getattr(neuron_obj,att) is None and eval(att) is None: raise Exception(f"{att} is None") st = time.time() # syn_keys = [dict(synapse_id=syn.syn_id, # synapse_type=syn.syn_type, # nucleus_id=neuron_obj.nucleus_id, # segment_id=neuron_obj.segment_id, # split_index = neuron_obj.split_index, # skeletal_distance_to_soma = np.round(syn.soma_distance,2)) for syn in synapses] syn_keys = [dict(export_func(syn,output_spine_str=output_spine_str), nucleus_id=getattr(neuron_obj,"nucleus_id",nucleus_id), segment_id=neuron_obj.segment_id, split_index = getattr(neuron_obj,"split_index",split_index)) for syn in synapses] #adding on the secondary seg if verbose: print(f"valid_synapses = {valid_synapses}") print(f"Time for {len(syn_keys)} synapse entries = {time.time() - st}") if ver is not None: syn_keys = [dict(k,ver=ver) for k in syn_keys] return syn_keys
[docs]def presyn_on_dendrite_synapses( neuron_obj, split_index=0, nucleus_id=0, return_dj_keys = False, verbose = True, **kwargs ): syns = syu.query_synapses( neuron_obj,query="(compartment=='dendrite') and (syn_type=='presyn')", return_synapses=True ) if verbose: print(f"# of presyns on dendrite = {len(syns)}") if return_dj_keys: return syu.synapses_to_dj_keys( neuron_obj, synapses=syns, valid_synapses=False, nucleus_id=nucleus_id, split_index = split_index, verbose = verbose) return syns
[docs]def presyn_on_dendrite_synapses_non_axon_like( neuron_obj, limb_branch_dict = None, plot = False, **kwargs): """ Purpose: To get the presyns on dendrites where the dendrites are restricted to those that aren't axon-like """ if limb_branch_dict is None: limb_branch_dict = neuron_obj.non_axon_like_limb_branch_on_dendrite return syu.query_synapses( neuron_obj, query = syu.presyns_on_dendrite_query, limb_branch_dict=limb_branch_dict, plot = plot, **kwargs )
[docs]def presyns_on_dendrite(neuron_obj, verbose = False, return_df=False, return_column = "syn_id", ): """ Purpose: Be able to find the synapses that are presyn on dendrite Pseudocode: 1) query the synapses_df for "(label=='limb_branch') and (compartment=='dendrite') and (syn_type=='presyn')" """ query_df = syu.query_synapses(neuron_obj, query=presyns_on_dendrite_query, return_df=True, verbose = False) if return_df: return query_df else: return query_df[return_column].to_numpy()
[docs]def axon_synapses(neuron_obj, ): return syu.query_synapses(neuron_obj, query="compartment=='axon'", return_df=False, verbose = False)
[docs]def n_presyns_on_dendrite(neuron_obj): return len(syu.presyns_on_dendrite(neuron_obj))
[docs]def synapse_ids_to_synapses(neuron_obj, synapse_ids, verbose = True): """ If have list of synapse ids and want to find the corresponding objects (not used in queries at all) """ st = time.time() match_syn = [k for k in neuron_obj.synapses_total if k.syn_id in set(synapse_ids)] if verbose: print(f"Total time for retrieving synapses: {time.time() - st}") return match_syn
[docs]def synapse_indexes_to_synapses(neuron_obj, synapse_indexes, verbose = False): st = time.time() match_syn = list(np.array(neuron_obj.synapses_total)[synapse_indexes]) if verbose: print(f"Total time for retrieving synapses: {time.time() - st}") return match_syn
[docs]def synapses_to_feature(synapses,feature): return [getattr(k,feature) for k in synapses]
[docs]def synapses_to_synapse_ids(synapses): return syu.synapses_to_feature(synapses,feature="syn_id")
[docs]def synapses_to_coordinates(synapses): return syu.synapses_to_feature(synapses,feature="coordinate")
[docs]def synapses_error_pre_coordinates(neuron_obj): return syu.synapses_to_coordinates(syu.synapses_error_pre(neuron_obj))
[docs]def synapses_error_post_coordinates(neuron_obj): return syu.synapses_to_coordinates(syu.synapses_error_post(neuron_obj))
[docs]def synapses_valid_pre_coordinates(neuron_obj): return syu.synapses_to_coordinates(syu.synapses_valid_pre(neuron_obj))
[docs]def synapses_valid_post_coordinates(neuron_obj): return syu.synapses_to_coordinates(syu.synapses_valid_post(neuron_obj))
[docs]def synapse_pre_post_valid_errror_stats_dict(neuron_obj): presyn_error_syn_non_axon_ids = syu.presyns_on_dendrite(neuron_obj) stats_dict = dict(n_valid_syn_presyn = len(syu.synapses_valid_pre(neuron_obj)), n_valid_syn_postsyn = len(syu.synapses_valid_post(neuron_obj)), n_errored_syn_presyn = len(syu.synapses_error_pre(neuron_obj)), n_errored_syn_postsyn = len(syu.synapses_error_post(neuron_obj)), presyn_error_syn_non_axon_ids = presyn_error_syn_non_axon_ids, n_errored_syn_presyn_non_axon = len(presyn_error_syn_non_axon_ids)) return stats_dict
[docs]def synapses_error_ids(neuron_obj): return syu.query_synapses(neuron_obj, query=error_query())
[docs]def synapse_pre_post_valid_errror_coordinates_dict(neuron_obj): """ Purpose: To make a dictionary that has the valid and error synapses Pseudocode: For valid and error: for presyn and postsyn 1) Get the corresponding synapses 2) extract the coordinates from the synapses 3) store in the dictionary """ return dict(valid_syn_centers_presyn=syu.synapses_valid_pre_coordinates(neuron_obj), errored_syn_centers_presyn = syu.synapses_error_pre_coordinates(neuron_obj), valid_syn_centers_postsyn = syu.synapses_valid_post_coordinates(neuron_obj), errored_syn_centers_postsyn = syu.synapses_error_post_coordinates(neuron_obj))
# ------------ Function to replace the old filtering function ----------- #
[docs]def synapse_filtering_vp2( neuron_obj, split_index = None, nucleus_id = None, original_mesh = None, verbose = True, compute_synapse_to_soma_skeletal_distance = False, return_synapse_filter_info = True, return_error_synapse_ids = True, return_synapse_center_data = False, return_errored_synapses_ids_non_axons = True, return_error_table_entries = True, return_neuron_obj = False, apply_non_axon_presyn_errors = True, plot_synapses = False, validation = False): """ Purpose: Applying the synpase filtering by using the synapses incorporated in the neuron object """ syu.add_synapses_to_neuron_obj(neuron_obj, validation = validation, verbose = verbose, original_mesh = original_mesh, plot_valid_error_synapses = False, calculate_synapse_soma_distance = False, add_valid_synapses = False, add_error_synapses=True) #---- 8/29: Will add limb and branch idx to synapses ------ syu.set_limb_branch_idx_to_synapses(neuron_obj) # prework: adding the nucleus_id,split-index and calculating the soma distances if nucleus_id is not None: neuron_obj.nucleus_id = nucleus_id if split_index is not None: neuron_obj.split_index = split_index syu.presyns_on_dendrite_as_errors = apply_non_axon_presyn_errors if compute_synapse_to_soma_skeletal_distance: syu.calculate_neuron_soma_distance(neuron_obj,verbose = True) keys_to_write_without_version = syu.synapses_to_dj_keys(neuron_obj, valid_synapses = True, verbose = True) keys_to_write_without_version_errors = syu.synapses_to_dj_keys(neuron_obj, valid_synapses = False, verbose = True) synapse_stats = syu.synapse_pre_post_valid_errror_stats_dict(neuron_obj) total_error_synapse_ids = syu.synapses_error_ids(neuron_obj) if verbose: print(f"# of total_error_synapse_ids = {len(total_error_synapse_ids)}") if return_synapse_center_data: synapse_center_coordinates = syu.synapse_pre_post_valid_errror_coordinates_dict(neuron_obj) if plot_synapses: print("Displaying the Synapse Classifications") syu.plot_valid_error_synpases(neuron_obj) syu.set_presyns_on_dendrite_as_errors_default() if ((not return_synapse_filter_info) and (not return_synapse_center_data) and (not return_error_synapse_ids) and (not return_error_table_entries) and (not return_neuron_obj) ): return data_to_write return_value = [keys_to_write_without_version] if return_synapse_filter_info: return_value.append(synapse_stats) if return_synapse_center_data: return_value.append(synapse_center_coordinates) if return_error_synapse_ids: return_value.append(total_error_synapse_ids) if return_error_table_entries: return_value.append(keys_to_write_without_version_errors) if return_neuron_obj: return_value.append(neuron_obj) return return_value
# ------------- 6/25: For the synapse near the endpoint -----------
[docs]def synapse_endpoint_dist_upstream_downstream(limb_obj, branch_idx, direction, synapses = None, synapse_type = "synapses", verbose = False): """ Purpose: Will compute the upstream or downstream distance of a synapse or group of synapses Pseudocode: 1) Get the upstream or downstream endpoint index For each synapse 2) Get the upstream or downstream distance 3) Return the list Ex: from neurd import synapse_utils as syu syu.synapse_endpoint_dist_upstream_downstream(limb_obj, branch_idx = 16, direction="downstream", verbose = True) """ singular_flag = False if synapses is None: synapses = getattr(limb_obj[branch_idx],synapse_type) else: if not nu.is_array_like(synapses): singular_flag = True synapses = [synapses] #1) Get the upstream or downstream endpoint index if direction == "upstream": endpoint_idx = nru.upstream_endpoint(limb_obj,branch_idx,return_endpoint_index=True) elif direction == "downstream": endpoint_idx = nru.downstream_endpoint(limb_obj,branch_idx,return_endpoint_index=True) if verbose: print(f"using direction {direction}, endpoint_idx = {endpoint_idx}") dist_from_endpoint = np.array([syn.endpoints_dist[endpoint_idx] for syn in synapses]) if verbose: print(f"dist_from_endpoint = {dist_from_endpoint}") if singular_flag: return dist_from_endpoint[0] return dist_from_endpoint
[docs]def synapse_endpoint_dist_downstream(limb_obj, branch_idx, synapses = None, synapse_type = "synapses", verbose = False): return synapse_endpoint_dist_upstream_downstream(limb_obj, branch_idx, direction="downstream", synapses = synapses, synapse_type = synapse_type, verbose = verbose)
[docs]def synapse_endpoint_dist_upstream(limb_obj, branch_idx, synapses = None, synapse_type = "synapses", verbose = False): return synapse_endpoint_dist_upstream_downstream(limb_obj, branch_idx, direction="upstream", synapses = synapses, synapse_type = synapse_type, verbose = verbose)
[docs]def plot_synapses_objs(neuron_obj, synapses, plot_with_spines = False, synapse_color = "red", synapse_size = 0.15, **kwargs): """ Purpose: To plot a certain group of synapses on top of the neuron object Ex: syu.plot_synapse_objs(neuron_obj_exc_syn_sp, synapses = syu.synapses_shaft(neuron_obj_exc_syn_sp), synapse_color="yellow" ) """ if nru.is_neuron_obj(neuron_obj): if not plot_with_spines: nviz.visualize_neuron_lite(neuron_obj, show_at_end=False) else: spu.plot_spines_head_neck(neuron_obj, show_at_end=False) else: nviz.plot_objects(neuron_obj, show_at_end=False) nviz.plot_objects( scatters=[syu.synapses_to_coordinates(synapses)], scatter_size=synapse_size, scatters_colors=synapse_color, append_figure=True)
[docs]def plot_head_neck_shaft_synapses(neuron_obj, plot_with_spines = True, head_color = "yellow", neck_color = "blue", shaft_color = "black", no_head_color = "purple", bouton_color = "pink", non_bouton_color = "brown", synapse_size = 0.15, verbose = False, **kwargs): """ Purpose: To plot all of the head neck and shaft spines of a neuron Ex: syu.plot_head_neck_shaft_synapses(neuron_obj_exc_syn_sp, synapse_size=0.08) """ if not plot_with_spines or neuron_obj.n_spines == 0: nviz.visualize_neuron_lite(neuron_obj, show_at_end=False) else: spu.plot_spines_head_neck(neuron_obj, show_at_end=False) synapses = [] synapses_colors = [] for t,col in zip(["head","neck","shaft","no_head","bouton","non_bouton"], [head_color,neck_color,shaft_color,no_head_color,bouton_color,non_bouton_color]): syns = getattr(syu,f"synapses_{t}")(neuron_obj) if verbose: print(f"# of {t} = {len(syns)} ({col}) ") if len(syns) > 0: synapses.append(np.array(syu.synapses_to_coordinates(syns)).reshape(-1,3)) synapses_colors.append(col) nviz.plot_objects( scatters=synapses, scatter_size=synapse_size, scatters_colors=synapses_colors, append_figure=True, **kwargs)
[docs]def synapses_over_limb_branch_dict(neuron_obj, limb_branch_dict, synapse_type = "synapses", plot_synapses=False): synapses = nru.feature_over_limb_branch_dict(neuron_obj, limb_branch_dict=limb_branch_dict, branch_func_instead_of_feature=getattr(syu,f"{synapse_type}")) if plot_synapses: syu.plot_synapses_objs(neuron_obj, synapses=synapses) return synapses
[docs]def synapse_density_over_limb_branch(neuron_obj, limb_branch_dict, synapse_type = "synapses", multiplier = 1, verbose = False, return_skeletal_length = False, density_type = "skeletal_length", ): """ Purpose: To calculate the synapse density over lmb branch Application: To be used for cell type (E/I) classification Pseudocode: 1) Restrict the neuron branches to be processed for postsynaptic density 2) Calculate the skeletal length over the limb branch 3) Find the number of postsyns over limb branch 4) Compute postsynaptic density Ex: syu.synapse_density_over_limb_branch(neuron_obj = neuron_obj_exc_syn_sp, limb_branch_dict=syn_dens_limb_branch, #neuron_obj = neuron_obj_inh_syn_sp, verbose = True, synapse_type = "synapses_post", #synapse_type = "synapses_head", #synapse_type = "synapses_shaft", multiplier = 1000) """ sk_length = nru.sum_feature_over_limb_branch_dict(neuron_obj, limb_branch_dict=limb_branch_dict, feature=density_type) n_synapses = nru.sum_feature_over_limb_branch_dict(neuron_obj, limb_branch_dict=limb_branch_dict, branch_func_instead_of_feature=getattr(syu,f"n_{synapse_type}")) if sk_length != 0: density = n_synapses/sk_length else: density = 0 density = density*multiplier if verbose: print(f"{density_type} = {sk_length}") print(f"# of {synapse_type} = {n_synapses}") print(f"Density = {density}") if return_skeletal_length: return density,sk_length else: return density
# ----------------- 7/20: helping with axon and dendrite merge errors ---------- #
[docs]def synapse_pre_perc_downstream(limb_obj, branch_idx, verbose = False): """ Purpose: Find the downstream downstream of a branch syu.synapse_pre_perc_downstream( limb_obj = neuron_obj_exc_syn_sp[0], branch_idx = 6, verbose = True, ) """ synapses_downstream = cnu.synapses_downstream(limb_obj,branch_idx, only_non_branching=False) pre_perc = syu.synapse_pre_perc(list(synapses_downstream)) if verbose: print(f"# of downstream synapses = {len(synapses_downstream)}") print(f"pre_perc = {pre_perc}") return pre_perc
[docs]def synapse_post_perc_downstream(limb_obj, branch_idx, verbose = False): """ Purpose: Find the downstream downstream of a branch Ex: syu.synapse_post_perc_downstream( limb_obj = neuron_obj_exc_syn_sp[0], branch_idx = 6, verbose = True, ) """ synapses_downstream = cnu.synapses_downstream(limb_obj,branch_idx, only_non_branching=False) post_perc = syu.synapse_post_perc(list(synapses_downstream)) if verbose: print(f"# of downstream synapses = {len(synapses_downstream)}") print(f"post_perc = {post_perc}") return post_perc
[docs]def synapses_downstream(limb_obj, branch_idx, verbose = False): synapses_downstream = cnu.synapses_downstream(limb_obj,branch_idx, only_non_branching=False) if verbose: print(f"# of downstream synapses = {len(synapses_downstream)}") return synapses_downstream
[docs]def n_synapses_downstream(limb_obj, branch_idx, verbose = False): return len(synapses_downstream(limb_obj, branch_idx, verbose))
[docs]def synapses_post_downstream(limb_obj, branch_idx, verbose = False): """ Purpose: Find the downstream downstream of a branch syu.synapse_pre_perc_downstream( limb_obj = neuron_obj_exc_syn_sp[0], branch_idx = 6, verbose = True, ) """ synapses_downstream = cnu.synapses_downstream(limb_obj,branch_idx, only_non_branching=False) post_synapses = syu.synapses_post(list(synapses_downstream)) if verbose: print(f"# of downstream synapses = {len(synapses_downstream)}") print(f"post_synapses = {post_synapses}") return post_synapses
[docs]def synapses_pre_downstream(limb_obj, branch_idx, verbose = False): """ Purpose: Find the downstream downstream of a branch syu.synapse_pre_perc_downstream( limb_obj = neuron_obj_exc_syn_sp[0], branch_idx = 6, verbose = True, ) """ synapses_downstream = cnu.synapses_downstream(limb_obj,branch_idx, only_non_branching=False) pre_synapses = syu.synapses_pre(list(synapses_downstream)) if verbose: print(f"# of downstream synapses = {len(synapses_downstream)}") print(f"pre_synapses = {pre_synapses}") return pre_synapses
[docs]def n_synapses_post_downstream(limb_obj, branch_idx, verbose = False): return len(synapses_post_downstream(limb_obj, branch_idx, verbose))
[docs]def n_synapses_pre_downstream(limb_obj, branch_idx, verbose = False): return len(synapses_pre_downstream(limb_obj, branch_idx, verbose))
# --------------- 7/26: Help with axon identification -------------
[docs]def synapses_within_distance_of_endpoint_upstream_downstream(branch_obj, direction, distance, synapse_type = "synapses", verbose = True): """ Purpose: Will measure the number of synapses within a certain distance of the upstream or downstream endpoint Pseudocode: 1) Get the desired synapses 2) Query the synapses based on the direction attribute Ex: branch_obj = neuron_obj[0][2] synapses_within_upstream_downstream_endpoint(branch_obj, direction="downstream", distance =15000, synapse_type="synapses_post", ) """ synapses = getattr(branch_obj,synapse_type) if verbose: print(f"# of unfiltered synapses = {len(synapses)}") if synapses is not None and len(synapses) > 0: syn_filtered = syu.query_synapses(synapses, query = f"{direction}_dist < {distance}", return_synapses=True) if verbose: print(f"# of syn_filtered = {len(syn_filtered)}") return syn_filtered else: return []
[docs]def n_synapses_within_distance_of_endpoint_upstream_downstream(branch_obj, direction, distance, synapse_type = "synapses", verbose = False, **kwargs): return len(syu.synapses_within_distance_of_endpoint_upstream_downstream(branch_obj, direction, distance, synapse_type = synapse_type, verbose = verbose, **kwargs))
[docs]def n_synapses_within_distance_of_endpoint_downstream(branch_obj, distance, synapse_type = "synapses", verbose = False, **kwargs): return syu.n_synapses_within_distance_of_endpoint_upstream_downstream(branch_obj, direction="downstream", distance=distance, synapse_type = synapse_type, verbose = verbose, **kwargs)
[docs]def n_synapses_within_distance_of_endpoint_upstream(branch_obj, distance, synapse_type = "synapses", verbose = False, **kwargs): return syu.n_synapses_within_distance_of_endpoint_upstream_downstream(branch_obj, direction="upstream", distance=distance, synapse_type = synapse_type, verbose = verbose, **kwargs)
[docs]def n_synapses_pre_within_distance_of_endpoint_upstream(branch_obj, distance, verbose = False, **kwargs): return syu.n_synapses_within_distance_of_endpoint_upstream(branch_obj, distance=distance, synapse_type = "synapses_pre", verbose = verbose, **kwargs)
[docs]def n_synapses_post_within_distance_of_endpoint_upstream(branch_obj, distance, verbose = False, **kwargs): return syu.n_synapses_within_distance_of_endpoint_upstream(branch_obj, distance=distance, synapse_type = "synapses_post", verbose = verbose, **kwargs)
[docs]def n_synapses_pre_within_distance_of_endpoint_downstream(branch_obj, distance, verbose = False, **kwargs): return syu.n_synapses_within_distance_of_endpoint_downstream(branch_obj, distance=distance, synapse_type = "synapses_pre", verbose = verbose, **kwargs)
[docs]def n_synapses_post_within_distance_of_endpoint_downstream(branch_obj, distance, verbose = False, **kwargs): return syu.n_synapses_within_distance_of_downstream_endpoint(branch_obj, distance=distance, synapse_type = "synapses_post", verbose = verbose, **kwargs)
[docs]def n_synapses_spine_within_distance_of_endpoint_downstream(branch_obj, distance, verbose = False, **kwargs): return syu.n_synapses_within_distance_of_endpoint_downstream(branch_obj, distance=distance, synapse_type = "synapses_spine", verbose = verbose, **kwargs)
[docs]def synapse_density_post_within_distance_of_endpoint_downstream(branch_obj, distance, verbose = False, **kwargs): n_post_syns = syu.n_synapses_within_distance_of_endpoint_downstream(branch_obj, distance=distance, synapse_type = "synapses_post", verbose = verbose, **kwargs) return n_post_syns/branch_obj.skeletal_length
# ---- offset n_synapses ------------
[docs]def synapses_offset_distance_of_endpoint_upstream_downstream(branch_obj, direction, distance, synapse_type = "synapses", verbose = True): """ Purpose: Will measure the number of synapses within a certain distance of the upstream or downstream endpoint Pseudocode: 1) Get the desired synapses 2) Query the synapses based on the direction attribute Ex: branch_obj = neuron_obj[0][2] synapses_within_upstream_downstream_endpoint(branch_obj, direction="downstream", distance =15000, synapse_type="synapses_post", ) """ # verbose = True if verbose: print(f"distance = {distance}") synapses = getattr(branch_obj,synapse_type) if verbose: print(f"# of unfiltered synapses = {len(synapses)}") if synapses is not None and len(synapses) > 0: syn_filtered = syu.query_synapses(synapses, query = f"{direction}_dist > {distance}", return_synapses=True) if verbose: print(f"# of syn_filtered = {len(syn_filtered)}") return syn_filtered else: return []
[docs]def n_synapses_offset_distance_of_endpoint_upstream_downstream(branch_obj, direction, distance, synapse_type = "synapses", verbose = False, **kwargs): return len(syu.synapses_offset_distance_of_endpoint_upstream_downstream(branch_obj, direction, distance, synapse_type = synapse_type, verbose = verbose, **kwargs))
[docs]def n_synapses_offset_distance_of_endpoint_downstream(branch_obj, distance, synapse_type = "synapses", verbose = False, **kwargs): return syu.n_synapses_offset_distance_of_endpoint_upstream_downstream(branch_obj, direction="downstream", distance=distance, synapse_type = synapse_type, verbose = verbose, **kwargs)
[docs]def n_synapses_offset_distance_of_endpoint_upstream(branch_obj, distance, synapse_type = "synapses", verbose = False, **kwargs): return syu.n_synapses_offset_distance_of_endpoint_upstream_downstream(branch_obj, direction="upstream", distance=distance, synapse_type = synapse_type, verbose = verbose, **kwargs)
[docs]def n_synapses_pre_offset_distance_of_endpoint_upstream(branch_obj, distance, verbose = False, **kwargs): return syu.n_synapses_offset_distance_of_endpoint_upstream(branch_obj, distance=distance, synapse_type = "synapses_pre", verbose = verbose, **kwargs)
[docs]def n_synapses_pre_offset_distance_of_endpoint_downstream(branch_obj, distance, verbose = False, **kwargs): return syu.n_synapses_offset_distance_of_endpoint_downstream(branch_obj, distance=distance, synapse_type = "synapses_pre", verbose = verbose, **kwargs)
[docs]def n_synapses_post_offset_distance_of_endpoint_upstream(branch_obj, distance, verbose = False, **kwargs): return syu.n_synapses_offset_distance_of_endpoint_upstream(branch_obj, distance=distance, synapse_type = "synapses_post", verbose = verbose, **kwargs)
[docs]def n_synapses_post_offset_distance_of_endpoint_downstream(branch_obj, distance=10_000, verbose = False, **kwargs): return syu.n_synapses_offset_distance_of_endpoint_downstream(branch_obj, distance=distance, synapse_type = "synapses_post", verbose = verbose, **kwargs)
[docs]def n_synapses_spine_offset_distance_of_endpoint_downstream(branch_obj, distance, verbose = False, **kwargs): return syu.n_synapses_offset_distance_of_endpoint_downstream(branch_obj, distance=distance, synapse_type = "synapses_spine", verbose = verbose, **kwargs)
[docs]def n_synapses_spine_offset_distance_of_endpoint_upstream(branch_obj, distance, verbose = False, **kwargs): return syu.n_synapses_offset_distance_of_endpoint_upstream(branch_obj, distance=distance, synapse_type = "synapses_spine", verbose = verbose, **kwargs)
[docs]def synapse_density_post_offset_distance_of_endpoint_downstream(branch_obj, distance, verbose = False, **kwargs): n_post_syns = syu.n_synapses_post_offset_distance_of_endpoint_downstream(branch_obj, distance=distance, verbose = verbose, **kwargs) return n_post_syns/branch_obj.skeletal_length
[docs]def synapse_density_post_offset_distance_of_endpoint_upstream(branch_obj, distance, verbose = False, **kwargs): n_post_syns = syu.n_synapses_post_offset_distance_of_endpoint_upstream(branch_obj, distance=distance, verbose = verbose, **kwargs) return n_post_syns/branch_obj.skeletal_length
[docs]def synapse_density_offset_distance_of_endpoint_upstream(branch_obj, distance, verbose = False, **kwargs): n_post_syns = syu.n_synapses_offset_distance_of_endpoint_upstream(branch_obj, distance=distance, verbose = verbose, **kwargs) return n_post_syns/branch_obj.skeletal_length
[docs]def plot_synapses_on_limb(neuron_obj, limb_idx, limb_branch_synapse_type = "synapses", **kwargs ): limb_name = nru.get_limb_string_name(limb_idx) nviz.visualize_neuron(neuron_obj, limb_branch_dict={limb_name:"all"}, limb_branch_synapses = True, limb_branch_synapse_type=limb_branch_synapse_type, **kwargs)
[docs]def limb_branch_with_synapses(neuron_obj, min_n_synapses = 1, synapse_type = "synapses"): syn_name = f"n_{synapse_type}" return ns.query_neuron(neuron_obj, functions_list=[syn_name], query = f"{syn_name} > {min_n_synapses}",)
[docs]def set_branch_synapses_attribute(branch_obj, synapse_attribute, branch_func, catch_errors = False, default_value=None, verbose = False, ): """ Purpose: Will set the synapse attributes on a branch object Ex: def new_func(branch_obj): raise Exception("") syu.set_branch_synapses_attribute(neuron_obj[0][0], synapse_attribute="compartment", #branch_func = apu.compartment_label_from_branch_obj, branch_func = new_func, catch_errors=True, default_value="exception_label", verbose = True) """ try: branch_val = branch_func(branch_obj) except Exception as e: if catch_errors: branch_val = default_value else: raise Exception(f"{str(e)}") if verbose: print(f"branch_val = {branch_val}") for s in branch_obj.synapses: setattr(s,synapse_attribute,branch_val)
[docs]def set_branch_synapses_compartment(branch_obj, catch_errors = False, default_value=None, verbose = False, ): syu.set_branch_synapses_attribute(branch_obj, synapse_attribute="compartment", branch_func=apu.compartment_label_from_branch_obj, catch_errors = catch_errors, default_value=default_value, verbose = verbose, )
[docs]def set_neuron_synapses_compartment(neuron_obj, ): """ Purpose: Will set the compartment labels of all synapses based on the compartment label of te branch """ nru.set_branch_attribute_over_neuron(neuron_obj, branch_func=syu.set_branch_synapses_compartment, catch_errors = False, default_value=None, verbose = False,) for s_name in neuron_obj.get_soma_node_names(): for s_syn in neuron_obj[s_name].synapses: s_syn.compartment = "soma"
''' def set_neuron_synapses_attribute(neuron_obj, synapse_attribute, branch_func, catch_errors = False, default_value=None, verbose = False,): """ Purpose: To set the attribute of synapses in an entire neuron based on a value computed from the branch """ nru.set_branch_attribute_over_neuron(neuron_obj, branch_func=branch_func, verbose = verbose, synapse_attribute=synapse_attribute, catch_errors=catch_errors, default_value=default_value) '''
[docs]def soma_face_offset_value(soma_name): soma_idx = int(soma_name[1:]) soma_value = -1*(nru.soma_face_offset + soma_idx)
[docs]def set_limb_branch_idx_to_synapses(neuron_obj): """ Purpose: Will add limb and branch indexes for all synapses in a Neuron object """ for limb_idx in neuron_obj.get_limb_names(return_int=True): limb_obj = neuron_obj[limb_idx] for branch_idx in limb_obj.get_branch_names(): branch_obj = limb_obj[branch_idx] for s in branch_obj.synapses: s.limb_idx = limb_idx s.branch_idx = branch_idx for soma_name in neuron_obj.get_soma_node_names(): soma_value = syu.soma_face_offset_value(soma_name) for s in neuron_obj[soma_name].synapses: s.limb_idx = soma_value s.branch_idx = soma_value
[docs]def get_synapses_compartment(neuron_obj, compartments, verbose = False): """ Purpose: will get synapses of a certain compartment if synapses are labeled Ex: synapses = syu.get_synapses_compartment(o_neuron, compartments=["apical","oblique"], verbose = True) """ compartments = nu.convert_to_array_like(compartments) query = f"compartment in {list(compartments)}" if verbose: print(f"query = {query}") synapse_objs = syu.query_synapses(neuron_obj, query = query, return_synapses=True) if verbose: print(f"Synapses in {compartments}: {len(synapse_objs)}") return synapse_objs
[docs]def plot_synapses_compartment(neuron_obj, compartments, synapse_size = 1, verbose =False, ): """ Purpose: To plot all synapses of a certain compartment Ex: synapses = syu.get_synapses_compartment(o_neuron, compartments=["apical","oblique"], verbose = True) """ synapses = syu.get_synapses_compartment(neuron_obj, compartments, verbose = verbose) syu.plot_synapses_objs(neuron_obj, synapses, synapse_size=synapse_size)
[docs]def plot_synapses_query(neuron_obj, query, synapse_size = 1, verbose = False): """ Purpose: To plot the synapses from a query Ex: syu.plot_synapses_query(neuron_obj, query = "syn_type=='presyn'") """ synapse_objs = syu.query_synapses(neuron_obj, query = query, return_synapses=True) if verbose: print(f"# of synapses in query = {len(synapse_objs)}") syu.plot_synapses_objs(neuron_obj, synapse_objs, synapse_size=synapse_size)
[docs]def plot_synapses_presyn_dendrite_errors(neuron_obj, verbose = False): syu.plot_synapses_query(neuron_obj, syu.presyns_on_dendrite_query, verbose = verbose)
[docs]def plot_synapses_soma(neuron_obj, synapse_size = 3, verbose =False, ): """ Ex: syu.plot_synapses_soma(o_neuron) """ syu.plot_synapses_compartment(neuron_obj, compartments="soma", synapse_size = synapse_size, verbose =verbose, )
[docs]def plot_synapses_valid_from_neuron_obj(neuron_obj, synapse_size = 0.3, verbose = True ): valid_syn = neuron_obj.synapses_valid if verbose: print(f"# of valid synapses = {len(valid_syn)}") syu.plot_synapses_objs(neuron_obj, valid_syn, synapse_size=synapse_size)
[docs]def plot_synapses_error_from_neuron_obj(neuron_obj, synapse_size = 0.3, verbose = True ): valid_syn = neuron_obj.synapses_error if verbose: print(f"# of error synapses = {len(valid_syn)}") syu.plot_synapses_objs(neuron_obj, valid_syn, synapse_size=synapse_size)
[docs]def synapse_compartment_spine_type_title( compartment_label=None, spine_label = None, syn_type = None, add_n_syn_to_title = False, verbose = False ): c = compartment_label sp_l= spine_label syn_l = syn_type title_str = [k for k in [c,sp_l,syn_l] if k is not None] if len(title_str)>1: title = "_".join(title_str) else: title = title_str[0] if verbose: print(f" {title}: {n_syns}") if add_n_syn_to_title: title = f"n_syn_{title}" return title
[docs]def synapses_by_compartment_spine_type( neuron_obj, compartment_label = None, spine_label = None, syn_type = None, plot_synapses=False, synapse_size=0.2, verbose = False, return_title = False, add_n_syn_to_title = False, **kwargs): """ Purpose: To be able to get the synapses of any specification of compartment and head_neck_shaft Pseudocode: 1) Get the spine int label 2) Get the compartment string label 3) Decide whether should be presyn or postsyn 4) Assemble query 5) Query the synapses 6) Return the synapses """ compartment_label_original = copy.copy(compartment_label) spine_label_original = copy.copy(spine_label) syn_type_original = copy.copy(syn_type) compartment_query = None if compartment_label is not None: if not nu.is_array_like(compartment_label): compartment_label = apu.compartment_label_to_all_labels(compartment_label) compartment_query = f"(compartment in {compartment_label})" spine_query = None if spine_label is not None: if not nu.is_array_like(spine_label): spine_label = [spine_label] spine_label = [spu.spine_int_label(k) for k in spine_label] spine_query = f"(head_neck_shaft in {spine_label})" syn_type_query = None if syn_type is None and compartment_label is not None: if len(np.intersect1d(apu.dendrite_labels,compartment_label)) > 0: syn_type = ["postsyn"] # elif len(np.intersect1d(apu.dendrite_labels,["axon"])) > 0: # syn_type = ["presyn"] else: syn_type = ["presyn","postsyn"] elif type(syn_type) == str: syn_type = nu.convert_to_array_like(syn_type) elif syn_type is None or None in syn_type: syn_type = ["presyn","postsyn"] else: syn_type = nu.convert_to_array_like(syn_type) syn_type_query = f"(syn_type in {syn_type})" if verbose: print(f"compartment_query = {compartment_query}") print(f"spine_query = {spine_query}") print(f"syn_type_query = {syn_type_query}") non_none_queries = [k for k in [compartment_query,spine_query,syn_type_query] if k is not None] if len(non_none_queries) == 0: raise Exception("No non None queries") elif len(non_none_queries) == 1: final_query = non_none_queries[0] else: final_query = " and ".join(non_none_queries) if verbose: print(F"final_query = {final_query}") returned_syns =syu.query_synapses(neuron_obj, query=final_query, return_synapses=True, **kwargs) if verbose: print(f"# of synapses in query = {len(returned_syns)}") if plot_synapses: if len(returned_syns) > 0: syu.plot_synapses_objs(neuron_obj, returned_syns, synapse_size=synapse_size) else: print(f"No synapses to plot") if return_title: title = syu.synapse_compartment_spine_type_title( compartment_label = compartment_label_original , spine_label = spine_label_original , syn_type = syn_type_original , add_n_syn_to_title = add_n_syn_to_title ) return returned_syns,title else: return returned_syns
[docs]def n_synapses_by_compartment_spine_type( neuron_obj, compartment_label = None, spine_label = None, syn_type = None, plot_synapses=False, synapse_size=0.2, verbose = False, return_title = False, add_n_syn_to_title = True, **kwargs): """ Return the number of synapses of a certain type """ return_value = syu.synapses_by_compartment_spine_type( neuron_obj, compartment_label = compartment_label, spine_label = spine_label, syn_type = syn_type, plot_synapses=plot_synapses, synapse_size=synapse_size, return_title = return_title, add_n_syn_to_title = add_n_syn_to_title, verbose = verbose, **kwargs) if return_title: return len(return_value[0]),return_value[1] else: return len(return_value)
[docs]def n_synapses_all_compartment_spine_type(neuron_obj, compartment_labels = None, spine_labels = None, syn_types = None, verbose = False, return_synapse_objs = False, add_n_syn_in_keys = True, **kwargs): """ Purpose: To get all combinations of compartments, spine labels and synapse types that should be computed """ synapse_dict = dict() if compartment_labels is None: compartment_labels = apu.compartment_labels_for_synapses_stats() # if spine_labels is None: # spine_labels = spu.spine_labels() # if syn_types is None: # syn_types = ["presyn","postsyn"] if verbose: print(f"compartment_labels = {compartment_labels}") # print(f"spine_labels = {spine_labels}") # print(f"syn_types = {syn_types}") all_combs = [] if not return_synapse_objs: func = syu.n_synapses_by_compartment_spine_type else: func = syu.synapses_by_compartment_spine_type for c in compartment_labels: cp = c if verbose: print(f"--- Working on comparment {c} ---") if spine_labels is None: c_spine_labels = apu.spine_labels_from_compartment(c) else: c_spine_labels = spine_labels if syn_types is None: c_syn_type = apu.syn_type_from_compartment(c) else: c_syn_type = syn_types for sp_l in c_spine_labels: for syn_l in c_syn_type: #print(f"{c}_{sp_l}_{syn_l}") n_syns,title = func( neuron_obj, compartment_label = c, spine_label = sp_l, syn_type = syn_l, plot_synapses = False, verbose = False, return_title = True, add_n_syn_to_title = add_n_syn_in_keys ) synapse_dict[f"{title}"] = n_syns # if add_n_syn_in_keys: # synapse_dict = {f"n_syn_{k}":v for k,v in synapse_dict.items()} return synapse_dict
[docs]def n_synapses_all_compartments(neuron_obj, compartment_labels = None, verbose = False, return_synapse_objs = False, **kwargs): """ Purpose: To get all combinations of compartments, spine labels and synapse types that should be computed """ return n_synapses_all_compartment_spine_type(neuron_obj, compartment_labels = compartment_labels, spine_labels = [None], syn_types = [None], verbose = verbose, return_synapse_objs = return_synapse_objs, **kwargs)
[docs]def n_synapses_all_spine_labels(neuron_obj, compartment_labels = None, verbose = False, return_synapse_objs = False, **kwargs): """ Purpose: To get all combinations of compartments, spine labels and synapse types that should be computed """ return n_synapses_all_compartment_spine_type(neuron_obj, compartment_labels = [None], spine_labels = spu.spine_labels(include_no_label=True), syn_types = [None], verbose = verbose, return_synapse_objs = return_synapse_objs, **kwargs)
[docs]def synapses_mesh_errored(neuron_obj): return syu.query_synapses(neuron_obj, query="label == 'mesh_errored'", return_synapse_objs=True)
[docs]def synapses_distance_errored(neuron_obj): return syu.query_synapses(neuron_obj, query="label == 'distance_errored'", return_synapse_objs=True)
[docs]def n_synapses_mesh_errored(neuron_obj): return len(syu.synapses_mesh_errored(neuron_obj))
[docs]def n_synapses_distance_errored(neuron_obj): return len(syu.synapses_distance_errored(neuron_obj))
[docs]def n_synapses_all_valid_error(neuron_obj): return dict( n_syn_valid = syu.n_synapses_valid(neuron_obj), n_syn_valid_pre = syu.n_synapses_valid_pre(neuron_obj), n_syn_valid_post = syu.n_synapses_valid_post(neuron_obj), n_syn_error = syu.n_synapses_error(neuron_obj), n_syn_error_pre = syu.n_synapses_error_pre(neuron_obj), n_syn_error_post = syu.n_synapses_error_post(neuron_obj), n_syn_presyns_on_dendrite = syu.n_presyns_on_dendrite(neuron_obj), n_syn_mesh_errored=syu.n_synapses_mesh_errored(neuron_obj), n_syn_distance_errored=syu.n_synapses_distance_errored(neuron_obj), )
[docs]def complete_n_synapses_analysis(neuron_obj, include_axon_ais_syn = True): syn_valid_error_dict = syu.n_synapses_all_valid_error(neuron_obj) syn_spine_dict = syu.n_synapses_all_spine_labels(neuron_obj) syn_compartment_dict = syu.n_synapses_all_compartments(neuron_obj) syn_comp_spine_type_dict = syu.n_synapses_all_compartment_spine_type(neuron_obj, verbose = False) syn_dict = dict() if include_axon_ais_syn: syn_dict["n_syn_axon_ais_postsyn"] = syu.n_axon_ais_synapses(neuron_obj) return gu.merge_dicts([syn_valid_error_dict, syn_spine_dict, syn_compartment_dict, syn_comp_spine_type_dict, syn_dict])
[docs]def n_synapses_analysis_axon_dendrite( neuron_obj, verbose = True, include_axon_ais_syn = True, include_soma_syn = True ): """ Puporse: calculating synapses """ syn_dict = syu.n_synapses_all_compartment_spine_type( neuron_obj, compartment_labels=["axon","dendrite"], verbose = verbose ) if include_axon_ais_syn: syn_dict["n_syn_axon_ais_postsyn"] = syu.n_axon_ais_synapses(neuron_obj) if include_soma_syn: syn_dict["n_syn_soma_postsyn"] = syu.n_synapses_somas_postsyn(neuron_obj) return syn_dict
synapse_attribute_to_dj_key_map = dict( syn_type="synapse_type", syn_id="synapse_id", soma_distance = "skeletal_distance_to_soma", ) dj_key_to_synapse_attribute_map = gu.invert_mapping(synapse_attribute_to_dj_key_map,one_to_one=True) dj_key_to_synapse_attribute_map
[docs]def synapse_obj_from_dj_synapse_dict(synapse_dict, ): """ Purpose: To convert a list of dictionaries to synapses objects Pseudocode: 1) convert the compartment_fine to just one label 2) convert the spine_bouton to the number 3) Send the new dictionary to a spine object """ if "compartment_fine" in synapse_dict.keys(): if synapse_dict["compartment_fine"] is not None: compartment = synapse_dict["compartment_fine"] else: compartment = synapse_dict["compartment_coarse"] else: compartment = "error" if "spine_bouton" in synapse_dict.keys(): head_neck_shaft = spu.spine_int_label(synapse_dict["spine_bouton"] ) else: head_neck_shaft = None if "skeletal_distance_to_soma" not in synapse_dict.keys(): synapse_dict["skeletal_distance_to_soma"] = -1 new_key = {k:v for k,v in synapse_dict.items() if k not in ["compartment_coarse", "compartment_fine", "spine_bouton"]} new_key.update(dict(compartment=compartment,head_neck_shaft = head_neck_shaft,)) for k,v in dj_key_to_synapse_attribute_map.items(): if k in new_key.keys(): new_key[v] = new_key[k] #return new_key return syu.Synapse(**new_key)
[docs]def synapses_obj_groups_from_queries(synapses_obj, queries, verbose = False): """ Purpose; Will divide synapses ob into groups based on a xeries of queries """ return_syns = [syu.query_synapses(synapses_obj,q, verbose=verbose, return_synapses=True) for q in queries] return return_syns
[docs]def valid_error_groups_from_synapses_obj(synapses_obj): syn_groups = syu.synapses_obj_groups_from_queries(synapses_obj, queries = [syu.valid_query(), syu.error_query()]) return syn_groups
[docs]def compartment_groups_from_synapses_obj(synapses_obj, compartments=None, verbose = False): if compartments is None: compartments = apu.compartments_to_plot queries = [f"compartment == '{c}'" for c in compartments] if verbose: print(f"For compartments: {compartments}") return syu.synapses_obj_groups_from_queries(synapses_obj, queries = queries, verbose = verbose)
[docs]def spine_bouton_groups_from_synapses_obj(synapses_obj, spine_bouton_labels = None, verbose = False): if spine_bouton_labels is None: spine_bouton_labels = spu.spine_labels(include_no_label=True) queries = [f"head_neck_shaft == '{spu.spine_int_label(c)}'" for c in spine_bouton_labels] if verbose: print(f"For spine_bouton_labels: {spine_bouton_labels}") return syu.synapses_obj_groups_from_queries(synapses_obj, queries = queries, verbose = verbose)
[docs]def presyn_postsyn_groups_from_synapses_obj(synapses_obj, verbose = False): return [syu.synapses_pre(synapses_obj),syu.synapses_post(synapses_obj)]
[docs]def synapse_plot_items_by_type_or_query( synapses_objs, synapses_size = 0.15, synapse_plot_type = "spine_bouton",#"compartment"# "valid_error", "soma" synapse_compartments = None, synapse_spine_bouton_labels = None, plot_error_synapses = True, valid_synapses_color = "orange", error_synapses_color = "aliceblue", synapse_queries = None, synapse_queries_colors = None, verbose = False, print_spine_colors = True): if synapse_compartments is None: synapse_compartments = apu.compartments_to_plot """ Purpose: will """ if synapse_spine_bouton_labels is None: synapse_spine_bouton_labels = spu.spine_bouton_labels_to_plot() def print_color_dict(color_dict): print(f"Synapse Colors:") for k,v in color_dict.items(): print(f" {k}:{v}") already_plotted_errors = False if synapse_queries is None: if synapse_plot_type == "valid_error": synapse_groups = syu.valid_error_groups_from_synapses_obj(synapses_objs) synapse_colors = [valid_synapses_color,error_synapses_color] color_dict = dict(valid=valid_synapses_color,error=error_synapses_color) already_plotted_errors = True elif synapse_plot_type == "compartment": synapse_groups = syu.compartment_groups_from_synapses_obj(synapses_objs, compartments = synapse_compartments, verbose=verbose) synapse_colors = apu.colors_from_compartments(synapse_compartments) color_dict = {k:v for k,v in zip(synapse_compartments,synapse_colors)} elif synapse_plot_type == "spine_bouton": synapse_groups = syu.spine_bouton_groups_from_synapses_obj( synapses_objs, spine_bouton_labels = synapse_spine_bouton_labels, verbose = verbose) synapse_colors = spu.colors_from_spine_bouton_labels(synapse_spine_bouton_labels) color_dict = {k:v for k,v in zip(synapse_spine_bouton_labels,synapse_colors)} elif synapse_plot_type == "valid_presyn_postsyn": valid_syns = syu.synapses_obj_groups_from_queries(synapses_objs,[syu.valid_query()])[0] synapse_groups = presyn_postsyn_groups_from_synapses_obj(valid_syns) color_dict = dict(presyn="yellow",postsyn="blue") synapse_colors = ["yellow","blue"] elif synapse_plot_type == "soma": valid_syns = syu.synapses_obj_groups_from_queries(synapses_objs,["compartment == 'soma'"])[0] synapse_groups = presyn_postsyn_groups_from_synapses_obj(valid_syns) print(f"# of syn_soma_pre = {len(synapse_groups[0])}" + f", # of syn_soma_post = {len(synapse_groups[1])}") color_dict = dict(presyn="yellow",postsyn="blue") synapse_colors = ["yellow","blue"] else: raise Exception(f"Unimplemented synapse_plot_type = {synapse_plot_type}") else: synapse_groups = syu.synapses_obj_groups_from_queries(synapses_objs, queries=synapse_queries, verbose = verbose) synapse_colors = synapse_queries_colors color_dict = {f"query_{i+1}":c for i,c in enumerate(synapse_colors)} if not already_plotted_errors and plot_error_synapses: error_syn = syu.synapses_error(synapses_objs) synapse_groups.append(error_syn) synapse_colors.append(error_synapses_color) color_dict["error"] = error_synapses_color if print_spine_colors: print_color_dict(color_dict) scatters = [syu.synapses_to_coordinates(k) for k in synapse_groups] scatters_colors = synapse_colors scatters_sizes = [synapses_size]*len(synapse_groups) return scatters,scatters_colors,scatters_sizes
# --------------- 10/25 --------------------#
[docs]def calculate_neuron_soma_distance_euclidean(neuron_obj, verbose =False, store_soma_placeholder = True, store_error_placeholder = True): """ Purpose: To calculate all of the soma distances for all the valid synapses on limbs Ex: calculate_neuron_soma_distance(neuron_obj, verbose = True) """ st = time.time() soma_center = neuron_obj["S0"].mesh_center for syn in neuron_obj.synapses: syn.soma_distance_euclidean = np.linalg.norm(soma_center - syn.coordinate) if store_soma_placeholder: if verbose: print(f"Putting Soma Placeholders") for s_idx in neuron_obj.get_soma_indexes(): st_loc = time.time() soma_synapses = neuron_obj[f"S{s_idx}"].synapses for syn in soma_synapses: syn.soma_distance_euclidean = -1*(nru.soma_face_offset + s_idx) if verbose: print(f"\n--- Soma {s_idx} soma calculation time = {np.round(time.time() - st_loc,3)}") if store_error_placeholder: st_loc = time.time() if verbose: print(f"Putting Error Placeholders") for syn in neuron_obj.synapses_error: syn.soma_distance_euclidean = -1 if verbose: print(f"\n--- Error soma calculation time = {np.round(time.time() - st_loc,3)}") if verbose: print(f"Total soma distance calculation time = {time.time() - st}")
# -------- attempting to get ais synapses -------
[docs]def axon_ais_synapses( neuron_obj, max_ais_distance_from_soma = None, plot = False, verbose = False, return_synapses = False, **kwargs ): """ Purpose: to get the postsyns synapses of those on the axon within a certain distance of the soma (so ideally the ais) Ex: """ if max_ais_distance_from_soma is None: max_ais_distance_from_soma = au.max_ais_distance_from_soma syu.calculate_neuron_soma_distance(neuron_obj) curr_syns = syu.query_synapses(neuron_obj, query="(compartment == 'axon') and (syn_type=='postsyn')" f" and (soma_distance < {max_ais_distance_from_soma})", return_synapses=return_synapses, plot=plot) if verbose: print(f"# of AIS postsyns = {len(curr_syns)}") return curr_syns
[docs]def n_axon_ais_synapses( neuron_obj, plot = False, verbose = False, **kwargs ): return len(syu.axon_ais_synapses( neuron_obj, plot = plot, verbose = verbose, **kwargs ))
[docs]def adjust_obj_with_face_offset( synapse_obj, face_offset, attributes_not_to_adjust = ("closest_face_idx",), verbose = False, ): """ Purpose: To adjust the spine properties that would be affected by a different face idx Ex: b_test = neuron_obj[0][18] sp_obj = b_test.spines_obj[0] sp_obj.export() spu.adjust_spine_obj_with_face_offset( sp_obj, face_offset = face_offset, verbose = True ).export() """ new_obj = copy.deepcopy(synapse_obj) for k,v in synapse_obj.export().items(): if "face_idx" not in k: continue if v is None: continue if k in attributes_not_to_adjust: #print(f"skipping {v} to not adjust") continue if verbose: print(f"Adjusting {k} because face_idx and not None") setattr(new_obj,k,v + face_offset) return new_obj
[docs]def endpoint_dist_extrema_over_syn( branch_obj, endpoint_type="downstream", extrema_type="max", default_dist = 100000000, verbose = False, **kwargs): syns = branch_obj.synapses if len(syns) > 0: dists = np.array([getattr(k,f"{endpoint_type}_dist") for k in syns]) return_value = getattr(np,extrema_type)(dists) else: return_value = default_dist if verbose: print(f"{extrema_type} {endpoint_type} dist = {return_value}") return return_value
[docs]def downstream_dist_min_over_syn( branch_obj, verbose = False, **kwargs ): return syu.endpoint_dist_extrema_over_syn( branch_obj, verbose = verbose, endpoint_type="downstream", extrema_type="min", **kwargs )
[docs]def downstream_dist_max_over_syn( branch_obj, verbose = False, **kwargs ): return syu.endpoint_dist_extrema_over_syn( branch_obj, verbose = verbose, endpoint_type="downstream", extrema_type="max", **kwargs )
[docs]def synapse_coordinates_from_synapse_df(df): return np.vstack(df["coordinate"].to_numpy()).reshape(-1,3)
[docs]def axon_on_dendrite_synapses( neuron_obj, plot_limb_branch = False, verbose = False, ): ax_on_d_lb = pru.axon_on_dendrite_plus_downstream( neuron_obj, plot = plot_limb_branch, ) axon_on_dendrite_synapses = syu.synapses_over_limb_branch_dict( neuron_obj, ax_on_d_lb ) if verbose: print(f"# of axon on dendrite merge synapses: {len(axon_on_dendrite_synapses)}") return axon_on_dendrite_synapses
[docs]def presyn_on_dendrite_synapses_after_axon_on_dendrite_filter_away( neuron_obj, axon_on_dendrite_limb_branch_dict = None, plot = False, **kwargs ): if axon_on_dendrite_limb_branch_dict is None: axon_on_dendrite_limb_branch_dict = ax_on_d_lb = pru.axon_on_dendrite_plus_downstream( neuron_obj, plot = False, ) lb = nru.limb_branch_invert(neuron_obj,axon_on_dendrite_limb_branch_dict) if len(lb) == 0: return np.array([]) return syu.query_synapses( neuron_obj, query = syu.presyns_on_dendrite_query, limb_branch_dict=lb, plot = plot, **kwargs )
[docs]def synapses_to_dj_keys( self, neuron_obj, valid_synapses = True, verbose = False, nucleus_id = None, split_index = None, output_spine_str=True, add_secondary_segment = True, ver=None, synapses = None, key = None): """ Pseudocode: 1) Get either the valid of invalid synapses 2) For each synapses export the following as dict synapse_id=syn, synapse_type=synapse_type, nucleus_id = nucleus_id, segment_id = segment_id, split_index = split_index, skeletal_distance_to_soma=np.round(syn_dist[syn_i],2), return the list Ex: import numpy as np dj_keys = syu.synapses_to_dj_keys(neuron_obj, verbose = True, nucleus_id=12345, split_index=0) np.unique([k["compartment"] for k in dj_keys],return_counts=True) Ex: How to get error keys with version: dj_keys = syu.synapses_to_dj_keys(neuron_obj, valid_synapses = False, verbose = True, nucleus_id=12345, split_index=0, ver=158) """ segment_id = neuron_obj.segment_id if nucleus_id is not None: neuron_obj.nucleus_id = nucleus_id if split_index is not None: neuron_obj.split_index = split_index if synapses is not None: if valid_synapses: export_func = syu.synapses_dj_export_dict_valid else: export_func = syu.synapses_dj_export_dict_error elif valid_synapses: synapses = neuron_obj.synapses_valid export_func = syu.synapses_dj_export_dict_valid else: synapses = neuron_obj.synapses_error export_func = syu.synapses_dj_export_dict_error for att in ["nucleus_id","segment_id","split_index"]: # globs = globals() # locs = locals() if getattr(neuron_obj,att) is None and eval(att) is None: raise Exception(f"{att} is None") st = time.time() syn_keys = [dict(export_func(syn,output_spine_str=output_spine_str), primary_nucleus_id=getattr(neuron_obj,"nucleus_id",nucleus_id), primary_seg_id=neuron_obj.segment_id, split_index = getattr(neuron_obj,"split_index",split_index)) for syn in synapses] #adding on the secondary seg """ Purpose: To add on the secondary """ if add_secondary_segment and len(syn_keys) > 0: syn_keys_df = pd.DataFrame(syn_keys) df = self.segment_id_to_synapse_table_optimized( neuron_obj.segment_id, return_df = True) df_secondary = df[["synapse_id","secondary_seg_id"]] syn_keys= pu.df_to_dicts(pd.merge(syn_keys_df,df_secondary,on="synapse_id")) if verbose: print(f"valid_synapses = {valid_synapses}") print(f"Time for {len(syn_keys)} synapse entries = {time.time() - st}") if ver is not None: syn_keys = [dict(k,ver=ver) for k in syn_keys] if key is not None: syn_keys = [gu.merge_dicts([k,key.copy()]) for k in syn_keys] return syn_keys
[docs]def synapse_df_from_synapse_dict( synapse_dict, segment_id = None, ): """ Purpose: convert synapse dict into a dataframe """ all_results = [] for prepost,p_data in synapse_dict.items(): for syn_id,syn_coord,syn_size in zip( p_data["synapse_ids"], p_data["synapse_coordinates"], p_data["synapse_sizes"], ): x,y,z = syn_coord curr_dict = dict( prepost = prepost, synapse_id = syn_id, synapse_x = x, synapse_y = y, synapse_z = z, synapse_size = syn_size ) all_results.append(curr_dict) df = pd.DataFrame.from_records(all_results) if segment_id is not None: df['segment_id'] = segment_id return df
[docs]def add_nm_to_synapse_df( df, scaling, ): df[ ["synapse_x_nm",'synapse_y_nm','synapse_z_nm'] ] = df[ ["synapse_x",'synapse_y','synapse_z'] ].to_numpy() * scaling df["synapse_size_nm"] = df["synapse_size"]*(scaling.prod()) return df
[docs]def synapse_df_from_csv( synapse_filepath, segment_id = None, coordinates_nm = True, scaling = None, verbose = True, **kwargs, ): """ Purpose: to read in a csv file """ if scaling is None: scaling = vdi.voxel_to_nm_scaling df = pu.csv_to_df( synapse_filepath ) if segment_id is not None: df = df.query(f"segment_id == {segment_id}").reset_index(drop=True) if coordinates_nm: df = add_nm_to_synapse_df( df, scaling=scaling, ) return df
[docs]def synapse_dict_from_synapse_df( df, scaling = None, verbose = True, coordinates_nm = True, syn_types = ["presyn","postsyn"], **kwargs ): if coordinates_nm: syn_coord_names = ["synapse_x_nm",'synapse_y_nm','synapse_z_nm','synapse_size_nm'] else: syn_coord_names = ["synapse_x",'synapse_y','synapse_z',"synapse_size"] synapse_dict = dict() for synapse_type in syn_types: df_curr = df.query(f"prepost == '{synapse_type}'").reset_index(drop=True) synapse_ids, centroid_xs, centroid_ys, centroid_zs,synapse_sizes = df_curr[ ["synapse_id"] + syn_coord_names ].to_numpy().T if len(synapse_ids) > 0: synapse_centers = np.vstack([centroid_xs,centroid_ys,centroid_zs]).T if scaling is not None: synapse_centers = synapse_centers* scaling else: synapse_centers = np.array([]) synapse_ids = np.array([]) synapse_sizes = np.array([]) synapse_dict[synapse_type] = dict( synapse_ids = synapse_ids, synapse_coordinates= synapse_centers, synapse_sizes = synapse_sizes ) if verbose: print(f"# of {synapse_type}: {len(synapse_dict[synapse_type]['synapse_coordinates'] )}") return synapse_dict
[docs]def synapse_dict_from_synapse_csv( synapse_filepath, segment_id = None, scaling = None, verbose = True, coordinates_nm = True, **kwargs ): """ Purpose: to injest the synapse information for a segment id in some manner Example implementation: injesting synapse inforation from a csv Pseudocode: 1) Read in the csv 2) Filter to the segment id 3) Creates the prepost dictionary to be filled: Iterates through pre and post (call preprost): a) filters for certain prepost b) Gets the synapse id, x, y, z and synapse size c) Stacks the syz and scales them if need d) Stores all data in dictionary for that prepost """ df = synapse_df_from_csv( synapse_filepath, segment_id = segment_id, coordinates_nm = coordinates_nm, scaling = scaling, verbose = verbose, ) return synapse_dict_from_synapse_df( df, scaling = None, verbose = verbose, coordinates_nm = coordinates_nm, **kwargs )
[docs]def fetch_synapse_dict_by_mesh_labels( segment_id, mesh, synapse_dict = None, original_mesh = None, original_mesh_kd = None, validation = False, verbose = False, original_mesh_method = True, mapping_threshold = 500, plot_synapses=False, plot_synapses_type = None, **kwargs): """ Purpose: To return a synapse dictionary mapping type (presyn/postsyn)---> mesh_label --> list of synapse ids for a segment id based on which original mesh face the synapses map to Pseudocode: 1) get synapses for the segment id Iterate through presyn and postsyn a. Find the errors because of distance b. Find the errors because of mesh cancellation c. Find the valid mesh (by set difference) store all error types in output dict 2) Plot the synapses if requested Example: mesh_label_dict = syu.fetch_synapse_dict_by_mesh_labels( segment_id=o_neuron.segment_id, mesh = nru.neuron_mesh_from_branches(o_neuron), original_mesh = du.fetch_segment_id_mesh(segment_id), validation=True, plot_synapses=True, verbose = True) """ if synapse_dict is None: synapse_dict = vdi.segment_id_to_synapse_dict( segment_id, validation=validation, verbose=verbose, **kwargs) mesh_label_dict = dict() for synapse_type in ["presyn","postsyn"]: if verbose: print(f"-- Working on {synapse_type}--") synapse_centers_scaled = synapse_dict[synapse_type]["synapse_coordinates"] synapse_ids = synapse_dict[synapse_type]["synapse_ids"] distance_errored_syn_idx = np.array([],dtype="int") mesh_errored_syn_idx = np.array([],dtype="int") valid_syn_idx = np.array([],dtype="int") local_label_dict = dict() if len(synapse_centers_scaled) > 0: if not original_mesh_method: distance_errored_syn_idx = tu.valid_coordiantes_mapped_to_mesh(mesh=mesh, coordinates=synapse_centers_scaled, mapping_threshold = mapping_threshold, return_idx = True, return_errors = True) valid_syn_idx = np.delete(np.arange(len(synapse_centers_scaled)),distance_errored_syn_idx) else: """ Pseudocode: """ if verbose: print(f"Using original_mesh_method") if original_mesh is None: original_mesh = vdi.fetch_segment_id_mesh(segment_id) distance_errored_syn_idx = tu.valid_coordiantes_mapped_to_mesh(mesh=original_mesh, coordinates=synapse_centers_scaled, mapping_threshold = mapping_threshold, return_idx = True, return_errors = True) mesh_errored_syn_idx_pre = tu.valid_coordiantes_mapped_to_mesh(mesh=mesh, original_mesh = original_mesh, original_mesh_kdtree=original_mesh_kd, coordinates=synapse_centers_scaled, mapping_threshold = mapping_threshold, return_idx = True, return_errors = True) mesh_errored_syn_idx = np.setdiff1d(mesh_errored_syn_idx_pre,distance_errored_syn_idx) total_error_syn_idx = np.hstack([distance_errored_syn_idx,mesh_errored_syn_idx]) valid_syn_idx = np.delete(np.arange(len(synapse_centers_scaled)),total_error_syn_idx) if verbose: print(f"# of distance_errored_syn_idx = {len(distance_errored_syn_idx)}") print(f"# of mesh_errored_syn_idx = {len(mesh_errored_syn_idx)}") print(f"# of valid_syn_idx = {len(valid_syn_idx)}") local_label_dict["distance_errored"] = synapse_ids[distance_errored_syn_idx] local_label_dict["mesh_errored"] = synapse_ids[mesh_errored_syn_idx] local_label_dict["valid"] = synapse_ids[valid_syn_idx] mesh_label_dict[synapse_type] = local_label_dict if plot_synapses: output_syn_dict = syu.synapse_dict_mesh_labels_to_synapse_coordinate_dict(synapse_mesh_labels_dict=mesh_label_dict, synapse_dict=synapse_dict) syu.plot_valid_error_synpases(neuron_obj = None, synapse_dict=output_syn_dict, mesh = mesh, original_mesh = original_mesh, keyword_to_plot=plot_synapses_type) return mesh_label_dict
[docs]def synapse_df_abridged( neuron_obj, ): syn_df = syu.synapses_df(syu.synapses_valid(neuron_obj)) syn_df_new = syn_df[["syn_id","syn_type","coordinate","volume","compartment","limb_idx","branch_idx","soma_distance"]] syn_df_new[["synapse_x_nm","synapse_y_nm","synapse_z_nm"]] = np.vstack(syn_df_new["coordinate"].to_numpy()) syn_df_new = pu.rename_columns( syn_df_new, dict( syn_type = "prepost", syn_id = "synapse_id", volume = "synapse_size", ) ) return syn_df_new
# ------------- Setting up parameters ----------- # -- default attributes_dict_default = dict( voxel_to_nm_scaling = mvu.voxel_to_nm_scaling, vdi = mvu.data_interface ) global_parameters_dict_default = dict( #max_ais_distance_from_soma = 50_000 ) # -- microns global_parameters_dict_microns = {} attributes_dict_microns = {} #-- h01-- attributes_dict_h01 = dict( voxel_to_nm_scaling = hvu.voxel_to_nm_scaling, vdi = hvu.data_interface ) global_parameters_dict_h01 = dict() # data_type = "default" # algorithms = None # modules_to_set = [syu] # def set_global_parameters_and_attributes_by_data_type(data_type, # algorithms_list = None, # modules = None, # set_default_first = True, # verbose=False): # if modules is None: # modules = modules_to_set # modu.set_global_parameters_and_attributes_by_data_type(modules,data_type, # algorithms=algorithms_list, # set_default_first = set_default_first, # verbose = verbose) # set_global_parameters_and_attributes_by_data_type(data_type, # algorithms) # def output_global_parameters_and_attributes_from_current_data_type( # modules = None, # algorithms = None, # verbose = True, # lowercase = True, # output_types = ("global_parameters"), # include_default = True, # algorithms_only = False, # **kwargs): # if modules is None: # modules = modules_to_set # return modu.output_global_parameters_and_attributes_from_current_data_type( # modules, # algorithms = algorithms, # verbose = verbose, # lowercase = lowercase, # output_types = output_types, # include_default = include_default, # algorithms_only = algorithms_only, # **kwargs, # ) #--- from neurd_packages --- from . import apical_utils as apu from . import axon_utils as au from . import branch_attr_utils as bau from . import concept_network_utils as cnu from . import h01_volume_utils as hvu from . import microns_volume_utils as mvu from . import neuron_searching as ns from . import neuron_statistics as nst from . import neuron_utils as nru from . import neuron_visualizations as nviz from . import proofreading_utils as pru from . import spine_utils as spu presyns_on_dendrite_query = ("(label=='limb_branch') and ((compartment=='dendrite') or " f" (compartment in {apu.dendrite_compartment_labels()})) and (syn_type=='presyn')") #--- from mesh_tools --- from mesh_tools import skeleton_utils as sk from mesh_tools import trimesh_utils as tu #--- from datasci_tools --- from datasci_tools import general_utils as gu from datasci_tools import module_utils as modu from datasci_tools import numpy_dep as np from datasci_tools import numpy_utils as nu from datasci_tools import pandas_utils as pu from . import neuron from . import synapse_utils as syu