Running multiple standalone simulations [Request for Feedback]

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:

  1. 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 the start_t part, since each new simulation will always start at 0). The run_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 and stimulus_strength in the post I linked above) via run_args.
  2. If your input data is too big to be in memory all at once, you can also re-create a TimedArray using a NeuronGroup and a run_regularly operation, by making use of internal machinery that allows you to make a variable (e.g. your rate) 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 2D TimedArray 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!