I am new to the Brian2 simulator and I am a bit confused about 2 things:
- When defining a synapse, is a weight indirectly added to the neuron, or do I need to specify a weight? I have this code that I wrote:
synapse_equations = '''
dcontrol/dt = -control/(tau_value) : amp*meter**-2
total_post = (control/(coming_neurons - 1))*int(coming_neurons > 1) + (control/(coming_neurons))*int(coming_neurons == 1) + 0*amp*meter**-2*int(coming_neurons == 0) : 1 (summed)
coming_neurons : 1
syn = Synapses(neuron, neuron, synapse_equations, on_pre = 'control += w', method = 'euler')
where the variable “control” tracks the amount of amps/meter^2 from a pre-synaptic neuron to a post-synaptic neuron, and once it fires an action potential, a weight of w is added to “control” of the pre-synaptic variable. The variable “total” collects all of the “control” amounts from each pre-synaptic neuron and sums them up together and then divides everything by the number of pre-synaptic neurons. The variable “coming_neurons” represents the number of pre-synaptic neurons connected to a post-synaptic neuron.
I am worried that if a weight is automatically added once you use Synapse(), then by specifying another equation using on_pre, then I would be adding a weight two times. Is this the case or is it not automatically added when you use Synapse()?
- I am trying to use inhibitory and excitatory neurons for my neuron model, but I haven’t found a way to specify if neurons are excitatory or inhibitory. I saw this example on Brian2’s website: https://brian2.readthedocs.io/en/stable/examples/frompapers.Stimberg_et_al_2018.example_1_COBA.html, where different synaptic conductances and neurotransmitters were used in order to tell the difference between the neurons. Is this the only way of specifying inhibitory and excitatory neurons in Brian2, or are there other ways?
Thank you in advance for your help!
Hi and welcome. I am not sure I understand completely, so please clarify things if my answer is off-target.
Synapses model, you have one variable
control that gets increased by
w for every incoming spike, and every time step you update the post-synaptic variable
total based on the value of
control on all synapses connecting to it. I don’t quite see where you think this could add
w twice, the only part where
w is added is in
on_pre, i.e. triggered by pre-synaptic spikes. However, you are saying that
which is not quite correct since you are adding
w to the synaptic variable
control. I.e., each synapse has its own
control variable, even though for all synapses that come from the same pre-synaptic cell, this value will be identical. The result would be identical if instead you declared
control in the equations of the pre-synaptic neuron (so it only gets stored/updated once per cell) and update it not via
on_pre in the
Synapses, but via the
reset statement in the
NeuronGroup. Your equation for
total_post then has to refer to
control_pre. Just to make this clear: this will not change anything in the result, it will just calculate things more efficiently. Regarding efficiency, one more remark: you do not need the
coming_neurons variable, this value is already provided by Brian as
N_incoming. But more importantly, you are recalculating the normalization for every synapse and every time step, even though it will not change during the run. Instead, you could calculate it once before the simulation starts. Something along the lines of:
synapses_equations = '''
total_post = normalization * control_pre : 1 (summed)
normalization : 1 (constant)
syn = Synapses(...)
syn.normalization = '1.0/(N_incoming - 1)*int(N_incoming > 1) + (1.0/N_incoming)*int(N_incoming == 1) + 0*amp*meter**-2*int(N_incoming == 0)'
Do you mean to make a difference between different neuron types (e.g. regular spiking excitatory pyramidal cells vs. fast spiking inhibitory interneurons) or just between excitatory and inhibitory synapses? For both, there is no general way, all depends on the desired complexity of your model. E.g. in a very simple integrate-and-fire model like the CUBA example, both types of neurons are modeled in the same way and the only difference between the synapses is their sign. On the other end of the spectrum, you could model each cell type in detail with different types of ion channels and different sizes/capacitances/etc. and use detailed neurotransmitter models for AMPA, NMDA, GABA, …, synapses. And of course there are many intermediate solutions, e.g. for relatively abstract integrate-and-fire models the most common way to model the difference between excitatory and inhibitory neurons is to simply give the inhibitory neurons a shorter time constant, and similarly you can get a crude approximation of different neurotransmitters by changing the time constant of your synapses.
Thank you for your reply. You were definitely not off in understanding my questions. It clarified a lot of things for me!
Thank you also for taking the time in explaining how I could make my code more efficient. I really appreciate it.