"""
Name: madexp_psc_alpha_ref - Energy-based leaky integrate-and-fire neuron.
Description:
The dynamics are given by:
C_m dV_m/dt = g_L*(V-E_L) - w + I_e + I_syn_ex + I_syn_in
tau_w dw/dt = a(V-E_L) - epsilon/epsilon_0 w + I_KATP*epsilon_0/(epsilon_0 + epsilon)
tau_e depsilon/dt = (1-epsilon/(alpha*epsilon_0))**3 - (V-E_f)/(E_d-E_f) - gamma*w
E_L = E_0 + (E_u - E_0)(1-epsilon/epsilon_0)
if V_m >= V_th and epsilon > epsilon_c:
V_m is set to V_reset
On each spike arrival, the membrane potential feels an alpha-shaped current
of the form:
I_syn = I_0 * t * exp(-t/tau_syn) / tau_syn.
Sends: SpikeEvent
Receives: SpikeEvent, CurrentEvent, DataLoggingRequest
FirstVersion: 2019
Author: Tanguy Fardet
"""
neuron madexp_psc_alpha_ref:
state:
r integer = 0 # number of steps for refractory phase
epsilon real = alpha*epsilon_0 # Energy
V_m mV = E_0 + (E_u - E_0)*(1 - epsilon/epsilon_0) # Membrane potential
w pA = 0*pA # Adaptation current
end
function I_spike(epsilon real, V_m mV) pA:
Ispk pA = 0. pA
arg_exp real = 0.
if Delta_T > 0. mV:
arg_exp = clip((V_m - V_th) / Delta_T, -20., 20.)
Ispk = (epsilon-epsilon_c)*g_L*Delta_T*exp(arg_exp) / epsilon_0
end
return Ispk
end
equations:
inline eps_bound real = max(epsilon, 0.) # non-negative energy
inline V_bound mV = min(V_m, V_peak) # prevent exponential divergence
# synapses: alpha functions
kernel I_syn_in = (e/tau_syn_in) * t * exp(-t/tau_syn_in)
kernel I_syn_ex = (e/tau_syn_ex) * t * exp(-t/tau_syn_ex)
inline E_L mV = E_0 + (E_u - E_0)*(1 - eps_bound / epsilon_0)
inline I_in pA = convolve(I_syn_in, spikesInh)
inline I_ex pA = convolve(I_syn_ex, spikesExc)
inline Ispike pA = I_spike(eps_bound, V_bound)
V_m' = (g_L*(E_L - V_bound) + Ispike - w + I_e + I_in + I_ex + currents) / C_m
w' = (a*(V_bound-E_L) - w + I_KATP*epsilon_c/(eps_bound + epsilon_c)) / tau_w
epsilon' = ((1 - eps_bound / (alpha*epsilon_0))*(1 - eps_bound / (alpha*epsilon_0))*(1 - eps_bound / (alpha*epsilon_0)) - (V_bound-E_f)/(E_d-E_f) - w / gamma) / tau_e
end
parameters:
C_m pF = 100. pF # Membrane capacitance
g_L nS = 9. nS # leak conductance
Delta_T mV = 1.0 mV # Slope factor
V_peak mV = 0 mV # Spike detection threshold
E_0 mV = -65. mV # resting potential
E_u mV = -58. mV # upper potential
E_d mV = -50. mV # energy depletion potential
E_f mV = -60. mV # energy inflexion potential
epsilon_0 real = 0.5 # standard resting energy level
epsilon_c real = 0.2 # energy threshold for spike generation
alpha real = 1. # energetic health
delta real = 0.1 # energy consumption per spike
tau_e ms = 1000. ms # time constant for energy production
I_e pA = 0. pA # Constant input current
V_th mV = -55. mV # Spike generation threshold
a nS = 1. nS # subthreshold adaptation
b pA = 2. pA # spike-triggered adaptation
gamma pA = 1000. pA # normalization of adaptation energy
I_KATP pA = 10. pA # peak ATP-gated potassium current
tau_w ms = 300. ms # timescale of the adaptation current
V_reset mV = -62. mV # Reset potential
tau_syn_ex ms = 0.2 ms # Synaptic Time Constant Excitatory Synapse
tau_syn_in ms = 2.0 ms # Synaptic Time Constant for Inhibitory Synapse
t_ref ms = 2.0 ms # Refractory period
end
internals:
RefractoryCounts integer = steps(t_ref) # refractory time in steps
Vspike real = Delta_T == 0 ? min(V_th, V_peak) : V_peak
end
input:
spikesInh pA <- inhibitory spike
spikesExc pA <- excitatory spike
currents pA <- continuous
end
output: spike
update:
integrate_odes()
if epsilon < 0.:
epsilon = 0.
end
# refractoriness and threshold crossing
if r > 0: # is refractory?
r -= 1
V_m = V_reset
elif V_m >= Vspike and epsilon > epsilon_c:
# this test is necessary to support Delta_T = 0
V_m = V_reset
epsilon -= delta
w += b
emit_spike()
r = RefractoryCounts
end
end
end