Hi again. So I hope I understand correctly what you want to do: every 500ms, you want to randomly select a neuron and have it’s i_offset
current jump and then decay as an inverse of time, correct?
In your current network_operation
, you assign to N.i_offset
. An assignment to a variable sets its current value. In your case this is a string referring to time t
, but this string will be evaluated once when you do the assignment. According to your model equations, i_offset
is a parameter, not a dynamical variable, so its value will not change after that assignment. Also, note that t
refers to the time since the start of the simulation, so at t=500*ms
, you’ll increase your i_offset
only by 0.02nA.
There are several ways you can implement a dynamically decaying current spike. The easiest is to have it decay exponentially by defining it as a differential equation that decays back to the base value with time constant tau_i
(changing this time constant allows you to change the width of the spike).
tau_i = 2*ms
base_i_offset = 20*nA
eqs = """
R : ohm
di_offset/dtau_i = (base_i_offset - i_offset)/tau_i : amp
tau : second
Vr : volt
Vt : volt
dv/dt = (R*i_offset-v)/tau : volt (unless refractory)
"""
# The neurons with threshold voltage, reset voltage and refractoriness
N = NeuronGroup(n, eqs, threshold='v > Vt', reset='v = Vr', refractory=t_ref,
method='euler', name='neurons')
You can then make the i_offset
value jump up every 500ms. You could do this via a network_operation
, but it might be more straightforward to pre-generate the indices of the neurons that should receive this spike, i.e. something like this:
n_spikes = 10
spike_trigger = SpikeGeneratorGroup(n, np.random.randint(n, size=n_spikes), 500*ms*(np.arange(n_spikes) + 1)
trigger = Synapses(spike_trigger, N, on_pre='i_offset += 10*nA')
If it is important to have an \frac{1}{1 + \alpha t} shape of the current, then you can put it directly into the definition of the current:
base_i_offset = 20*nA
eqs = """
R : ohm
i_offset = base_i_offset + (10 / (1 + 1000 * (t - last_injection) / second)) * nA : amp
last_injection : second # time of the last current injection for this neuron
tau : second
Vr : volt
Vt : volt
dv/dt = (R*i_offset-v)/tau : volt (unless refractory)
"""
N = ...
N.last_injection = -1e9*second
Now, instead of directly increasing the current each time, you’ll just update the last_injection
time:
spike_trigger = SpikeGeneratorGroup(...)
trigger = Synapses(spike_trigger, N, on_pre='last_injection = t')
I hope this all makes sense and I did not misunderstand what you are trying to do!