From ff305b25fca42541d5d54a0ab12e9d0398fa9408 Mon Sep 17 00:00:00 2001 From: p-rakriti Date: Fri, 22 Jul 2022 15:06:09 +0530 Subject: [PATCH] Seqsynhandler with addspike --- snippets/seq_response_graphs.py | 125 +++++++++++++++++++++++++++ snippets/seqsynhandler_lif_neuron.py | 119 +++++++++++++++++++++++++ 2 files changed, 244 insertions(+) create mode 100644 snippets/seq_response_graphs.py create mode 100644 snippets/seqsynhandler_lif_neuron.py diff --git a/snippets/seq_response_graphs.py b/snippets/seq_response_graphs.py new file mode 100644 index 00000000..e0254499 --- /dev/null +++ b/snippets/seq_response_graphs.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[1]: + + +#This program sets up an LIF neuron that is sequence selective temporally. +#Currently it will give the maximum response for a reverse sequence and +#both forward as well as any scrambled sequence will not give as amplified a response, allowing us +#to pick out the reverse sequence from the rest. +#A sequence of 4 is given for each of the cases. The sequence selecting threshold in this case is -0.04 mV. +#The connections are set up such that the first synapse is activated at the time value of the first spike, +#second synapse is activated at the time value of the second spike and so on. + +#Author: Upinder Bhalla, Prakriti Parthasarathy +#Date: Friday, July 22nd 2022 + +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth +# Floor, Boston, MA 02110-1301, USA. + + + +import numpy as np +import matplotlib.pyplot as plt +import moose +from itertools import permutations + + +RUNTIME = 30.0 +SYN_WEIGHT = 0.01 + +# Creating a LIF neuron that processes sequential input: + +def makeSeqCell(): + seq = moose.LIF( '/seq' ) + seq.Rm = 1e8 + seq.Cm = 1e-9 + syn = moose.SeqSynHandler( '/seq/syn' ) + syn.historyTime = 5 + syn.kernelEquation = "(x==t)*10 + (xt)*-10" + syn.kernelWidth = 5 + syn.synapse.num = 10 + for ii in range( syn.synapse.num ): + syn.synapse[ii].weight = SYN_WEIGHT + syn.synapse[ii].delay = 0 + syn.seqDt = 1 + syn.baseScale = 0.0 + syn.sequenceScale = 1.0 + syn.plasticityScale = 0.0 + syn.synapseOrderOption = -1 + nk = np.array( syn.kernel ) + nk.shape = ( len(nk)//syn.kernelWidth, syn.kernelWidth ) + print( nk, "\n") #Printing out the kernel + moose.connect( syn, 'activationOut', seq, 'activation' ) + plots = moose.Neutral( '/plots' ) + plot2 = moose.Table( '/plots/p2' ) + plot3 = moose.Table( '/plots/p3' ) + moose.connect( plot2, 'requestOut', seq, 'getVm' ) + moose.connect( plot3, 'requestOut', syn, 'getSeqActivation' ) + +def runSeq( seqDt, stimTimes, runtime ): + moose.reinit() + stimTimes = [ [1+ii*seqDt, 20-ii*seqDt] for ii in range(4)] + print( stimTimes ) + syn = moose.element( '/seq/syn' ) + syn.seqDt = seqDt + for idx, vv in enumerate( stimTimes ): + for tt in vv: + syn.synapse[idx].addSpike( tt ) + moose.start( runtime ) + vec = np.array( moose.element( '/plots/p2' ).vector ) + middle = len( vec ) // 2 + return max(vec[:middle]), max( vec[middle:] ) + + +def main(): + stimTimes = [[1, 18], [2, 17], [3, 16], [4, 15]] #sequence of 4 is given to 4 synapses in both forward and reverse order + 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 ] + + makeSeqCell() + + h1 = [] + h2 = [] + + for seqDt in dts: + r1, r2 = runSeq( seqDt, stimTimes, RUNTIME ) + h1.append( r1 ) + h2.append( r2 ) + + + moose.start( RUNTIME ) + + + plt.figure() + plt.plot( dts, h1, 'g' ) + plt.title( "Forward sequences" ) + plt.xlabel( "seqDt (s)" ) + plt.ylabel( "max Vm (mV)" ) + plt.ylim( -0.07, -0.0003 ) + plt.figure() + plt.plot( dts, h2, 'g' ) + plt.title( "Reverse sequences" ) + plt.xlabel( "seqDt (s)" ) + plt.ylabel( "max Vm (mV)" ) + plt.ylim( -0.07, -0.0003 ) + + + + plt.show() + +if __name__ == "__main__": + main() + diff --git a/snippets/seqsynhandler_lif_neuron.py b/snippets/seqsynhandler_lif_neuron.py new file mode 100644 index 00000000..79a8a467 --- /dev/null +++ b/snippets/seqsynhandler_lif_neuron.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[1]: + + +#This program creates a sequence detecting LIF neuron. +#We can see the shapes of the membrane potential produced by various kernels. +#The connections are set up such that the first synapse receives a spike at 3s, second at 4s and third at 5s. +#The connections, kernel and seqDt can be varied to obtain different results. + +#Author: Upinder Bhalla, Prakriti Parthasarathy +#Date: Friday, July 22nd 2022 + +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth +# Floor, Boston, MA 02110-1301, USA. + + + +import sys +import os +import moose +import matplotlib.pyplot as plt +import numpy as np + +RUNTIME = 30 +SYN_WEIGHT = 0.01 + + +#creating the LIF neuron + +def seqCell(stimTimes): + model = moose.Neutral('/model') + + seq = moose.LIF( '/model/seq' ) + seq.Rm = 1e8 + seq.Cm = 1e-9 + + synh = moose.SeqSynHandler( '/model/seq/synh' ) + synh.historyTime = 5 + synh.kernelEquation = "x==t"#"(10 - 5*max((x-t), 0))" + synh.kernelWidth = 5 + synh.synapse.num = 10 + for ii in range( synh.synapse.num ): + synh.synapse[ii].weight = SYN_WEIGHT + synh.synapse[ii].delay = 0 + synh.seqDt = 1 + synh.baseScale = 0.0 + synh.sequenceScale = 1.0 + synh.plasticityScale = 0.0 + synh.synapseOrderOption = -1 + nk = np.array( synh.kernel ) + nk.shape = ( len(nk)//synh.kernelWidth, synh.kernelWidth ) + print( nk, "\n") + moose.connect( synh, 'activationOut', seq, 'activation' ) + + + plots = moose.Neutral( '/plots' ) + plot2 = moose.Table( '/plots/p2' ) + plot3 = moose.Table( '/plots/p3' ) + + + + moose.connect( plot2, 'requestOut', seq, 'getVm' ) #Vm of seq + moose.connect( plot3, 'requestOut', synh, 'getSeqActivation' ) #synapse activation of seq due to 1st input + + moose.reinit() + + for idx, vv in enumerate( stimTimes ): + for tt in vv: + synh.synapse[idx].addSpike( tt ) + print("idx", idx, "tt", tt) + + moose.start( RUNTIME ) + +def main(): + seqCell([[3], [4], [5]]) + + + + + plot2 = moose.element( '/plots/p2' ) + plot3 = moose.element( '/plots/p3' ) + + + dt = plot2.dt + + plt.figure() + t = np.linspace( 0, RUNTIME, len( plot2.vector ) ) + + plt.plot( t, plot2.vector ) + plt.title( "SeqSynHandler- Membrane potential" ) + plt.xlabel( "time (s)" ) + plt.ylabel( "Vm (mV)" ) + plt.figure() + plt.title( "SeqSynHandler- Synaptic Activation" ) + plt.xlabel( "time (s)" ) + plt.ylabel( "synapse activation (arb units)" ) + plt.plot( t, plot3.vector ) + + + + plt.show() + +if __name__ == "__main__": + main() +