parameter_scan_merged_micro_circuit_empirical.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. import copy
  2. import warnings
  3. import brian2 as br
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. from brian2.units import *
  7. from brian2 import network_operation
  8. from scripts.models import hodgkin_huxley_eqs_with_synaptic_conductance, exponential_synapse, \
  9. exponential_synapse_on_pre, exponential_synapse_params, eqs_ih, hodgkin_huxley_params, \
  10. ih_params, delta_synapse_model, delta_synapse_on_pre
  11. def set_parameters_from_dict(neurongroup, dictionary_of_parameters):
  12. for param_key, param_value in dictionary_of_parameters.items():
  13. try:
  14. neurongroup.__setattr__(param_key, param_value)
  15. except AttributeError as err:
  16. warnings.warn("{:s} has no parameter {:s}".format(neurongroup.name, param_key))
  17. '''
  18. Model for the excitatory neurons
  19. '''
  20. # Hodgkin Huxley model from Brian2 documentation
  21. spike_threshold = 40*mV
  22. excitatory_neuron_options = {
  23. "threshold" : "v > spike_threshold",
  24. "refractory" : "v > spike_threshold",
  25. "method" : 'exponential_euler'
  26. }
  27. '''
  28. Model for the interneuron, currently only the inhibition timing is of interest thus the lif model
  29. '''
  30. lif_interneuron_eqs = """
  31. dv/dt =1.0/tau* (-v + u_ext) :volt (unless refractory)
  32. u_ext = u_ext_const : volt
  33. """
  34. lif_interneuron_params = {
  35. "tau": 7*ms,
  36. "v_threshold": -40*mV,
  37. "v_reset": -50*mV,
  38. "tau_refractory": 0.0*ms,
  39. "u_ext_const" : - 41 * mV
  40. }
  41. lif_interneuron_options = {
  42. "threshold": "v>v_threshold",
  43. "reset": "v=v_reset",
  44. "refractory": "tau_refractory",
  45. }
  46. '''
  47. Synapse Models
  48. '''
  49. delta_synapse_delay = 2.0 * ms
  50. '''
  51. Setup of the Model
  52. '''
  53. ## With voltage delta synapse
  54. ei_synapse_options = {
  55. 'model' : delta_synapse_model,
  56. 'on_pre' : delta_synapse_on_pre,
  57. }
  58. #
  59. # ie_synapse_options = {
  60. # 'model' : delta_synapse_model,
  61. # 'on_pre' : delta_synapse_on_pre,
  62. # 'delay' : delta_synapse_delay
  63. # }
  64. excitatory_neuron_eqs = hodgkin_huxley_eqs_with_synaptic_conductance + eqs_ih
  65. excitatory_neuron_params = hodgkin_huxley_params
  66. excitatory_neuron_params.update(ih_params)
  67. excitatory_neuron_params.update(excitatory_neuron_params)
  68. excitatory_neuron_params.update({"E_i": -120 * mV})
  69. # excitatory_neuron_params["stimulus"] = stimulus_array
  70. # excitatory_neuron_params["stimulus"] = stimulus_fun
  71. # ### With conductance based delta synapse
  72. # neuron_eqs = hodgkin_huxley_eqs_with_synaptic_conductance + eqs_ih
  73. #
  74. # synapse_model = exponential_synapse
  75. # synapse_on_pre = exponential_synapse_on_pre
  76. # synapse_params = exponential_synapse_params
  77. #
  78. # neuron_params = hodgkin_huxley_params
  79. # neuron_params.update(ih_params)
  80. # neuron_params.update({"E_i": -80 * mV})
  81. #
  82. # inhibition_off = 0.0 * nS
  83. # inhibition_on = 100 * nS
  84. network_params = copy.deepcopy(excitatory_neuron_params)
  85. network_params.update(lif_interneuron_params)
  86. network_params["spike_threshold"] = spike_threshold
  87. record_variables = ['v', 'I']
  88. integration_method = 'exponential_euler'
  89. initial_states = {
  90. "v": hodgkin_huxley_params["El"]
  91. }
  92. threshold_eqs = """
  93. spike_threshold: volt
  94. """
  95. '''
  96. Setup of the neuron groups, synapses and ultimately the network
  97. '''
  98. excitatory_neurons = br.NeuronGroup(N=2, \
  99. model=excitatory_neuron_eqs, \
  100. threshold=excitatory_neuron_options["threshold"], \
  101. refractory=excitatory_neuron_options["refractory"], \
  102. method=excitatory_neuron_options["method"])
  103. # set_parameters_from_dict(excitatory_neurons, excitatory_neuron_params) Why doesnt this work?
  104. set_parameters_from_dict(excitatory_neurons, initial_states)
  105. # excitatory_neurons.I_ext_const = 0.15*nA
  106. input_current = 0.15*nA
  107. excitatory_neurons.I = input_current
  108. inhibitory_neurons = br.NeuronGroup(N=1, \
  109. model=lif_interneuron_eqs, \
  110. threshold=lif_interneuron_options["threshold"], \
  111. refractory=lif_interneuron_options["refractory"], \
  112. reset=lif_interneuron_options["reset"])
  113. # set_parameters_from_dict(inhibitory_neurons, lif_interneuron_params) Same here
  114. e_to_i_synapses = br.Synapses(source=excitatory_neurons, \
  115. target=inhibitory_neurons, \
  116. model=ei_synapse_options["model"], \
  117. on_pre=ei_synapse_options["on_pre"])
  118. e_to_i_synapses.connect()
  119. i_to_e_synapses = br.Synapses(source=inhibitory_neurons, \
  120. target=excitatory_neurons, \
  121. model=exponential_synapse, \
  122. on_pre=exponential_synapse_on_pre, \
  123. delay=2.0*ms)
  124. i_to_e_synapses.connect()
  125. set_parameters_from_dict(i_to_e_synapses,exponential_synapse_params)
  126. exc_spike_recorder = br.SpikeMonitor(source=excitatory_neurons)
  127. inh_spike_recorder = br.SpikeMonitor(source=inhibitory_neurons)
  128. neuron_state_recorder = br.StateMonitor(excitatory_neurons, record_variables, record=[0,1])
  129. '''
  130. External Stimulus
  131. '''
  132. pulse_length = 50*ms
  133. pulse_1_start = 200*ms
  134. pulse_2_start = 400*ms
  135. pulse_3_start = 600*ms
  136. pulse_strength = 0.6 * nA
  137. @network_operation(dt=1*ms)
  138. def update_input(t):
  139. if t > pulse_1_start and t < pulse_1_start + 2*ms:
  140. excitatory_neurons[0].I = pulse_strength
  141. elif t > pulse_1_start + pulse_length and t < pulse_1_start + pulse_length + 2*ms:
  142. excitatory_neurons[0].I = input_current
  143. elif t > pulse_2_start and t < pulse_2_start + 2*ms:
  144. excitatory_neurons[1].I = pulse_strength
  145. elif t > pulse_2_start + pulse_length and t < pulse_2_start + pulse_length + 2*ms:
  146. excitatory_neurons[1].I = input_current
  147. elif t > pulse_3_start and t < pulse_3_start + 2 * ms:
  148. excitatory_neurons[0].I = pulse_strength
  149. elif t > pulse_3_start + pulse_length and t < pulse_3_start + pulse_length + 2 * ms:
  150. excitatory_neurons[0].I = input_current
  151. net = br.Network(update_input)
  152. net.add(excitatory_neurons)
  153. net.add(inhibitory_neurons)
  154. net.add(e_to_i_synapses)
  155. net.add(i_to_e_synapses)
  156. net.add(exc_spike_recorder)
  157. net.add(inh_spike_recorder)
  158. net.add(neuron_state_recorder)
  159. net.store()
  160. '''
  161. Run of the simulation
  162. '''
  163. def plot_spiking():
  164. ex_spike_trains = exc_spike_recorder.spike_trains()
  165. in_spike_trains = inh_spike_recorder.spike_trains()
  166. fig = plt.figure()
  167. ax = fig.add_subplot(111)
  168. for key, times in ex_spike_trains.items():
  169. ax.plot(times / ms, key / 2.0 * np.ones(times.shape), 'b|')
  170. offset = 2
  171. for key, times in in_spike_trains.items():
  172. ax.plot(times / ms, (key + offset) / 2.0 * np.ones(times.shape), 'r|')
  173. ax.grid(axis='x')
  174. ax.set_ylim(-0.1, 1.1)
  175. ax.set_xlabel("Time(ms)");
  176. def run_sim(inh_strength, exc_strength, record_states=True, run_time=50 * ms):
  177. net.restore()
  178. e_to_i_synapses.synaptic_strength = exc_strength
  179. i_to_e_synapses.synaptic_strength = inh_strength
  180. # neuron_state_recorder.record = record_states
  181. net.run(duration=run_time, namespace=network_params)
  182. run_time = 1000. * ms
  183. exc_strength = lif_interneuron_params["v_threshold"]-lif_interneuron_params["v_reset"] + 5*mV
  184. '''
  185. Gain in merged microcircuit
  186. '''
  187. input_current = 0.15*nA
  188. n_ghbar = 5
  189. ghbar_range = linspace(0.0,50.0,n_ghbar)*nS
  190. n_syn_strength = 5
  191. synaptic_strength_range = linspace(0.0,160.0,n_syn_strength)*nS
  192. bistable_array = ndarray((n_ghbar,n_syn_strength), dtype=float)
  193. # Incredibly, enumerate doesn't work with Quantity objects
  194. syn_str_id = 0
  195. for synaptic_strength_val in synaptic_strength_range:
  196. ghbar_id = 0
  197. for ghbar_val in ghbar_range:
  198. net.restore()
  199. network_params['ghbar'] = ghbar_val
  200. net.store()
  201. run_sim(inh_strength=synaptic_strength_val, exc_strength=exc_strength, record_states=True, run_time=run_time)
  202. period_unperturbed, inhibitory_delay, periods = timed_inhibition_experiment.measure_response_curve(n_simulations,
  203. inhibition_on,
  204. offset_before_spike_peak=before_spike,
  205. offset_after_spike_peak=after_spike)
  206. isbistable = bistability_from_iterative_map_unidirectional(period_unperturbed, inhibitory_delay, periods)
  207. print(synaptic_strength_val,ghbar_val,isbistable)
  208. bistable_array[ghbar_id,syn_str_id] = isbistable
  209. ghbar_id = ghbar_id + 1
  210. syn_str_id = syn_str_id + 1
  211. rates_disconnected = np.array(rates_disconnected)
  212. rates_merged = np.array(rates_merged)
  213. rates_unidirectional = np.array(rates_unidirectional)
  214. fig, axs = plt.subplots(2, sharex=True, sharey=True)
  215. axs[0].plot(ex_drive_range / nA, rate_diff_disconnected * ms, 'C1',label='disconnected')
  216. axs[0].plot(ex_drive_range / nA, rate_diff_merged * ms, 'C2', label='merged')
  217. axs[0].plot(ex_drive_range / nA, rate_diff_unidirectional * ms, 'C3', label='unidirectional')
  218. axs[1].plot(ex_drive_range / nA,rates_disconnected[:,0] * ms,'C1')
  219. axs[1].plot(ex_drive_range / nA,rates_disconnected[:,1] * ms,'C1',linestyle='--')
  220. axs[1].plot(ex_drive_range / nA,rates_merged[:,0] * ms,'C2')
  221. axs[1].plot(ex_drive_range / nA,rates_merged[:,1] * ms,'C2',linestyle='--')
  222. axs[1].plot(ex_drive_range / nA,rates_unidirectional[:,0] * ms,'C3')
  223. axs[1].plot(ex_drive_range / nA,rates_unidirectional[:,1] * ms,'C3',linestyle='--')
  224. axs[1].set_xlabel('Input Current [nA]')
  225. axs[0].set_ylabel('Firing Rate [Hz]')
  226. axs[1].set_ylabel('Firing Rate [Hz]')
  227. axs[0].legend()
  228. # run_sim(inh_strength=0*nS, exc_strength=10.*mV, record_states=True, run_time=run_time)
  229. # plot_spiking()
  230. #
  231. # plt.show()
  232. plt.show()