figure_max_entropy_rule.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # from scripts.spatial_network.perlin_map.paper_figures_spatial_head_direction_network_perlin_map import FIGURE_SAVE_PATH
  4. FIGURE_SAVE_PATH = '../../../figures/figure_4_paper_perlin/'
  5. from scripts.spatial_network.perlin_map.run_simulation_perlin_map import get_perlin_map
  6. from scripts.spatial_maps.supplement_max_entropy_rule.spatial_layout import SpatialLayout
  7. from scripts.spatial_maps.spatial_network_layout import Interneuron, get_excitatory_phases_in_inhibitory_axon, get_position_mesh, plot_neural_sheet
  8. from scripts.spatial_maps.supplement_max_entropy_rule.spatial_layout import get_entropy
  9. # Get input map
  10. seed = 1
  11. correlation_length = 200
  12. map_size = 900
  13. long_half = 100
  14. short_half = 25
  15. Ne = 3600
  16. Ni = 400
  17. Ne_per_row = int(np.sqrt(Ne))
  18. Ni_per_row = int(np.sqrt(Ni))
  19. input_map = get_perlin_map(correlation_length, seed, map_size, Ne)
  20. spatial_layout = SpatialLayout(input_map, Ne, Ni, long_half, short_half, map_size)
  21. plot_neural_sheet(spatial_layout.ex_positions, spatial_layout.ex_tunings)
  22. # Choose interneuron and get entropies
  23. in_idx = 144
  24. pos_x = spatial_layout.in_positions[in_idx][0]
  25. pos_y = spatial_layout.in_positions[in_idx][1]
  26. equivalent_radius = np.sqrt(long_half * short_half)
  27. circular_axon = Interneuron(pos_x, pos_y, equivalent_radius, equivalent_radius, 0)
  28. neuron_positions = spatial_layout.ex_positions
  29. neuron_tunings = spatial_layout.ex_tunings
  30. number_of_phases = 36
  31. phases = np.linspace(-np.pi / 2, np.pi / 2, number_of_phases, endpoint=False)
  32. number_of_bins = 10
  33. tuning_bins = np.linspace(-np.pi, np.pi, number_of_bins + 1)
  34. tunings = []
  35. entropies = []
  36. for phase in phases:
  37. axonal_cloud = Interneuron(pos_x, pos_y, long_half, short_half, phase)
  38. tunings.append(get_excitatory_phases_in_inhibitory_axon(neuron_positions, neuron_tunings, axonal_cloud))
  39. entropies.append(get_entropy(axonal_cloud, neuron_positions, neuron_tunings, tuning_bins))
  40. circular_entropy = get_entropy(circular_axon, neuron_positions, neuron_tunings, tuning_bins)
  41. max_entropy = max(entropies)
  42. max_phase = phases[np.argmax(entropies)]
  43. max_id = np.argmax(entropies)
  44. min_entropy = min(entropies)
  45. min_phase = phases[np.argmin(entropies)]
  46. min_id = np.argmin(entropies)
  47. circular_tuning = get_excitatory_phases_in_inhibitory_axon(neuron_positions, neuron_tunings, circular_axon)
  48. # Figures
  49. import matplotlib
  50. # In[20]:
  51. plt.style.use('../../spatial_network/perlin_map/figures.mplstyle')
  52. # In[21]:
  53. width = 4.0 / 2.54
  54. height = 3.2 / 2.54
  55. detail_size = 2.5 * long_half
  56. detail_x_low = pos_x - detail_size / 2.0
  57. detail_x_high = pos_x + detail_size / 2.0
  58. detail_y_low = pos_y - detail_size / 2.0
  59. detail_y_high = pos_y + detail_size / 2.0
  60. colormap = matplotlib.cm.get_cmap('hsv')
  61. bar_colors = [colormap(value) for value in np.linspace(0, 1, number_of_bins)]
  62. X, Y = get_position_mesh(spatial_layout.ex_positions)
  63. head_dir_preference = np.array(spatial_layout.ex_tunings).reshape((Ne_per_row, Ne_per_row))
  64. # ### Polar Interneuron
  65. # In[22]:
  66. fig = plt.figure(figsize=(width, height))
  67. ax_map = fig.add_axes([0.05, 0.1, 0.7 * height / width, 0.7])
  68. ax_map.pcolor(X, Y, head_dir_preference, vmin=-np.pi, vmax=np.pi, cmap=colormap)
  69. line_length = 1.2 * detail_size
  70. max_entropy_ell = Interneuron(pos_x, pos_y, long_half, short_half, max_phase).get_ellipse()
  71. max_entropy_line = plt.Line2D(
  72. [pos_x - np.cos(max_phase) * line_length / 2.0, pos_x + np.cos(max_phase) * line_length / 2.0],
  73. [pos_y - np.sin(max_phase) * line_length / 2.0, pos_y + np.sin(max_phase) * line_length / 2.0])
  74. max_entropy_line.set_linestyle('dotted')
  75. max_entropy_line.set_clip_on(False)
  76. min_entropy_ell = Interneuron(pos_x, pos_y, long_half, short_half, min_phase).get_ellipse()
  77. min_entropy_ell.set_linestyle('dashed')
  78. min_entropy_line = plt.Line2D(
  79. [pos_x - np.cos(min_phase) * line_length / 2.0, pos_x + np.cos(min_phase) * line_length / 2.0],
  80. [pos_y - np.sin(min_phase) * line_length / 2.0, pos_y + np.sin(min_phase) * line_length / 2.0])
  81. min_entropy_line.set_linestyle('dotted')
  82. min_entropy_line.set_clip_on(False)
  83. ax_map.add_artist(max_entropy_ell)
  84. ax_map.add_artist(max_entropy_line)
  85. ax_map.add_artist(min_entropy_ell)
  86. ax_map.add_artist(min_entropy_line)
  87. ax_map.set_xlim(detail_x_low, detail_x_high)
  88. ax_map.set_ylim(detail_y_low, detail_y_high)
  89. ax_map.spines["right"].set_visible(False)
  90. ax_map.spines["left"].set_visible(False)
  91. ax_map.spines["top"].set_visible(False)
  92. ax_map.spines["bottom"].set_visible(False)
  93. ax_map.xaxis.set_ticks([])
  94. ax_map.yaxis.set_ticks([])
  95. ax_map.text(pos_x - np.cos(max_phase) * line_length / 2.0, pos_y - np.sin(max_phase) * line_length / 2.0,
  96. "$\\phi_{max}$", va='bottom', ha='left')
  97. ax_map.text(pos_x + np.cos(min_phase) * line_length / 2.0, pos_y + np.sin(min_phase) * line_length / 2.0,
  98. "$\\phi_{min}$", va='center', ha='left')
  99. ax_dist_max = fig.add_axes(
  100. [0.05 + 0.7 * height / width + 0.03, 0.1, 1 - 0.75 * height / width - 0.05 - 0.05 - 0.1, 0.27])
  101. n_max_entropy, _, bars = ax_dist_max.hist(tunings[max_id], bins=number_of_bins, range=(-np.pi, np.pi))
  102. for bar, bar_color in zip(bars, bar_colors):
  103. bar.set_color(bar_color)
  104. ax_dist_max.text(0, 1.4, "$\\phi_{max}$\n" + "S={:.2f}".format(entropies[max_id]), transform=ax_dist_max.transAxes,
  105. va='top')
  106. ax_dist_min = fig.add_axes(
  107. [0.05 + 0.7 * height / width + 0.03, 0.48, 1 - 0.75 * height / width - 0.05 - 0.05 - 0.1, 0.27])
  108. n_min_entropy, _, bars = ax_dist_min.hist(tunings[min_id], bins=number_of_bins, range=(-np.pi, np.pi))
  109. for bar, bar_color in zip(bars, bar_colors):
  110. bar.set_color(bar_color)
  111. ax_dist_min.text(0, 1.6, "$\\phi_{min}$\n" + "S={:.2f}".format(entropies[min_id]), transform=ax_dist_min.transAxes,
  112. va='top')
  113. for ax in [ax_dist_max, ax_dist_min]:
  114. ax.set_ylim(0, max(max(n_max_entropy), max(n_min_entropy)))
  115. ax.spines["right"].set_visible(False)
  116. ax.spines["left"].set_visible(False)
  117. ax.spines["top"].set_visible(False)
  118. ax.spines["bottom"].set_linewidth(0.5)
  119. ax.xaxis.set_ticks([])
  120. ax.yaxis.tick_right()
  121. fig.savefig(FIGURE_SAVE_PATH + "B_ii_max_entropy_rule_polar_ins.png")
  122. # ### Circular Interneuron
  123. # In[25]:
  124. from scripts.model_figure.figure_utils import add_length_scale
  125. # In[36]:
  126. fig = plt.figure(figsize=(width, height))
  127. ax_map = fig.add_axes([0.05, 0.1, 0.7 * height / width, 0.7])
  128. ax_map.pcolor(X, Y, head_dir_preference, vmin=-np.pi, vmax=np.pi, cmap=colormap)
  129. circle = Interneuron(pos_x, pos_y, equivalent_radius, equivalent_radius, 0).get_ellipse()
  130. ax_map.add_artist(circle)
  131. ax_map.set_xlim(detail_x_low, detail_x_high)
  132. ax_map.set_ylim(detail_y_low, detail_y_high)
  133. ax_map.spines["right"].set_visible(False)
  134. ax_map.spines["left"].set_visible(False)
  135. ax_map.spines["top"].set_visible(False)
  136. ax_map.spines["bottom"].set_visible(False)
  137. ax_map.xaxis.set_ticks([])
  138. ax_map.yaxis.set_ticks([])
  139. add_length_scale(ax_map, 100, detail_x_high + 30, detail_x_high + 10 + 100, detail_y_low + 40, detail_y_low + 40)
  140. ax_dist = fig.add_axes([0.05 + 0.7 * height / width + 0.03, 0.375, 1 - 0.75 * height / width - 0.05 - 0.05 - 0.1, 0.27])
  141. n_circle, _, bars = ax_dist.hist(circular_tuning, bins=number_of_bins, range=(-np.pi, np.pi))
  142. for bar, bar_color in zip(bars, bar_colors):
  143. bar.set_color(bar_color)
  144. ax_dist.text(0, 1.6, "circ. \nS={:.2f}".format(circular_entropy), transform=ax_dist.transAxes, va='top')
  145. for ax in [ax_dist]:
  146. ax.set_ylim(0, max(max(n_max_entropy), max(n_min_entropy)))
  147. ax.spines["right"].set_visible(False)
  148. ax.spines["left"].set_visible(False)
  149. ax.spines["top"].set_visible(False)
  150. ax.spines["bottom"].set_linewidth(0.5)
  151. ax.xaxis.set_ticks([])
  152. ax.yaxis.tick_right()
  153. fig.savefig(FIGURE_SAVE_PATH + "B_ii_max_entropy_rule_circular_in.png")