spatial_layout.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import numpy as np
  2. import scipy.stats as stats
  3. from scripts.spatial_maps.spatial_network_layout import get_excitatory_phases_in_inhibitory_axon, create_grid_of_excitatory_neurons, \
  4. Interneuron
  5. def distance(interneuron_1, interneuron_2):
  6. return np.sqrt((interneuron_1.x - interneuron_2.x) ** 2 + (interneuron_1.y - interneuron_2.y) ** 2)
  7. def contains(interneuron, XX, YY):
  8. d1, d2 = distance_to_points(interneuron, XX, YY)
  9. return d1 + d2 < interneuron.c
  10. def distance_to_points(interneuron, XX, YY):
  11. x_p_1, y_p_1 = interneuron.get_p1()
  12. x_p_2, y_p_2 = interneuron.get_p2()
  13. d1 = np.sqrt((XX - x_p_1) ** 2 + (YY - y_p_1) ** 2)
  14. d2 = np.sqrt((XX - x_p_2) ** 2 + (YY - y_p_2) ** 2)
  15. return d1, d2
  16. def get_overlap(interneuron_1, interneuron_2, ds=0.1):
  17. if distance(interneuron_1, interneuron_2) > 2 * (max(interneuron_1.a, interneuron_1.b) + max(interneuron_2.a, interneuron_2.b)):
  18. overlap = 0
  19. else:
  20. bb_x_min = interneuron_1.x - max(interneuron_1.a, interneuron_1.b)
  21. bb_x_max = interneuron_1.x + max(interneuron_1.a, interneuron_1.b)
  22. bb_y_min = interneuron_1.y - max(interneuron_1.a, interneuron_1.b)
  23. bb_y_max = interneuron_1.y + max(interneuron_1.a, interneuron_1.b)
  24. bb_X, bb_Y = np.meshgrid(np.arange(bb_x_min, bb_x_max, ds), np.arange(bb_y_min, bb_y_max, ds))
  25. in_1 = contains(interneuron_1, bb_X, bb_Y)
  26. in_2 = contains(interneuron_2, bb_X, bb_Y)
  27. overlap = np.sum(np.logical_and(in_1, in_2)) * ds ** 2
  28. return overlap
  29. def get_uniform_grid(sheet_size, grid_points_per_row):
  30. XX, YY = np.meshgrid(np.linspace(0, sheet_size, grid_points_per_row),
  31. np.linspace(0, sheet_size, grid_points_per_row))
  32. return np.vstack((XX.reshape((np.prod(XX.shape),)), YY.reshape((np.prod(YY.shape),)))).T
  33. def get_overlap_matrix(axonal_clouds, ds):
  34. overlaps = np.zeros((len(axonal_clouds), len(axonal_clouds)))
  35. for row_idx, cloud1 in enumerate(axonal_clouds):
  36. for column_idx, cloud2 in enumerate(axonal_clouds[row_idx + 1:]):
  37. overlaps[row_idx, row_idx + 1 + column_idx] = get_overlap(cloud1, cloud2, ds)
  38. return overlaps
  39. def get_entropy(cloud, ex_positions, ex_tunings, entropy_bins):
  40. phase_vals = get_excitatory_phases_in_inhibitory_axon(ex_positions, ex_tunings, cloud)
  41. phase_distr, _ = np.histogram(phase_vals, entropy_bins, density=True)
  42. return stats.entropy(phase_distr)
  43. def get_entropies(axonal_clouds, ex_positions, ex_tunings, entropy_bins):
  44. return [get_entropy(cloud, ex_positions, ex_tunings, entropy_bins) for cloud in axonal_clouds]
  45. class SpatialLayout(object):
  46. def __init__(self, orientation_map, NE, NI, long_axis, short_axis, sheet_size):
  47. self.orientation_map = orientation_map
  48. self.NE = NE
  49. self.NI = NI
  50. self.long_axis = long_axis
  51. self.short_axis = short_axis
  52. self.sheet_size = sheet_size
  53. ex_positions, ex_tunings = create_grid_of_excitatory_neurons(sheet_size, int(np.sqrt(NE)),
  54. orientation_map)
  55. self.ex_positions = ex_positions
  56. self.ex_tunings = ex_tunings
  57. self.in_positions = get_uniform_grid(sheet_size, int(np.sqrt(NI)))
  58. def get_axonal_clouds(self, orientation_array):
  59. return [Interneuron(in_x_y[0], in_x_y[1], self.long_axis, self.short_axis, orientation) for in_x_y, orientation in
  60. zip(
  61. self.in_positions, orientation_array)]
  62. def get_entropies(self, orientation_array, number_of_bins):
  63. entropy_bins = np.linspace(-np.pi, np.pi, number_of_bins + 1)
  64. axonal_clouds = self.get_axonal_clouds(orientation_array)
  65. return get_entropies(axonal_clouds, self.ex_positions, self.ex_tunings, entropy_bins)
  66. def get_mean_entropy(self, orientation_array, number_of_bins):
  67. return np.mean(self.get_entropies(orientation_array, number_of_bins))
  68. def get_negative_mean_entropy(self, orientation_array, number_of_bins):
  69. return -self.get_mean_entropy(orientation_array, number_of_bins)
  70. def get_overlap(self, orientation_array, ds):
  71. axonal_clouds = self.get_axonal_clouds(orientation_array)
  72. overlaps = get_overlap_matrix(axonal_clouds, ds)
  73. return np.sum(overlaps)