Hi everyone !
I am new to Brian2 and I am trying to connect two conductance based point LIF neuron model through alpha synapses. Neuron n1 receives sinusoidal input and Neuron n2 receives input from neuron n1 through alpha synapse. Here is my code :
import pandas as pd
import numpy as np
from scipy import signal
start_scope()
seed(11922)
# Parameters
n_n1=5
n_n2=5
# Neuron Parameters
# n_n1
E_l_n1=-70*mV # Leak Reversal Potential
E_e_n1=0*mV # Excitatory synaptic reversal potential
E_i_n1=-80*mV # Inhibitory synaptic reversal potential
C_m_n1=198*pF # Membrane Capacitance
tau_n1=20*ms # Membrane time constant
g_L_n1=C_m_n1/tau_n1 # Leak conductance
tau_e_n1=5*ms # Excitatory synaptic time constant
tau_i_n1=10*ms # Inhibitory synaptic time constant
tau_r_n1=5*ms # Refractory period
V_th_n1=-55*mV # Firing threshold
V_r_n1=E_l_n1 # Reset potential
# Synapse parameters
w_e_n1=0.05*nS # Excitatory synaptic conductance
w_i_n1=1.0*nS # Inhibitory synaptic conductance
# n_n2
E_l_n2=-70*mV # Leak Reversal Potential
E_e_n2=0*mV # Excitatory synaptic reversal potential
E_i_n2=-80*mV # Inhibitory synaptic reversal potential
C_m_n2=198*pF # Membrane Capacitance
tau_n2=20*ms # Membrane time constant
g_L_n2=C_m_n2/tau_n2 # Leak conductance
tau_e_n2=5*ms # Excitatory synaptic time constant
tau_i_n2=10*ms # Inhibitory synaptic time constant
tau_r_n2=5*ms # Refractory period
V_th_n2=-53*mV # Firing threshold
V_r_n2=E_l_n2 # Reset potential
# Synapse parameters
w_e_n2=0.05*nS # Excitatory synaptic conductance
w_i_n2=1.0*nS # Inhibitory synaptic conductance
t_recorded=np.arange(int(20000*ms/defaultclock.dt))*defaultclock.dt
I_rec_1_sin=TimedArray(I1_1_sin*amp,dt=defaultclock.dt)
eqs_n1='''
dv/dt=(I_syn_e/C_m_n1)+(I/(g_L_n1*tau_n1))+(g_L_n1*(v-E_l_n1)+g_e*(v-E_e_n1)+g_i*(v-E_i_n1))/C_m_n1:volt
I_syn_e=g_e*(E_e_n1-v):amp
I=I_rec_1_sin(t):amp
dg_e/dt=(s_e-g_e)/tau_e_n1:siemens
dg_i/dt=(s_i-g_i)/tau_i_n1:siemens
ds_e/dt=-s_e/tau_e_n1:siemens
ds_i/dt=-s_i/tau_i_n1:siemens
'''
eqs_n2='''
dv/dt=(I_syn_e/C_m_n2)+(g_L_n2*(v-E_l_n2)+g_e*(v-E_e_n2)+g_i*(v-E_i_n2))/C_m_n2:volt
I_syn_e=g_e*(E_e_n2-v):amp
dg_e/dt=(s_e-g_e)/tau_e_n2:siemens
dg_i/dt=(s_i-g_i)/tau_i_n2:siemens
ds_e/dt=-s_e/tau_e_n2:siemens
ds_i/dt=-s_i/tau_i_n2:siemens
'''
G_n1=NeuronGroup(n_n1,eqs_n1,threshold='v>V_th_n1',reset='v=V_r_n1',refractory='tau_r_n1',method='rk2')
G_n2=NeuronGroup(n_n2,eqs_n2,threshold='v>V_th_n2',reset='v=V_r_n2',refractory='tau_r_n2',method='rk2')
# Random initial membrane potential values and conductances
G_n1.v='E_l_n1+rand()*(V_th_n1-E_l_n1)'
G_n1.g_e='rand()*w_e_n1'
G_n1.g_i='rand()*w_i_n1'
G_n2.v='E_l_n2+rand()*(V_th_n2-E_l_n2)'
G_n2.g_e='rand()*w_e_n2'
G_n2.g_i='rand()*w_i_n2'
S_n1_n2=Synapses(G_n1,G_n2,on_pre='s_e+=w_e_n1',method='rk2')
S_n1_n2.connect(p=0.5)
# Record the spikes
M_n1=SpikeMonitor(G_n1)
M_n2=SpikeMonitor(G_n2)
# Record the membrane voltage
V_n1=StateMonitor(G_n1,'v',record=True)
V_n2=StateMonitor(G_n2,'v',record=True)
run(20*second)
I found that neuron n2 is not spiking at all inspite of increasing Excitatory synaptic conductance of neuron n1 (which I am using to increment variable s_e while making synaptic connection from n1 to n2. Is my implementation of conductance based neuron with alpha synapses correct ?
Hoping for an early response.
Thanks and Regards
Shavika Rastogi
PhD Scholar
Hi @Shavika. I think there is a problem with your neuron models – in general, I’d recommend to make sure that the neuron model is working as expected before adding synapses. In the equations eqs_n1
, the leak current is defined as g_L_n1*(v-E_l_n1)
. This is either missing a minus sign or should be ...*(E_I_n1-v)
. The way it is formulated right now, it pushes away from the leak reversal potential, instead of pulling towards it. The same is true for the formulations of the synaptic currents. There is also a duplication: you have both a I_syn_e
current (with the correct sign) and a g_e*(v-E_e_n1)
term (with the incorrect sign), so you should remove one of them. If your n1
neuron is only receiving current input, you could also completely leave away all synaptic currents/conductances in its equations, of course.
After fixing these issues, the neurons/synapses would work as expected. Note that you also need to chose appropriate weights, I think the ones you currently use are too weak to make n2
spike with so few incoming synapses.
Hi @mstimberg ! Thank you so much for your response. After inverting the sign and eliminating the excitatory conductance term (g_e*(E_e_n1-v)) from the equation of neuron n1 keeping I_syn_e intact, I am getting output spikes for neuron n2.
If I understood your suggestion correctly, I can eliminate all conductances and synapse terms in equation of neuron n1 and include only the input current. The equation will then look something like this:
eqs_n1=‘’’
dv/dt=(I/(g_L*tau_n1))-(v/tau_n1):volt (unless refractory)
I=I_rec_1_sin(t);amp
g_L=g_L_n1:siemens
‘’’
But this will reduce this neuron to current based neuron. Isn’t it ? Then how can I make neurons communicate through alpha synapses ?
A follow up question : If I want to make synapses inhibitory instead of excitatory (for conductance based alpha synapses), I should only change I_syn_e in the equation to I_syn_i = g_i_n1*(E_i_n1-v) and increment s_i instead of s_e in the Synapses() function. Isn’t it ?
There are current-based and conductance-based synapses, not neurons. In your code, the neuron group 1 does not receive any input via synapses, group 1 is connected to group 2 but not the other way round. The equations therefore do not need equations for synaptic conductances – they will stay 0 anyhow.
Yes. But note that typically you would have both, excitatory and inhibitory currents in the equation. You would have then one Synapses
object for the excitatory synapses (increasing s_e
in on_pre
) and one object for the inhibitory synapses (increasing s_i
).
Hi @mstimberg ! Thanks for your input. I tried as you suggested : I eliminated all conductance terms from the equation of neuron n1. Now, neuron n1 is connected to neuron n2 through current based synapses (w_n1_n2=0.0001*volt). After elimination of conductance, there is very high activity for the case of neuron n1 which was not observed earlier when I was including conductance terms. If synaptic conductance is not doing anything for the case of neuron n1, then why there is very high activity for neuron n1 after their elimination ?
Here is my code :
import pandas as pd
import numpy as np
from scipy import signal
start_scope()
seed(11922)
# Parameters
n_n1=5
n_n2=5
# Neuron Parameters
# n_n1
E_l_n1=-70*mV # Leak Reversal Potential
C_m_n1=198*pF # Membrane Capacitance
tau_n1=20*ms # Membrane time constant
tau_r_n1=5*ms # Refractory period
g_L_n1=C_m_n1/tau_n1 # Leak conductance
V_th_n1=-55*mV # Firing threshold
V_r_n1=E_l_n1 # Reset potential
# n_n2
E_l_n2=-70*mV # Leak Reversal Potential
E_e_n2=0*mV # Excitatory synaptic reversal potential
E_i_n2=-80*mV # Inhibitory synaptic reversal potential
C_m_n2=198*pF # Membrane Capacitance
tau_n2=20*ms # Membrane time constant
g_L_n2=C_m_n2/tau_n2 # Leak conductance
tau_e_n2=10*ms # Excitatory synaptic time constant
tau_i_n2=10*ms # Inhibitory synaptic time constant
tau_r_n2=5*ms # Refractory period
V_th_n2=-45*mV # Firing threshold
V_r_n2=E_l_n2 # Reset potential
# Synapse parameters
w_e_n2=5.0*nS # Excitatory synaptic conductance
w_i_n2=1.0*nS # Inhibitory synaptic conductance
w_n1_n2=0.0001*volt
t_recorded=np.arange(int(20000*ms/defaultclock.dt))*defaultclock.dt
I_rec_1_sin=TimedArray(I1_1_sin*amp,dt=defaultclock.dt)
eqs_n1='''
dv/dt=(I/(g_L*tau_n1))-(v/tau_n1):volt (unless refractory)
I=I_rec_1_sin(t):amp
g_L=g_L_n1:siemens
'''
eqs_n2='''
dv/dt=(I_syn_e/C_m_n2)+(g_L_n2*(E_l_n2-v)+g_i*(E_i_n2-v))/C_m_n2:volt
I_syn_e=g_e*(E_e_n2-v):amp
dg_e/dt=(s_e-g_e)/tau_e_n2:siemens
dg_i/dt=(s_i-g_i)/tau_i_n2:siemens
ds_e/dt=-s_e/tau_e_n2:siemens
ds_i/dt=-s_i/tau_i_n2:siemens
'''
G_n1=NeuronGroup(n_n1,eqs_n1,threshold='v>V_th_n1',reset='v=V_r_n1',refractory='tau_r_n1',method='rk2')
G_n2=NeuronGroup(n_n2,eqs_n2,threshold='v>V_th_n2',reset='v=V_r_n2',refractory='tau_r_n2',method='rk2')
# Random initial membrane potential values and conductances
G_n1.v='E_l_n1+rand()*(V_th_n1-E_l_n1)'
G_n2.v='E_l_n2+rand()*(V_th_n2-E_l_n2)'
G_n2.s_e='rand()*w_e_n2'
G_n2.s_i='rand()*w_i_n2'
S_n1_n2=Synapses(G_n1,G_n2,on_pre='v+=w_n1_n2',method='rk2')
S_n1_n2.connect(p=0.5)
# Record the spikes
M_n1_2=SpikeMonitor(G_n1)
M_n2_2=SpikeMonitor(G_n2)
# Record the membrane voltage
V_n1_2=StateMonitor(G_n1,'v',record=True)
V_n2_2=StateMonitor(G_n2,'v',record=True)
# Record excitatory synaptic conductance
g_e_n2_2=StateMonitor(G_n2,'g_e',record=True)
s_e_n2_2=StateMonitor(G_n2,'s_e',record=True)
run(20*second)
I did not suggest deleting all conductance terms, but only the synaptic conductances, since they are not used (nothing connects to the neurons in G_n1
). The leak conductance term (g_L*(E_l_n1 - v)
or equivalently (E_l_n1 - v)/tau_n1
) should still be there, otherwise the activity will change – you have a v/tau_n1
term, which means your “leak” current is pulling toward 0mV instead of towards E_l_n1
I don’t quite understand. Why did you change the synaptic model, I thought you wanted to use conductance-based alpha synapses? Now the g_e
, s_e
terms in eqs_n2
are no longer used… Just keep the old model (targeting s_e
– this refers to the post-synaptic variable, i.e. the values in eqs_n2
/G_n2
!).
As mentioned above, your leak current is incorrect.