Hello, I have neurons with two types of events. I want to activate different synaptic pathways depending on 1) which event occurred and 2) whether it happened at the pre- or post-synaptic neuron. All the information I found in the documentation does not explain such a general case.
The spike and under events in this code are recognised correctly. However, both paths a and b get executed at presynaptic spikes, and paths c and d at postsynaptic spikes. Nothing seems to happen at the under event. I would like to have paths b and d happen and the pre- or postsynaptic under events. How can I do this?
Thank you
Hi @mmiekus, very interesting use case! This is a pity, our underlying machinery would support this effortlessly, but we are not exposing this in the Synapses interface. In fact, the on_event dictionary should only refer to pre and post, i.e. you can only set one event type for all pre and one event type for all post pathways. Fixing this in the code is almost trivial, but I’d need to have a more thorough look to make sure that this does not break anything. Do you necessarily need all these pathways to be in a single Synapses object, i.e. should they operate on the same variables? Otherwise, you could have two Synapses objects, each with a single pre/post event it listens to.
Thank you for the response. Unfortunately, I was planning to use the pathways to modify the same synaptic variables. However, the whole setup is actually my attempt at implementing a change in synaptic weight, which should happen when both pre- and postsynaptic neurons are above the threshold (without reset). And the change should happen only once, when the second of the neurons crosses the threshold (and not at each timestep). Maybe you would have any ideas if I can implement it somehow in a more straightforward way? I suppose I can always use some NetworkOperations.
A simpler question: is there an easy way to get an event only at the first timestep when the threshold condition is fulfilled?
Hah, if I understand correctly, this should actually be quite straightforward to implement, and doesn’t even need custom events The trick is to only care about the spike event of the second neuron, but make your weight update conditional on the membrane potential of the first neuron by multiplying it by int(V_pre >= 0.3). This expression will be 0 or 1 depending on whether the pre-synaptic neuron is above the threshold.
Here’s an example:
import brian2 as br
import matplotlib.pyplot as plt
n = br.NeuronGroup(2, model="""dV/dt = cos(2*pi*freq*t)/msecond : 1
freq: Hz (constant)""",
threshold = "V>=0.3", reset="", refractory="V>=0.3")
n.V = [0, -0.5]
n.freq = [100, 150]*br.Hz
weight_update = 0.1
s = br.Synapses(n, n,
model="w : 1",
# update on post-synaptic spike, but only if pre-synaptic is above threshold as well
on_post="w += int(V_pre>=0.3)*weight_update")
s.connect(i=0, j=1)
state_mon = br.StateMonitor(n, 'V', record=True)
weight_mon = br.StateMonitor(s, 'w', record=True)
spike_mon = br.SpikeMonitor(n)
br.run(0.05*br.second)
plt.plot(state_mon.t/br.ms, state_mon.V[0], color='C0')
plt.plot(state_mon.t/br.ms, state_mon.V[1], color='C1')
post_spikes = spike_mon.spike_trains()[1]
plt.plot(post_spikes/br.ms, [0.3]*len(post_spikes), '^', color='C1')
ax_2 = plt.twinx()
ax_2.plot(weight_mon.t/br.ms, weight_mon.w.T, 'C2')
plt.show()
As you can see, the synaptic weight (green line), is only updated when the post-synaptic neuron (orange line) fires and the pre-synaptic neuron (blue line) is above threshold at the same time.