Note
Go to the end to download the full example code
PyNEST EI-clustered network: Helper FunctionsΒΆ
Run this example as a Jupyter notebook:
See our guide for more information and troubleshooting.
Helper functions to calculate synaptic weights to construct random balanced networks and plot raster plot with color groups.
import matplotlib.pyplot as plt
import numpy as np
def postsynaptic_current_to_potential(tau_m, tau_syn, c_m=1.0, e_l=0.0):
"""Maximum post-synaptic potential amplitude
for exponential synapses and a synaptic efficacy J of 1 pA.
Parameters
----------
tau_m: float
Membrane time constant [ms]
tau_syn: float
Synapse time constant [ms]
c_m: float (optional)
Membrane capacity [pF] (default: 1.0)
e_l: float (optional)
Resting potential [mV] (default: 0.0)
Returns
-------
float
maximum psp amplitude (for a 1 pA current spike) [mV]
"""
# time of maximum deflection of the psp [ms]
tmax = np.log(tau_syn / tau_m) / (1 / tau_m - 1 / tau_syn)
# we assume here the current spike is 1 pA, otherwise [mV/pA]
pre = tau_m * tau_syn / c_m / (tau_syn - tau_m)
return (e_l - pre) * np.exp(-tmax / tau_m) + pre * np.exp(-tmax / tau_syn)
def calculate_RBN_weights(params):
"""Calculate synaptic weights for a random balanced network.
The synaptic weights are calculated according to the method
described in Eqs. 7-10 [1]_.
References
----------
.. [1] Rostami V, Rost T, Riehle A, van Albada SJ and Nawrot MP. 2020.
Excitatory and inhibitory motor cortical clusters account for balance,
variability, and task performance. bioRxiv 2020.02.27.968339.
DOI: `10.1101/2020.02.27.968339
<https://doi.org/10.1101/2020.02.27.968339>`__.
Parameters
----------
params: dict
Dictionary of network parameters
Returns
-------
ndarray
synaptic weights 2x2 matrix [[EE, EI], [IE, II]]
"""
N_E = params.get("N_E") # excitatory units
N_I = params.get("N_I") # inhibitory units
N = N_E + N_I # total units
E_L = params.get("E_L")
V_th_E = params.get("V_th_E") # threshold voltage
V_th_I = params.get("V_th_I")
tau_E = params.get("tau_E")
tau_I = params.get("tau_I")
tau_syn_ex = params.get("tau_syn_ex")
tau_syn_in = params.get("tau_syn_in")
gei = params.get("gei")
gii = params.get("gii")
gie = params.get("gie")
amp_EE = postsynaptic_current_to_potential(tau_E, tau_syn_ex)
amp_EI = postsynaptic_current_to_potential(tau_E, tau_syn_in)
amp_IE = postsynaptic_current_to_potential(tau_I, tau_syn_ex)
amp_II = postsynaptic_current_to_potential(tau_I, tau_syn_in)
baseline_conn_prob = params.get("baseline_conn_prob") # connection probs
js = np.zeros((2, 2))
K_EE = N_E * baseline_conn_prob[0, 0]
js[0, 0] = (V_th_E - E_L) * (K_EE**-0.5) * N**0.5 / amp_EE
js[0, 1] = -gei * js[0, 0] * baseline_conn_prob[0, 0] * N_E * amp_EE / (baseline_conn_prob[0, 1] * N_I * amp_EI)
K_IE = N_E * baseline_conn_prob[1, 0]
js[1, 0] = gie * (V_th_I - E_L) * (K_IE**-0.5) * N**0.5 / amp_IE
js[1, 1] = -gii * js[1, 0] * baseline_conn_prob[1, 0] * N_E * amp_IE / (baseline_conn_prob[1, 1] * N_I * amp_II)
return js
def rheobase_current(tau_m, e_l, v_th, c_m):
"""Rheobase current for membrane time constant and resting potential.
Parameters
----------
tau_m: float
Membrane time constant [ms]
e_l: float
Resting potential [mV]
v_th: float
Threshold potential [mV]
c_m: float
Membrane capacity [pF]
Returns
-------
float
rheobase current [pA]
"""
return (v_th - e_l) * c_m / tau_m
def raster_plot(spiketimes, tlim=None, colorgroups=None, ax=None, markersize=0.5):
"""Raster plot of spiketimes.
Plots raster plot of spiketimes withing given time limits and
colors neurons according to colorgroups.
Parameters
----------
spiketimes: ndarray
2D array [2xN_Spikes]
of spiketimes with spiketimes in row 0 and neuron IDs in row 1.
tlim: list of floats (optional)
Time limits of plot: [tmin, tmax],
if None: [min(spiketimes), max(spiketimes)]
colorgroups: list of tuples (optional)
Each element is a tuple in the format
(color, start_neuron_ID, stop_neuron_ID]) for coloring neurons in
given range, if None is given all neurons are black.
ax: axis object (optional)
If None a new figure is created,
else the plot is added to the given axis.
markersize: float (optional)
Size of markers. (default: 0.5)
Returns
-------
axis object
Axis object with raster plot.
"""
if ax is None:
fig, ax = plt.subplots()
if tlim is None:
tlim = [min(spiketimes[0]), max(spiketimes[0])]
if colorgroups is None:
colorgroups = [("k", 0, max(spiketimes[1]))]
for color, start, stop in colorgroups:
ax.plot(
spiketimes[0][np.logical_and(spiketimes[1] >= start, spiketimes[1] < stop)],
spiketimes[1][np.logical_and(spiketimes[1] >= start, spiketimes[1] < stop)],
color=color,
marker=".",
linestyle="None",
markersize=markersize,
)
ax.set_xlim(tlim)
ax.set_ylim([0, max(spiketimes[1])])
ax.set_xlabel("Time [ms]")
ax.set_ylabel("Neuron ID")
return ax