123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- import pickle
- import graph_tool as gt
- import itertools
- import numpy as np
- from interneuron_polarity.model.morphology.volume import get_distance_from_to
- class RecurrentInhibition:
- INTERNEURON_IDENTITY = "interneuron_idx"
- POSITION = "position"
- def __init__(self, in_ex_connectivity, ex_somata_positions):
- n_in, n_ex = tuple(in_ex_connectivity.shape)
- g = gt.Graph(directed=False)
- interneuron_identity = g.new_edge_property("int")
- positions = g.new_vertex_property("vector<float>")
- exs = g.add_vertex(n_ex)
- for ex in exs:
- positions[ex] = ex_somata_positions[:, g.vertex_index[ex]]
- for interneuron_idx in range(n_in):
- connected_exs_indices = np.where(in_ex_connectivity[interneuron_idx, :] == 1)[0]
- for comb in itertools.combinations(set(connected_exs_indices), 2):
- ex1, ex2 = comb
- new_edge = g.add_edge(ex1, ex2)
- interneuron_identity[new_edge] = interneuron_idx
- g.edge_properties[RecurrentInhibition.INTERNEURON_IDENTITY] = interneuron_identity
- g.vertex_properties[RecurrentInhibition.POSITION] = positions
- self.n_in = n_in
- self.n_ex = n_ex
- self.positions = ex_somata_positions
- self.g = g
- def get_distance_to_neighbors(self, excitatory_neuron_index):
- neighbors = self.g.get_out_neighbors(excitatory_neuron_index)
- distances = self.get_distance(excitatory_neuron_index, neighbors)
- return distances[0,:]
- def get_distances_to_neighbors(self):
- distances = [self.get_distance_to_neighbors(idx) for idx in np.arange(0, self.n_ex)]
- return np.concatenate(tuple(distances))
- def get_number_of_neighbors(self):
- return np.array([len(self.g.get_out_neighbors(v)) for v in self.g.vertices()])
- def get_second_order_neighbors(self, tested_vertex):
- first_order_neighbors = self.g.get_out_neighbors(tested_vertex)
- excluded_neighbors = set(first_order_neighbors).union([tested_vertex])
- second_order_neighbors = []
- for first_order_neighbor in first_order_neighbors:
- potential_second_order_neighbors = set(self.g.get_out_neighbors(first_order_neighbor))
- second_order_neighbors.extend(potential_second_order_neighbors.difference(excluded_neighbors))
- return second_order_neighbors
- def get_distance_to_second_order_neighbors(self, excitatory_idx):
- second_order_neighbors = self.get_second_order_neighbors(excitatory_idx)
- distances = self.get_distance(excitatory_idx, second_order_neighbors)
- return distances[0,:]
- def get_distances_to_second_order_neighbors(self):
- distances = [self.get_distance_to_second_order_neighbors(idx) for idx in np.arange(0, self.n_ex)]
- return np.concatenate(tuple(distances))
- def get_connected_interneuron_indices(self, excitatory_neuron_index):
- edges = self.g.get_out_edges(excitatory_neuron_index)
- return np.array([self.g.edge_properties[RecurrentInhibition.INTERNEURON_IDENTITY][edge] for edge in edges])
- def get_numbers_of_containing_axonal_clouds(self):
- number_of_containing_axonal_clouds = [len(np.unique(self.get_connected_interneuron_indices(idx))) for idx in range(self.n_ex)]
- return number_of_containing_axonal_clouds
- def get_distance(self, from_idx, to):
- this_position = self.positions[:, from_idx]
- neighbor_positions = self.positions[:, to]
- distances = get_distance_from_to(this_position, neighbor_positions)
- return distances
- def save(self, filename):
- with open(filename, 'wb') as file:
- pickle.dump(self, file)
- @staticmethod
- def load(filename):
- with open(filename, 'rb') as file:
- recurrent_inhibition_graph = pickle.load(file)
- return recurrent_inhibition_graph
- class OverlapMatrix:
- def __init__(self, excitatory_neurons, inhibitory_neurons, overlaps):
- self.excitatory_neurons = excitatory_neurons
- self.inhibitory_neurons = inhibitory_neurons
- self.overlaps = overlaps
- def ex_on_ex(self):
- return self.overlaps[:self.excitatory_neurons.number, :self.excitatory_neurons.number]
- def ex_on_in(self):
- return self.overlaps[:self.excitatory_neurons.number, self.excitatory_neurons.number:-1]
- def in_on_in(self):
- return self.overlaps[self.excitatory_neurons.number:-1, self.excitatory_neurons.number:-1]
- def in_on_ex(self):
- return self.overlaps[self.excitatory_neurons.number:-1, :self.excitatory_neurons.number]
- def get_submatrices(self):
- return self.ex_on_ex(), self.ex_on_in(), self.in_on_in(), self.in_on_ex()
- def save_overlap(filename, overlap_matrix):
- with open(filename, 'wb') as file:
- pickle.dump(overlap_matrix,file)
- def load_overlap(filename):
- with open(filename, 'rb') as file:
- overlap_matrix = pickle.load(file)
- return overlap_matrix
|