From 964ab630329d7d155eea1a27deb8d2033d7bee18 Mon Sep 17 00:00:00 2001 From: Sebastian Schmitt Date: Fri, 25 Feb 2022 17:39:08 +0100 Subject: [PATCH 1/6] Add simulations to reproduce figure 8 of Brunel (2000) --- examples/frompapers/Brunel_2000.py | 159 +++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100755 examples/frompapers/Brunel_2000.py diff --git a/examples/frompapers/Brunel_2000.py b/examples/frompapers/Brunel_2000.py new file mode 100755 index 000000000..cd58b91d1 --- /dev/null +++ b/examples/frompapers/Brunel_2000.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +""" +Fig. 8 from: + +Brunel, N. Dynamics of Sparsely Connected Networks of Excitatory and +Inhibitory Spiking Neurons. J Comput Neurosci 8, 183–208 +(2000). https://doi.org/10.1023/A:1008925309027 + +Inspired by http://neuronaldynamics.epfl.ch + +Sebastian Schmitt, 2022 +""" + +import random +from brian2 import * +import matplotlib.pyplot as plt + + +def sim(g, nu_ext_over_nu_thr, sim_time, ax_spikes, ax_rates, rate_tick_step): + """ + g -- relative inhibitory to excitatory synaptic strength + nu_ext_over_nu_thr -- ratio of external stimulus rate to threshold rate + sim_time -- simulation time + ax_spikes -- matplotlib axes to plot spikes on + ax_rates -- matplotlib axes to plot rates on + rate_tick_step -- step size for rate axis ticks + """ + + # network parameters + N_E = 10000 + gamma = 0.25 + N_I = round(gamma * N_E) + N = N_E + N_I + epsilon = 0.1 + C_E = epsilon * N_E + C_ext = C_E + + # neuron parameters + tau = 20 * ms + theta = 20 * mV + V_r = 10 * mV + tau_rp = 2 * ms + + # synapse parameters + J = 0.1 * mV + D = 1.5 * ms + + # external stimulus + nu_thr = theta / (J * C_E * tau) + + defaultclock.dt = 0.1 * ms + + neurons = NeuronGroup(N, + """ + dv/dt = -v/tau : volt (unless refractory) + index : integer (constant) + """, + threshold="v > theta", + reset="v = V_r", + refractory=tau_rp, + method="exact", + ) + + excitatory_neurons = neurons[:N_E] + inhibitory_neurons = neurons[N_E:] + + exc_synapses = Synapses(excitatory_neurons, target=neurons, on_pre="v += J", delay=D) + exc_synapses.connect(p=epsilon) + + inhib_synapses = Synapses(inhibitory_neurons, target=neurons, on_pre="v += -g*J", delay=D) + inhib_synapses.connect(p=epsilon) + + nu_ext = nu_ext_over_nu_thr * nu_thr + + external_poisson_input = PoissonInput( + target=neurons, target_var="v", N=C_ext, rate=nu_ext, weight=J + ) + + rate_monitor = PopulationRateMonitor(neurons) + + # shuffle indices to randomly select neurons + indices = neurons.i[:] + np.random.shuffle(indices) + neurons.index = indices + + spike_monitor = SpikeMonitor(neurons[:50]) + + run(sim_time) + + ax_spikes.plot(spike_monitor.t / ms, spike_monitor.i, "|") + ax_rates.plot(rate_monitor.t / ms, rate_monitor.rate / Hz) + + ax_spikes.set_yticks([], []) + + ax_spikes.set_xlim(*params["t_range"]) + ax_rates.set_xlim(*params["t_range"]) + + ax_rates.set_ylim(*params["rate_range"]) + ax_rates.set_xlabel("t [ms]") + + ax_rates.set_yticks( + np.arange( + params["rate_range"][0], params["rate_range"][1] + rate_tick_step, rate_tick_step + ) + ) + + plt.subplots_adjust(hspace=0) + + +parameters = { + "A": { + "g": 3, + "nu_ext_over_nu_thr": 2, + "t_range": [500, 600], + "rate_range": [0, 6000], + "rate_tick_step": 1000, + }, + "B": { + "g": 6, + "nu_ext_over_nu_thr": 4, + "t_range": [1000, 1200], + "rate_range": [0, 400], + "rate_tick_step": 100, + }, + "C": { + "g": 5, + "nu_ext_over_nu_thr": 2, + "t_range": [1000, 1200], + "rate_range": [0, 200], + "rate_tick_step": 50, + }, + "D": { + "g": 4.5, + "nu_ext_over_nu_thr": 0.9, + "t_range": [1000, 1200], + "rate_range": [0, 250], + "rate_tick_step": 50, + }, +} + +for panel, params in parameters.items(): + + fig = plt.figure(figsize=(4, 5)) + fig.suptitle(panel) + + gs = fig.add_gridspec(ncols=1, nrows=2, height_ratios=[4, 1]) + + ax_spikes, ax_rates = gs.subplots(sharex="col") + + sim( + params["g"], + params["nu_ext_over_nu_thr"], + params["t_range"][1] * ms, + ax_spikes, + ax_rates, + params["rate_tick_step"], + ) + +plt.show() From e09c0b0b91ddfb9acf579c4fb454c735914dbf92 Mon Sep 17 00:00:00 2001 From: Sebastian Schmitt Date: Tue, 1 Mar 2022 08:35:51 +0100 Subject: [PATCH 2/6] Update examples/frompapers/Brunel_2000.py Co-authored-by: Marcel Stimberg --- examples/frompapers/Brunel_2000.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/frompapers/Brunel_2000.py b/examples/frompapers/Brunel_2000.py index cd58b91d1..92b9d546f 100755 --- a/examples/frompapers/Brunel_2000.py +++ b/examples/frompapers/Brunel_2000.py @@ -90,7 +90,7 @@ def sim(g, nu_ext_over_nu_thr, sim_time, ax_spikes, ax_rates, rate_tick_step): ax_spikes.plot(spike_monitor.t / ms, spike_monitor.i, "|") ax_rates.plot(rate_monitor.t / ms, rate_monitor.rate / Hz) - ax_spikes.set_yticks([], []) + ax_spikes.set_yticks([]) ax_spikes.set_xlim(*params["t_range"]) ax_rates.set_xlim(*params["t_range"]) From 0032816e804fd9ce82766ddb450cf412c633acf5 Mon Sep 17 00:00:00 2001 From: Sebastian Schmitt Date: Tue, 1 Mar 2022 08:35:57 +0100 Subject: [PATCH 3/6] Update examples/frompapers/Brunel_2000.py Co-authored-by: Marcel Stimberg --- examples/frompapers/Brunel_2000.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/frompapers/Brunel_2000.py b/examples/frompapers/Brunel_2000.py index 92b9d546f..e995c978d 100755 --- a/examples/frompapers/Brunel_2000.py +++ b/examples/frompapers/Brunel_2000.py @@ -85,7 +85,7 @@ def sim(g, nu_ext_over_nu_thr, sim_time, ax_spikes, ax_rates, rate_tick_step): spike_monitor = SpikeMonitor(neurons[:50]) - run(sim_time) + run(sim_time, report='text') ax_spikes.plot(spike_monitor.t / ms, spike_monitor.i, "|") ax_rates.plot(rate_monitor.t / ms, rate_monitor.rate / Hz) From 29f397c5e8ebdb7e72abecb0122642a8b6d1a7be Mon Sep 17 00:00:00 2001 From: Sebastian Schmitt Date: Tue, 1 Mar 2022 11:16:03 +0100 Subject: [PATCH 4/6] Record from first 50 excitatory neurons --- examples/frompapers/Brunel_2000.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/frompapers/Brunel_2000.py b/examples/frompapers/Brunel_2000.py index e995c978d..9ab1dfbea 100755 --- a/examples/frompapers/Brunel_2000.py +++ b/examples/frompapers/Brunel_2000.py @@ -78,11 +78,7 @@ def sim(g, nu_ext_over_nu_thr, sim_time, ax_spikes, ax_rates, rate_tick_step): rate_monitor = PopulationRateMonitor(neurons) - # shuffle indices to randomly select neurons - indices = neurons.i[:] - np.random.shuffle(indices) - neurons.index = indices - + # record from the first 50 excitatory neurons spike_monitor = SpikeMonitor(neurons[:50]) run(sim_time, report='text') From 0c6b0f14d9b99d1e18b4dea70c0e5a25a118dd49 Mon Sep 17 00:00:00 2001 From: Sebastian Schmitt Date: Tue, 1 Mar 2022 11:32:24 +0100 Subject: [PATCH 5/6] Remove (now) unnecessary index --- examples/frompapers/Brunel_2000.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/frompapers/Brunel_2000.py b/examples/frompapers/Brunel_2000.py index 9ab1dfbea..eebf653fc 100755 --- a/examples/frompapers/Brunel_2000.py +++ b/examples/frompapers/Brunel_2000.py @@ -53,7 +53,6 @@ def sim(g, nu_ext_over_nu_thr, sim_time, ax_spikes, ax_rates, rate_tick_step): neurons = NeuronGroup(N, """ dv/dt = -v/tau : volt (unless refractory) - index : integer (constant) """, threshold="v > theta", reset="v = V_r", From fd65d865767da7f1fc0f9739b8f615d0c4750b3a Mon Sep 17 00:00:00 2001 From: Marcel Stimberg Date: Tue, 1 Mar 2022 11:45:48 +0100 Subject: [PATCH 6/6] Update resources link for example images [ci skip] --- docs_sphinx/resources | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs_sphinx/resources b/docs_sphinx/resources index 3925abc4b..76d98e6fc 160000 --- a/docs_sphinx/resources +++ b/docs_sphinx/resources @@ -1 +1 @@ -Subproject commit 3925abc4b96e07da7a2fdd192a82ec675dc364eb +Subproject commit 76d98e6fcfbe61f95444ee2c197fcede82d4a437