forked from bernhardkaplan/bcpnn-mt
/
CheckDelayScale.py
executable file
·311 lines (252 loc) · 12.8 KB
/
CheckDelayScale.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
"""
Simple network with a Poisson spike source projecting to populations of of IF_cond_exp neurons
"""
import time
import numpy as np
import numpy.random as nprnd
import sys
import os
import CreateConnections as CC
import utils
import pylab
class CompareSimulations(object):
def __init__(self, parameter_storage):
self.parameter_storage = parameter_storage
self.params = parameter_storage.params
assert os.path.exists(self.params['tuning_prop_means_fn']), \
'\nFile not found: %s\n\nPlease run NetworkSimModuleNoColumns.py or run_all.sh before with NO connectivity!\n' % (self.params['tuning_prop_means_fn'])
self.tuning_prop_exc = np.loadtxt(self.params['tuning_prop_means_fn'])
self.tuning_prop_inh = np.loadtxt(self.params['tuning_prop_inh_fn'])
self.color_dict = {}
self.input_rate = {}
self.input_spike_trains = {}
self.time_of_max_stim = {}
self.fig = pylab.figure(figsize=(14, 12))
self.n_fig_y, self.n_fig_x = 6, 1
self.fig_cnt = 1
pylab.subplots_adjust(hspace=.45)
self.spiketrains_with_connectivity = None
self.spiketrains_without_connectivity = None
def set_gids_to_plots(self, n_cells=2, cell_type='exc'):
"""
Choose n_cells which shall be plotted.
Look at the tuning properties and choose cells that get sequentially activated.
Assign colors to cells.
"""
self.n_cells = n_cells
if cell_type == 'exc':
tp = self.tuning_prop_exc
else:
tp = self.tuning_prop_inh
good_gids = np.loadtxt(self.params['gids_to_record_fn'], dtype='int')
idx_sorted_by_xpos = tp[good_gids, 0].argsort()
idx_ = np.linspace(0, good_gids.size, n_cells + 2, endpoint=False)
idx_to_plot = [int(round(i)) for i in idx_[1:-1]]
print 'idx_to_plot', idx_to_plot
self.gids_to_plot = good_gids[idx_sorted_by_xpos[idx_to_plot]]
print 'Plotting GIDS\tx\t\ty\t\tu\tv\t\tdx'
print 'tp[%d, :] =\t' % self.gids_to_plot[0], tp[self.gids_to_plot[0], :]
for i_ in xrange(1, len(self.gids_to_plot)):
gid = self.gids_to_plot[i_]
print 'tp[%d, :] =\t' % gid, tp[gid, :], tp[gid, 0] - tp[self.gids_to_plot[i_-1], 0]
# assign a certain color to each cell
color_list = ['b', 'g', 'r', 'y', 'c', 'm', '#00f80f', '#deff00', '#ff00e4', '#00ffe6', 'k']
for i_, gid in enumerate(self.gids_to_plot):
self.color_dict[gid] = color_list[i_]
self.input_spike_trains[gid] = {}
self.input_rate[gid] = {}
def create_input(self):
nprnd.seed(self.params['input_spikes_seed'])
dt = self.params['dt_rate'] # [ms] time step for the non-homogenous Poisson process
self.time = np.arange(0, self.params['t_sim'], dt)
blank_idx = np.arange(1./dt * self.params['t_stimulus'], 1. / dt * (self.params['t_stimulus'] + self.params['t_blank']))
L_input = np.zeros((self.n_cells, self.time.shape[0]))
for i_time, time_ in enumerate(self.time):
if (i_time % 1000 == 0):
print "t:", time_
L_input[:, i_time] = utils.get_input(self.tuning_prop_exc[self.gids_to_plot, :], self.params, time_/self.params['t_stimulus'])
L_input[:, i_time] *= self.params['f_max_stim']
L_input_noblank = L_input.copy()
for i_time in blank_idx:
L_input[:, i_time] = 0.
# create input with blank
for i_, gid in enumerate(self.gids_to_plot):
rate_of_t = L_input[i_, :]
n_steps = rate_of_t.size
spike_times= []
for i in xrange(n_steps):
r = nprnd.rand()
if (r <= ((rate_of_t[i]/1000.) * dt)): # rate is given in Hz -> 1/1000.
spike_times.append(i * dt)
self.input_spike_trains[gid]['with_blank'] = spike_times
self.input_rate[gid]['with_blank'] = L_input[i_, :]
# create input without blank
print 'GID\tTime of max stim'
for i_, gid in enumerate(self.gids_to_plot):
rate_of_t = L_input_noblank[i_, :]
n_steps = rate_of_t.size
spike_times= []
for i in xrange(n_steps):
r = nprnd.rand()
if (r <= ((rate_of_t[i]/1000.) * dt)): # rate is given in Hz -> 1/1000.
spike_times.append(i * dt)
self.input_spike_trains[gid]['no_blank'] = spike_times
self.input_rate[gid]['no_blank'] = L_input_noblank[i_, :]
self.time_of_max_stim[gid] = L_input_noblank[i_, :].argmax() * dt
print '%d\t%.1f' % (gid, L_input_noblank[i_, :].argmax() * dt)
def plot_input(self, fill_blank=True):
"""
This function iterates through self.gids_to_plot,
and computes how the L_i (rate envelope) and the spike train would
look like for each cell with the blank and if fill_blank is set, also
without the blank.
"""
self.create_input()
ax = self.fig.add_subplot(self.n_fig_y, self.n_fig_x, self.fig_cnt)
self.fig_cnt += 1
for gid in self.gids_to_plot:
ax.plot(self.time, self.input_rate[gid]['with_blank'], c=self.color_dict[gid], lw=2)
ax.plot(self.time, self.input_rate[gid]['no_blank'], c=self.color_dict[gid], lw=2, ls='--')
ax.set_title('Input with and without blank', fontsize=14)
# ax.set_xlabel('Time [ms]', fontsize=14)
ax.set_ylabel('Input rate [Hz]', fontsize=14)
self.plot_blank(ax, txt='Blank')
# ax = self.fig.add_subplot(self.n_fig_y, self.n_fig_x, self.fig_cnt)
# self.fig_cnt += 1
# ax.set_ylim((0, len(self.gids_to_plot)))
y_min, y_max = ax.get_ylim()
ypos = np.linspace(y_max, y_min, len(self.gids_to_plot)+1, endpoint = False)
dy = ypos[1] - ypos[0]
for i_, gid in enumerate(self.gids_to_plot):
spiketimes = self.input_spike_trains[gid]['with_blank']
# (y_min, y_max) = (i_, i_+ 1)
self.plot_spikes(ax, spiketimes, gid, ypos[i_]+.5*dy, ypos[i_+1])
ax.set_title('Input spike trains', fontsize=14)
# ax.set_xlabel('Time [ms]', fontsize=14)
# ax.set_ylabel('Cell index', fontsize=14)
self.plot_blank(ax, txt='Blank')
def plot_response(self, title, connectivity=None):
"""
Plots the cell's membrane potential and output spikes in response to the
stimulus alone (that's why you need to simulate without connectivity before),
and the response with connectivity.
"""
volt_fn = self.params['exc_volt_fn_base'] + '.v'
print 'Loading membrane potentials from:', volt_fn
volt_data = np.loadtxt(volt_fn)
spike_fn = self.params['exc_spiketimes_fn_merged'] + '%d.ras' % 0
nspikes, spiketimes = utils.get_nspikes(spike_fn, self.params['n_exc'], get_spiketrains=True)
if connectivity == False:
self.spiketrains_without_connectivity = spiketimes
else:
self.spiketrains_with_connectivity = spiketimes
ax = self.fig.add_subplot(self.n_fig_y, self.n_fig_x, self.fig_cnt)
self.fig_cnt += 1
ax2 = self.fig.add_subplot(self.n_fig_y, self.n_fig_x, self.fig_cnt)
self.fig_cnt += 1
y_min, y_max = -70, -45
for i_, gid in enumerate(self.gids_to_plot):
time_axis, volt = utils.extract_trace(volt_data, gid)
ax.plot(time_axis, volt, lw=1, label='nspikes[%d]=%d' % (gid, nspikes[gid]), color=self.color_dict[gid])
# self.plot_spikes(ax, spiketimes[gid], gid, y_min, y_max, lw=2)
self.plot_spike_histogram(ax2, gid, i_, spiketimes[gid])
ax.legend()
ax.set_ylim((y_min, y_max))
ax.set_ylabel('Membrane voltage [mV]', fontsize=14)
ax.set_title(title, fontsize=14)
self.plot_blank(ax, txt='Blank')
def plot_response_difference(self):
ax = self.fig.add_subplot(self.n_fig_y, self.n_fig_x, self.fig_cnt)
self.fig_cnt += 1
for i_, gid in enumerate(self.gids_to_plot):
n_bins = 20
c = self.color_dict[gid]
n_with_conn, bins = np.histogram(self.spiketrains_with_connectivity[gid], bins=n_bins, range=(0, self.params['t_sim']))
n_without_conn, bins = np.histogram(self.spiketrains_without_connectivity[gid], bins=n_bins, range=(0, self.params['t_sim']))
bin_width = (bins[1] - bins[0]) / len(self.gids_to_plot)
shift = i_
bins += shift * bin_width
ax.bar(bins[:-1], n_with_conn - n_without_conn, width=bin_width, facecolor=c)
ax.set_ylabel('Output spike histogram', fontsize=14)
ax.set_title('NSpikes With - without connectivity')
self.plot_blank(ax, txt='Blank')
def plot_spike_histogram(self, ax, gid, shift, spiketimes):
n_bins = 20
c = self.color_dict[gid]
n, bins = np.histogram(spiketimes, bins=n_bins, range=(0, self.params['t_sim']))
bin_width = (bins[1] - bins[0]) / len(self.gids_to_plot)
bins += shift * bin_width
ax.bar(bins[:-1], n, width=bin_width, facecolor=c)
ax.set_ylabel('Output spike histogram', fontsize=14)
def plot_spikes(self, ax, spiketimes, gid, y_min=0, y_max=1, lw=1):
"""
Plots spiketrain for the given gid into the ax with a certain row idx
"""
for s in spiketimes:
ax.plot((s, s), (y_min+0.1, y_max-.1), c=self.color_dict[gid], lw=lw)
# ax.plot((s, s), (0.2 * (y_max-y_min) + y_min, 0.8 * (y_max-y_min) + y_min), c=self.color_dict[gid])
def plot_blank(self, ax, c='k', txt=''):
ylim = ax.get_ylim()
ax.plot((self.params['t_stimulus'], self.params['t_stimulus']), (ylim[0], ylim[1]), ls='--', c=c, lw=2)
ax.plot((self.params['t_stimulus'] + self.params['t_blank'], self.params['t_stimulus'] + self.params['t_blank']), (ylim[0], ylim[1]), ls='--', c=c, lw=2)
if txt != '':
txt_pos_x = (self.params['t_stimulus'] + .25 * self.params['t_blank'])
ylim = ax.get_ylim()
txt_pos_y = ylim[0] + .85 * (ylim[1] - ylim[0])
ax.annotate(txt, (txt_pos_x, txt_pos_y), fontsize=14, color='k')
def print_delays(self):
fn = self.params['merged_conn_list_ee']
if not os.path.exists(fn):
print 'File: %s not found\nCalling merge_connlists.py now...\n'
os.system('python merge_connlists.py')
conn_mat, delays = utils.convert_connlist_to_matrix(fn, self.params['n_exc'], self.params['n_exc'])
for i_, src in enumerate(self.gids_to_plot):
for j_, tgt in enumerate(self.gids_to_plot):
if src != tgt:
t1 = self.time_of_max_stim[src]
t2 = self.time_of_max_stim[tgt]
w, delay = conn_mat[src, tgt], delays[src, tgt]
if t1 < t2:
optimal_tau_prediction = (t2 - t1) / self.params['t_stimulus']
optimal_delay_scale = delay / (self.params['delay_scale'] * (t2 - t1))
print '%d (%d)\t->\t%d (%d)\t: dt_max_stim = %.1f\toptimal_tau_prediction = %.1f\toptimal_delay_scale = %.1f' % (src, t1, tgt, t2, t2 - t1, optimal_tau_prediction, optimal_delay_scale)
if __name__ == '__main__':
import simulation_parameters
ps = simulation_parameters.parameter_storage()
# set parameters
ps.params['connectivity_ee'] = False
ps.params['connectivity_ei'] = False
ps.params['connectivity_ie'] = False
ps.params['connectivity_ii'] = False
ps.set_filenames()
CS = CompareSimulations(ps)
CS.set_gids_to_plots(n_cells = 3)
CS.plot_input(fill_blank=True)
CS.plot_response('Response to stimulus only (without connectivity)', connectivity=False)
# ps.params['connectivity_ee'] = 'anisotropic'
# ps.params['connectivity_ei'] = 'random'
# ps.params['connectivity_ie'] = 'random'
# ps.params['connectivity_ii'] = 'random'
ps.params['connectivity_ee'] = 'anisotropic'
ps.params['connectivity_ei'] = 'isotropic'
ps.params['connectivity_ie'] = 'isotropic'
ps.params['connectivity_ii'] = 'isotropic'
# ps.params['connectivity_ee'] = 'anisotropic'
# ps.params['connectivity_ei'] = 'anisotropic'
# ps.params['connectivity_ie'] = 'anisotropic'
# ps.params['connectivity_ii'] = 'anisotropic'
ps.set_filenames()
CS.ps = ps
CS.print_delays()
CS.plot_response('Response to stimulus with connectivity', connectivity=True)
CS.plot_response_difference()
axes = CS.fig.get_axes()
axes[-1].set_xlabel('Time [ms]', fontsize=14)
# ps.set_filenames()
# CS.plot_response()
#
#
output_fig = ps.params['figures_folder'] + 'tau_prediction%.1f.png' % ps.params['tau_prediction']
print 'Saving to:', output_fig
pylab.savefig(output_fig)
pylab.show()