// $Id: stim.hoc,v 1.19 2012/03/07 19:07:07 samn Exp $ //* Declarations dosetexvals=name_declared("wmatex")==0 // whether to set values in wmatex,ratex sprint(tstr,"d[%d][%d][%d]",numcols,CTYPi,STYPi) declare("wmatex",tstr,"ratex",tstr) // weights,avg. rate of external inputs declare("nstim","o[1]") declare("sgrdur",mytstop) //duration of poisson stims declare("inputseed",1236) declare("sgrhzEE",300,"sgrhzEI",300,"sgrhzII",125,"sgrhzIE",125,"sgrhzNM",50,"sgron",1,"sgrdel",0)//poisson rates declare("sgrhzdel",0)//variance in sgrhz for an INTF6 declare("EXGain",15) // gain for poisson external inputs declare("lcstim",new List()) // list of CSTIM objects {sprint(tstr,"o[%d]",numcols) declare("nqwmex",tstr)} // new NQS("ct","sy","w","rate") // NQS passed to CSTIM init {sprint(tstr,"d[%d]",numcols) declare("EIBalance",tstr)} // whether to balance rate of external E/I inputs declare("usens",1) // whether to use NetStims in CSTIM declare("EMWEXGain",1,"EMREXGain",1) // gains for external inputs to EM (1st is for weights, 2nd for rates) //* shock-related params declare("MAXSHOCK",10) sprint(tstr,"d[%d][%d][%d][%d]",numcols,CTYPi,STYPi,MAXSHOCK) declare("wshock",tstr,"durshock",tstr,"prctshock",tstr,"nshock",tstr,"isishock",tstr,"startshock",tstr) //* "modulation"-related params -- just modulates external input weights to ModType // applies modulation at t = modulationT ms. // ModGain is scaling factor for AM2,NM2 synapses declare("ModONT",0,"fid","o[1]","ModGain",1,"ModType",EM) // when to apply modulation to ModType declare("ModOFFT",-1) // modulation stays on full sim -- -1==never modulate off //* Training-signal related params declare("TrainISI",0,"TrainNUM",0,"TrainTY",E4,"TrainW",0,"TrainDUR",1,"TrainPRCT",100,"TrainSY",AM2) declare("dosendex",0,"nqwrex","o[2]","fix","o[1]","EXRedStartT",5e3,"EXDT",5e3,"EXFctr",0.99) SCAHP=SCTH=1 //* "zip"-related params -- modulates strength of internal weights from E->X declare("ZipONT",0,"zid","o[1]","EERed",1,"EIRed",1) declare("ZipOFFT",-1) // zip stays on full sim -- -1==never zip off //* ModulateON -- applies ModGain to AM2,NM2 inputs to ModType cells (NetCon weights) proc ModulateON () { local i localobj nc,ncl print "Modulation of " , ModGain, " to " , CTYP.o(ModType).s, " ON at t = ", t for i=0,numcols-1 { ncl = col[i].cstim.ncl for ltr(nc,ncl) if(!isojt(nc.pre,INTF6[0]) && isojt(nc.syn,INTF6[0])) { if(nc.syn.type==ModType) { if(nc.weight(AM2)>0) nc.weight(AM2) = wmatex[i][ModType][AM2] * ModGain if(nc.weight(NM2)>0) nc.weight(NM2) = wmatex[i][ModType][NM2] * ModGain } } } } //* ModulateOFF -- applies ModGain to AM2,NM2 inputs to ModType cells (NetCon weights) proc ModulateOFF () { local i localobj nc,ncl print "Modulation of " , ModGain, " to " , CTYP.o(ModType).s, " OFF at t = ", t for i=0,numcols-1 { ncl = col[i].cstim.ncl for ltr(nc,ncl) if(!isojt(nc.pre,INTF6[0]) && isojt(nc.syn,INTF6[0])) { if(nc.syn.type==ModType) { if(nc.weight(AM2)>0) nc.weight(AM2) = wmatex[i][ModType][AM2] if(nc.weight(NM2)>0) nc.weight(NM2) = wmatex[i][ModType][NM2] } } } } //* InitModulation proc InitModulation () { if(ModGain!=1) { cvode.event(ModONT,"ModulateON()") if(ModOFFT > 0) cvode.event(ModOFFT,"ModulateOFF()") } } //* ZipON - turn on zip - reduce internal AM2,NM2 weights proc ZipON () { local i,j,k,c for c=0,numcols-1 for col[c].ctt(&i) if(!ice(i)) { for col[c].ctt(&j) if(col[c].div[i][j]) { if(ice(j)) { for case(&k,AM2,NM2) col[c].wd0[i][j][k] /= EIRed } else { for case(&k,AM2,NM2) col[c].wd0[i][j][k] /= EERed } } } } //* ZipOFF - turn off zip - resets internal weights back up proc ZipOFF () { local i,j,k,c for c=0,numcols-1 for col[c].ctt(&i) if(!ice(i)) { for col[c].ctt(&j) if(col[c].div[i][j]) { if(ice(j)) { for case(&k,AM2,NM2) col[c].wd0[i][j][k] *= EIRed } else { for case(&k,AM2,NM2) col[c].wd0[i][j][k] *= EERed } } } } //* InitZip proc InitZip () { if(EERed!=1 || EIRed!=1) { cvode.event(ZipONT,"ZipON()") if(ZipOFFT > 0) cvode.event(ZipOFFT,"ZipOFF()") } } //* setwmatex - set weights of external inputs to INTF6s proc setwmatex () { local ct,sy,c if(dosetexvals) { for c=0,numcols-1 { for ct=0,CTYPi-1 for sy=0,STYPi-1 wmatex[c][ct][sy]=0 for ct=0,CTYPi-1 if(col[c].numc[ct]) { if(ct==DP || ct==ES) continue // no external 'noise' to DP, ES cells if(ice(ct)) { ratex[c][ct][AM2]=sgrhzEI ratex[c][ct][GA2]=ratex[c][ct][GA]=sgrhzII } else { ratex[c][ct][AM2]=sgrhzEE ratex[c][ct][GA2]=ratex[c][ct][GA]=sgrhzIE } ratex[c][ct][NM2]=sgrhzNM if(IsLTS(ct)) { wmatex[c][ct][AM2] = 0.2 wmatex[c][ct][NM2] = 0.025 wmatex[c][ct][GA]=wmatex[c][ct][GA2]=0.125 } else if(ice(ct)) { wmatex[c][ct][NM2] = 0.100 wmatex[c][ct][AM2] = 0.275 wmatex[c][ct][GA]=wmatex[c][ct][GA2]=0.125 } else if(ct==EM) { wmatex[c][ct][NM2] = 0.05 * 1.0 wmatex[c][ct][AM2] = 0.25 * 1.05 wmatex[c][ct][GA]=wmatex[c][ct][GA2]=0.125 } else { wmatex[c][ct][NM2] = 0.05 wmatex[c][ct][AM2] = 0.25 wmatex[c][ct][GA]=wmatex[c][ct][GA2]=0.125 } for sy=0,STYPi-1 wmatex[c][ct][sy] *= EXGain // apply gain control } {wmatex[c][EM][AM2] *= EMWEXGain wmatex[c][EM][NM2] *= EMWEXGain} {ratex[c][EM][AM2] *=EMREXGain ratex[c][EM][NM2] *=EMREXGain} nqsdel(nqwmex[c]) nqwmex[c]=new NQS("ct","sy","w","rate") for ct=0,CTYPi-1 for sy=0,STYPi-1 if(wmatex[c][ct][sy]) nqwmex[c].append(ct,sy,wmatex[c][ct][sy],ratex[c][ct][sy]) } } } proc rewt () {} // nothing needs to be done since copy directly into wd0[][][] //* setcstim - set external inputs to COLUMNs using CSTIM proc setcstim () { local i,seed for i=0,lcol.count-1 { print i if(dbgcols)seed=inputseed else seed=(i+1)*inputseed lcstim.append(new CSTIM(lcol.o(i),seed,sgrdur,sgrhzdel,EIBalance[i],usens)) lcstim.o(lcstim.count-1).setwm(nqwmex[i]) lcstim.o(lcstim.count-1).setspks() } print "set external inputs" } //* clrshock -- clear all shock params and actual shocks proc clrshock () { local i,j,k,l for i=0,numcols-1 for j=0,CTYPi-1 for k=0,STYPi-1 for l=0,MAXSHOCK-1 { wshock[i][j][k][l]=durshock[i][j][k][l]=prctshock[i][j][k][l]=nshock[i][j][k][l]=isishock[i][j][k][l]=startshock[i][j][k][l]=0 } setshock(1) } //* setshockp(celltype,column,synapsetype,weight,starttime,prctcells,nshocks,isi,dur,shocknum) proc setshockp () { local i,x,cty,col,syty,wt,tm,prct,ns,isi,dur,shockn cty=$1 col=$2 syty=$3 wt=$4 tm=$5 prct=$6 ns=$7 isi=$8 dur=$9 shockn=$10 wshock[col][cty][syty][shockn] = wt durshock[col][cty][syty][shockn] = dur prctshock[col][cty][syty][shockn] = prct nshock[col][cty][syty][shockn] = ns isishock[col][cty][syty][shockn] = isi startshock[col][cty][syty][shockn] = tm } //* setshock([clear vq first]) - set stims using shock matrices , NB: DEFAULT IS TO CLEAR vq FIRST proc setshock () { local clr,i,j,k,l,tt,set,ns if(numarg()>0) clr=$1 else clr=1 for i=0,numcols-1 for ns=0,1 { set=0 // whether setting new spikes if(clr) {col[i].cstim.vq.clear() col[i].ce.o(0).clrvspks()} // clear shocks to this column? for j=0,CTYPi-1 for k=0,STYPi-1 if(wshock[i][j][k][ns]>0 && nshock[i][j][k][ns]>0) { set = 1 tt = startshock[i][j][k][ns] // time for l=0,nshock[i][j][k][ns]-1 { col[i].cstim.shock(durshock[i][j][k][ns],prctshock[i][j][k][ns],j,tt,9342*(i+1)*(j+1)*(k+1)*(l+1),k,wshock[i][j][k][ns]) tt += isishock[i][j][k][ns] // inc by ISI } } if(set) { col[i].cstim.pushspks() print col[i].cstim.vq.size(-1) } } } //* trainsig(isi,signal number,weight,ty,dur,prct[,clear]) - setup training signal proc trainsig () { local i,numshocks,isi,clr,w,ty,dur,prct,sy if(numarg()>7) clr=$8 else clr=0 if(clr) clrshock() isi=$1 numshocks = (plastendT_INTF6 - plaststartT_INTF6) / isi w=$3 ty=$4 dur=$5 prct=$6 sy=$7 for i=0,numcols-1 setshockp(ty,i,sy,w,plaststartT_INTF6,prct,numshocks,isi,dur,$2) setshock(0) } //* wrex2nq(col) - return an NQS with external input info obfunc wrex2nq () { local i,sy,r,w,row,a localobj enq,col,nsl,ncl,nc,vsy,vm a=allocvecs(vsy,vm) vsy.append(GA,GA2,AM2,NM2) vm.append(0,0,1,0,3,4,2) col=$o1 ncl=col.cstim.ncl nsl=col.cstim.nsl enq = new NQS("id","wGA","wGA2","wAM2","wNM2","rGA","rGA2","rAM2","rNM2","bal") if(col.allcells<2) { dealloc(a) return enq } enq.v.indgen(0,col.allcells-1,1) enq.pad() for i=1,enq.m-1 enq.v[i].fill(0) for ltr(nc,ncl,&i) { row = nc.syn.id for vtr(&sy,vsy) if(nc.weight(sy)) { w = enq.v[vm.x(sy)].x(row) = nc.weight(sy) r = enq.v[vm.x(sy)+4].x(row) = 1e3/nsl.o(i).interval if(sy==AM2 || sy==NM2) { enq.v[9].x(row) += r*w } else { enq.v[9].x(row) -= r*w } break } } dealloc(a) return enq } //* nq2wrex(enq,col) - sets external weight/rate params based on NQS proc nq2wrex () { local i,sy,row,a localobj enq,col,nsl,ncl,nc,vsy,vm a=allocvecs(vsy,vm) vsy.append(GA,GA2,AM2,NM2) vm.append(0,0,1,0,3,4,2) enq = $o1 col=$o2 ncl=col.cstim.ncl nsl=col.cstim.nsl if(enq.v.size<1) return for ltr(nc,ncl,&i) { row = nc.syn.id for vtr(&sy,vsy) if(nc.weight(sy)) { nc.weight(sy) = enq.v[vm.x(sy)].x(row) nsl.o(i).interval = 1e3 / enq.v[vm.x(sy)+4].x(row) break } } dealloc(a) } //* updateEX proc updateEX () { local i,j localobj co print "updateEX at t = ", t for ltr(co,lcol,&i) { for j=1,4 nqwrex[i].v[j].mul(EXFctr) nq2wrex(nqwrex[i],col[i]) } cvode.event(t+EXDT,"updateEX()") // set next update weights event } //* mysendex - starts off the update EX q proc mysendex () { local i,sz localobj xo,co for ltr(co,lcol,&i) { nqsdel(nqwrex[i]) nqwrex[i] = wrex2nq(col[i]) } cvode.event(EXRedStartT,"updateEX()") } //* sethandlers - setup runtime events, if needed proc sethandlers () { // sets up modulation events to ModType, only matters if ModGain != 1 (supposed to be < 1 for damage) // fid = new FInitializeHandler(1,"InitModulation()") // sets up Zip, if applicable (only iff EERed !=1 or EIRed != 1) zid = new FInitializeHandler(1,"InitZip()") if(dosendex) fix=new FInitializeHandler("mysendex()") } //* func calls setwmatex() // sets params for poisson inputs if (!jcn) rjinet() //means no jitcon setcstim() // creates poisson inputs if(TrainW>0 && TrainISI>0) { trainsig(TrainISI,0,TrainW,TrainTY,TrainDUR,TrainPRCT,TrainSY)//optional training signal during plasticity period } sethandlers() // for events during run