Synapses

The Synapses class was introduced in Brian version 1.4 and can be used to define everything around synaptic interactions. It can replace the Connection class but is much more flexible, in particular it allows to directly incorporate descriptions of synaptic plasticity. See section Synapses in the user manual for instructions how to use the class.

class brian.Synapses(source, target=None, model=None, pre=None, post=None, max_delay=0.0 * second, level=0, clock=None, code_namespace=None, unit_checking=True, method=None, freeze=False, implicit=False, order=1)

Set of synapses between two neuron groups

Initialised with arguments:

source
The source NeuronGroup.
target=None
The target NeuronGroup. By default, target=source.
model=None
The equations that defined the synaptic variables, as an Equations object or a string. The syntax is the same as for a NeuronGroup.
pre=None
The code executed when presynaptic spikes arrive at the synapses. There can be multiple presynaptic codes, passed as a list or tuple of strings.
post=None
The code executed when postsynaptic spikes arrive at the synapses.
max_delay=0*ms
The maximum pre and postsynaptic delay. This is only useful if the delays can change during the simulation.
level=0
See Equations for details.
clock=None
The clock for updating synaptic state variables according to model. Currently, this must be identical to both the source and target clocks.
compile=False
Whether or not to attempt to compile the differential equation solvers (into Python code). Typically, for best performance, both compile and freeze should be set to True for nonlinear differential equations.
freeze=False
If True, parameters are replaced by their values at the time of initialization.
method=None
If not None, the integration method is forced. Possible values are linear, nonlinear, Euler, exponential_Euler (overrides implicit and order keywords).
unit_checking=True
Set to False to bypass unit-checking.
order=1
The order to use for nonlinear differential equation solvers. TODO: more details.
implicit=False
Whether to use an implicit method for solving the differential equations. TODO: more details.
code_namespace=None
Namespace for the pre and post codes.

Methods

state(var)

Returns the vector of values for state variable var, with length the number of synapses. The vector is an instance of class SynapticVariable.

synapse_index(i)

Returns the synapse indexes correspond to i, which can be a tuple or a slice. If i is a tuple (m,n), m and n can be an integer, an array, a slice or a subgroup.

save_connectivity(fn)

Saves the connectivity matrices and delays to a file fn, so that they can be reloaded afterwards.

Notice that this only saves the connectivity, not the current state of the variables in the Synapses class. In fact, it is completely decoupled from the pre/post synaptic groups, and the models of the Synapses object.

Example: Say we want to save the connectivity of Synapses, and some other state of the network, say my_state. We would simply do:

array_to_save = synapses.my_state[:,:]
synapses.save_connectivity('./somefile')
...
new_synapses = Synapses(newgroup0, newgroup0, model = newmodel, pre = newpre, ...)
new_synapses.load_connectivity('./somefile')
new_synapses.my_state[:,:] = array_that_was_saved_and_then_reloaded

Note: You have to deal with dynamical delays as you would with any other variable.

The following usages are also possible for a Synapses object ``S``:

len(S)
Returns the number of synapses in S.

Attributes:

delay
The presynaptic delays for all synapses (synapse->delay). If there are multiple presynaptic delays (multiple pre codes), this is a list.
delay_pre
Same as delay.
delay_post
The postsynaptic delays for all synapses (synapse->delay post).
lastupdate
The time of last update of all synapses (synapse->last update). This only exists if there are dynamic synaptic variables.

Internal attributes:

source
The source neuron group.
target
The target neuron group.
_S
The state matrix (a 2D dynamical array with values of synaptic variables). At run time, it is transformed into a static 2D array (with compress()).
presynaptic
The (dynamic) array of presynaptic neuron indexes for all synapses (synapse->i).
postsynaptic
The array of postsynaptic neuron indexes for all synapses (synapse->j).
synapses_pre
A list of (dynamic) arrays giving the set of synapse indexes for each presynaptic neuron i (i->synapses)
synapses_post
A list of (dynamic) arrays giving the set of synapse indexes for each postsynaptic neuron j (j->synapses)
queues
List of SpikeQueues for pre and postsynaptic spikes.
codes
The compiled codes to be executed on pre and postsynaptic spikes.
namespaces
The namespaces for the pre and postsynaptic codes.
class brian.SynapticEquations(expr='', level=0, **kwds)

Equations for the Synapses class. The only difference with Equations is that differential equations can be marked for an event-driven implementation, e.g.:

