# Ambiguous on_pre operation

I have a problem with setting up a slightly comlicated `on_pre` operation.

Here’s the code that is supposed to increase the voltage of post-synapse. The set-up is standard: An LIF neuron connected to a spike generating source. However, I noticed a combination of “synaptic equations + spike generator object” leads to the correct behavior while some others don’t. In such a way that it seems unpredictable.

``````#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Oct  5 11:43:46 2022

@author: arash
"""

import matplotlib.pyplot as plt
import numpy as np
import brian2 as b2

def plot():
"""to plot results"""
fig, axs = plt.subplots(4,1, sharex=True)

for i in range(G.N):
axs[0].plot(monS.t, monG.v[i,:], label='v')

for id_ in range(len(S)):
axs[1].plot(monS.t, monS.g[id_,:] ,label='g'+str(id_))
axs[2].plot(monS.t, monS.h[id_,:] ,label='h'+str(id_))
axs[3].plot(monS.t, monS.v_post[id_,:] ,label='v_post_'+str(id_))

for ax in axs:
ax.legend()

b2.start_scope()

G = b2.NeuronGroup(1,
'''
dv/dt = -(v+70*mV)/tau : volt (unless refractory)
tau = 10*ms : second (shared)
''',
'euler',
threshold='v>-50*mV',
refractory=2*b2.ms,
reset='v=-70*mV')

# a convenient way to switch spike generation method
spk_gen='poisson'
if spk_gen =='poisson':
P = b2.PoissonGroup(1, rates= 50*b2.Hz)
else:
indices = np.array([0, 1, 2])
times = np.array([1, 20, 30])*b2.ms
P = b2.SpikeGeneratorGroup(3, indices, times)

S = b2.Synapses(P, G,
'''
dg/dt = (-g + h)/tau_s : 1 (clock-driven)
dh/dt = -h/tau_s : 1 (clock-driven)
tau_s = 5*ms : second (shared)
J = 10*mV : volt
''',
on_pre='''
v_post += J*g
h = 1
''', # here is when the bug might be...
method='exact')

S.connect()
monG = b2.StateMonitor(G, ['v'],True)
monS = b2.StateMonitor(S, ['h','g','v_post'], record=True)
G.v = -70*b2.mV
b2.run(100*b2.ms)
plot()
``````

Running this leads to the expected result that is depicted below:

However, if I change the `spk_gen` flag and create spikes from `SpikeGeneratorGroup`, then the same code leads to the following, suggesting that the post_synapse is not updated at all:

Interestingly, if I change my `on_pre` argument using some explicit numerical value, say `v_post += 10*mV, ...`, or `v_post += J` (no multiplication by `g`), It works:

Why is that? How can I predict the behavior and how can I avoid unwanted responses?
Thank you very much!

Arash

Hi @arashgmn. The problem is that at the beginning of your simulation, g and h are both 0. This means that the very first spike for each synapse does not have any effect. In the `PoissonGroup` input, you have a single synapse that receives all the spikes, and all but the first one therefore have the expected effect. In the `SpikeGeneratorGroup` version, you create 3 synapses, and each of them only receives a single spike, so none of them is propagated. If you use a stimulation that is more similar to your `PoissonGroup` example, e.g.:

``````    indices = [0, 0, 0]
times = [1, 20, 30]*b2.ms
P = b2.SpikeGeneratorGroup(1, indices, times)
``````

you will get the expected result (note that the first spike triggers updates of g and h but no post-synaptic change):

Hope that clears things up!

It makes complete sense! Thank you @mstimberg for your prompt response. Hope this prevents others to make the same silly mistake

1 Like