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
andfreeze
should be set toTrue
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 classSynapticVariable
.
-
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 andn
is the number of synapses. The methodsrand
andrandn
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 valuemutiple_synapses = 'first'
takes the first valuemutiple_synapses = 'min'
takes the min of the valuesmutiple_synapses = 'max'
takes the max of the valuesmutiple_synapses = 'sum'
takes the sum of the valuesPlease 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 themax_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 iscurrentime
. 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.