def postfocality_to_dendrogram_coloring( x: pd.DataFrame, p_val: float, neuron: navis.TreeNeuron ): """ Function to take the results of synaptic focality tests and create colour dict for plotting """ x_thresh = x[x.p_val < p_val].copy() partner_dict = dict(zip(x_thresh.partner_neuron, x_thresh.partner_type)) # fetching synapse connections conn = nvneu.fetch_synapse_connections(target_criteria=neuron.id, source_criteria=x_thresh.partner_neuron.tolist()) # filtering for highly probably synapses conn_thresh = conn[(conn.confidence_pre > 0.9) & (conn.confidence_post > 0.9)].copy() pal = sns.color_palette('turbo', len(partner_dict)) pal_dict = dict(zip(partner_dict.keys(), pal)) nodes_matched = nbm.match_connectors_to_nodes(conn_thresh, neuron, synapse_type='post') c2n = dict(zip(nodes_matched.connector, nodes_matched.bodyId_pre)) c2color = {i: pal_dict[c2n[i]] for i in c2n.keys()} return(c2color, c2n, conn_thresh, partner_dict)
def aba_postsyn_focality( neuron: navis.TreeNeuron, confidence_threshold: Tuple = (0.0, 0.0), n_iter: int = 100, syn_thresh: int = 1 ): print('Fetching synaptic connections...') syn = nvneu.fetch_synapse_connections(target_criteria=neuron.id) print('Thresholding synapses by confidences...') syn = syn[(syn.confidence_pre > confidence_threshold[0]) & (syn.confidence_post > confidence_threshold[1])].copy() print('Thresholding synapses by synapse count...') count_dict = dict(Counter(syn.bodyId_pre).most_common()) syn = syn[[count_dict[i] > syn_thresh for i in syn.bodyId_pre]].copy() print('Matching connections to nodes...') # syn_wmc = synaptic connections with connectors matched syn_wmc = nbm.match_connectors_to_nodes(syn, neuron, synapse_type='post') connector2node = dict(zip(neuron.connectors.connector_id, neuron.connectors.node_id)) syn_wmc['node'] = syn_wmc.connector.map(connector2node).to_numpy() unique_usns = syn_wmc.bodyId_pre.unique() neuron_to_uNodes = {i: syn_wmc[syn_wmc.bodyId_pre == i].node.unique() for i in unique_usns} print('Calculating all by all geodesic matrix for nodes...') g_mat = navis.geodesic_matrix(neuron) df = pd.DataFrame() df['unique_ids'] = unique_usns T_obs_list = [] An_list = [] Bn_list = [] rdsd_list = [] print('Calculating T obs and drawing from random samples...') for i in unique_usns: T_obs, An, Bn = calculate_T_obs(neuron_id=i, neuron_to_node_dict=neuron_to_uNodes, gmat=g_mat) rdsd = random_draw_sample_dist(n_iter, g_mat, T_obs, An, Bn) T_obs_list.append(T_obs) An_list.append(An) Bn_list.append(Bn) rdsd_list.append(rdsd) df['T_obs'] = T_obs_list df['An'] = An_list df['Bn'] = Bn_list df['rdsd'] = rdsd_list return(df)
def matching_inputs_to_compartments( neuron_id: int, roi: navis.Volume, Ra: float, Rm: float, Cm: float): # Fetch the healed skeleton full_skeleton = nvneu.fetch_skeletons(neuron_id, heal=True)[0] # which of the whole neuron's nodes are in the roi skeleton_in_roi = navis.in_volume(full_skeleton.nodes[['x', 'y', 'z']], roi, mode='IN') # Fetch the neurons synapses postsyn = nvneu.fetch_synapse_connections(target_criteria=neuron_id) # match the connectors to nodes syn_to_node = match_connectors_to_nodes(postsyn, full_skeleton, synapse_type='post') # which of these are in the roi roi_syn_con = syn_to_node[syn_to_node.node.isin(full_skeleton.nodes[skeleton_in_roi].node_id.tolist())].copy() # Count how many synapses the upstream neurons have on your neuron of interest n_syn = dict(Counter(roi_syn_con.bodyId_pre.tolist()).most_common()) # fetch these neurons a, b = nvneu.fetch_neurons(roi_syn_con.bodyId_pre.unique()) a['n_syn'] = [n_syn[i] for i in a.bodyId.tolist()] # adding the instance names to the synapses in the roi bid_to_instance = dict(zip(a.bodyId.tolist(), a.instance.tolist())) roi_syn_con['instance'] = [bid_to_instance[i] for i in roi_syn_con.bodyId_pre] # compartmentalise the neuron and find the nodes in each compartment for the prepared neuron compartments_in_roi, nodes_in_roi = find_compartments_in_roi(full_skeleton, roi=roi, min_samples=6, Cm=Cm, Ra=Ra, Rm=Rm) clusters = compartments_in_roi.nodes.node_cluster.unique() cluster_dict = {} # find the nodes that make up each compartment in the full neuron for i in clusters: clust_nodes = cluster_to_all_nodes(full_skeleton, start_end_node_pairs=permute_start_end(compartments_in_roi, nodes_in_roi, cluster=i)) cluster_dict[i] = clust_nodes # cluster_dict = {k : s for s, k in cluster_dict.items()} # roi_syn_con['compartment'] = [cluster_dict[i] for i in roi_syn_con.node.tolist()] return(cluster_dict)
def synaptic_focality_KS_test( x: navis.TreeNeuron, synapse_type: str = 'pre', confidence_threshold: Tuple = (0.9, 0.9) ): if synapse_type == 'pre': g_mat = navis.geodesic_matrix(x) syn = nvneu.fetch_synapse_connections(source_criteria=x.id) syn = syn[(syn.confidence_pre > confidence_threshold[0]) & (syn.confidence_post > confidence_threshold[1])].copy() syn = nbm.match_connectors_to_nodes(syn, x, synapse_type=synapse_type) df = pd.DataFrame() df['partner_id'] = syn.bodyId_post.unique() partner_gt = {} partner_statistic = {} partner_pval = {} for i, j in enumerate(df.partner_id): nodes = syn[syn.bodyId_post == j].node.tolist() truth_array = np.isin(g_mat.index, nodes) partner_geo_dist_vals = g_mat[truth_array].values.mean(axis=1) total_geo_dist_vals = g_mat[~truth_array].values.mean(axis=1) partner_gt[j] = partner_geo_dist_vals KS_test = ks_2samp(partner_geo_dist_vals, total_geo_dist_vals) partner_statistic[j] = KS_test.statistic partner_pval[j] = KS_test.pvalue df['gT'] = df.partner_id.map(partner_gt) df['KS statistic'] = df.partner_id.map(partner_statistic) df['KS pval'] = df.partner_id.map(partner_pval) df['n_syn'] = [len(i) for i in df.gT] elif synapse_type == 'post': g_mat = navis.geodesic_matrix(x) syn = nvneu.fetch_synapse_connections(target_criteria=x.id) syn = syn[(syn.confidence_pre > confidence_threshold[0]) & (syn.confidence_post > confidence_threshold[1])].copy() syn = nbm.match_connectors_to_nodes(syn, x, synapse_type=synapse_type) df = pd.DataFrame() df['partner_id'] = syn.bodyId_pre.unique() partner_gt = {} partner_statistic = {} partner_pval = {} for i, j in enumerate(df.partner_id): nodes = syn[syn.bodyId_pre == j].node.tolist() truth_array = np.isin(g_mat.index, nodes) partner_geo_dist_vals = g_mat[truth_array].values.mean(axis=1) total_geo_dist_vals = g_mat[~truth_array].values.mean(axis=1) partner_gt[j] = partner_geo_dist_vals KS_test = ks_2samp(partner_geo_dist_vals, total_geo_dist_vals) partner_statistic[j] = KS_test.statistic partner_pval[j] = KS_test.pvalue df['gT'] = df.partner_id.map(partner_gt) df['KS statistic'] = df.partner_id.map(partner_statistic) df['KS pval'] = df.partner_id.map(partner_pval) df['n_syn'] = [len(i) for i in df.gT] return(df)
def compartmentalise_neuron( neuron_id: int, Rm: float, Ra: float, Cm: float, roi: navis.Volume, return_electromodel: bool): # Fetching the neuron ds_neuron = nvneu.fetch_skeletons(neuron_id, heal=True)[0] original_neuron = ds_neuron.copy() # Electrotonic model DS_NEURON = prepare_neuron(ds_neuron, change_units=True, factor=1e3) test_m, test_memcap = calculate_M_mat(DS_NEURON, Rm, Ra, Cm, solve=False) test_m_solved = np.linalg.inv(sparse.csr_matrix.todense(test_m)) # running PHATE phate_operator = phate.PHATE(n_components=3, n_jobs=-2, verbose=False) mat_red, labels, n_clusters, n_noise = find_clusters( test_m_solved, phate_operator, eps=1e-02, min_samples=6) # index and labels index_to_label = dict(zip(range(0, len(labels)), labels)) ds_neuron.nodes['node_cluster'] = ds_neuron.nodes.index.map(index_to_label) # node_to_compartment = dict(zip(ds_neuron.nodes.node_id.tolist(), # ds_neuron.nodes.node_cluster.tolist())) unique_compartments = ds_neuron.nodes.node_cluster.unique() # Finding the cluster of the nodes that were removed when downsampling the neuron whole_neuron_node_to_cluster = [] for i in unique_compartments: nodes_to_permute = ds_neuron.nodes[ds_neuron.nodes.node_cluster == i].node_id.tolist() start_end = [i for i in itertools.permutations(nodes_to_permute, 2)] # start_end = [i for i in itertools.permutations( # ds_neuron.nodes[ds_neuron.nodes.node_cluster == i].node_id.tolist(), 2)] nodes_of_cluster = cluster_to_all_nodes(original_neuron, start_end) node_to_cluster_dictionary = dict(zip(nodes_of_cluster, [i] * len(nodes_of_cluster))) whole_neuron_node_to_cluster.append(node_to_cluster_dictionary) whole_neuron_node_to_cluster_dict = {k:v for d in whole_neuron_node_to_cluster for k, v in d.items()} # Fetching postsynapses ds_neuron_postsynapses = nvneu.fetch_synapse_connections(target_criteria=neuron_id) ds_neuron_synapse_to_node = match_connectors_to_nodes(ds_neuron_postsynapses, original_neuron, synapse_type='post') # Which nodes are in the CA? if roi is not None: skeleton_in_roi = navis.in_volume(original_neuron.nodes[['x', 'y', 'z']].values, roi, inplace=False) ds_isin = ds_neuron_synapse_to_node.node.isin(original_neuron.nodes[skeleton_in_roi].node_id.tolist()) roi_syn_con = ds_neuron_synapse_to_node[ds_isin].copy() else: roi_syn_con = ds_neuron_synapse_to_node.copy() # roi_syn_con = ds_neuron_synapse_to_node[ds_neuron_synapse_to_node.node.isin( # original_neuron.nodes[skeleton_in_roi].node_id.tolist())].copy() a, b = nvneu.fetch_neurons(roi_syn_con.bodyId_pre.unique()) bid_to_instance = dict(zip(a.bodyId.tolist(), a.instance.tolist())) roi_syn_con['instance'] = [bid_to_instance[i] for i in roi_syn_con.bodyId_pre] nodes_to_query = roi_syn_con[~roi_syn_con.node.isin(whole_neuron_node_to_cluster_dict.keys())].node.tolist() comp_of_missing_nodes = find_compartments_of_missing_nodes(roi_syn_con, list(whole_neuron_node_to_cluster_dict.keys()), original_neuron, ds_neuron) whole_neuron_node_to_cluster_dict = {**whole_neuron_node_to_cluster_dict, **comp_of_missing_nodes} roi_syn_con['compartment'] = [whole_neuron_node_to_cluster_dict[i] for i in roi_syn_con.node.tolist()] original_neuron = node_to_compartment_full_neuron(original_neuron, ds_neuron) if return_electromodel: return(original_neuron, ds_neuron, roi_syn_con, test_m, test_memcap) else: return(original_neuron, ds_neuron, roi_syn_con)
def adjx_from_syn_conn( x: List[int], presyn_postsyn: str = "pre", roi: Optional = None, ct: tuple = (0.0, 0.0), rename_index: bool = False, ): """ Creates an adjacency matrix from synapse connections Parameters ---------- presyn_postsyn: x : list a list of bodyIds of which you want to find their synaptic (pre/post) connections presyn_postsyn : str a string of either 'pre' or 'post' If 'pre', the function will search for the presynaptic connections / downstream neurons of x If 'post', the function will search for the postsynaptic connections / upstream neurons of x roi : navis.Volume A region of interest within which you are filtering the connections for ct : tuple Confidence threshold tuple containing the confidence value to filter above The first value is presynaptic confidence and the second value postsynaptic confidence e.g. (0.9, 0.8) will filter for connections where the presynaptic confidence > 0.9 and the postsynaptic confidence > 0.8 rename_index : bool Whether to rename the index using the type of the connected neuron Returns ------- df : a DataFrame where x are the columns, the connection type (pre/post) are the rows and the values the number of connections partner_type_dict : a dictionary where the keys are bodyIds of the upstream/downstream neurons and the values are their types Examples -------- """ if presyn_postsyn == "pre": con = nvneu.fetch_synapse_connections(source_criteria=x) if roi: tt = navis.in_volume(con[["x_pre", "y_pre", "z_pre"]].values, roi) con = con[tt].copy() if ct[0] or ct[1] > 0.0: con = con[(con.confidence_pre > ct[0]) & (con.confidence_post > ct[1])].copy() neurons = con.bodyId_post.unique() n, _ = nvneu.fetch_neurons(neurons) partner_type_dict = dict(zip(n.bodyId.tolist(), n.type.tolist())) count = Counter(con.bodyId_post) count = count.most_common() count_dict = dict(count) df = pd.DataFrame(columns=[x], index=[i for i, j in count], data=[count_dict[i] for i, j in count]) elif presyn_postsyn == "post": con = nvneu.fetch_synapse_connections(target_criteria=x) if roi: tt = navis.in_volume(con[["x_post", "y_post", "z_post"]].values, roi) con = con[tt].copy() if ct[0] or ct[1] > 0.0: con = con[(con.confidence_pre > ct[0]) & (con.confidence_post > ct[1])].copy() neurons = con.bodyId_pre.unique() n, _ = nvneu.fetch_neurons(neurons) partner_type_dict = dict(zip(n.bodyId.tolist(), n.type.tolist())) count = Counter(con.bodyId_pre) count = count.most_common() count_dict = dict(count) df = pd.DataFrame(index=[i for i, j in count], columns=[x], data=[count_dict[i] for i, j in count]) df = df.T.copy() # df = pd.DataFrame( # columns=[x], index=[i for i, j in count], data=[count_dict[i] for i, j in count]) if rename_index: df.index = [partner_type_dict[i] for i in df.index] return (df, partner_type_dict)