Skip to content

Commit ff305b2

Browse files
committed
Seqsynhandler with addspike
1 parent 17122be commit ff305b2

File tree

2 files changed

+244
-0
lines changed

2 files changed

+244
-0
lines changed

snippets/seq_response_graphs.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env python
2+
# coding: utf-8
3+
4+
# In[1]:
5+
6+
7+
#This program sets up an LIF neuron that is sequence selective temporally.
8+
#Currently it will give the maximum response for a reverse sequence and
9+
#both forward as well as any scrambled sequence will not give as amplified a response, allowing us
10+
#to pick out the reverse sequence from the rest.
11+
#A sequence of 4 is given for each of the cases. The sequence selecting threshold in this case is -0.04 mV.
12+
#The connections are set up such that the first synapse is activated at the time value of the first spike,
13+
#second synapse is activated at the time value of the second spike and so on.
14+
15+
#Author: Upinder Bhalla, Prakriti Parthasarathy
16+
#Date: Friday, July 22nd 2022
17+
18+
# This program is free software; you can redistribute it and/or
19+
# modify it under the terms of the GNU General Public License as
20+
# published by the Free Software Foundation; either version 3, or
21+
# (at your option) any later version.
22+
#
23+
# This program is distributed in the hope that it will be useful,
24+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
25+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26+
# General Public License for more details.
27+
#
28+
# You should have received a copy of the GNU General Public License
29+
# along with this program; see the file COPYING. If not, write to
30+
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth
31+
# Floor, Boston, MA 02110-1301, USA.
32+
33+
34+
35+
import numpy as np
36+
import matplotlib.pyplot as plt
37+
import moose
38+
from itertools import permutations
39+
40+
41+
RUNTIME = 30.0
42+
SYN_WEIGHT = 0.01
43+
44+
# Creating a LIF neuron that processes sequential input:
45+
46+
def makeSeqCell():
47+
seq = moose.LIF( '/seq' )
48+
seq.Rm = 1e8
49+
seq.Cm = 1e-9
50+
syn = moose.SeqSynHandler( '/seq/syn' )
51+
syn.historyTime = 5
52+
syn.kernelEquation = "(x==t)*10 + (x<t)*-10 + (x>t)*-10"
53+
syn.kernelWidth = 5
54+
syn.synapse.num = 10
55+
for ii in range( syn.synapse.num ):
56+
syn.synapse[ii].weight = SYN_WEIGHT
57+
syn.synapse[ii].delay = 0
58+
syn.seqDt = 1
59+
syn.baseScale = 0.0
60+
syn.sequenceScale = 1.0
61+
syn.plasticityScale = 0.0
62+
syn.synapseOrderOption = -1
63+
nk = np.array( syn.kernel )
64+
nk.shape = ( len(nk)//syn.kernelWidth, syn.kernelWidth )
65+
print( nk, "\n") #Printing out the kernel
66+
moose.connect( syn, 'activationOut', seq, 'activation' )
67+
plots = moose.Neutral( '/plots' )
68+
plot2 = moose.Table( '/plots/p2' )
69+
plot3 = moose.Table( '/plots/p3' )
70+
moose.connect( plot2, 'requestOut', seq, 'getVm' )
71+
moose.connect( plot3, 'requestOut', syn, 'getSeqActivation' )
72+
73+
def runSeq( seqDt, stimTimes, runtime ):
74+
moose.reinit()
75+
stimTimes = [ [1+ii*seqDt, 20-ii*seqDt] for ii in range(4)]
76+
print( stimTimes )
77+
syn = moose.element( '/seq/syn' )
78+
syn.seqDt = seqDt
79+
for idx, vv in enumerate( stimTimes ):
80+
for tt in vv:
81+
syn.synapse[idx].addSpike( tt )
82+
moose.start( runtime )
83+
vec = np.array( moose.element( '/plots/p2' ).vector )
84+
middle = len( vec ) // 2
85+
return max(vec[:middle]), max( vec[middle:] )
86+
87+
88+
def main():
89+
stimTimes = [[1, 18], [2, 17], [3, 16], [4, 15]] #sequence of 4 is given to 4 synapses in both forward and reverse order
90+
dts = [ 0.1, 0.2, 0.4, 0.6, 0.8, 0.9, 1.0, 1.1, 1.2, 1.4, 1.6, 1.8, 2, 2.2, 2.4 ]
91+
92+
makeSeqCell()
93+
94+
h1 = []
95+
h2 = []
96+
97+
for seqDt in dts:
98+
r1, r2 = runSeq( seqDt, stimTimes, RUNTIME )
99+
h1.append( r1 )
100+
h2.append( r2 )
101+
102+
103+
moose.start( RUNTIME )
104+
105+
106+
plt.figure()
107+
plt.plot( dts, h1, 'g' )
108+
plt.title( "Forward sequences" )
109+
plt.xlabel( "seqDt (s)" )
110+
plt.ylabel( "max Vm (mV)" )
111+
plt.ylim( -0.07, -0.0003 )
112+
plt.figure()
113+
plt.plot( dts, h2, 'g' )
114+
plt.title( "Reverse sequences" )
115+
plt.xlabel( "seqDt (s)" )
116+
plt.ylabel( "max Vm (mV)" )
117+
plt.ylim( -0.07, -0.0003 )
118+
119+
120+
121+
plt.show()
122+
123+
if __name__ == "__main__":
124+
main()
125+
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env python
2+
# coding: utf-8
3+
4+
# In[1]:
5+
6+
7+
#This program creates a sequence detecting LIF neuron.
8+
#We can see the shapes of the membrane potential produced by various kernels.
9+
#The connections are set up such that the first synapse receives a spike at 3s, second at 4s and third at 5s.
10+
#The connections, kernel and seqDt can be varied to obtain different results.
11+
12+
#Author: Upinder Bhalla, Prakriti Parthasarathy
13+
#Date: Friday, July 22nd 2022
14+
15+
# This program is free software; you can redistribute it and/or
16+
# modify it under the terms of the GNU General Public License as
17+
# published by the Free Software Foundation; either version 3, or
18+
# (at your option) any later version.
19+
#
20+
# This program is distributed in the hope that it will be useful,
21+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
22+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23+
# General Public License for more details.
24+
#
25+
# You should have received a copy of the GNU General Public License
26+
# along with this program; see the file COPYING. If not, write to
27+
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth
28+
# Floor, Boston, MA 02110-1301, USA.
29+
30+
31+
32+
import sys
33+
import os
34+
import moose
35+
import matplotlib.pyplot as plt
36+
import numpy as np
37+
38+
RUNTIME = 30
39+
SYN_WEIGHT = 0.01
40+
41+
42+
#creating the LIF neuron
43+
44+
def seqCell(stimTimes):
45+
model = moose.Neutral('/model')
46+
47+
seq = moose.LIF( '/model/seq' )
48+
seq.Rm = 1e8
49+
seq.Cm = 1e-9
50+
51+
synh = moose.SeqSynHandler( '/model/seq/synh' )
52+
synh.historyTime = 5
53+
synh.kernelEquation = "x==t"#"(10 - 5*max((x-t), 0))"
54+
synh.kernelWidth = 5
55+
synh.synapse.num = 10
56+
for ii in range( synh.synapse.num ):
57+
synh.synapse[ii].weight = SYN_WEIGHT
58+
synh.synapse[ii].delay = 0
59+
synh.seqDt = 1
60+
synh.baseScale = 0.0
61+
synh.sequenceScale = 1.0
62+
synh.plasticityScale = 0.0
63+
synh.synapseOrderOption = -1
64+
nk = np.array( synh.kernel )
65+
nk.shape = ( len(nk)//synh.kernelWidth, synh.kernelWidth )
66+
print( nk, "\n")
67+
moose.connect( synh, 'activationOut', seq, 'activation' )
68+
69+
70+
plots = moose.Neutral( '/plots' )
71+
plot2 = moose.Table( '/plots/p2' )
72+
plot3 = moose.Table( '/plots/p3' )
73+
74+
75+
76+
moose.connect( plot2, 'requestOut', seq, 'getVm' ) #Vm of seq
77+
moose.connect( plot3, 'requestOut', synh, 'getSeqActivation' ) #synapse activation of seq due to 1st input
78+
79+
moose.reinit()
80+
81+
for idx, vv in enumerate( stimTimes ):
82+
for tt in vv:
83+
synh.synapse[idx].addSpike( tt )
84+
print("idx", idx, "tt", tt)
85+
86+
moose.start( RUNTIME )
87+
88+
def main():
89+
seqCell([[3], [4], [5]])
90+
91+
92+
93+
94+
plot2 = moose.element( '/plots/p2' )
95+
plot3 = moose.element( '/plots/p3' )
96+
97+
98+
dt = plot2.dt
99+
100+
plt.figure()
101+
t = np.linspace( 0, RUNTIME, len( plot2.vector ) )
102+
103+
plt.plot( t, plot2.vector )
104+
plt.title( "SeqSynHandler- Membrane potential" )
105+
plt.xlabel( "time (s)" )
106+
plt.ylabel( "Vm (mV)" )
107+
plt.figure()
108+
plt.title( "SeqSynHandler- Synaptic Activation" )
109+
plt.xlabel( "time (s)" )
110+
plt.ylabel( "synapse activation (arb units)" )
111+
plt.plot( t, plot3.vector )
112+
113+
114+
115+
plt.show()
116+
117+
if __name__ == "__main__":
118+
main()
119+

0 commit comments

Comments
 (0)