brunel-delta-nest_mod.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. # -*- coding: utf-8 -*-
  2. #
  3. # brunel-delta-nest.py
  4. #
  5. # This file is part of NEST.
  6. #
  7. # Copyright (C) 2004 The NEST Initiative
  8. #
  9. # NEST is free software: you can redistribute it and/or modify
  10. # it under the terms of the GNU General Public License as published by
  11. # the Free Software Foundation, either version 2 of the License, or
  12. # (at your option) any later version.
  13. #
  14. # NEST is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License
  20. # along with NEST. If not, see <http://www.gnu.org/licenses/>.
  21. '''
  22. Script to generate test data for the nestIO.
  23. Uses conductance-based integrate-and-fire neurons.
  24. Records spikes, voltages and conductances.
  25. based on:
  26. Random balanced network (delta synapses)
  27. ----------------------------------------
  28. This script simulates an excitatory and an inhibitory population on
  29. the basis of the network used in
  30. Brunel N, Dynamics of Sparsely Connected Networks of Excitatory and
  31. Inhibitory Spiking Neurons, Journal of Computational Neuroscience 8,
  32. 183–208 (2000).
  33. When connecting the network customary synapse models are used, which
  34. allow for querying the number of created synapses. Using spike
  35. detectors the average firing rates of the neurons in the populations
  36. are established. The building as well as the simulation time of the
  37. network are recorded.
  38. '''
  39. '''
  40. Importing all necessary modules for simulation, analysis and plotting.
  41. '''
  42. import nest
  43. import nest.raster_plot
  44. import time
  45. from numpy import exp
  46. nest.ResetKernel()
  47. '''
  48. Assigning the current time to a variable in order to determine the
  49. build time of the network.
  50. '''
  51. startbuild = time.time()
  52. '''
  53. Assigning the simulation parameters to variables.
  54. '''
  55. dt = 0.1 # the resolution in ms
  56. simtime = 500.0 # Simulation time in ms
  57. tstart = 400.0 # Start time for recording in ms for test cases
  58. delay = 1.5 # synaptic delay in ms
  59. '''
  60. Definition of the parameters crucial for asynchronous irregular firing
  61. of the neurons.
  62. '''
  63. g = 5.0 # ratio inhibitory weight/excitatory weight
  64. eta = 2.0 # external rate relative to threshold rate
  65. epsilon = 0.1 # connection probability
  66. '''
  67. Definition of the number of neurons in the network and the number of
  68. neuron recorded from
  69. '''
  70. order = 250
  71. NE = 4*order # number of excitatory neurons
  72. NI = 1*order # number of inhibitory neurons
  73. N_neurons = NE+NI # number of neurons in total
  74. N_rec = 50 # record from 50 neurons
  75. '''
  76. Definition of connectivity parameter
  77. '''
  78. CE = int(epsilon*NE) # number of excitatory synapses per neuron
  79. CI = int(epsilon*NI) # number of inhibitory synapses per neuron
  80. C_tot = int(CI+CE) # total number of synapses per neuron
  81. '''
  82. Initialization of the parameters of the integrate and fire neuron and
  83. the synapses. The parameter of the neuron are stored in a dictionary.
  84. '''
  85. neuron_params_cond = {"C_m": 250.0,
  86. "E_L": -70.0,
  87. "E_ex": 0.0,
  88. "E_in": -85.0,
  89. "V_m": -60.0,
  90. "V_reset": -60.0,
  91. "V_th": -55.0,
  92. "g_L": 17.0,
  93. "t_ref": 2.0,
  94. "tau_syn_ex": 0.2,
  95. "tau_syn_in": 2.0}
  96. neuron_params_curr = {"C_m": 250.0,
  97. "E_L": -70.0,
  98. "V_m": -60.0,
  99. "V_reset": -60.0,
  100. "V_th": -55.0,
  101. "t_ref": 2.0,
  102. "tau_syn_ex": 0.2,
  103. "tau_syn_in": 2.0}
  104. J = 0.1 # postsynaptic amplitude in mV
  105. J_ex = J # amplitude of excitatory postsynaptic potential
  106. J_in = -g*J_ex # amplitude of inhibitory postsynaptic potential
  107. p_rate_ex = 240000. # external firing rate of a poisson generator
  108. p_rate_in = 18800000. # external firing rate of a poisson generator
  109. '''
  110. Configuration of the simulation kernel by the previously defined time
  111. resolution used in the simulation. Setting "print_time" to True prints
  112. the already processed simulation time as well as its percentage of the
  113. total simulation time.
  114. '''
  115. nest.SetKernelStatus({"resolution": dt,
  116. "print_time": True,
  117. "overwrite_files": True })
  118. print("Building network")
  119. '''
  120. Configuration of the model `iaf_psc_delta` and `poisson_generator`
  121. using SetDefaults(). This function expects the model to be the
  122. inserted as a string and the parameter to be specified in a
  123. dictionary. All instances of theses models created after this point
  124. will have the properties specified in the dictionary by default.
  125. '''
  126. nest.SetDefaults("iaf_cond_exp", neuron_params_cond)
  127. nest.SetDefaults("iaf_psc_exp", neuron_params_curr)
  128. '''
  129. Creation of the nodes using `Create`. We store the returned handles in
  130. variables for later reference. Here the excitatory and inhibitory, as
  131. well as the poisson generator and two spike detectors. The spike
  132. detectors will later be used to record excitatory and inhibitory
  133. spikes.
  134. '''
  135. nodes_ex = nest.Create("iaf_cond_exp", NE)
  136. nodes_in = nest.Create("iaf_psc_exp", NI)
  137. noise_ex = nest.Create("poisson_generator", 1, {"rate": p_rate_ex})
  138. noise_in = nest.Create("poisson_generator", 1, {"rate": p_rate_in})
  139. espikes = nest.Create("spike_detector")
  140. ispikes = nest.Create("spike_detector")
  141. '''
  142. Configuration of the spike detectors recording excitatory and
  143. inhibitory spikes using `SetStatus`, which expects a list of node
  144. handles and a list of parameter dictionaries. Setting the variable
  145. "to_file" to True ensures that the spikes will be recorded in a .gdf
  146. file starting with the string assigned to label. Setting "withtime"
  147. and "withgid" to True ensures that each spike is saved to file by
  148. stating the gid of the spiking neuron and the spike time in one line.
  149. '''
  150. nest.SetStatus(espikes,[{"label": "brunel-py-ex",
  151. "withtime": True,
  152. "withgid": True,
  153. "to_file": True}])
  154. nest.SetStatus(ispikes,[{"label": "brunel-py-in",
  155. "withtime": True,
  156. "withgid": True,
  157. "to_file": True}])
  158. '''
  159. 4 spike detectors and multimeters will be connected to the
  160. excitatory population for different recording test cases for withgid and time_in_steps.
  161. These multimeters only record V_m.
  162. '''
  163. recdict = {"to_file" : True,
  164. "withtime" : True,
  165. "withgid" : True,
  166. "time_in_steps": False,
  167. "start" : tstart}
  168. spike_detectors_gidtime = nest.Create("spike_detector", 4, recdict)
  169. recdict["interval"] = 5.0 # only for multimeters
  170. '''
  171. Additional multimeters to record different combinations of analog signals.
  172. '''
  173. multimeters_cond = nest.Create("multimeter", 5, recdict)
  174. multimeters_curr = nest.Create("multimeter", 1, recdict)
  175. '''
  176. Multimeter to record from one single neuron.
  177. '''
  178. multimeter_1n = nest.Create("multimeter", 3, recdict)
  179. '''
  180. Set parameters of spike detectors and the first 4 multimeters
  181. for the test cases.
  182. '''
  183. for i,sd in enumerate(spike_detectors_gidtime):
  184. lst = [spike_detectors_gidtime[i]]
  185. nest.SetStatus(lst, [{"to_file" : True,
  186. "withtime": True}])
  187. if i==0:
  188. nest.SetStatus(lst, [{"label" : "0time",
  189. "withgid" : False,
  190. "time_in_steps": False}])
  191. elif i==1:
  192. nest.SetStatus(lst, [{"label" : "0gid-1time",
  193. "withgid" : True,
  194. "time_in_steps": False}])
  195. elif i==2:
  196. nest.SetStatus(lst, [{"label" : "0time_in_steps",
  197. "withgid" : False,
  198. "time_in_steps": True}])
  199. elif i==3:
  200. nest.SetStatus(lst, [{"label" : "0gid-1time_in_steps",
  201. "withgid" : True,
  202. "time_in_steps": True}])
  203. '''
  204. Additional multimeters
  205. '''
  206. nest.SetStatus([multimeters_cond[0]], [{"record_from": ["V_m"],
  207. "label" : "0gid-1time-2Vm"}])
  208. nest.SetStatus([multimeters_cond[1]], [{"record_from": ["V_m", "g_ex", "g_in"],
  209. "label" : "0gid-1time-2Vm-3gex-4gin"}])
  210. nest.SetStatus([multimeters_cond[2]], [{"record_from": ["g_ex", "V_m"],
  211. "label" : "0gid-1time-2gex-3Vm"}])
  212. nest.SetStatus([multimeters_cond[3]], [{"record_from": ["g_ex"],
  213. "label" : "0gid-1time-2gex"}])
  214. nest.SetStatus([multimeters_cond[4]], [{"record_from": ["V_m"],
  215. "label" : "0gid-1time_in_steps-2Vm",
  216. "time_in_steps": True}])
  217. nest.SetStatus([multimeters_curr[0]], [{"record_from": ["V_m", "input_currents_ex", "input_currents_in"],
  218. "label" : "0gid-1time-2Vm-3Iex-4Iin"}])
  219. nest.SetStatus([multimeter_1n[0]], [{"record_from": ["V_m"],
  220. "label" : "N1-0gid-1time-2Vm",
  221. "withgid" : True,
  222. "withtime" : True}])
  223. nest.SetStatus([multimeter_1n[1]], [{"record_from": ["V_m"],
  224. "label" : "N1-0time-1Vm",
  225. "withgid" : False,
  226. "withtime" : True}])
  227. nest.SetStatus([multimeter_1n[2]], [{"record_from": ["V_m"],
  228. "label" : "N1-0Vm",
  229. "withgid" : False,
  230. "withtime" : False}])
  231. print("Connecting devices")
  232. '''
  233. Definition of a synapse using `CopyModel`, which expects the model
  234. name of a pre-defined synapse, the name of the customary synapse and
  235. an optional parameter dictionary. The parameters defined in the
  236. dictionary will be the default parameter for the customary
  237. synapse. Here we define one synapse for the excitatory and one for the
  238. inhibitory connections giving the previously defined weights and equal
  239. delays.
  240. '''
  241. nest.CopyModel("static_synapse","excitatory",{"weight":J_ex, "delay":delay})
  242. nest.CopyModel("static_synapse","inhibitory",{"weight":J_in, "delay":delay})
  243. '''
  244. Connecting the previously defined poisson generator to the excitatory
  245. and inhibitory neurons using the excitatory synapse. Since the poisson
  246. generator is connected to all neurons in the population the default
  247. rule ('all_to_all') of Connect() is used. The synaptic properties are
  248. inserted via syn_spec which expects a dictionary when defining
  249. multiple variables or a string when simply using a pre-defined
  250. synapse.
  251. '''
  252. nest.Connect(noise_ex,nodes_ex, syn_spec="excitatory")
  253. nest.Connect(noise_in,nodes_in, syn_spec="excitatory")
  254. '''
  255. Connecting the first N_rec nodes of the excitatory and inhibitory
  256. population to the associated spike detectors using excitatory
  257. synapses. Here the same shortcut for the specification of the synapse
  258. as defined above is used.
  259. '''
  260. nest.Connect(nodes_ex[:N_rec], espikes, syn_spec="excitatory")
  261. nest.Connect(nodes_in[:N_rec], ispikes, syn_spec="excitatory")
  262. '''
  263. Connect only excitatory neurons to the spike detectors and multimeters
  264. for test cases.
  265. '''
  266. nest.Connect(nodes_ex[:N_rec], spike_detectors_gidtime, syn_spec="excitatory")
  267. nest.Connect(multimeters_cond, nodes_ex[:N_rec], syn_spec="excitatory")
  268. nest.Connect(multimeters_curr, nodes_in[:N_rec], syn_spec="excitatory")
  269. nest.Connect(multimeter_1n, [nodes_ex[0]], syn_spec="excitatory")
  270. print("Connecting network")
  271. print("Excitatory connections")
  272. '''
  273. Connecting the excitatory population to all neurons using the
  274. pre-defined excitatory synapse. Beforehand, the connection parameter
  275. are defined in a dictionary. Here we use the connection rule
  276. 'fixed_indegree', which requires the definition of the indegree. Since
  277. the synapse specification is reduced to assigning the pre-defined
  278. excitatory synapse it suffices to insert a string.
  279. '''
  280. conn_params_ex = {'rule': 'fixed_indegree', 'indegree': CE}
  281. nest.Connect(nodes_ex, nodes_ex+nodes_in, conn_params_ex, "excitatory")
  282. print("Inhibitory connections")
  283. '''
  284. Connecting the inhibitory population to all neurons using the
  285. pre-defined inhibitory synapse. The connection parameter as well as
  286. the synapse paramtere are defined analogously to the connection from
  287. the excitatory population defined above.
  288. '''
  289. conn_params_in = {'rule': 'fixed_indegree', 'indegree': CI}
  290. nest.Connect(nodes_in, nodes_ex+nodes_in, conn_params_in, "inhibitory")
  291. '''
  292. Storage of the time point after the buildup of the network in a
  293. variable.
  294. '''
  295. endbuild=time.time()
  296. '''
  297. Simulation of the network.
  298. '''
  299. print("Simulating")
  300. nest.Simulate(simtime)
  301. '''
  302. Storage of the time point after the simulation of the network in a
  303. variable.
  304. '''
  305. endsimulate= time.time()
  306. '''
  307. Reading out the total number of spikes received from the spike
  308. detector connected to the excitatory population and the inhibitory
  309. population.
  310. '''
  311. events_ex = nest.GetStatus(espikes,"n_events")[0]
  312. events_in = nest.GetStatus(ispikes,"n_events")[0]
  313. '''
  314. Calculation of the average firing rate of the excitatory and the
  315. inhibitory neurons by dividing the total number of recorded spikes by
  316. the number of neurons recorded from and the simulation time. The
  317. multiplication by 1000.0 converts the unit 1/ms to 1/s=Hz.
  318. '''
  319. rate_ex = events_ex/simtime*1000.0/N_rec
  320. rate_in = events_in/simtime*1000.0/N_rec
  321. '''
  322. Reading out the number of connections established using the excitatory
  323. and inhibitory synapse model. The numbers are summed up resulting in
  324. the total number of synapses.
  325. '''
  326. num_synapses = nest.GetDefaults("excitatory")["num_connections"]+\
  327. nest.GetDefaults("inhibitory")["num_connections"]
  328. '''
  329. Establishing the time it took to build and simulate the network by
  330. taking the difference of the pre-defined time variables.
  331. '''
  332. build_time = endbuild-startbuild
  333. sim_time = endsimulate-endbuild
  334. '''
  335. Printing the network properties, firing rates and building times.
  336. '''
  337. print("Brunel network simulation (Python)")
  338. print("Number of neurons : {0}".format(N_neurons))
  339. print("Number of synapses: {0}".format(num_synapses))
  340. print(" Exitatory : {0}".format(int(CE * N_neurons) + N_neurons))
  341. print(" Inhibitory : {0}".format(int(CI * N_neurons)))
  342. print("Excitatory rate : %.2f Hz" % rate_ex)
  343. print("Inhibitory rate : %.2f Hz" % rate_in)
  344. print("Building time : %.2f s" % build_time)
  345. print("Simulation time : %.2f s" % sim_time)
  346. '''
  347. Plot a raster of the excitatory neurons and a histogram.
  348. '''
  349. nest.raster_plot.from_device(espikes, hist=True)
  350. '''
  351. Do more plots.
  352. '''
  353. nest.raster_plot.from_device(ispikes, hist=True)
  354. # import matplotlib.pyplot as plt
  355. # # plt.figure()
  356. # # import nest.voltage_trace as v
  357. # # v.from_device([multimeters[5]])
  358. # # plt.figure()
  359. # # v.from_device([multimeters[4]])
  360. # plt.show()