dx/dt=-x/tau : 1 (event-driven)

class brian.synapses.synapticvariable.SynapticVariable(data, synapses, name)

A vector of synaptic variables that is returned by Synapses.__getattr__(), and that can be subscripted with 2 or 3 arguments.

Example usages, where S is Synapses object:

S.w[12]
Value of variable w for synapse 12.
S.w[1,3]
Value of variable w for synapses from neuron 1 to neuron 3. This is an array, as there can be several synapses for a given neuron pair (e.g. with different delays)
S.w[1,3,4]
Value of variable w for synapse 4 from neuron 1 to neuron 3.

Indexes can be integers, slices, arrays or groups.

Synaptic variables can be assigned values as follows:

S.w[P,Q]=x
where x is a float or a 1D array. The number of elements in the array must equal the number of selected synapses.
S.w[P,Q]=s
where s is a string. The string is Python code that is executed in a single vectorised operation, where i is the presynaptic neuron index (a vector of length the number of synapses), j is the postsynaptic neuron index and n is the number of synapses. The methods rand and randn return arrays of n random values.

Initialised with arguments:

data
Vector of values.
synapses
The Synapses object.
to_matrix(multiple_synapses='last')

Returns the wanted state as a matrix of shape (# presynaptic neurons, # postsynaptic neurons) for visualization purposes. The returned array value at [i,j] is the value of the wanted synaptic variable for the synapse between (i, j). If not synapse exists between those two neurons, then the value is np.nan.

  • Dealing with multiple synapses between two neurons

Outputting a 2D matrix is not generally possible, because multiple synapses can exist for a given pair or pre- and post-synaptic neurons. In this case, the state values for all the synapses between neurons i and j are aggregated in the (i, j) position of the matrix. This is done according to the multiple_synapses keyword argument which can be changed:

mutiple_synapses = 'last' (default) takes the last value

mutiple_synapses = 'first' takes the first value

mutiple_synapses = 'min' takes the min of the values

mutiple_synapses = 'max' takes the max of the values

mutiple_synapses = 'sum' takes the sum of the values

Please note that this function should be used for visualization, and should not be used to store or reload synaptic variable values. If you want to do so, refer to the documentation at Synapses.save_connectivity().

class brian.synapses.synapticvariable.SynapticDelayVariable(data, synapses, name)

A synaptic variable that is a delay. The main difference with SynapticVariable is that delays are stored as integers (timebins) but accessed as absolute times (in seconds).

TODO: pass the clock as argument.

class brian.synapses.spikequeue.SpikeQueue(source, synapses, delays, max_delay=0.0 * second, maxevents=1, precompute_offsets=True)

Spike queue

Initialised with arguments:

source
The neuron group that sends spikes.
synapses
A list of synapses (synapses[i]=array of synapse indices for neuron i).
delays
An array of delays (delays[k]=delay of synapse k).
max_delay=0*ms
The maximum delay (in second) of synaptic events. At run time, the structure is resized to the maximum delay in delays, and thus the max_delay should only be specified if delays can change during the simulation (in which case offsets should not be precomputed).
maxevents = INITIAL_MAXSPIKESPER_DT
The initial size of the queue for each timestep. Note that the data structure automatically grows to the required size, and therefore this option is generally not useful.
precompute_offsets = True
A flag to precompute offsets. By default, offsets (an internal array derived from delays, used to insert events in the data structure, see below) are precomputed for all neurons, the first time the object is run. This usually results in a speed up but takes memory, which is why it can be disabled.

Data structure

A spike queue is implemented as a 2D array X that is circular in the time direction (rows) and dynamic in the events direction (columns). The row index corresponding to the current timestep is currentime. Each element contains the target synapse index.

The class is implemented as a SpikeMonitor, so that the propagate() method is called at each timestep (of the monitored group).

Methods

next()

Advances by one timestep.

peek()

Returns the all the synaptic events corresponding to the current time, as an array of synapse indexes.

precompute_offsets()

Precompute all offsets corresponding to delays. This assumes that delays will not change during the simulation. If they do (between two runs for example), then this method can be called.

Offsets

Offsets are used to solve the problem of inserting multiple synaptic events with the same delay. This is difficult to vectorise. If there are n synaptic events with the same delay, these events are given an offset between 0 and n-1, corresponding to their relative position in the data structure. They can be either precalculated (faster), or determined at run time (saves memory). Note that if they are determined at run time, then it is possible to also vectorise over presynaptic spikes.