### from conmorph.connections import load_overlap import numpy as np import matplotlib.pyplot as plt file_path = "/home/pfeiffer/Projects/subiculum_interneuron_polarity/data/" file_name = "circular_inhibitory_neurons_overlap_matrix_0" path_to_store = file_path + "/" + file_name + ".pickle" overlap_matrix = load_overlap(path_to_store) plt.imshow(overlap_matrix.overlaps) plt.show() ### Use a transfer function to turn the overlaps into connection probabilities # The transfer function determines how much an overlap is weighted in comparison to others, the identity weighs all overlaps equally, a higher power will prefer high overlaps def transfer_function(overlap): return overlap**2 # From the transferred overlap, one normalizes the results such that if each entry is treated as a probability the expected number of connections equals the number of (experimentally observed ones) # what is the expected number of connections, given a number N of non-zero overlaps, it is just the sum of probabilites, at each overlap the mean number is the probability, so that the sum is the total number of expected connections, note that the number of overlaps has to be bigger than the expected connectivity, that is a first sanity check of the number of ovelaps p_ex_ex = 0 p_ex_in = 0.02 p_in_in = 0.01 p_in_ex = 0.02 ex_ex, ex_in, in_in, in_ex = overlap_matrix.get_submatrices() # Problem to normalize a matrix with only few more entries than necessary, make all one that are above one leads to too few connections def normalize(transferred_overlaps, connection_probabiity): number_of_available_connections = np.sum(transferred_overlaps>0) number_of_expected_connections = connection_probabiity * np.prod(transferred_overlaps.shape) if number_of_available_connections < number_of_expected_connections: print("Warning: for an expected number of {:d} connections only {:d} overlaps available. No valid connection probabilities available") normalization = number_of_expected_connections / np.sum(transferred_overlaps) normalized = transferred_overlaps*normalization normalized[np.where(normalized>1.0)] = 1.0 return normalized conn_probs = [normalize(transfer_function(overlap), p) for overlap, p in zip(overlap_matrix.get_submatrices(), [p_ex_ex, p_ex_in, p_in_in, p_in_ex])] total_connection_probability_matrix = np.vstack((np.concatenate((conn_probs[0], conn_probs[1]), axis=1), np.concatenate((conn_probs[2], conn_probs[3]), axis=1))) def realize(connection_probability_matrix): return np.random.binomial(1, connection_probability_matrix) connectivity = realize(total_connection_probability_matrix) n_ex = overlap_matrix.excitatory_neurons.number n_in = overlap_matrix.inhibitory_neurons.number # Get realized connectivities c_ex_ex = np.sum(connectivity[:n_ex, :n_ex]) c_ex_in = np.sum(connectivity[:n_ex, n_ex+1:-1]) c_in_ex = np.sum(connectivity[n_ex+1:-1, :n_ex]) c_in_in = np.sum(connectivity[n_ex+1:-1, n_ex+1:-1]) first_order_connectivity = [float(c_ex_ex) / n_ex ** 2, float(c_ex_in) / n_ex / n_in, float(c_in_ex) / n_ex / n_ex, float(c_in_in) / n_in ** 2] print(first_order_connectivity) plt.bar(range(4), first_order_connectivity) plt.xticks(range(4), ["E-E", "E-I", "I-E", "I-I"]) plt.ylabel("Abundance") plt.show() exit() print([np.sum(realize(p_conn)) for p_conn in conn_probs]) plt.imshow(realize(conn_probs[-1])) plt.show() print([np.prod(overlap.shape)* p for overlap, p in zip(overlap_matrix.get_submatrices(), [p_ex_ex, p_ex_in, p_in_in, p_in_ex])]) print([np.sum(p_conn) for p_conn in conn_probs])