-
Notifications
You must be signed in to change notification settings - Fork 4
/
simulation_parameters.py
executable file
·556 lines (476 loc) · 31.4 KB
/
simulation_parameters.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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import json
import numpy as np
import numpy.random as rnd
import os
import utils
class parameter_storage(object):
"""
This class contains the simulation parameters in a dictionary called params.
"""
def __init__(self, fn=None):
"""
fn -- (string) can be the .json file name storing an existing parameter dictionary
or the FOLDER which holds the .json file in the FOLDER/Parameters/simulation_parameters.json
"""
if fn == None:
self.params = {}
self.set_default_params()
self.set_filenames()
else:
self.params = self.load_params_from_file(fn)
def set_default_params(self):
# self.params['simulator'] = 'hw_ess' # 'brian' #
self.params['simulator'] = 'nest' # 'brian' #
# new parameter make distinguishment between one / two dimensional model easy
self.params['n_grid_dimensions'] = 2
# ###################
# HEXGRID PARAMETERS
# ###################
self.params['N_RF'] = 30 # 200 for plotting, 2000 before # for more than 2-D tuning space: np.int(n_cells/N_V/N_theta)
self.params['N_RF_X'] = self.params['N_RF']
self.params['N_RF_Y'] = 1
self.params['n_orientation'] = 1 # only for compatitibility with code borrowed from v1-anticipation branch
if self.params['n_grid_dimensions'] == 2:
self.params['N_V'], self.params['N_theta'] = 4, 8# resolution in velocity norm and direction
self.params['N_RF_X'] = np.int(np.sqrt(self.params['N_RF'] * np.sqrt(3)))
self.params['N_RF_Y'] = np.int(np.sqrt(self.params['N_RF']))
# np.sqrt(np.sqrt(3)) comes from resolving the problem "how to quantize the square with a hex grid of a total of n_rfdots?"
else:
self.params['N_V'], self.params['N_theta'] = 10, 1# resolution in velocity norm and direction
self.params['N_RF_X'] = self.params['N_RF']
self.params['N_RF_Y'] = 1
self.params['N_theta'] = 1
self.params['log_scale'] = 2.0 # base of the logarithmic tiling of particle_grid; linear if equal to one
self.params['sigma_RF_pos'] = .01 # some variability in the position of RFs
# self.params['sigma_RF_pos'] = .05 # some variability in the position of RFs
self.params['sigma_RF_speed'] = .00 # some variability in the speed of RFs
# self.params['sigma_RF_speed'] = .30 # some variability in the speed of RFs
self.params['sigma_RF_direction'] = .00 * 2 * np.pi # some variability in the direction of RFs
# self.params['sigma_RF_direction'] = .25 * 2 * np.pi # some variability in the direction of RFs
self.params['sigma_RF_orientation'] = .1 * np.pi
# ###################
# NETWORK PARAMETERS
# ###################
self.params['n_exc'] = self.params['N_RF_X'] * self.params['N_RF_Y'] * self.params['N_V'] * self.params['N_theta'] # number of excitatory cells per minicolumn
self.params['n_exc_per_mc'] = 1 # only for compatitibility with code borrowed from v1-anticipation branch
self.params['fraction_inh_cells'] = 0.25 # fraction of inhibitory cells in the network, only approximately!
# for 2-Dimensional tuning property space use sqrt(fraction_inh_cells), in n-dim tuning-property space use fraction_inh_cells**(1./n_dim)
self.params['N_V_INH'] = int(round(np.sqrt(self.params['fraction_inh_cells']) * self.params['N_V']))
self.params['N_X_INH'] = int(round(np.sqrt(self.params['fraction_inh_cells']) * self.params['N_RF_X']))
self.params['N_Y_INH'] = 1 # for 2-dim tuning space only
self.params['N_theta_inh'] = 1
self.params['N_RF_INH'] = self.params['N_V_INH'] * self.params['N_X_INH'] * self.params['N_theta_inh']
self.params['n_inh' ] = self.params['N_RF_INH']
self.params['n_cells'] = self.params['n_exc'] + self.params['n_inh']
# ###################
# CELL PARAMETERS #
# ###################
self.params['neuron_model'] = 'IF_cond_exp'
# self.params['neuron_model'] = 'IF_cond_alpha'
# self.params['neuron_model'] = 'EIF_cond_exp_isfa_ista'
self.params['tau_syn_exc'] = 5.0 # 10.
self.params['tau_syn_inh'] = 10.0 # 20.
if self.params['neuron_model'] == 'IF_cond_exp':
self.params['cell_params_exc'] = {'cm':1.0, 'tau_refrac':1.0, 'v_thresh':-50.0, 'tau_syn_E': self.params['tau_syn_exc'], 'tau_syn_I':self.params['tau_syn_inh'], 'tau_m' : 10., 'v_reset' : -70., 'v_rest':-70}
self.params['cell_params_inh'] = {'cm':1.0, 'tau_refrac':1.0, 'v_thresh':-50.0, 'tau_syn_E': self.params['tau_syn_exc'], 'tau_syn_I':self.params['tau_syn_inh'], 'tau_m' : 10., 'v_reset' : -70., 'v_rest':-70}
elif self.params['neuron_model'] == 'IF_cond_alpha':
self.params['cell_params_exc'] = {'cm':1.0, 'tau_refrac':1.0, 'v_thresh':-50.0, 'tau_syn_E': self.params['tau_syn_exc'], 'tau_syn_I':self.params['tau_syn_inh'], 'tau_m' : 10., 'v_reset' : -70., 'v_rest':-70}
self.params['cell_params_inh'] = {'cm':1.0, 'tau_refrac':1.0, 'v_thresh':-50.0, 'tau_syn_E': self.params['tau_syn_exc'], 'tau_syn_I':self.params['tau_syn_inh'], 'tau_m' : 10., 'v_reset' : -70., 'v_rest':-70}
elif self.params['neuron_model'] == 'EIF_cond_exp_isfa_ista':
self.params['cell_params_exc'] = {'cm':1.0, 'tau_refrac':1.0, 'v_thresh':-50.0, 'tau_syn_E':self.params['tau_syn_exc'], 'tau_syn_I':self.params['tau_syn_inh'], 'tau_m' : 10., 'v_reset' : -70., 'v_rest':-70., \
'b' : 0.5, 'a':4.}
self.params['cell_params_inh'] = {'cm':1.0, 'tau_refrac':1.0, 'v_thresh':-50.0, 'tau_syn_E':self.params['tau_syn_exc'], 'tau_syn_I':self.params['tau_syn_inh'], 'tau_m' : 10., 'v_reset' : -70., 'v_rest':-70., \
'b' : 0.5, 'a':4.}
# default parameters: /usr/local/lib/python2.6/dist-packages/pyNN/standardmodels/cells.py
# v = voltage
self.params['v_init'] = -65. # [mV]
self.params['v_init_sigma'] = 10. # [mV]
# v = speed preference
self.params['v_max_tp'] = 3.0 # [Hz] maximal velocity in visual space for tuning proprties (for each component), 1. means the whole visual field is traversed within 1 second
self.params['v_min_tp'] = 0.05 # [a.u.] minimal velocity in visual space for tuning property distribution
# #######################
# CONNECTIVITY PARAMETERS
# #######################
"""
For each connection type ('ee', 'ei', 'ie', 'ii') choose one form of connectivity
"""
self.params['connectivity_ee'] = 'anisotropic'
#self.params['connectivity_ee'] = 'isotropic'
# self.params['connectivity_ee'] = 'random'
# self.params['connectivity_ee'] = False
# self.params['connectivity_ei'] = 'anisotropic'
self.params['connectivity_ei'] = 'isotropic'
# self.params['connectivity_ei'] = 'random'
# self.params['connectivity_ei'] = False
# self.params['connectivity_ie'] = 'anisotropic'
self.params['connectivity_ie'] = 'isotropic'
# self.params['connectivity_ie'] = 'random'
# self.params['connectivity_ie'] = False
# self.params['connectivity_ii'] = 'anisotropic'
self.params['connectivity_ii'] = 'isotropic'
# self.params['connectivity_ii'] = 'random'
# self.params['connectivity_ii'] = False
self.params['conn_conf'] = 'motion-based'
# self.params['conn_conf'] = 'direction-based'
# self.params['conn_conf'] = 'orientation-direction'
self.params['IJCNN_code'] = 'MBP' # determines the following parameters:
# compensated_delay
# w_sigma_v
# when the initial connections are derived on the cell's tuning properties, these two values are used
self.params['connectivity_radius'] = 1.00 # this determines how much the directional tuning of the src is considered when drawing connections, the connectivity_radius affects the choice w_sigma_x/v
self.params['delay_scale'] = 1000. # this determines the scaling
self.params['all_connections_have_equal_delays'] = True # if True: IJCNN-paper like motion-based-prediction/anticipation, all have the same delay
# if False: Frontiers like distribution of conduction delays --> necessary for HW-permutation
self.params['randomize_delays'] = False# if True: permutate all delays (-->ESS-like), makes only sense if set all_connections_have_equal_delays is set to False
#from the latency in second (d(src, tgt) / v_src) to the connection
#delay (delay_ij = latency_ij * delay_scale) in ms
self.params['tau_prediction'] = .005 # [s] fixed latency for neural signaling, determines preferred projection sites of neurons
self.params['delay_range'] = [0.1, 100.] # [ms], restricts remaining connections to have delays within this range
# self.params['delay_range'] = [0.1, self.params['tau_prediction'] * 1000.] # [ms], restricts remaining connections to have delays within this range
self.params['w_sigma_x'] = 0.1 # width of connectivity profile for pre-computed weights
if self.params['IJCNN_code'] == 'MBP':
self.params['w_sigma_v'] = 0.1 # small w_sigma: tuning_properties get stronger weight when deciding on connection
else:
self.params['w_sigma_v'] = 100. # small w_sigma: tuning_properties get stronger weight when deciding on connection
# large w_sigma: make conn prob independent of tuning_properties
self.params['w_sigma_isotropic'] = 0.10 # spatial reach of isotropic connectivity, should not be below 0.05 otherwise you don't get the desired p_effective
# self.params['equal_weights'] = True # if True, connection weights are all equal and w_sigma_ determine only connection probability
self.params['equal_weights'] = False # if True, connection weights are all equal and w_sigma_ determine only connection probability
# for anisotropic connections each target cell receives a defined sum of incoming connection weights
#self.params['w_tgt_in_per_cell_ee'] = 0.30 # [uS] how much input should an exc cell get from its exc source cells?
#self.params['w_tgt_in_per_cell_ei'] = 0.45 # [uS] how much input should an inh cell get from its exc source cells?
#self.params['w_tgt_in_per_cell_ie'] = 1.60 # [uS] how much input should an exc cell get from its inh source cells?
#self.params['w_tgt_in_per_cell_ii'] = 0.15 # [uS] how much input should an inh cell get from its source cells?
self.params['w_tgt_in_per_cell_ee'] = 0.10 # [uS] how much input should an exc cell get from its exc source cells?
self.params['w_tgt_in_per_cell_ei'] = 1.0 * self.params['w_tgt_in_per_cell_ee']
self.params['w_tgt_in_per_cell_ie'] = 1.0 * self.params['w_tgt_in_per_cell_ee'] / self.params['fraction_inh_cells']
self.params['w_tgt_in_per_cell_ii'] = 0.10 #1.0 * self.params['w_tgt_in_per_cell_ee'] / self.params['fraction_inh_cells']
self.params['w_tgt_in_per_cell_ee'] *= 5. / self.params['tau_syn_exc']
self.params['w_tgt_in_per_cell_ei'] *= 5. / self.params['tau_syn_exc']
self.params['w_tgt_in_per_cell_ie'] *= 5. / self.params['tau_syn_inh']
self.params['w_tgt_in_per_cell_ii'] *= 5. / self.params['tau_syn_inh']
self.params['w_sigma_distribution'] = 0.2 # percentage of w_mean_isotropic for the sigma of the weight distribution (gaussian) when drawn for isotropic connectivity
self.params['conn_types'] = ['ee', 'ei', 'ie', 'ii']
self.params['w_range_hw'] = (0.004516379807692308, 0.04589923076923077)
# self.params['p_to_w'] =
self.params['p_ee'] = 0.005 # fraction of network cells allowed to connect to each target cell, used in CreateConnections
self.params['w_min'] = 5e-4 # When probabilities are transformed to weights, they are scaled so that the map into this range
self.params['w_max'] = 8e-3
self.params['n_src_cells_per_neuron'] = round(self.params['p_ee'] * self.params['n_exc']) # only excitatory sources
# exc - inh
self.params['p_ei'] = 0.02 #self.params['p_ee']
self.params['w_ei_mean'] = 0.005
self.params['w_ei_sigma'] = 0.001
# inh - exc
self.params['p_ie'] = 0.02 #self.params['p_ee']
self.params['w_ie_mean'] = 0.005
self.params['w_ie_sigma'] = 0.001
# inh - inh
self.params['p_ii'] = 0.02
self.params['w_ii_mean'] = 0.003
self.params['w_ii_sigma'] = 0.001
# for random connections only:
self.params['standard_delay'] = 3 # [ms]
self.params['standard_delay_sigma'] = 1 # [ms]
# ######################
# SIMULATION PARAMETERS
# ######################
self.params['seed'] = 0
self.params['np_random_seed'] = 0
# self.params['np_random_seed'] = self.params['seed']
self.params['t_sim'] = 1600. # [ms] total simulation time
self.params['t_stimulus'] = 1600. # [ms] time for a stimulus of speed 1.0 to cross the whole visual field from 0 to 1.
self.params['t_start'] = 200. # [ms] Time before stimulus starts
self.params['t_blank'] = 0. # [ms] duration of 'blanked' input (if zero, assumes no blank)
self.params['t_before_blank'] = self.params['t_start'] + 400. # [ms] time when blanking starts, i.e. t_reappear = t_before_blank + t_blank
self.params['tuning_prop_seed'] = self.params['seed'] # seed for randomized tuning properties
self.params['input_spikes_seed'] = self.params['seed']
self.params['dt_sim'] = self.params['delay_range'][0] * 1 # [ms] time step for simulation
self.params['dt_rate'] = .1 # [ms] time step for the non-homogenous Poisson process
self.params['n_gids_to_record'] = 30
self.params['sensory_delay'] = 0.10 # [s] real, physical delay accumulated along the thalamo-cortical pathways
if self.params['IJCNN_code'] == 'MBP':
self.params['compensated_delay'] = 0.10
else:
self.params['compensated_delay'] = 0.00
# ######
# INPUT
# ######
self.params['f_max_stim'] = 1000. # [Hz]
self.params['w_input_exc'] = 6.00e-3 * 10. / self.params['tau_syn_exc'] # [uS] mean value for input stimulus ---< exc_units (columns
#self.params['w_input_exc'] = 5.00e-2 # [uS] mean value for input stimulus ---< exc_units (columns
# self.params['w_input_exc'] = 6.00e-3 * 10. / self.params['tau_syn_exc'] # [uS] mean value for input stimulus ---< exc_units (columns
# ###############
# MOTION STIMULUS
# ###############
"""
x0 (y0) : start position on x-axis (y-axis)
u0 (v0) : velocity in x-direction (y-direction)
"""
self.params['torus_width'] = 1.
self.params['torus_height'] = 1.
self.params['motion_params'] = (0.1, 0.5 , 0.5, 0) # stimulus start parameters (x, y, v_x, v_y)
self.params['blur_X'], self.params['blur_V'] = .05, .05
self.params['anticipatory_mode'] = True # if True record selected cells to gids_to_record_fn
self.params['n_cells_to_record_per_location'] = 10
# record the membrane potentials of some selected cells around these locations:
# self.params['locations_to_record'] = (.15, .20, .25, .30, .35, .45) # these values + motion_params[0] will determine the cells to record from
self.params['locations_to_record'] = [ .05 + self.params['motion_params'][0], \
.15 + self.params['motion_params'][0], \
.25 + self.params['motion_params'][0], \
.35 + self.params['motion_params'][0]]
# the blur parameter represents the input selectivity:
# high blur means many cells respond to the stimulus
# low blur means high input selectivity, few cells respond
# the maximum number of spikes as response to the input alone is not much affected by the blur parameter
self.params['rf_size_x_gradient'] = .2 # receptive field size for x-pos increases with distance to .5
self.params['rf_size_y_gradient'] = .2 # receptive field size for y-pos increases with distance to .5
self.params['rf_size_x_min'] = .02 # cells situated at .5 have this receptive field size
self.params['rf_size_y_min'] = .02 # cells situated at .5 have this receptive field size
self.params['rf_size_vx_gradient'] = .2 # receptive field size for vx-pos increases with distance to 0.0
self.params['rf_size_vy_gradient'] = .2 #
self.params['rf_size_vx_min'] = .02 # cells situated at .5 have this receptive field size
self.params['rf_size_vy_min'] = .02 # cells situated at .5 have this receptive field size
# ######
# NOISE
# ######
self.params['w_exc_noise'] = 4e-3 * 5. / self.params['tau_syn_exc'] # [uS] mean value for noise ---< columns
self.params['f_exc_noise'] = 2000 # [Hz]
self.params['w_inh_noise'] = 4e-3 * 10. / self.params['tau_syn_inh'] # [uS] mean value for noise ---< columns
self.params['f_inh_noise'] = 2000 # [Hz]
# no noise:
# self.params['w_exc_noise'] = 1e-5 # [uS] mean value for noise ---< columns
# self.params['f_exc_noise'] = 1# [Hz]
# self.params['w_inh_noise'] = 1e-5 # [uS] mean value for noise ---< columns
# self.params['f_inh_noise'] = 1# [Hz]
self.print_cell_numbers()
def set_folder_name(self, folder_name=None):
# folder naming code:
# PREFIX + XXXX + parameters
# X = ['A', # for anisotropic connections
# 'I', # for isotropic connections
# 'R', # for random connections
# '-', # for non-existant connections
# order of X: 'ee', 'ei', 'ie', 'ii'
connectivity_code = ''
if self.params['connectivity_ee'] == 'anisotropic':
connectivity_code += 'A'
elif self.params['connectivity_ee'] == 'isotropic':
connectivity_code += 'I'
elif self.params['connectivity_ee'] == 'random':
connectivity_code += 'R'
elif self.params['connectivity_ee'] == False:
connectivity_code += '-'
if self.params['connectivity_ei'] == 'anisotropic':
connectivity_code += 'A'
elif self.params['connectivity_ei'] == 'isotropic':
connectivity_code += 'I'
elif self.params['connectivity_ei'] == 'random':
connectivity_code += 'R'
elif self.params['connectivity_ei'] == False:
connectivity_code += '-'
if self.params['connectivity_ie'] == 'anisotropic':
connectivity_code += 'A'
elif self.params['connectivity_ie'] == 'isotropic':
connectivity_code += 'I'
elif self.params['connectivity_ie'] == 'random':
connectivity_code += 'R'
elif self.params['connectivity_ie'] == False:
connectivity_code += '-'
if self.params['connectivity_ii'] == 'anisotropic':
connectivity_code += 'A'
elif self.params['connectivity_ii'] == 'isotropic':
connectivity_code += 'I'
elif self.params['connectivity_ii'] == 'random':
connectivity_code += 'R'
elif self.params['connectivity_ii'] == False:
connectivity_code += '-'
self.params['connectivity_code'] = connectivity_code
if folder_name == None:
folder_name = '%s_vx%.1f_eqD%d_compDelay%.2f_%s_nRF%d_tauPred%d_delayMax%d_pee%.2e_wee%.2e_wsx%.2e_wsv%.2e_wiso%.2f_taue%d_taui%d_seed%d/' % (\
self.params['IJCNN_code'], self.params['motion_params'][2], self.params['all_connections_have_equal_delays'], self.params['compensated_delay'], \
self.params['connectivity_code'], self.params['N_RF'], \
self.params['tau_prediction'] * 1000., self.params['delay_range'][1], self.params['p_ee'], self.params['w_tgt_in_per_cell_ee'], \
self.params['w_sigma_x'], self.params['w_sigma_v'], self.params['w_sigma_isotropic'], \
self.params['tau_syn_exc'], self.params['tau_syn_inh'], self.params['seed'])
# folder_name += '/'
# if parameters should be stored in the folder name:
self.params['folder_name'] = folder_name
else:
self.params['folder_name'] = folder_name
print 'Folder name:', self.params['folder_name']
def set_filenames(self, folder_name=None):
self.set_folder_name(folder_name)
print 'Folder name:', self.params['folder_name']
# in order to NOT re-compute the input spike trains when the stimulus parameters have not changed, do NOT store them in a subfolder of self.params['folder_name']
self.params['input_folder'] = "InputSpikeTrains_x0%.2e_v0%.2e_bX%.2e_bV%.2e_fstim%.1e_tsim%d_tblank%d_tbeforeblank%d_%dnrns/" % \
(self.params['motion_params'][0], self.params['motion_params'][2], self.params['blur_X'], self.params['blur_V'], \
self.params['f_max_stim'], self.params['t_sim'], self.params['t_blank'], self.params['t_before_blank'], self.params['n_cells'])
# if you want to store the input files in a subfolder of self.params['folder_name'], do this:
# self.params['input_folder'] = "%sInputSpikeTrains/" % self.params['folder_name']# folder containing the input spike trains for the network generated from a certain stimulus
self.params['spiketimes_folder'] = "%sSpikes/" % self.params['folder_name']
self.params['volt_folder'] = "%sVoltageTraces/" % self.params['folder_name']
self.params['parameters_folder'] = "%sParameters/" % self.params['folder_name']
self.params['connections_folder'] = "%sConnections/" % self.params['folder_name']
self.params['figures_folder'] = "%sFigures/" % self.params['folder_name']
self.params['movie_folder'] = "%sMovies/" % self.params['folder_name']
self.params['tmp_folder'] = "%stmp/" % self.params['folder_name']
self.params['data_folder'] = '%sData/' % (self.params['folder_name']) # for storage of analysis results etc
# all folders to be created if not yet existing:
self.params['folder_names'] = [self.params['folder_name'], \
self.params['spiketimes_folder'], \
self.params['volt_folder'], \
self.params['parameters_folder'], \
self.params['connections_folder'], \
self.params['figures_folder'], \
self.params['movie_folder'], \
self.params['tmp_folder'], \
self.params['data_folder'], \
self.params['input_folder']]
self.params['params_fn_json'] = '%ssimulation_parameters.json' % (self.params['parameters_folder'])
# input spiketrains
self.params['merged_input_spiketrains_fn'] = "%sinput_spiketrain_merged.dat" % (self.params['input_folder'])
self.params['input_st_fn_base'] = "%sstim_spike_train_" % self.params['input_folder']# input spike trains filename base
self.params['input_rate_fn_base'] = "%srate_" % self.params['input_folder']# input spike trains filename base
# output spiketrains
self.params['exc_spiketimes_fn_base'] = '%sexc_spikes_' % self.params['spiketimes_folder']
self.params['exc_spiketimes_fn_merged'] = '%sexc_spikes_merged_' % self.params['spiketimes_folder']
self.params['exc_nspikes_fn_merged'] = '%sexc_nspikes' % self.params['spiketimes_folder']
self.params['exc_nspikes_nonzero_fn'] = '%sexc_nspikes_nonzero.dat' % self.params['spiketimes_folder']
self.params['inh_spiketimes_fn_base'] = '%sinh_spikes_' % self.params['spiketimes_folder']
self.params['inh_spiketimes_fn_merged'] = '%sinh_spikes_merged_' % self.params['spiketimes_folder']
self.params['inh_nspikes_fn_merged'] = '%sinh_nspikes' % self.params['spiketimes_folder']
self.params['inh_nspikes_nonzero_fn'] = '%sinh_nspikes_nonzero.dat' % self.params['spiketimes_folder']
self.params['exc_volt_fn_base'] = '%sexc_volt' % self.params['volt_folder']
self.params['exc_gsyn_fn_base'] = '%sexc_gsyn' % self.params['volt_folder']
self.params['inh_volt_fn_base'] = '%sinh_volt' % self.params['volt_folder']
self.params['rasterplot_exc_fig'] = '%srasterplot_exc.png' % (self.params['figures_folder'])
self.params['rasterplot_inh_fig'] = '%srasterplot_inh.png' % (self.params['figures_folder'])
# tuning properties and other cell parameter files
self.params['tuning_prop_means_fn'] = '%stuning_prop_means.prm' % (self.params['parameters_folder']) # for excitatory cells
self.params['tuning_prop_inh_fn'] = '%stuning_prop_inh.prm' % (self.params['parameters_folder']) # for inhibitory cells
self.params['tuning_prop_fig_exc_fn'] = '%stuning_properties_exc.png' % (self.params['figures_folder'])
self.params['tuning_prop_fig_inh_fn'] = '%stuning_properties_inh.png' % (self.params['figures_folder'])
self.params['gids_to_record_fn'] = '%sgids_to_record.dat' % (self.params['parameters_folder'])
self.params['prediction_fig_fn_base'] = '%sprediction_' % (self.params['figures_folder'])
# CONNECTION FILES
self.params['weight_and_delay_fig'] = '%sweights_and_delays.png' % (self.params['figures_folder'])
# connection lists have the following format: src_gid tgt_gid weight delay
# E - E
self.params['conn_list_ee_fn_base'] = '%sconn_list_ee_' % (self.params['connections_folder'])
self.params['merged_conn_list_ee'] = '%smerged_conn_list_ee.dat' % (self.params['connections_folder'])
# E - I
self.params['conn_list_ei_fn_base'] = '%sconn_list_ei_' % (self.params['connections_folder'])
self.params['merged_conn_list_ei'] = '%smerged_conn_list_ei.dat' % (self.params['connections_folder'])
# I - E
self.params['conn_list_ie_fn_base'] = '%sconn_list_ie_' % (self.params['connections_folder'])
self.params['merged_conn_list_ie'] = '%smerged_conn_list_ie.dat' % (self.params['connections_folder'])
# I - I
self.params['conn_list_ii_fn_base'] = '%sconn_list_ii_' % (self.params['connections_folder'])
self.params['merged_conn_list_ii'] = '%smerged_conn_list_ii.dat' % (self.params['connections_folder'])
# used for different projections ['ee', 'ei', 'ie', 'ii'] for plotting
self.params['conn_mat_fn_base'] = '%sconn_mat_' % (self.params['connections_folder'])
self.params['delay_mat_fn_base'] = '%sdelay_mat_' % (self.params['connections_folder'])
# ANALYSIS RESULTS
# these files receive the output folder when they are create / processed --> more suitable for parameter sweeps
self.params['xdiff_vs_time_fn'] = 'xdiff_vs_time.dat'
self.params['vdiff_vs_time_fn'] = 'vdiff_vs_time.dat'
def check_folders(self):
"""
Returns True if all folders exist, False otherwise
"""
all_folders_exist = True
for f in self.params['folder_names']:
if not os.path.exists(f):
all_folders_exist = False
return all_folders_exist
def create_folders(self, p=None):
"""
Must be called from 'outside' this class before the simulation
"""
if p == None:
p = self.params
for f in p['folder_names']:
if not os.path.exists(f):
print 'Creating folder:\t%s' % f
os.system("mkdir %s" % (f))
def load_params(self):
"""
return the simulation parameters in a dictionary
"""
# self.ParamSet = ntp.ParameterSet(self.params)
# return self.ParamSet
return self.params
def load_params_from_file(self, fn):
if os.path.isdir(fn):
folder_name = os.path.abspath(fn) + '/'
fn = folder_name + 'Parameters/simulation_parameters.json'
f = file(fn, 'r')
print 'Loading parameters from', fn
self.params = json.load(f)
return self.params
def update_values(self, kwargs):
for key, value in kwargs.iteritems():
self.params[key] = value
# update the dependent parameters
self.set_filenames()
# self.ParamSet = ntp.ParameterSet(self.params)
def write_parameters_to_file(self, fn=None, params=None):
"""
Keyword arguments:
fn -- (optional) target output filename for json dictionary
params -- (optional) the modified parameter dictionary that is to write
"""
if fn == None:
fn = self.params['params_fn_json']
if params == None:
params_to_write = self.params
if not (os.path.isdir(params_to_write['folder_name'])):
print 'Creating folder:\n\t%s' % params_to_write['folder_name']
self.create_folders(params_to_write)
print 'Writing parameters to: %s' % (fn)
output_file = file(fn, 'w')
d = json.dump(params_to_write, output_file, sort_keys=True, indent=4)
def print_cell_numbers(self):
print 'Excitatory cells:'
print 'N_RF_X %d\tN_RF_Y %d\tN_V %d' % (self.params['N_RF_X'], self.params['N_RF_Y'], self.params['N_V'])
print 'Inhibitory cells:'
print 'N_X_INH % d\tN_Y_INH %d\tN_V_INH %d' % (self.params['N_X_INH'], self.params['N_Y_INH'], self.params['N_V_INH'])
# print 'N_HC: %d N_MC_PER_HC: %d' % (self.params['N_RF_X'] * self.params['N_RF_Y'], self.params['N_V'] * self.params['N_theta'])
print 'n_cells: %d\tn_exc: %d\tn_inh: %d\nn_inh / n_exc = %.3f\tn_inh / n_cells = %.3f' % (self.params['n_cells'], self.params['n_exc'], self.params['n_inh'], \
self.params['n_inh'] / float(self.params['n_exc']), self.params['n_inh'] / float(self.params['n_cells']))
class ParameterContainer(parameter_storage):
def __init__(self, fn):
super(ParameterContainer, self).__init__()
self.root_dir = os.path.dirname(fn)
# If the folder has been moved, all filenames need to be updated
self.update_values({self.params['folder_name'] : self.root_dir})
def load_params(self, fn):
f = file(fn, 'r')
print 'Loading parameters from', fn
self.params = json.load(f)
def update_values(self, kwargs):
for key, value in kwargs.iteritems():
self.params[key] = value
# update the dependent parameters
# --> to be implemented by another function (e.g. set_filenames())
def create_folders(self):
"""
Must be called from 'outside' this class before the simulation
"""
for f in self.params['folder_names']:
if not os.path.exists(f):
print 'Creating folder:\t%s' % f
os.system("mkdir %s" % (f))
def load_params(self):
"""
return the simulation parameters in a dictionary
"""
return self.ParamSet
def write_parameters_to_file(self, fn=None):
if fn == None:
fn = self.params['params_fn_json']
print 'Writing parameters to: %s' % (fn)
self.ParamSet.save(fn)