Time dependent rate for PoissinGroup

Hi,
I am converting an old Brian1 code to the current version. It has a rate to PossonGroup like this:

sim_duration = 1000
stimulus = sin(arange(0, sim_duration)*2*pi/sim_duration)

def input_rates(t):
        '''
        Returns firing rates for spatially patterned stimulus to E cells.  
        stimulus is array of stimulus orientations as function of time in ms.
        Range of stimulus is 0 - 1.
        '''
        return 400*(1+0.35* cos(2*pi*stimulus[floor(t*1000) 
                                % size (stimulus)] + pi + linspace(2*pi/N],  2*pi,N)))*Hz

poisson_to_E = PoissonGroup(N, input_rates)

So the input _rates give an array of size N at each time step, right?
and for the current version should be converted to something like this:

input_rates = b2.TimedArray(400.0*(1 + 0.35 * np.cos(2*pi*stimulus[int(floor(t*1000) % stimulus.size)]))*b2.Hz, dt=dt0)

Making an array stimulus at each time step is not clear for me.

Hi. Brian 1 required you to think of things in terms of indices and matrices, while Brian 2 uses an approach that abstracts away the implementation and focuses on the mathematical formulation.

In principle, you could have a 2D array as the TimedArray which would be the closest to the Brian 1 solution. It would look like this (assuming that the dt is 0.1ms and the 1000 steps in the stimulus array therefore correspond to 100ms):

sim_duration = 1000
N = 50
stimulus = sin(arange(0, sim_duration)*2*pi/sim_duration)
input_rates = b2.TimedArray(400.0*(1 + 0.35 * np.cos(2*pi*stimulus[:, None] +
                                                     np.pi + np.linspace(2*pi/N, 2*pi, N)))*b2.Hz, dt=dt0)

poisson_to_E = PoissonGroup(N, rates='input_rates(t % (100*ms), i)')

But in this specific case there is no need to pre-generate the stimulus and store it in a TimedArray. Brian 2’s string syntax is powerful enough to calculate the rates during the simulation by expressing them as a function of time and the neuron index:

poisson_to_E = PoissonGroup(N, rates='400.0*(1 + 0.35 * cos(2*pi*sin(2*pi*t/(100*ms)) + pi +'
                                                           '2*pi/N + (1.0*i/N)*2*pi))*Hz')

(Not 100% sure it is correct, but you get the idea).

2 Likes

Great! Thank you Marcel for quick replay.