2022-10-17 • General simulator software design

2022-10-17 • General simulator software design

In the previous notebook, the firing rate error in the N-to-1 simulations was fixed. We want to know re-run those simulations with actual lognormal Poisson inputs.

When writing the network simulation code, the N-to-1 simulation code was copied and adapted. I.e. there is duplication in functionality, and divergence in their APIs. It’s time for consolidation. Advantage: easier to also investigate LIF/EIF neurons, different neuron types, etc.

Imports

#
using MyToolbox
@time_imports using VoltoMapSim

Differential equations

izh = @eqs begin
    
    dv/dt = (k*(v-vₗ)*(v-vₜ) - u - I_syn) / C
    du/dt = a*(b*(v-vᵣ) - u)

    I_syn = gₑ*(v-Eₑ) + gᵢ*(v-Eᵢ)

    dgₑ/dt = -gₑ / τ  # Represents sum over all exc synapses
    dgᵢ/dt = -gᵢ / τ
end;
izh
SpikeLab.Model_
 with variables {v, u, I_syn, gₑ, gᵢ}
 and parameters {C, Eᵢ, Eₑ, a, b, k, vᵣ, vₗ, vₜ, τ}
izh.generated_func
:((diff, vars, params)->begin
          @unpack (v, u, I_syn, gₑ, gᵢ) = vars
          @unpack (C, Eᵢ, Eₑ, a, b, k, vᵣ, vₗ, vₜ, τ) = params
          diff.v = ((k * (v - vₗ) * (v - vₜ) - u) - I_syn) / C
          diff.u = a * (b * (v - vᵣ) - u)
          vars.I_syn = gₑ * (v - Eₑ) + gᵢ * (v - Eᵢ)
          diff.gₑ = -gₑ / τ
          diff.gᵢ = -gᵢ / τ
      end)

Initialize buffers

params = (
    # Cortical regular spiking (same as always)
    C  =  100    * pF,
    k  =    0.7  * (nS/mV),
    vₗ = - 60    * mV,
    vₜ = - 40    * mV,
    a  =    0.03 / ms,
    b  = -  2    * nS,
    # Not in model eqs above (yet)
    vₛ =   35    * mV,  # spike
    vᵣ = - 50    * mV,  # reset
    Δu =  100    * pA,

    # Synapses
    Eₑ =   0 * mV,
    Eᵢ = -80 * mV,  # Higher than Nto1 (was -65); same as nets.
    τ  =   7 * ms,
)

init = (
    v  = params.vᵣ,
    u  = 0 * pA,
    gₑ = 0 * nS,
    gᵢ = 0 * nS,
    I_syn = 0 * nA,
);
vars = CVec{Float64}(init)
diff = similar(vars)
diff .= 0
ComponentVector{Float64}(v = 0, u = 0, gₑ = 0, gᵢ = 0, I_syn = 0)
duration = 1 * second
Δt       = 0.1 * ms
Nt = to_timesteps(duration, Δt)
10000
for ti in 1:Nt
    izh.f(diff, vars, params)
    vars .+= diff .* Δt
end
Revise.revise(SpikeLab);
Revise.revise(VoltoMapSim);
poisson_spikes(5Hz, 20minutes)
6086-element Vector{Float64}:
 0.0584
 0.246
 0.264
 0.304
 0.318
 0.369
 0.445
 0.821
 0.9
 1.04
 1.28
 1.31
 1.35
 ⋮
 1.2E+03
 1.2E+03
 1.2E+03
 1.2E+03
 1.2E+03
 1.2E+03
 1.2E+03
 1.2E+03
 1.2E+03
 1.2E+03
 1.2E+03
 1.2E+03
(julia.exe:17984): Gdk-CRITICAL **: 13:16:50.068: gdk_seat_default_remove_tool: assertion 'tool != NULL' failed

(julia.exe:17984): Gdk-CRITICAL **: 13:16:50.284: gdk_seat_default_remove_tool: assertion 'tool != NULL' failed

(julia.exe:17984): Gdk-CRITICAL **: 13:16:50.420: gdk_seat_default_remove_tool: assertion 'tool != NULL' failed
?poisson_spikes
search: poisson_spikes gen_Poisson_spikes
poisson_spikes(r, T)

Generate a Poisson spike train with firing rate $r$ on the time interval $[0, T]$.

More precisely, simulate a Poisson process by drawing inter-spike-intervals from an Exponential distribution with rate parameter $r$, accumulating them until $T$ is reached. The number of spikes $N$ in $[0, T]$ will be Poisson-distributed, with mean = $rT$.

The output is a length-$N$ (i.e. variable length) vector of spike times.

Pause for now, and continue with the science.