uniform_perlin_map.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from opensimplex import OpenSimplex
  4. from pypet import Trajectory
  5. from scipy.signal import correlate2d
  6. from scipy.optimize import leastsq
  7. from scripts.interneuron_placement import create_grid_of_excitatory_neurons, \
  8. create_interneuron_sheet_entropy_max_orientation, get_correct_position_mesh
  9. from scripts.spatial_maps.orientation_maps.orientation_map import OrientationMap
  10. from scripts.spatial_maps.orientation_maps.orientation_map_generator_pypet import TRAJ_NAME_ORIENTATION_MAPS
  11. DATA_FOLDER = "../../data/"
  12. class UniformPerlinMap:
  13. def __init__(self,x_dim,y_dim, corr_len, sheet_x=0, sheet_y=0, rnd_seed = 1):
  14. self.x_dim = x_dim
  15. self.y_dim = y_dim
  16. self.corr_len = corr_len
  17. self.sheet_x = sheet_x
  18. self.sheet_y = sheet_y
  19. self.rnd_seed = rnd_seed
  20. noise = OpenSimplex(seed=self.rnd_seed)
  21. nrow = self.x_dim
  22. size = self.sheet_x
  23. scale = corr_len #TODO: Probably this needs to be a linear interpolation
  24. x = y = np.linspace(0, size, nrow)
  25. n = [[noise.noise2d(i/scale, j/scale) for j in y] for i in x]
  26. m = np.concatenate(n)
  27. sorted_idx = np.argsort(m)
  28. max_val = nrow * 2
  29. idx = len(m) // max_val
  30. for ii, val in enumerate(range(max_val)):
  31. m[sorted_idx[ii * idx:(ii + 1) * idx]] = val
  32. p_map = (m - nrow) / nrow
  33. self.map = p_map.reshape(nrow, -1)
  34. self.map *= np.pi
  35. # def uniform_perlin_map(self):
  36. # noise = OpenSimplex(seed=self.rnd_seed)
  37. # nrow = self.x_dim
  38. # size = self.sheet_x
  39. # x = y = np.linspace(0, size, nrow)
  40. # n = [[noise.noise2d(i, j) for j in y] for i in x]
  41. # m = np.concatenate(n)
  42. # sorted_idx = np.argsort(m)
  43. # max_val = nrow * 2
  44. # idx = len(m) // max_val
  45. # for ii, val in enumerate(range(max_val)):
  46. # m[sorted_idx[ii * idx:(ii + 1) * idx]] = val
  47. # landscape = (m - nrow) / nrow
  48. #
  49. # # pl.hist(landscape, bins=np.arange(-1, 1.01, 0.01))
  50. #
  51. # # pl.matshow(landscape.reshape(nrow, -1), vmin=-1, vmax=1)
  52. # # pl.colorbar()
  53. # #
  54. # # pl.show()
  55. def get_meshgrid_of_neuron_positions(self):
  56. xmin = np.min(0.)
  57. xmax = np.max(self.sheet_x)
  58. dx = (xmax - xmin) / (self.x_dim - 1)
  59. ymin = np.min(0.)
  60. ymax = np.max(self.sheet_y)
  61. dy = (ymax - ymin) / (self.y_dim - 1)
  62. X, Y = np.meshgrid(np.arange(xmin, xmax + 2 * dx, dx) - dx / 2., np.arange(ymin, ymax + 2 * dy, dy) - dy / 2.)
  63. return X, Y
  64. def get_tuning(self,x,y):
  65. id_x = int(x * (self.x_dim - 1) / self.sheet_x)
  66. id_y = int(y * (self.y_dim - 1) / self.sheet_y)
  67. return self.map[id_x, id_y]
  68. def get_tuning_by_id(self,id_x, id_y):
  69. return self.map[id_x, id_y]
  70. def plot_map(self, ax=None):
  71. if ax is None:
  72. fig, ax = plt.subplots(1, 1)
  73. X, Y = self.get_meshgrid_of_neuron_positions()
  74. Z = np.zeros((self.x_dim, self.y_dim))
  75. # For correctly displaying ticks
  76. for y_idx in range(Z.shape[1]):
  77. for x_idx in range(Z.shape[0]):
  78. o_map_val = self.get_tuning_by_id(x_idx, y_idx)
  79. Z[x_idx, y_idx] = o_map_val
  80. if ax is None:
  81. fig = plt.figure()
  82. ax = fig.add_subplot(111)
  83. plt.set_cmap('twilight')
  84. pcm = ax.pcolormesh(X, Y, Z.T)
  85. plt.gcf().colorbar(pcm, ax=ax)
  86. def get_orientation_map(correlation_length, seed, sheet_size, N_E, data_folder=None):
  87. if data_folder is None:
  88. data_folder = DATA_FOLDER
  89. traj = Trajectory(filename=data_folder + TRAJ_NAME_ORIENTATION_MAPS + ".hdf5")
  90. traj.f_load(index=-1, load_parameters=2, load_results=2)
  91. available_lengths = sorted(list(set(traj.f_get("corr_len").f_get_range())))
  92. closest_length = available_lengths[np.argmin(np.abs(np.array(available_lengths)-correlation_length))]
  93. if closest_length!=correlation_length:
  94. print("Warning: desired correlation length {:.1f} not available. Taking {:.1f} instead".format(
  95. correlation_length, closest_length))
  96. corr_len = closest_length
  97. seed = seed
  98. map_by_params = lambda x, y: x == corr_len and y == seed
  99. idx_iterator = traj.f_find_idx(['corr_len', 'seed'], map_by_params)
  100. # TODO: Since it has only one entry, maybe iterator can be replaced
  101. for idx in idx_iterator:
  102. traj.v_idx = idx
  103. map_angle_grid = traj.crun.map
  104. number_of_excitatory_neurons_per_row = int(np.sqrt(N_E))
  105. map = OrientationMap(number_of_excitatory_neurons_per_row + 1, number_of_excitatory_neurons_per_row + 1,
  106. corr_len, sheet_size, sheet_size, seed)
  107. map.angle_grid = map_angle_grid
  108. return map
  109. def plot_auto_corr(map, ax=None):
  110. if ax is None:
  111. fig, ax = plt.subplots(1, 1)
  112. X, Y = map.get_meshgrid_of_neuron_positions()
  113. Z = np.zeros((map.x_dim, map.y_dim))
  114. # For correctly displaying ticks
  115. for y_idx in range(Z.shape[1]):
  116. for x_idx in range(Z.shape[0]):
  117. o_map_val = map.get_tuning_by_id(x_idx, y_idx)
  118. Z[x_idx, y_idx] = o_map_val
  119. if ax is None:
  120. fig = plt.figure()
  121. ax = fig.add_subplot(111)
  122. plt.set_cmap('viridis')
  123. Z = correlate2d(Z,Z)
  124. Z = Z / np.max(Z)
  125. pcm = ax.pcolormesh(X, Y, Z[30:,30:].T)
  126. plt.gcf().colorbar(pcm, ax=ax)
  127. return Z
  128. def get_auto_corr(map):
  129. Z = np.zeros((map.x_dim, map.y_dim))
  130. for y_idx in range(Z.shape[1]):
  131. for x_idx in range(Z.shape[0]):
  132. o_map_val = map.get_tuning_by_id(x_idx, y_idx)
  133. Z[x_idx, y_idx] = o_map_val
  134. Z = correlate2d(Z,Z)
  135. Z = Z / np.max(Z)
  136. return Z
  137. def f(x, u, v, z_data):
  138. corr_len = x[0]
  139. modelled_z = np.exp(-(np.sqrt(u**2 + v**2)/corr_len))
  140. diffs = modelled_z - z_data
  141. return diffs.flatten()
  142. def fit_correlation(map, data):
  143. # Here we need the actual positions and not ticks for plotting
  144. x_max = map.sheet_x
  145. d_x = x_max / (map.x_dim - 1)
  146. y_max = map.sheet_y
  147. d_y = y_max / (map.y_dim - 1)
  148. u_range = np.arange(0, x_max + d_x, d_x)
  149. v_range = np.arange(0, y_max + d_y, d_y)
  150. u, v = np.meshgrid(u_range, v_range)
  151. u = u.flatten()
  152. v = v.flatten()
  153. data = data.flatten()
  154. result = leastsq(f, [50.5], args=(u, v, data))
  155. return result
  156. def test_plot_fit_func(corr_len, map, ax=None):
  157. if ax is None:
  158. fig, ax = plt.subplots(1, 1)
  159. X, Y = map.get_meshgrid_of_neuron_positions()
  160. Z = np.exp(-(np.sqrt(X**2 + Y**2)/corr_len))
  161. plt.set_cmap('viridis')
  162. pcm = ax.pcolormesh(X, Y, Z.T)
  163. plt.gcf().colorbar(pcm, ax=ax)
  164. def plot_example(map):
  165. fig, axes = plt.subplots(1, 3, figsize=(13.5, 4.5))
  166. map.plot_map(ax=axes[0])
  167. axes[0].set_title('map')
  168. map_auto_corr = plot_auto_corr(map, ax=axes[1])
  169. axes[1].set_title('auto correlation')
  170. map_corr_len = fit_correlation(map, map_auto_corr[30:, 30:])
  171. axes[2].set_title('fit of auto correl.')
  172. test_plot_fit_func(map_corr_len[0][0], map, ax=axes[2])
  173. def get_correlation_length(tunings, size, dim):
  174. tun_auto_corr = correlate2d(tunings, tunings)
  175. tun_auto_corr = tun_auto_corr / np.max(tun_auto_corr)
  176. x_max = size
  177. d_x = x_max / (dim - 1)
  178. y_max = size
  179. d_y = y_max / (dim - 1)
  180. u_range = np.arange(0, x_max + d_x, d_x)
  181. v_range = np.arange(0, y_max + d_y, d_y)
  182. u, v = np.meshgrid(u_range, v_range)
  183. u = u.flatten()
  184. v = v.flatten()
  185. data = tun_auto_corr[30:, 30:].flatten()
  186. tun_corr_len = leastsq(f, [50.5], args=(u, v, data))
  187. return tun_corr_len[0][0]
  188. def plot_map_and_axons(map, n_inh):
  189. ex_positions, ex_tunings = create_grid_of_excitatory_neurons(map.sheet_x, map.sheet_y, map.x_dim, map.get_tuning)
  190. inhibitory_axonal_clouds, _ = create_interneuron_sheet_entropy_max_orientation(
  191. ex_positions, ex_tunings, n_inh, inhibitory_axon_long_axis,
  192. inhibitory_axon_short_axis, size,
  193. size, trial_orientations=30)
  194. X, Y = get_correct_position_mesh(ex_positions)
  195. fig, ax = plt.subplots(1, 1)
  196. head_dir_preference = np.array(ex_tunings).reshape((dim, dim))
  197. # TODO: Why was this transposed for plotting? (now changed)
  198. c = ax.pcolor(X, Y, head_dir_preference, vmin=-np.pi, vmax=np.pi, cmap='hsv')
  199. for i, p in enumerate(inhibitory_axonal_clouds):
  200. ell = p.get_ellipse()
  201. ax.add_artist(ell)
  202. ax.set_title('Perlin, size: {}'.format(size))
  203. ax.set_aspect('equal')
  204. if __name__ == '__main__':
  205. dim = 30
  206. size = 450
  207. inhibitory_axon_long_axis = 100
  208. inhibitory_axon_short_axis = 25
  209. corr_len = 200
  210. # orientation_map = get_orientation_map(corr_len, 1, size, dim*dim)
  211. # orientation_map.plot_map()
  212. # plt.gca().set_title('Orientation, size: {}'.format(size))
  213. perlin_map = UniformPerlinMap(dim, dim, corr_len, size, size, 1)
  214. plot_map_and_axons(perlin_map, 100)
  215. size = 900
  216. dim = 90
  217. perlin_map = UniformPerlinMap(dim, dim, corr_len, size, size, 1)
  218. plot_map_and_axons(perlin_map, 400)
  219. plt.gca().set_title('Perlin, size: {}'.format(size))
  220. # orientation_map = get_orientation_map(corr_len, 1, size, dim * dim)
  221. # orientation_map.plot_map()
  222. # plt.gca().set_title('Orientation, size: {}'.format(size))
  223. # corr_len_range = np.linspace(1.0, 400.0, 30, endpoint=True)
  224. # p_map_corr_lengths = []
  225. # o_map_corr_lengths = []
  226. # for corr_len in corr_len_range:
  227. # perlin_map = UniformPerlinMap(dim + 1, dim + 1, corr_len, size, size, 1)
  228. # p_map_auto_corr = get_auto_corr(perlin_map)
  229. # p_map_corr_len = fit_correlation(perlin_map, p_map_auto_corr[30:, 30:])
  230. # print('perlin: ', p_map_corr_len)
  231. # p_map_corr_lengths.append(p_map_corr_len[0][0])
  232. #
  233. # orientation_map = get_orientation_map(corr_len, 1, size, dim * dim)
  234. #
  235. # o_map_auto_corr = get_auto_corr(orientation_map)
  236. # o_map_corr_len = fit_correlation(orientation_map, o_map_auto_corr[30:, 30:])
  237. # print('orientation ', o_map_corr_len)
  238. # o_map_corr_lengths.append(o_map_corr_len[0][0])
  239. #
  240. # fig, ax = plt.subplots(1, 1)
  241. #
  242. # ax.plot(corr_len_range,o_map_corr_lengths, label='orientation')
  243. # ax.plot(corr_len_range,p_map_corr_lengths, label='perlin')
  244. # plt.legend()
  245. plt.show()