generate_connectivity_matrices.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. ###
  2. from conmorph.connections import load_overlap
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. file_path = "/home/pfeiffer/Projects/subiculum_interneuron_polarity/data/"
  6. file_name = "circular_inhibitory_neurons_overlap_matrix_0"
  7. path_to_store = file_path + "/" + file_name + ".pickle"
  8. overlap_matrix = load_overlap(path_to_store)
  9. plt.imshow(overlap_matrix.overlaps)
  10. plt.show()
  11. ### Use a transfer function to turn the overlaps into connection probabilities
  12. # 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
  13. def transfer_function(overlap):
  14. return overlap**2
  15. # 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)
  16. # 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
  17. p_ex_ex = 0
  18. p_ex_in = 0.02
  19. p_in_in = 0.01
  20. p_in_ex = 0.02
  21. ex_ex, ex_in, in_in, in_ex = overlap_matrix.get_submatrices()
  22. # Problem to normalize a matrix with only few more entries than necessary, make all one that are above one leads to too few connections
  23. def normalize(transferred_overlaps, connection_probabiity):
  24. number_of_available_connections = np.sum(transferred_overlaps>0)
  25. number_of_expected_connections = connection_probabiity * np.prod(transferred_overlaps.shape)
  26. if number_of_available_connections < number_of_expected_connections:
  27. print("Warning: for an expected number of {:d} connections only {:d} overlaps available. No valid connection probabilities available")
  28. normalization = number_of_expected_connections / np.sum(transferred_overlaps)
  29. normalized = transferred_overlaps*normalization
  30. normalized[np.where(normalized>1.0)] = 1.0
  31. return normalized
  32. 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])]
  33. 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)))
  34. def realize(connection_probability_matrix):
  35. return np.random.binomial(1, connection_probability_matrix)
  36. connectivity = realize(total_connection_probability_matrix)
  37. n_ex = overlap_matrix.excitatory_neurons.number
  38. n_in = overlap_matrix.inhibitory_neurons.number
  39. # Get realized connectivities
  40. c_ex_ex = np.sum(connectivity[:n_ex, :n_ex])
  41. c_ex_in = np.sum(connectivity[:n_ex, n_ex+1:-1])
  42. c_in_ex = np.sum(connectivity[n_ex+1:-1, :n_ex])
  43. c_in_in = np.sum(connectivity[n_ex+1:-1, n_ex+1:-1])
  44. 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,
  45. float(c_in_in) / n_in ** 2]
  46. print(first_order_connectivity)
  47. plt.bar(range(4), first_order_connectivity)
  48. plt.xticks(range(4), ["E-E", "E-I", "I-E", "I-I"])
  49. plt.ylabel("Abundance")
  50. plt.show()
  51. exit()
  52. print([np.sum(realize(p_conn)) for p_conn in conn_probs])
  53. plt.imshow(realize(conn_probs[-1]))
  54. plt.show()
  55. 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])])
  56. print([np.sum(p_conn) for p_conn in conn_probs])