|
| 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 | + |
0 commit comments