Good question, I had not thought of this! The run_args
method cannot currently change the value in a TimedArray
– it only deals with variables of groups (NeuronGroup
, Synapses
, …). I’ll look into supporting it, there are a few technical subtleties but in principle it should be doable via the same mechanism.
Until then, you have two options:
- If you can store all the input images in memory at the same time, then you can use the basic approach that I described here: Changing stimuli programmatically in C++ standalone, i.e. instead of directly using the rate at time
t
from the array, you’d shift the time according to the stimulus you want (no need for thestart_t
part, since each new simulation will always start at 0). Therun_args
mechanism will still make your life much simpler, since you don’t have to use Brian’s built-in mechanisms (Synapses
,run_regularly
, etc.) to program the whole logic (spike count, deciding whether to switch the stimulus or to increase its strength, etc.). Instead, you can do this after each run in Python, and then set the stimulus (stimulus_idx
andstimulus_strength
in the post I linked above) viarun_args
. - If your input data is too big to be in memory all at once, you can also re-create a
TimedArray
using aNeuronGroup
and arun_regularly
operation, by making use of internal machinery that allows you to make a variable (e.g. yourrate
) a “view” on a subset of values in another group (storing a “flat” version of your input image). Here’s a little example that shows how this works:
A simple 2DTimedArray
like this:
values = np.array([[1, 2], [4, 5], [3, 4]])
ta = TimedArray(values, dt=1*ms)
G = NeuronGroup(2, 'x = ta(t, i) : 1')
can be replaced by this (exact same results!):
value_group = NeuronGroup(6, 'values : 1')
value_group.values = values.flatten()
G = NeuronGroup(2, 'index : integer')
# The variable x does not appear in the equations, but is a variable of
# the model, added manually via add_reference:
G.variables.add_reference('x' , value_group, 'values', index='index')
# a bit silly: indices have to start at negative values, since the run_regularly
# operation will already run once at t=0s
G.index = 'i - N'
G.run_regularly('index += N', dt=1*ms) # Advance to next "row" of array
Now while this of course looks quite a bit more complex, it has the advantage that the values (i.e. your input image) are now stored in a simple NeuronGroup
variable: value_group.values
. You can therefore swap out the underlying values with
device.run(run_args={value_group.values: new_values.flatten()})
Hope that gets you going!