// $Id: syncode.hoc,v 1.412 2011/07/29 18:56:31 billl Exp $ print "Loading syncode.hoc..." //* setup {load_file("grvec.hoc")} {load_file("labels.hoc")} {load_file("nqs.hoc")} strdef syn1,syn2 thresh = -20 objref cp,svs,ncq,intf,vq objref ivspks,vspks,wvspks,ncl[1][1][1] objref sp[3], c[1], ce, nc[1], cells[10] // enough room for 10 cell types objref vite double numc[CTYPi],ix[CTYPi],ixe[CTYPi],wmat[CTYPi][CTYPi][STYPi],wd0[CTYPi][CTYPi][STYPi] Incol=2 ncl = new List() sp = new NQS() //* iterator ixt(),ctt(),stt() // ctt() iterates over all cells; eg for ctt() print ii iterator ctt () { local jj // global ii if (argtype(2)==3) $&2=0 else i1=0 for jj=0,CTYPi-1 if (numc[jj]!=0) { if (ce!=nil) if (ix[jj]=0;jj-=1) if (numc[jj]!=0) { if (ce!=nil) if (ix[jj]=0) ib=im=$1 if (argtype(2)==0) if ($2>=0) jb=jm=$2 if (argtype(4)==3) $&4=0 for ia=ib,im for ja=jb,jm if (numc[ia]!=0 && numc[ja]!=0) { if (ce!=nil) if (ix[ia]=ix[$2] && $1<=ixe[$2]) } else { for ii=0,CTYPi-1 if ($1>=ix[ii] && $1<=ixe[ii]) return ii return -1 } } // ixt(type[,col,vec]); ixt(type,&x); ixt(type,col,&x) iterator ixt () { local ty,col,a,lfl,ixa,i localobj o ty=$1 lfl=0 if (argtype(2)==0) col=$2 else { col=-1 if (argtype(2)==3) lfl=2 } if (argtype(3)==1) { o=$o3 vrsz(numc[ty],o,"O") } else if (argtype(3)==3) lfl=3 i=lfl if (col<0) { for ({ixa=ix[ty] ixj=0};ixa<=ixe[ty];{ixa+=1 ixj+=1}) { XO=ce.o(ixa) if (lfl) $&i=ixa else ixi=ixa iterator_statement } } else { if (col>=ncols) printf("ixt ERR: Only %d columns (%d)\n",ncols,col) else { a=ix[ty]+col*numc[ty]/ncols for ({ixa=a ixj=0};ixa TRG: %s (%s)\n",XO,YO,YO.syns(syn)) XO.conn(YO.syns[syn]) } } //* synconn() synapse linking -- NQS routines //** synconn(preid,postid,pre#,post#,%div) // eg synconn(PYRi,PYRi,AMPAi,pmat[PYR][PYR]) // provides % connectivity based on C/pre==%div==%conv==D/post // S==C*post==D*pre %conv=S/(post*pre)=C/pre=D/post objref convec,convec1,convec2 // vectors to count how much div is from each nrn convec = new Vector(1e3) convec1 = convec.c // a scratch vector convec2 = convec.c // copy of convec to blot out self-connect and redundent connects proc synconn () { local preid,posid,pdiv,con,div,ii,jj,prn,pon,targ,sz,styp1,styp2 if (numarg()==0) { print "\tsynconn(preid,postid,prn,pon,pdiv)" return } preid=$1 posid=$2 prn=$3 pon=$4 pdiv=$5 CODEv=sp.v[sp.fi("CODE")] PRv=sp.v[sp.fi("PR")] POv=sp.v[sp.fi("PO")] sz=PRv.size if (pdiv==1) { if (preid==posid) div=pon-1 else div=pon con=div } else { con=int(pdiv*prn+1) div=int(pdiv*pon) } if (isobj(CTYP,"List")) { printf("%s->%s:\tdiv=%d,conv=%d (%d syns)\n",CTYP.object(preid).s,CTYP.object(posid).s,div,con,prn*div) } else { printf("%d->%d:\tdiv=%d,conv=%d (%d syns)\n",preid,posid,div,con,prn*div) } if (prn*div==0) return sp.pad(sz+prn*div) if (pdiv==1) { convec.indgen(0,pon-1,1) for ii=0,prn-1 { if (preid==posid) {convec.indgen(0,pon-1,1) convec.remove(ii)} POv.copy(convec,sz+ii*div) PRv.fill(ii,sz+ii*div,sz+(ii+1)*div-1) } } else { convec.resize(pon) convec.fill(0) // counter for convergence for ii=0,prn-1 { // sources convec2.copy(convec) if (preid==posid) convec2.x[ii]=1e10 // block self-connect for jj=1,div POv.set(sz+ii*div+jj-1,pickpost(pon,con)) // pick desired target PRv.fill(ii,sz+ii*div,sz+(ii+1)*div-1) } } CODEv.fill(mkcodf(preid,posid,0,0,0),sz,PRv.size-1) } proc syncnn () { local preb,pree,posb,pose,pdiv,con,div,ii,jj,prn,pon,targ,sz,styp1,styp2 if (numarg()==0) { print "\tsyncnn(preb,pree,posb,pose,pdiv)" return } preb=$1 pree=$2 posb=$3 pose=$4 pdiv=$5 CODEv=sp.v[sp.fi("CODE")] PRv=sp.v[sp.fi("PR")] POv=sp.v[sp.fi("PO")] sz=PRv.size prn=pree-preb+1 pon=pose-posb+1 if (pdiv==1) { if (preid==posid) div=pon-1 else div=pon con=div } else { con=int(pdiv*prn+1) div=int(pdiv*pon) } if (isobj(CTYP,"List")) { printf("%s->%s:\tdiv=%d,conv=%d (%d syns)\n",CTYP.object(preid).s,CTYP.object(posid).s,div,con,prn*div) } else { printf("%d->%d:\tdiv=%d,conv=%d (%d syns)\n",preid,posid,div,con,prn*div) } if (prn*div==0) return sp.pad(sz+prn*div) if (pdiv==1) { convec.indgen(0,pon-1,1) for ii=0,prn-1 { if (preid==posid) {convec.indgen(0,pon-1,1) convec.remove(ii)} POv.copy(convec,sz+ii*div) PRv.fill(ii,sz+ii*div,sz+(ii+1)*div-1) } } else { convec.resize(pon) convec.fill(0) // counter for convergence for ii=0,prn-1 { // sources convec2.copy(convec) if (preid==posid) convec2.x[ii]=1e10 // block self-connect for jj=1,div POv.set(sz+ii*div+jj-1,pickpost(pon,con)) // pick desired target PRv.fill(ii,sz+ii*div,sz+(ii+1)*div-1) } } PRv.add(preb) POv.add(posb) CODEv.fill(mkcodf(preid,posid,0,0,0),sz,PRv.size-1) } //** synconn2() uses elimrepeats() and shuffle methods proc synconn2 () { local preid,posid,pdiv,con,div,ii,jj,prn,pon if (numarg()==0) { print "\tsynconn2(preid,postid,prn,pon,pdiv)" return } preid=$2 posid=$3 prn=$4 pon=$5 pdiv=$6 $o1.clear() PRv=$o1.v[$o1.fi("PR")] POv=$o1.v[$o1.fi("PO")] con=int(pdiv*prn+1) div=int(pdiv*pon) if (prn*div==0) return printf("%s->%s:\tdiv=%d,conv=%d (%d syns)\n",CTYP.object(preid).s,CTYP.object(posid).s,div,con,prn*div) if (pdiv==1) { $o1.pad(prn*div) convec.indgen(0,pon-1,1) for ii=0,prn-1 { POv.copy(convec,ii*div) PRv.fill(ii,ii*div,(ii+1)*div-1) } } else { $o1.pad(1.5*prn*div) rdm.discunif(0,prn-1) PRv.setrand(rdm) rdm.discunif(0,pon-1) POv.setrand(rdm) $o1.elimrepeats("PR","PO") $o1.shuffle() $o1.pad(prn*div) } $o1.fill("CODE",1,preid) $o1.fill("CODE",2,posid) } //** synconn3() doesn't worry about eliminating repeats proc synconn3 () { local preid,posid,pdiv,con,div,ii,jj,prn,pon if (numarg()==0) { print "\tsynconn2(preid,postid,prn,pon,pdiv)" return } preid=$2 posid=$3 prn=$4 pon=$5 pdiv=$6 $o1.clear() PRv=$o1.v[$o1.fi("PR")] POv=$o1.v[$o1.fi("PO")] con=int(pdiv*prn+1) div=int(pdiv*pon) if (prn*div==0) return printf("%s->%s:\tdiv=%d,conv=%d (%d syns)\n",CTYP.object(preid).s,CTYP.object(posid).s,div,con,prn*div) $o1.pad(prn*div) rdm.discunif(0,prn-1) PRv.setrand(rdm) rdm.discunif(0,pon-1) POv.setrand(rdm) $o1.fill("CODE",1,preid) $o1.fill("CODE",2,posid) } //*** pickpost() tries to reduce divergence variance // pickpost(postlist,maxcon,YO) // maxcon == -1 means to ignore convergence // MUST do convec.resize() and convec.fill(0) before using func pickpost () { local ran, maxcon, maxpo, min, indx maxcon = $2 // max convergence to be allowed maxpo = $1 // number of postsyn choices min = convec2.min // convec should start all 0's if (min >= maxcon) { // all full up printf("Pickpost full WARNING: %d %d\n",min,maxcon) vlk(convec2) } convec1.indvwhere(convec2,"==",min) // look for all the smallest to fill up first inx = convec1.x[rdm.discunif(0,convec1.size-1)] convec.x[inx]+=1 convec2.x[inx]=1e10 // block from reconnecting here return inx } //** smap() // excitatory cells project to AMPA and inhibitory cells to GABA // assumes PRIDv ... defined by sp.mo(1) objref pro,poo // pre and post pointers func smap () { local ct,sy,conv,prdx,podx,prx,pox,delx,w0x,w1x localobj nc,ty ty=new Union() ct=cp.fi("PRID") sy=cp.fi("STYP") sp.resize("NC") sp.odec("NC") sp.pad() sp.mo(1) for ii=0,PRv.size-1 { uncodf(CODEv.x[ii],&prdx,&podx) prx=PRv.x[ii] pox=POv.x[ii] delx=DELv.x[ii] w0x=WT0v.x[ii] w1x=WT1v.x[ii] pro=c[prdx].object(prx) poo=c[podx].object(pox) NCv.x[ii]=sp.fcdo.append(nc=smap1(prdx))-1 for kk=0,nc.wcnt-1 nc.weight[kk]=0 x=cp.fetch(ct,prdx,sy) syntyp(x,ty) nc.weight[ty.x]=w0x if (ty.x[1]>-1) nc.weight[ty.x[1]]=w1x nc.delay=delx } return ii } //*** smap1(SYN#) poo has postsyn and pro has pre obfunc smap1 () { localobj si if (poo.fflag) { YO=poo } else { YO=poo.po[$1] if (isobj(YO,"List")) { snsr($1,poo) YO=YO.object(YO.count-1) } } if (pro.fflag) { si=new NetCon(pro, YO) } else { pro.soma si=new NetCon(&v(0.5),YO) } return si } //*** snsr() handles situation where multiple PPs must be hung onto postsyn objref proc snsr () { printf("PROBLEM: replace snsr() which uses an execute\n") if (isobj($o2.po[$1],"List")) { sprint(tstr,"%s.soma %s.po[%d].append(new %s(0.5))",$o2,$o2,$1,STYP.object($1).s) } else { sprint(tstr,"%s.soma %s.po[%d] = new %s(0.5)",$o2,$o2,$1,STYP.object($1).s) } execute(tstr) } //** umbrella(preid,postid,max,width[,shift]) // set lateral projections from pre to post out to width // sets direct connection (jj==ii) iff preid!=posid proc umbrella () { local ii,jj,preid,posid,width,sh,max,sz,styp1,styp2 preid=$1 posid=$2 max=$3 width=$4 if (numarg()>=5) sh=$5 else sh=0 sz=PRv.size styp1=styp2=-1 if (width) { for ii=0,max-1 for jj=ii-width+sh,ii+width+sh { if (jj>=0 && jj=5) sh=$5 else sh=0 sz=PRv.size styp1=styp2=-1 if (width) { for ii=0,max-1 for jj=ii-width+sh,ii+width+sh { if (preid!=posid || jj!=ii) { ja=jj if (jj<0) ja=-jj if (jj>max-1) ja=2*max-jj-2 PRv.append(ja) POv.append(ii) PRIDv.append(preid) POIDv.append(posid) } } } else { // just within column connections for ii=0,max-1 { PRv.append(ii) POv.append(ii) PRIDv.append(preid) POIDv.append(posid) } } sp.pad() // WID0v.fill(styp1,sz,PRv.size-1) // WID1v.fill(styp2,sz,PRv.size-1) } //** nqdiv(PRID,POID,PR,PO0[,PO1,...]) // nqdiv(PRID,POID,PR,POBEG,..,POEND) proc nqdiv () { local i,beg,end if (numarg()==0) { print "nqdiv(PRID,POID,PR,PO0[,PO1,...])\nnqdiv(PRID,POID,PR,POBEG,\"..\",POEND)" return } if (numarg()==6 && argtype(5)==2) { beg=$4 end=$6 for i=beg,end sp.append("CODE",EQU1,$1,"CODE",EQU2,$2,"PR",$3,"PO",i) } else for i=4,numarg() sp.append("CODE",EQU1,$1,"CODE",EQU2,$2,"PR",$3,"PO",$i) sp.pad() } //** nqconv(POID,PRID,PO,PR0[,PR1,...]) // nqconv(POID,PRID,PO,PRBEG,..,PREND) proc nqconv () { local i,beg,end if (numarg()==0) { print "nqconv(POID,PRID,PO,PR0[,PR1,...])\nnqconv(POID,PRID,PO,PRBEG,\"..\",PREND)" return } if (numarg()==6 && argtype(5)==2) { beg=$4 end=$6 for i=beg,end sp.append("PRID",$2,"POID",$1,"PR",i,"PO",$3) } else for i=4,numarg() sp.append("PRID",$2,"POID",$1,"PR",$i,"PO",$3) sp.pad() } //** proc nq1to1(PRID,POID,num) proc nq1to1 () { umbrella($1,$2,$3,0) } //* direct weight setting routines //** scale gmax proc synscgmax () { for ltr(XO,cvode.netconlist("" , "", $s1)) { XO.weight *= $2 } } //** set/get gmax proc synsetgmax () { if (numarg()==0) { print "synsetgmax(pre,post,type,wt)" } else if (numarg()==2) {for ltr(XO,cvode.netconlist("" , "", $s1)) XO.weight=$2 } else if (numarg()==3) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) XO.weight=$3 } else if (numarg()==4) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) XO.weight=$4 } else { print "ERROR: too many args" } if (i1==0) printf("WARNING: nothing set in synsetgmax(%s ...)\n",$s1) } // synnormgmax() -- like synsetgmax except normalizes the wt by convergence proc synnormgmax () { for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) { XO.weight=$4/cvode.netconlist($s1,XO.postcell,$s3).count } } proc syngetgmax () { if (numarg()==1) { if (strcmp($s1,"help")==0) { printf("type,post/type,pre/post/type\n") } else { for ltr(XO,cvode.netconlist("" , "", $s1)) printf("%g ",XO.weight) } } else if (numarg()==2) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) printf("%g ",XO.weight) } else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) printf("%g ",XO.weight) } else for ltr(XO,cvode.netconlist("","","")) printf("%g ",XO.weight) print "" } //** set/get delay proc synsetdel () { if (numarg()==2) {for ltr(XO,cvode.netconlist("" , "", $s1)) XO.delay=$2 } else if (numarg()==3) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) XO.delay=$3 } else if (numarg()==4) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) XO.delay=$4 } else { print "ERROR: too many args" } if (i1==0) printf("WARNING: nothing set in synsetdel(%s ...)\n",$s1) } proc syngetdel () { if (numarg()==1) {for ltr(XO,cvode.netconlist("" , "", $s1)) printf("%g ",XO.delay) } else if (numarg()==2) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) printf("%g ",XO.delay) } else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) printf("%g ",XO.delay) } else for ltr(XO,cvode.netconlist("","","")) printf("%g ",XO.delay) print "" } //** set/get thresh proc synsetthr () { if (numarg()==1) {for ltr(XO,cvode.netconlist("" , "", "")) XO.threshold=$1 } else if (numarg()==2) {for ltr(XO,cvode.netconlist($s1 , "", "")) XO.threshold=$2 } else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1, "", $s2)) XO.threshold=$3 } else if (numarg()==4) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) XO.threshold=$4 } else { print "ERROR: too many args" } if (i1==0) printf("WARNING: nothing set in synsetthr(%s ...)\n",$s1) } proc syngetthr () { if (numarg()==1) {for ltr(XO,cvode.netconlist($s1 , "", "")) printf("%g ",XO.threshold) } else if (numarg()==2) {for ltr(XO,cvode.netconlist($s1, "", $s2)) printf("%g ",XO.threshold) } else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) printf("%g ",XO.threshold) } else for ltr(XO,cvode.netconlist("","","")) printf("%g ",XO.threshold) print "" } //** synremove: remove post, pre/post, pre/post/type; synshow proc synremove () { if (numarg()==0) { printf("synremove: remove post, pre/post, pre/post/type\n") return } if (numarg()==1) tmplist = cvode.netconlist("", $s1 , "") if (numarg()==2) tmplist = cvode.netconlist("", $s1, $s2) if (numarg()==3) tmplist = cvode.netconlist($s1 , $s2, $s3) if (tmplist.count>0) for ltr(XO,tmplist) ncl.remove(ncl.index(XO)) tmplist = nil // need to remove these references too if (numarg()==1) tmplist = cvode.netconlist("", $s1 , "") if (numarg()==2) tmplist = cvode.netconlist("", $s1, $s2) if (numarg()==3) tmplist = cvode.netconlist($s1 , $s2, $s3) if (tmplist.count>0) for ltr(XO,tmplist) printf("ERROR: %s removed from ncl but still exists\n",XO) tmplist = nil } proc synshow () { sprint(temp_string_,"x=XO.%s",$s2) for ltr(XO,cvode.netconlist("" , "", $s1)) { execute(temp_string_) printf("%g ",x) } print "" } //* weight setting routines using NQS //** stwt(PREID,POSTID,WT0[,WT1,norm]) // stwtnorm() causes dividing by individual convergence values proc stwt () { local w0,w1 if (sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2) ==0) { printf("WARNING NO CONNECTS FROM %d TO %d\n",$1,$2) return } w0=$3 if (numarg()>=5) { w0=$3/$5 w1=$4/$5 } else if (numarg()>=4) { w1=$4 } if (numarg()>=4) sp.fillin("WT0",w0,"WT1",w1) else sp.fillin("WT0",w0) } //** strwt(PREID,POSTID,WT0,WT1,psdev[,norm]) proc strwt () { local w0,w1,psdev cnt=sp.select("CODE",EQU1,$1,"CODE",EQU2,$2) if (cnt==0) {printf("WARNING NO CONNECTS FROM %d TO %d\n",$1,$2) return } if (numarg()>=6) { w0=$3/$6 w1=$4/$6 } else { w0=$3 w1=$4 } psdev=$5 rdm.lognormal(w0,psdev*psdev*w0*w0) sp.out.v[sp.fi("WT0")].setrand(rdm) if (w1!=0) { rdm.lognormal(w1,psdev*psdev*w1*w1) sp.out.v[sp.fi("WT1")].setrand(rdm) } sp.delect() } //** strwt2(NQS,WT0,WT1,psdev[,norm]) proc strwt2 () { local w0,w1,psdev if (numarg()>=5) { w0=$2/$5 w1=$3/$5 } else { w0=$2 w1=$3 } psdev=$4 rdm.lognormal(w0,psdev*psdev*w0*w0) $o1.v[$o1.fi("WT0")].setrand(rdm) if (w1!=0) { rdm.lognormal(w1,psdev*psdev*w1*w1) $o1.v[$o1.fi("WT1")].setrand(rdm) } } //** strdel(PREID,POSTID,del,psdev) proc strdel () { local del0,psdev if (numarg()==4) { cnt=sp.select("CODE",EQU1,$1,"CODE",EQU2,$2) if (cnt==0) {printf("WARNING NO CONNECTS FROM %d TO %d\n",$1,$2) return } del0=$3 psdev=$4 rdm.lognormal(del0,psdev*psdev*del0*del0) sp.out.v[sp.fi("DEL")].setrand(rdm) sp.delect() } else { del0=$2 psdev=$3 rdm.lognormal(del0,psdev*psdev*del0*del0) $o1.v[sp.fi("DEL")].setrand(rdm) } } //** clrwt(PRID,POID,%clr) proc clrwt () { local n n=round($3*sp.select("CODE",EQU1,$1,"CODE",EQU2,$2)) sp.out.v[sp.fi("WT0")].fill(0,0,n) sp.delect() } //** chksp() confirm correspondance between sp and ncl -- defunct if using multiple ncl proc chksp () { local prid,poid,pr,po for ltr(XO,ncl,&x) { prid=sp.v[0].x[x] poid=sp.v[1].x[x] pr=sp.v[2].x[x] po=sp.v[3].x[x] if (XO.pre.id!=pr || XO.pre.type!=prid || XO.syn.id!=po || XO.syn.type!=poid) { printf("%d %d %d %d %d %d %d %d\n",XO.pre.id,pr,XO.pre.type,prid,XO.syn.id,po,XO.syn.type,poid) }} } //** swtmap() -- redund code to permit it to run relatively fast // no longer overloaded to set delay, delmap() or to clr clrwts() proc swtmap () { local ii,ct,sy,conv,prx,pox,delx,w0x,w1x localobj nc,ty ty=new Union() ct=cp.fi("PRID") sy=cp.fi("STYP") if (PRv.size!=$o1.count) { printf("swtmap ERR: size discrepency: %d vs %d\n",PRv.size,$o1.count) return } for ii=0,PRv.size-1 { prdx=PRIDv.x[ii] podx=POIDv.x[ii] prx=PRv.x[ii] pox=POv.x[ii] delx=DELv.x[ii] w0x=WT0v.x[ii] w1x=WT1v.x[ii] nc=$o1.object(ii) poo=nc.syn x=cp.fetch(ct,prdx,sy) syntyp(x,ty) nc.weight[ty.x]=w0x if (ty.x[1]>-1) nc.weight[ty.x[1]]=w1x nc.delay=delx } } //** wmul(PRID,POID,SYNID,MUL) multiplies set of syns by a factor // resets from weights stored in sp for ii=0,CTYPi-1 for jj=0,CTYPi-1 for kk=0,STYPi-1 wd0[ii][jj][kk]=1 proc wmul () { local ii,pr1,po1,sy1,w1,wd,sy2 pr1=$1 po1=$2 sy1=$3 w1=$4 if (wd0[pr1][po1][sy1]==0) { if (w1!=0) printf("\nWARNING: %s->%s(%s) set to 0 can't reset\n",\ CTYP.o(pr1).s,CTYP.o(po1).s,STYP.o(sy1).s) return } wd=w1/wd0[pr1][po1][sy1] if (wd!=1) { XO=ncl[pr1][po1][0] for ii=0,XO.count-1 XO.o(ii).weight[sy1]*=wd wd0[pr1][po1][sy1]=w1 } else printf(".") } //** wset(PRID,POID,SYNID,WT) resets weights to gaussian dist similar to strwt() // uses sp to determine how many weights are needed proc wset () { local num,prx,pox,sox,wet,a,err,psdev localobj v1 prx=$1 pox=$2 sox=$3 wet=$4 if (numarg()==5) psdev=$5*$5 else psdev=0 err=0 a=allocvecs(v1) if (cp.fetch("PRID",prx,"STYP")==EX && !(sox==AM || sox==NM)) err=1 if (cp.fetch("PRID",prx,"STYP")==IX && !(sox==GA || sox==GB)) err=1 if (err) { printf("cell/syn discrepancy: %d -> %d\n",prx,sox) return } if (Incol==2) num=sp.select(-1,"CODE",EQU1,prx,"CODE",EQU2,pox) else { num=sp.select(-1,"CODE",EQU1,prx,"CODE",EQU2,pox,"CODE",EQU3,Incol) } v1.resize(num) if (psdev) { rdm.normal(wet,psdev*wet*wet) v1.setrand(rdm) } else v1.fill(wet) vwtmap(v1,sp,sox) dealloc(a) } //** wbim(PRID,POID,SYNID,PSDEV,%A,WTA,%B,WTB,...) bimodal weight setting routines // uses sp to determine how many weights are needed proc wbim () { local fsz,i,prx,pox,sox,wet,a,err,psdev,pcw,ptot localobj v1,v2 prx=$1 pox=$2 sox=$3 psdev=$4*$4 pcw=$5 wet=$6 ptot=0 err=0 a=allocvecs(v1,v2) if (cp.fetch("PRID",prx,"STYP")==EX && !(sox==AM || sox==NM)) err=1 if (cp.fetch("PRID",prx,"STYP")==IX && !(sox==GA || sox==GB)) err=1 if (err) { printf("cell/syn discrepancy: %d -> %d\n",prx,sox) return } fsz=sp.select(-1,"CODE",EQU1,prx,"CODE",EQU2,pox) for i=5,numarg() { pcw=$i i+=1 wet=$i // if (pcw*fsz != int(pcw*fsz)){ printf("wbim WARNING: %d->%d non-int %gx%g=%g\n",prx,sox,pcw,fsz,pcw*fsz) } v2.resize(int(pcw*fsz)) rdm.normal(wet,psdev*wet*wet) v2.setrand(rdm) v1.append(v2) ptot+=pcw // keep track of percent filled } if (ptot!=1) printf("wbim WARNING: %d->%d only %g filled\n",prx,pox,ptot) if (v1.size!=fsz) { printf("wbim WARNING: %d->%d size error %d->%d\n",prx,sox,v1.size,fsz) v1.resize(fsz) } vwtmap(v1,sp,sox) dealloc(a) } //** vwtmap(VEC,NQS) -- copy weights from a vector onto ncl // vwtmap(NQS,VEC) -- copy weights from ncl into vector func vwtmap () { local wix if (numarg()==3) wix=$3 else wix=0 if (isojt($o2,sp)) { // copy from vector to sp.fcdo weights if ($o1.size!=$o2.ind.size){ printf("vwtmap ERR: size discrepency: %d vs %d\n",$o1.size,$o2.ind.size) return 0} for ii=0,$o1.size-1 $o2.fcdo.o[$o2.ind.x[ii]].weight[wix]=$o1.x[ii] return $o1.size } else { // copy from ncl weights to vector if ($o1.ind.size!=$o2.size){printf("vwtmap WARNING: resizing vec\n") $o2.resize($o1.ind.size)} for ii=0,$o2.size-1 $o2.x[ii]=$o1.o[$o1.ind.x[ii]].weight[wix] return $o2.size } } //** wtstat(WIX) -- check id of weights directly from the ncs // assume that have already been selected in sp.out proc wtstat () { local wix,a,sz,fnc localobj v1 a=allocvecs(v1) if (!eqojt(sp.cob,sp.out)) print "WARNING: no sp.select() done" sz=sp.size(1) fnc=sp.fi("NC") v1.resize(sz) v1.resize(0) if (numarg()==1) wix=$1 else wix=0 // for sp.qt(XO,"NC") v1.append(XO.weight[wix]) // 5x slower for ii=0,sz-1 v1.append(sp.fcdo.o(sp.out.v[fnc].x[ii]).weight[wix]) stat(v1) dealloc(a) } // need to set delays proc delmap () { local ii,deli,nc0,nc1 nc0=$o1.fi("NC0") nc1=$o1.fi("NC1","NOERR") deli=$o1.fi("DEL") for ii=0,$o1.v.size-1 { ncl.object($o1.v[nc0].x[ii]).delay=$o1.v[deli].x[ii] if (nc1!=-1) if ($o1.v[nc1].x[ii]!=-1) { ncl.object($o1.v[nc1].x[ii]).delay=$o1.v[deli].x[ii] } } } // clrwtmap proc clrwts () { local ii,jj,nc0,wt0,deli,nc1,wt1,typ,sy2,wid0,wid1,clr nc0=$o1.fi("NC0") wt0=$o1.fi("WT0") deli=$o1.fi("DEL") wid0=$o1.fi("WID0") typ=$o1.fi("TYPE") nc1=$o1.fi("NC1","NOERR") wt1=$o1.fi("WT1","NOERR") wid1=$o1.fi("WID1","NOERR") tobj=ncl.object($o1.v[nc0].x[ii]) for ii=0,$o1.v.size-1 { tobj=ncl.object($o1.v[nc0].x[ii]) for jj=0,tobj.wcnt-1 tobj.weight[jj]=0 // clear tobj.delay=1 tobj.threshold=0 if (nc1!=-1) if ($o1.v[nc1].x[ii]!=-1) for jj=0,tobj.wcnt-1 tobj.weight[jj]=0 // clear } } // swtchk(sp,"WT0","NC0") compare weights to sp weights func swtchk () { local ii,jj,nc0,wt0,n nc0=$o1.fi($s3) wt0=$o1.fi($s2) n=0 for ii=0,$o1.v.size-1 { if ($o1.v[nc0].x[ii]==-1) continue tobj=ncl.object($o1.v[nc0].x[ii]) if ($o1.v[wt0].x[ii]==tobj.weight) n+=1 else { printf("Mismatch %d: %g %g\n",ii,$o1.v[wt0].x[ii],tobj.weight) } } tobj=nil return n/ii } // synchk() look for internal consistency proc synchk () { for ltr(XO,cvode.netconlist("","","")) if (isassigned(XO.postcell) && XO.weight<0) { printf("Error for %s with wt %g\n",XO.syn,XO.weight) } } //** getwt() useful in eg sp.spr(".c.apply('getwt')") func getwt () { return NetCon[$1].weight } spnormflag = 0 // set this flag to normalize weights by number of projections //** actumb(PRID,POID,WIDTH) -- clears umbrella and then set sp.ind to chosen umbrella proc actumb () { local width,flag,divisor width=$3 if (width==-1) flag=1 else flag=0 sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2) if (! flag) { // width=-1 is flag for full connection if (sp.fi("WT1")!=-1) sp.fillin("WT0",0,"WT1",0) else sp.fillin("WT0",0) sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2,"DIST","()",-width,width) } if (! spnormflag) { // just set the values if (sp.fi("WT1")!=-1 && numarg()==5) sp.fillin("WT0",$4,"WT1",$5) else sp.fillin("WT0",$4) } else { // need to calculate convergence for individual cells here } } //** inline(PRID,POID,WT) sets the in-column weights proc inline () { local a sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2,"PR",EQV,"PO") if (numarg()==4) sp.fillin("WT0",$3,"WT1",$4) else sp.fillin("WT0",$3) } // stwtnorm(PREID,POSTID,WT0[,WT1,CONVVEC]) func stwtnorm () { local cv,a,b,ret a=b=allocvecs(2) b+=1 if (sp.select("CODE",EQU1,$1,"CODE",EQU2,$2)==0) { printf("WARNING NO CONNECTS FROM %d TO %d\n",$1,$2) return 0 } sp.uniq("PO") // only retains unique values of PO => cv>0 mso[a].copy(sp.out.v[sp.fi("PO")]) for vtr(&x,mso[a]) { cv=sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2,"PO",x) // do select without copy to out mso[b].append(cv) if (cv>0) { if (numarg()==4) sp.fillin("WT0",$3/cv,"WT1",$4/cv) else sp.fillin("WT0",$3/cv) } } ret=mso[b].mean // mean convergence if (numarg()==4) if (argtype(4)==1) $o4.copy(mso[b]) if (numarg()==5) if (argtype(5)==1) $o5.copy(mso[b]) dealloc(a) return ret } // wtnorm(PREID,POSTID) -- normalize the values according to convergence func wtnorm () { local cv,a,b,ret,wt0,wt1 wt0=sp.fi("WT0") wt1=sp.fi("WT1") if (sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2)==0) { printf("WARNING NO CONNECTS FROM %d TO %d\n",$1,$2) return } a=b=allocvecs(2) b+=1 sp.uniq("PO") // only retains unique values of PO => cv>0 mso[a].copy(sp.out.v[sp.fi("PO")]) for vtr(&x,mso[a]) { cv=sp.select("CODE",EQU1,$1,"CODE",EQU2,$2,"PO",x) mso[b].append(cv) if (cv>0) { sp.out.v[wt0].div(cv) if (wt1>-1) sp.out.v[wt1].div(cv) sp.delect() } } ret=mso[b].mean // mean convergence dealloc(a) return ret } proc setdist () { sp.spr("DIST",".c.sub().apply('abs')") } proc stwtvar() { local a,idr if (numarg()==5) idr=1 else idr=0 a=allocvecs(1) mso[a].resize(sp.ind.size) rdm.uniform($3*(1-$4),$3*(1+$4)) mso[a].setrand(rdm) if (spnormflag) mso[a].div(sp.ind.size) sp.wt[idr].indset(sp.ind,mso[a]) dealloc(a) } //** snc() -- set the actual netcons to the params in sp DEL=DELD=1 proc snc () { local ii for ii=0,sp.size-1 { nc[sp.nc.x[ii]].threshold=0 nc[sp.nc.x[ii]].weight=sp.wt.x[ii] nc[sp.nc.x[ii]].delay=DEL+DELD*sp.dist.x[ii] if (sp.nc[1].x[ii]>-1) { nc[sp.nc[1].x[ii]].weight=sp.wt[1].x[ii] nc[sp.nc[1].x[ii]].delay=DEL+DELD*sp.dist.x[ii] } } } //** snci() -- take a vec of indices (eg sp.ind) as arg proc snci () { local ii,jj for jj=0,$o1.size-1 { ii=$o1.x[jj] nc[sp.nc.x[ii]].weight=sp.wt.x[ii] nc[sp.nc.x[ii]].delay=DEL+DELD*sp.dist.x[ii] if (sp.nc[1].x[ii]>-1) { nc[sp.nc[1].x[ii]].weight=sp.wt[1].x[ii] nc[sp.nc[1].x[ii]].delay=DEL+DELD*sp.dist.x[ii] } } } //* informational procs //** proc print_pp_location(PP), from doc/html/refman/nocmodl.html proc print_pp_location() { local x //arg1 must be a point process x = $o1.get_loc() sectionname(section) printf("%s located at %s(%g)\n", $o1, section, x) pop_section() } //** pp_loc(PP,LOC,SCRATCH) returns true if point process PP is located in LOC (regexp match) func pp_loc () { local x //arg1 must be a point process x = 0 $o1.get_loc() if (numarg()==3) { sectionname($s3) } ifsec $s2 { x = 1 } pop_section() return x } //* ndivo, ncono, sdivo, scono: objects; ndivs, ncons, sdivs, scons: strings //** for use with INTF iterator divr () { local ii for ii=0,ncl.count-1 { XO=ncl.object(ii) if (object_id(sfunc.obj(XO.pre.p))==object_id(cells[$1].object($2))) { iterator_statement } } } iterator conr () { local ii for ii=0,ncl.count-1 { XO=ncl.object(ii) if (object_id(sfunc.obj(XO.syn.p))==object_id(cells[$1].object($2))) { iterator_statement } } } //** iterators // eg for syt("ns[0]","ns[1]") print XO,YO,nco iterator syt () { local num,err err=0 canobj($o1,"XO") canobj($o2,"YO") // canobj -- canonical object if ((num=cvode.netconlist(XO,"",YO).count)!=1) { printf("syt() ERROR num==%d (%s,%s)\n",num,XO,YO) err=1 } if (!err) { nco=cvode.netconlist(XO,"",YO).object(0) iterator_statement } XO=nil YO=nil nco=nil } // nca makes list backwards -- syn, then postcell, then precell iterator nca () { local ii tmplist.remove_all if (numarg()==0) { cvode.netconlist("", "", "",tmplist)} if (numarg()==1) { cvode.netconlist("", "", $s1,tmplist)} if (numarg()==2) { cvode.netconlist("", $s2, $s1,tmplist)} if (numarg()==3) { cvode.netconlist($s3, $s2, $s1,tmplist)} for ii=0,tmplist.count-1 { XO=tmplist.object(ii) iterator_statement } } func wtvec () { revec(vec) for nca($s1) vec.append(XO.weight) vlk(vec) return vec.size } func dlyvec () { revec(vec) for nca($s1) vec.append(XO.delay) vlk(vec) return vec.size } iterator prtr () { local ii tmplist.remove_all for ii=0,cvode.netconlist("", $s1, "").count-1 { nco=cvode.netconlist("", $s1, "").object(ii) iterator_statement } } iterator potr () { local ii for ii=0,cvode.netconlist($s1,"","").count-1 { nco=cvode.netconlist($s1,"","").object(ii) iterator_statement } } iterator sytr () { local ii for ii=0,cvode.netconlist("","",$s1).count-1 { nco=cvode.netconlist("","",$s1).object(ii) iterator_statement } } proc sdivo () {for ltr(XO,cvode.netconlist($o1, "", "")) prsxo() } func ndivo () { return cvode.netconlist($o1, "", "").count } func ncono () { return cvode.netconlist("", $o1, "").count } proc scono () {for ltr(XO,cvode.netconlist("", $o1, "")) prsxo() } func ndivs () { if (numarg()==1) return cvode.netconlist($s1, "", "").count else { return cvode.netconlist("" , "", "").count } } func ncons () { return cvode.netconlist("", $s1, "").count } proc sdivs () { for ltr(XO,cvode.netconlist($s1, "", "")) prsxo() } proc scons () { if (numarg()==0) for ltr(XO,cvode.netconlist("", "", "")) prsxo() if (numarg()==1) for ltr(XO,cvode.netconlist("", $s1, "")) prsxo() if (numarg()==2) for ltr(XO,cvode.netconlist("", $s1, $s2)) prsxo() if (numarg()==3) for ltr(XO,cvode.netconlist($s1, $s2,$s3)) prsxo() } // print pre,post,syntype,threshold,weight,delay proc prsxo () { if (isobj(XO.precell,"NULLobject")) { printf("%s:%s->%s (%s) (t%g,w%g,d%g)\n",XO,XO.pre,XO.postcell,XO.syn,XO.threshold,XO.weight,XO.delay) } else { printf("%s:%s->%s (%s) (t%g,w%g,d%g)\n",XO,XO.precell,XO.postcell,XO.syn,XO.threshold,XO.weight,XO.delay) } } //* avwtsp(), actwsc(), avwt() to get proper weight values obfunc sysel () { local pr,po,sy,co,vb,num if (numarg()==1) sy=$1 else { // already selected pr=$1 po=$2 sy=$3 co=$4 num=sp.select("CODE",EQU1,pr,"CODE",EQU2,po,"CODE",EQU3,co) if (num==0) { vec0.resize(0) return vec0} // kludge to get an error returned } if ((pr==IN && sy==GA) || sy==AM) return sp.getcol("WT0",0) else return sp.getcol("WT1",0) } //** avwtsp(PR,PO,COL) looks at NQS db to determine weights -- 7x faster than avwt() below // avwtsp(sp) if do select before checking this obfunc avwtsp () { local a,s1,s2,pr,po,co,wd localobj sp0,v1,o,vr pr=$1 po=$2 co=$3 sp0=sp o=new Union() a=allocvecs(v1) if (name_declared("netstem")==4) { sprint(tstr,"%s%sS%02d.spnqs",netstem,CTYP.o(po).s,scale) if (! strm(tstr,sp0.file)) { printf("Reading %s (was %s)\n",tstr,sp0.file) sp0.rd(tstr) } } if (pr==IN) {s1=GA s2=GB} else {s1=AM s2=NM} if (numarg()==4) sp0=$o4.cob else { sp0.verbose=0 vr=sysel(pr,po,s1,co) if (vr.size==0 && verbose) {printf("%s->%s EMPTY\n",CTYP.o(pr).s,CTYP.o(po).s) return sp0}} sp0.verbose=0 wd=ncq.ay(pr,po,s1,co).x vr.mul(wd) stat(vr,v1) // 0size,1max,2min,3mean,4sdev o.x=v1.x[3] printf("%s->%s %s %s: max: %g; min: %g; mean: %g; sdev: %g\n",\ CTYP.o(pr).s,CTYP.o(po).s,STYP.o(s1).s,INCOL.o(co).s,\ v1.x[1],v1.x[2],v1.x[3],v1.x[4]) wd=ncq.ay(pr,po,s2,co).x vr=sysel(s2) vr.mul(wd) stat(vr,v1) o.x[1]=v1.x[3] printf("%s->%s %s %s: max: %g; min: %g; mean: %g; sdev: %g\n",\ CTYP.o(pr).s,CTYP.o(po).s,STYP.o(s2).s,INCOL.o(co).s,\ v1.x[1],v1.x[2],v1.x[3],v1.x[4]) sp0.verbose=1 dealloc(a) return o } //** actwsc(PR,PO,SY,COCODE,COL,[,tMIN,tMAX]) func actwsc () { local ret,f1,a,wd,we,pr,po,min,max,u,x,y,sy,co,col,prspks,th,conv,diff localobj v1,v2,vr,q,p if (numarg()==0) { printf(" actwsc(PR,PO,SY,COCODE,COL,[,tMIN,tMAX])\n") return 0 } pr=$1 po=$2 sy=$3 co=$4 col=$5 // min,max: just look at activity during this period if (numarg()>5) {min=$6 max=$7} else {min=0 max=tstop} if (min==max) f1=0 else f1=1 a=allocvecs(v1,v2) q=new NQS() q.verbose=0 p=printlist if (f1) { // find name for raster plot should be eg 'SU' for ltr(XO,printlist) if (strc(XO.name,CTYP.o(pr).s)) {x=i1 break} for ixt(pr,col) v2.append(ixi) // get the values for this col q.resize("time",p.o(x).tvec,"ind",p.o(x).vec) u=q.select("time","[]",min,max,"ind","[]",v2.min,v2.max) // u=number of spikes in period min=q.applf(".min","time") max=q.applf(".max","time") q.out.v.sort() y=q.out.v.uniq() // y= uniq spikers if (max-min<10) diff=10 else diff=max-min // prspks = y/diff/numc[pr]*10 // number of spikes in 1 cell spike per 10ms prspks = y/diff/numc[pr]*ncols*10 // normalize by no. of cols x=prspks*(conv=cp.fetch("PRID",pr,"POID",po,"CONV")) // incoming spks over 10ms } sp.verbose=0 vr=sysel(pr,po,sy,co) sp.verbose=1 if (vr.size==0) {dealloc(a) return -1} vrsz(ce,v1,"O") for ixt(po) v1.append(XO.VTH-XO.RMP) stat(v1,v2) th=v2.x[3] // threhold stats wd=ncq.ay(pr,po,sy,co).x // current scaling factor we=4 // 4 cells must fire at about same time to get thresh-level drive if (f1) { printf("%s:%d,%d spks/%.2fms ~ %.2f spks/10ms (%d/%d)\n",\ CTYP.o(pr).s,u,y,max-min,prspks,x,conv) printf("Thresh: %.2f+/-%.2f PSP: %.2f+/-%.2f\n",th,v2.x[4],vr.mean,vr.stdev) printf("\tFor 1/%d continuous activation: ",we) // wd *= threshold/spks_in//weighting // wd is scaling_factor printf("\nwmul(%s,%s,%s,%s,%g)\n",\ CTYP.o(pr).t,CTYP.o(po).t,STYP.o(sy).t,INCOL.o(co).t,\ th/x/vr.mean/we*wd) ret=th/x/vr.mean/we*wd } else { printf("%s->%s %s,%s: %g\n",\ CTYP.o(pr).s,CTYP.o(po).s,STYP.o(sy).s,INCOL.o(co).s,\ vr.mean*wd/th*100) // percent of threshold ret=vr.mean*wd/th*100 } dealloc(a) return ret } //** avwt() goes through ncl list to sum weights proc avwt () { local pr,po,sy,co localobj nc,o pr=$1 po=$2 sy=$3 co=$4 o=ncq.ay(pr,po,sy,co) vrsz(o.o.count,ind,"O") for ltr(nc,o.o) ind.append(nc.weight[sy]) ind.mul(o.x) // mutiply by scale factor if (ind.mean!=0) { printf("%s%s %s: ",CTYP.o(pr).s,CTYP.o(po).s,STYP.o(sy).s) stat(ind) } } //* grvec addendum -- new_printlist_ //** new_printlist_nc(obj,id[,NAME]) records spikes from obj to vitem in printlist // with NAME creates a new vitem warn_flag=1 obfunc new_printlist_nc () { local id,thresh,yoset localobj xo,yo,ox,cvn ox=$o1 id=$2 thresh=-20 yoset=0 if (!isojt(ncl,tmplist)) ncl=new List() if (numarg()>=3) { if (argtype(3)==2) { printlist.append(yo=new vitem($s3,100)) yoset=1 } else if (argtype(3)==0) { thresh=$3 } else printf("new_printlist_nc arg 3 should be name or thresh\n") } if (numarg()>=4) thresh=$4 if (!yoset) if (printlist.count==0) { printlist.append(yo=new vitem("SPKS",100)) } else { yo=printlist.object(printlist.count-1) // continue with the last one } if (isobj(ox,"NetCon")) { xo=ox // use this NetCon } else { cvn=cvode.netconlist(ox, "", "") if (cvn.count==0) { // no netcons available if (! warn_flag) printf(".") else { warn_flag=0 // only warn first time printf("WARNING (new_printlist_nc) creating NetCon for %s ",ox) } if (ox.fflag) { xo=new NetCon(ox, nil) } else { ox.soma xo=new NetCon(&v(x), nil) } xo.threshold=thresh ncl.append(xo) } else { xo=cvn.object(0) // the first of the postsyn netcons if (0) if (xo.threshold!=thresh && isassigned(xo.precell)) { printf("Warning: new_printlist_nc resetting thresh for %s\n",xo) xo.threshold=thresh } } } xo.record(yo.tvec,yo.vec,id) return yo } //** proc new_printlist_nc2(VITEM,CELL or NETCON,ID#) -- don't bother looking for an existing synapse obfunc new_printlist_nc2 () { local id,thresh,yoset localobj xo,ox ox=$o1 xo=$o2 id=$3 thresh=-20 yoset=0 if (isobj(xo,"NetCon")) { // use this NetCon } else { if ($o2.fflag) { xo=new NetCon($o2, nil) } else { $o2.soma xo=new NetCon(&v(x), nil) } xo.threshold=thresh ncl.append(xo) } xo.record(ox.tvec,ox.vec,id) return xo } //** fipre(NETCON) find a presynaptic index for a netcon func fipre () { local nu if (isassigned($o1.pre)) { // a point-process return objnum($o1.pre) } else { if ($o1.preloc==-1) { printf("fipre() ERR: %s\n",$o1) err() } sscanf(secname(),"%*[^[][%d]",&x) // find number of the cell // eg grvecstr="PYR2 sINT sTC sRE" // use locations in this string as id if (sfunc.len(grvecstr)==0) { return x } else { sscanf(secname(),"%[^[]",tstr) nu=sfunc.substr(grvecstr,tstr)/5 return nu*50+x } pop_section() } } //** fspks (index,vec) put spike times for index in vec // fspks (index,vec,num) use printlist.object(num).vec // fspks (index,vec,spkvec,tvec) proc fspks () { local a,b,ix a=b=allocvecs(2) b+=1 if (numarg()==2) { ix=$1 XO=printlist.object(0).vec YO=printlist.object(0).tvec } if (numarg()==3) { ix=$1 XO=printlist.object($3).vec YO=printlist.object($3).tvec } if (numarg()==4) { ix=$1 XO=$o3 YO=$o4 } revec($o2) mso[a].indvwhere(XO,"==",ix) $o2.index(YO,mso[a]) dealloc(a) } // fspks1(index,vec) proc fspks1 () { local a,b,ix if (numarg()==2) { ix=$1 XO=printlist.object($1).vec YO=printlist.object($1).tvec } if (numarg()==4) { ix=$1 XO=$o3 YO=$o4 } $o2.resize(XO.size) $o2.xing(XO,YO,thresh) // times } //** spktimes(plist#,cell#) prints out spike times from a tvec/ivec printlist item // spktimes(tvec,vec,cell#) func spktimes () { local sz,wh,a,i localobj va,vb,tv,vv,o a=allocvecs(va,vb) i=0 // i serves as flag for saving to a vector if (numarg()==4) { tv=$o1 vv=$o2 wh=$3 i=4 } else if (numarg()==3) { if (argtype(1)==1) { tv=$o1 vv=$o2 wh=$3 } else { o=printlist.object($1) wh=$2 vv=o.vec tv=o.tvec i=3 } } else { if (numarg()==2) { o=printlist.object($1) wh=$2 } else if (numarg()==1) { o=printlist.object(0) wh=$1 } else wh=-1 vv=o.vec tv=o.tvec } sz=vv.size if (wh==-1) { vlk(tv,vv) } else { va.indvwhere(vv,"==",wh) vb.index(tv,va) sz=vb.size if (i) $oi.copy(vb) else vlk(vb) } dealloc(a) return sz } //** ceqi() cvode.event_queue_info(3,...) proc ceqi () { local flag,ii flag=$1 tmplist.remove_all revec(ind,vec) printf("\n\n\t**** t=%g ****\n\n",t) if (flag==3) { cvode.event_queue_info(3, ind, vec, tmplist) for ltr(XO,tmplist,100) printf("t=%g flag=%d nc=%s\n",ind.x[i1],vec.x[i1],XO) } else if (flag==2) { cvode.event_queue_info(2, ind, tmplist) for ltr(XO,tmplist,100) { printf("t=%g %s->%s:",ind.x[i1],XO.pre,XO.syn) for ii=0,XO.wcnt-1 printf("%g ",XO.weight[ii]) print "" } } else if (flag==0) { for ltr(XO,ncl,10) { printf("%s->%s:",XO.pre,XO.syn) for ii=0,XO.wcnt-1 printf("%g ",XO.weight[ii]) print "" } } } //** new_printlist_ac(obj,name[,NAME,num]) // adds params from an artificial cell with built-in vec dumping obfunc new_printlist_ac () { local i,max,num,svloc,sz,tsz localobj lo,st npacsz=1.2 st=new String() if(name_declared("vdt_INTF")==5) { vdt = vdt_INTF st.s="INTF" } else if(name_declared("vdt_INTF6")==5) { vdt = vdt_INTF6 st.s="INTF6" } else print "new_printlist_ac warning: no INTF/INTF6 found!" lo = new Union() if (numarg()>=4) num=$4 if (numarg()==4) { sprint(lo.s,"%s%d.%s",$s3,$4,$s2) } else { sprint(lo.s,"%s.%s",$o1,$s2) } if (tstop<=1e4) tsz=tstop else tsz=1e4 sz=npacsz*tsz/vdt vite = new vitem(lo.s,sz) vite.o=$o1 if ($o1.recflag==0) { // record tvec vite.tvec=new Vector(sz) $o1.initrec("time",vite.tvec) } else { for ltr(YO,printlist) if (eqobj($o1,YO.o)) vite.tvec=YO.tvec if (!isassigned(vite.tvec)) printf("ERR %s %s not found in printlist\n",st.s,$o1) } vite.tvflag=1 $o1.initrec($s2,vite.vec) printlist.append(vite) return vite } objref pfih psgchk = 1 proc psend () { local tt for ltr(XO,printlist) { if (strm(XO.var,"[()][()]$")) { revec(XO.vec,XO.tvec) for (tt=psgchk;tt<=tstop;tt+=psgchk) { sprint(tstr,"%s.append(%s)",XO.vec,XO.var) cvode.event(tt,tstr) sprint(tstr,"%s.append(t)",XO.tvec) cvode.event(tt,tstr) } } } } // eg new_printlist_fc("intf.M1()") // obsolete since intf.mod no longer defines M1(),M2(),... obfunc new_printlist_fc () { if (! isassigned(pfih)) { pfih = new FInitializeHandler("psend()") } if (! strm($s1,"\\(\\)$")){print "Should be func eg intf.M1()" return } XO = new vitem($s1,0) printlist.append(XO) return XO } //* misc and commentary // con=absolute convergence number, div=absolute div number // con = %con * pre // div * pre = con * post = S (total synapses) // %div = div/post = S/(pre*post) = con/pre = %con // div = %con * post // maxdiv = int((1 + var) * div) //** vari returns randomly chosen $1+/-$2, $2 is a percent func frani () { return int(rdm.uniform($1,$2+1)) } func uvari () { return $1 - $1*$2 + (rdm.uniform(0,1) * 2 * $1*$2) } func gvari () { return $1 - (rdm.normal(0,1) * $1*$2) } //** clearsyns() proc clearsyns () { for ltr(XO,ncl) XO.active(0) ncl.remove_all for ltr(XO,new List("NetCon")) printf("**** CLEARSYN WARNING %s STILL EXISTS ****\n",XO) } // findstr() look thru list for a string and return the index func findstr () { local flag flag = -1 // failure for ltr(XO,$o2) { if (strcmp($s1,XO.s) == 0) flag=i1 } return flag } //** syntyp() reads syntyps out of cp directory proc syntyp () { local x x=$1 if (x==EX) {$o2.x=AM $o2.x[1]=NM // excit } else if (x==IX) {$o2.x=GA $o2.x[1]=GB // inhib } else $o2.x[1]=-1 } //** excitp(PRE) -> T if cell is excitatory func excitp () { if ($1==SU || $1==DP || $1==TC) return 1 if ($1==RE || $1==IN) return 0 printf("ID not classified in excitp\n") return -1 } //* Saving and reading //** svnet() rdnet() proc svnet () { local ii ii=0 if (numarg()==1) filename=$s1 else { sprint(filename,"data/%s%c.net",datestr,97+ii) while (tmpfile.ropen(filename)) sprint(filename,"data/%s%c.net",datestr,97+ii+=1) printf("nqsnet output to %s\n",filename) } XO=usefiles("nqs.hoc","syncode.hoc","nqsnet.hoc","labels.hoc") cp.comment=XO.s sp.comment=XO.s cp.sv(filename) sp.sv(filename,1) tmpfile.close() } proc rdnet () { filename=$s1 if (!isobj(cp,"NQS")) {cp=new NQS() sp=new NQS()} printf("reading network file %s\n",filename) cp.rd(filename) sp.rd() // continue reading tmpfile.close() } //** svstate() rdstate() rerun() proc svstate () { if (! isobj(svs,"SaveState")) svs=new SaveState() svs.save tmpfile.wopen($s1) svs.fwrite(tmpfile) } proc rdstate () { if (! isobj(svs,"SaveState")) svs=new SaveState() tmpfile.ropen($s1) svs.fread(tmpfile) svs.restore } proc initrr () { printf("WARNING: initrr() -- init for rerun() -- not defined\n") } proc rerun () { local tstp,told tstp=tstop if (numarg()>0) rdstate($s1) else svs.restore if (numarg()==1) if (argtype(1)==0) tstp=$1 if (numarg()>1) tstp=$2 told=t initrr() if (t!=told) { printf("ERROR: initrr() appears to have reset t (finitialize()?) (%d->%d)\n",told,t) return } sprint(tstr,"cvode.solve(%g)",t+tstp) time(tstr) finish() } // mkvspks(NUMCELLS,NUMGROUPS,INVL1,SPREAD,[APPEND]) // produces ivspks index vector and vspks time vector for inserting activations // groups are not stable -- they are reconstituted at each spiking time // NUMCELLS indices will be drawn from 0..NUMCELLS-1 // NUMGROUPS will give the separate groupings for simultaneous activation across a group // there will be NUMCELLS/NUMGROUPS cells in each group // INVL1 is the average interval in ms between the inputs // SPREAD is the +/- SPREAD/2 sloppiness in this interval // APPEND is a flag saying to add on to existing ivspks/vspks vectors proc mkvspks () { local gcnt,numc,numg,inv1,inv2,a,ii,j,apflg localobj iv,tv numc=$1 numg=$2 inv1=$3 inv2=$4 apflg=0 if (numarg()>=5) if ($5) apflg=1 // 5th arg is append flag if (!apflg) revec(ivspks,vspks) gcnt = int(numc/numg) // number of cells in each group a=allocvecs(iv,tv) for ({ii=20 j=0};ii=1-1e-8) printf("mkvspks ERR: j>=1\n") // should never happen } ivspks.sortindex(iv) tv.index(vspks,iv) vspks.copy(tv) tv.index(ivspks,iv) ivspks.copy(tv) ivspks.rnd() wvspks.resize(ivspks.size) dealloc(a) } obfunc netconlist () { if (numarg()==1) { if (argtype(1)==1) return cvode.netconlist("","",$o1) if (argtype(1)==2) return cvode.netconlist("",$s2,"") } return cvode.netconlist("","","") } //* mkncq() -- this may not be useful since will slow down smap() still more proc smap () { } // stub proc mkncq () { local pr,po,sy,co localobj o if (!isassigned(ncq)) { ncq=new NQS("PRID","POID","SYN","INCOL","SCALE","NCL") ncq.odec("NCL") ncq.useslist("PRID",CTYP) ncq.useslist("POID",CTYP) ncq.useslist("SYN",STYP) ncq.useslist("INCOL",INCOL) } ncq.clear() sp.out.mo(1) // for smap // no syn specificity for ARTCELLs -- assume no NM w/out AM, no GB w/out GA for case(&pr,DP,SU,IN) for case(&po,DP,SU,IN) for case(&co,INC,RIT,LFT) { if (sp.select("CODE",EQU1,pr,"CODE",EQU2,po,"CODE",EQU3,co) == 0) { // printf("%s->%s (%s) EMPTY\n",CTYP.o(pr).s,CTYP.o(po).s,INCOL.o(co).s) } else { if (pr==IN) sy=GA else sy=AM o=ncl[pr][po][co] ncq.append(pr,po,sy ,co,1,o) // AM,GA ncq.append(pr,po,sy+1,co,1,o) // NM,GB smap(pr,po,sy,co,o) } } } proc smap () { local prdx,w0x,w1x,pr,po,sy,co localobj o pr=$1 po=$2 sy=$3 co=$4 o=$o5 for ii=0,PRv.size-1 { // need prior sp.out.mo(1) w0x=WT0v.x[ii] w1x=WT1v.x[ii] nc=new NetCon(ce.o(PRv.x[ii]),ce.o(POv.x[ii]),-10,DELv.x[ii],0) o.append(nc) for kk=0,nc.wcnt-1 nc.weight[kk]=0 if (pr==IN) { nc.weight[GA]=w0x if (w1x>0) nc.weight[GB]=w1x } else { nc.weight[AM]=w0x if (w1x>0) nc.weight[NM]=w1x } } } proc smap () { printf("NOW using dedicated smap() routines in network.hoc") } //* nrstim - stim cells with noise/random input // nrstim(celltype,[,maxt,clear,seed,nqs]) // maxt specifies time after which input turned off // clear specifies whether to clear nqs passed in (or vq if declared) // global params are pvar,pwght,prate,ppos described below {declare("pvar",2)} //variance of noise input {declare("pwght",0)} //mean value of noise input {declare("prate",1000)} //sampling rate for random input {declare("ppos",1)} //use abs value only -- should be 1 otherwise intf cant handle it!!! func nrstim () { local a,tt,i,j,ti,maxt,ct localobj rdp,vr,vt,vi,nq rdp=new Random() nq=nil a=allocvecs(vr,vt,vi) if(numarg()>1) maxt=$2 else maxt=tstop if(numarg()>4) nq=$o5 else if(name_declared("vq")) nq=vq if(nq==nil) { printf("nrstim ERRA: input nq==nil!\n") dealloc(a) return 0 } if(numarg()>2) { if($3) nq.clear() } else nq.clear() if(numarg()>3) rdp.ACG($4) else rdp.ACG(1234) rdp.normal(pwght,pvar) vt.indgen(0,maxt,1000/prate) vi.resize(vt.size) vr.resize(vt.size) for i=ix[$1],ixe[$1] { vr.setrand(rdp) if(ppos) vr.abs() vi.fill(i) nq.v[0].append(vi) nq.v[1].append(vt) nq.v[2].append(vr) } nq.sort("time") nq.sort("ind") intf.initvspks(nq.v,nq.v[1],nq.v[2]) dealloc(a) return 1 } //* subthstim(celltype,% of type,start,end,multiplier,bias,[nqs -- default is vq]) //this function takes the stim nqs , selects random % of cells (0-100), and between //start and end times multiplies the stim values by multiplier and adds bias //if the 7th argument is absent, the vq NQS should be declared, non-nil //& should have been initialized with nrstim or setnrstim func subthstim () { local startt,endt,fctr,ct,prc,bias,idx,a localobj vid,nq ct=$1 prc=$2 startt=$3 endt=$4 fctr=$5 bias=$6 a=allocvecs(vid) nq=nil if(numarg()>6) nq=$o7 else if(name_declared("vq")) nq=vq if(nq==nil) { printf("subthstim ERRA: input nq is nil!!\n") dealloc(a) return 0 } vid.resize(numc[ct]) vid.fill(0) vid.fill(1,0,int(numc[ct]*prc/100)) vid.shuffle() idx=nq.select(-1,"ind","[]",ix[ct],ixe[ct],"time","[]",startt,endt) printf("ni=%d\n",idx) for vtr(&idx,nq.ind) if(nq.v[2].x(idx)>0 && vid.x(nq.v[0].x(idx)-ix[ct])>0) { nq.v[2].x(idx) = nq.v[2].x(idx)*fctr+bias } dealloc(a) return 1 }