//* $Id: grvec.hoc,v 1.672 2011/10/25 16:16:14 billl Exp $ //* Objects argtype: 0:double; 1:obj; 2:str; 3:double pointer objref g[100],printlist,grv_,panobj,panobjl strdef symb symb = "O" load_file("nqs.hoc") // declare vectors gnum=-1 declare("show_panel",1) obfunc file_with_dot(){} // stubs to declare later, otherwise external barfs obfunc filname(){} obfunc dirname(){} func file_len(){} proc tog (){if (numarg()==1) print $&1=1-$&1 else print gvmarkflag=1-gvmarkflag} proc pvout2 () { } // stub for manipulating printlist proc rv2 () { } // stub for manipulating the vectors before graphing proc rv3 () { } // stub for manipulating the label func setfilt2 () { return 0 } // stub for setting filter func dir2mf2() {return 1} // stub for checking whether to include a trace //* template vfile_line (vector file line) template gives information about a line // in a file that gives a vector: name, size and location begintemplate vfile_line public name, size, loc, segs, num, ix, f, ty strdef name,f double loc[1] proc init () { segs=1 ty=4 if (argtype(5)==0) segs=$5 else if (argtype(5)==2) f=$s5 name=$s1 size=$2 num=$4 double loc[segs] loc[0] = $3 ix=-1 // can be used as index if needed } endtemplate vfile_line //* template vitem (vector item) is an internal vector used to store output from // new vitem(var_name,vec_size,friendly_name) // new vitem(var_name,vec_size,1) -- force tvec creation even if not cvode_local // a simulation holds the name and the vector itself tvflag_on=1 begintemplate vitem external cvode,tvflag_on,isassigned public tvec,vec,name,tvflag,pstep,o,code,resize objref tvec,vec,o,this // o not set here but used for Acells strdef tstr,name // variable name proc init () { name=$s1 tvflag=0 pstep=0 code=0 if (cvode.active()) { if (cvode.use_local_dt()) tvflag=1 else tvflag=-1 } if (tvflag_on) tvflag=1 if (argtype(2)==0) vec=new Vector($2) else if (argtype(2)==1) vec=$o2 if (argtype(3)==0) { // very sloppy -- what if pstep=1?? if ($3==1) tvflag=1 else {tvflag=0 pstep=$3} } else if (argtype(3)==1) { tvec=$o3 tvflag=1 // don't create another one } if (argtype(4)==0) if ($4==1) tvflag=1 else {tvflag=0 pstep=$4} if (tvflag==1 && !isassigned(tvec)) tvec=new Vector($2) if (tvflag==-1) { sprint(tstr,"if (!isassigned(tvec)) tvec=new Vector(%d)",$2) execute(tstr) sprint(tstr,"%s.tvec=tvec",this) execute(tstr) } } proc resize () { vec.resize($1) if (isassigned(tvec)) tvec.resize($1) if (numarg()==2) { vec.resize($2) // typically sizeup and then resize to 0 if (isassigned(tvec)) tvec.resize($2) } } endtemplate vitem //* main template: GRV // the attributes of a particular set of graphs including line colors, // world coordinates, etc // glist is a list of all graphs created from this panel // llist is a list of available names and associated vectors or locations begintemplate GRV public color,line,super,curcol,comment,vecpanel,mesg,tmplist,gxpan public glist,oglist,llist,tvec,size,shift,vsz,vjmp,tloc,vloc,remote public entries,segments,clear,keepgr public read_vfile,rvaltdisp,read_file,grvec,remgrs,clear,record,read_pclamp public cpplitem,chgplname,npl,new_pri,prlexp,numovecs,fchooser public read_vdotfile,rpanel,panobjl,ddir,filter public rlist,rvlist,attrpanl,wvpanl,remgrs,collapsegrs,viewplot,nvwall public geall,lblall,relbl,grall,grsel,tposvec,fliptb,setrange,setgrransel,grransel public chrange,rv,rv_readvec,rvec,rvl,read_rfile,gv public grrtsize,ge,pvall,pvother,pvplist,pvclose,vf2fwf public pvnext,pvout,prvec,pv,lpvec,nvplt,apbrowse,apkill public newpl,find_secname,mkmenu,dir2pr,dir2mf,read_mf public mkpanel,pbrgr,remprl,filename,onum,po,stub,go public rvtr,vrdr,prdr,tmpobj,printlist,output_file,attr0,attrnum,s,vite public glist,llist,tvec,ind,vec,vrtmp,tmpvec,tf1,tmpobj,apvb,printStep public gvmarkflag,gveraseflag,fchooser_flag,byte_store,bst,szstr,regexp,tmpfile public magga,mvga,ll,labelm,tstr double size[4],vsz[2],wvloc[4],x[4] objref glist, oglist, llist, tvec, ind, vec, vrtmp, tmpvec, tf1, tmpobj, apvb, ovb, printlist objref vite,scob,printlist,szstr[4],g,this,tmplist,panobj,panobjl,Xo,Yo,tmpfile, gcomms strdef comment,recstr,grvecstr,readtag,rvvec_name,grep,tstr,tstr2,ddir,filter strdef temp_string_,temp_string2_,output_file,s,filename,mesg,regexp external sfunc,osname,vfile_line,vitem,uname,nil,simname,gnum,XO,YO,graphList,isassigned external isobj,isit,mso,msoptr,allocvecs,dealloc,tstop,method,cvode,show_panel,rv2,rv3,setfilt2 external cvode_active,cvode_local,datestr,runnum,i1,graphItem,GRV,strm,objnum,DBL,dir2mf2 external file_with_dot,count_substr,file_len,filname,dirname,dir,grv_,repl_mstr,pvout2,symb // list iterator ltr // usage 'for ltr(YO, tmplist) { print YO }' iterator ltr () { local i ii1=0 for i = 0,$o2.count-1 { $o1 = $o2.object(i) iterator_statement ii1+=1 } $o1=nil } proc init () { local flag,nopan flag=1e9 if (numarg()==1) if (argtype(1)==0) flag=$1 if (numarg()==2) if (argtype(2)==0) flag=$2 else printf("2nd arg for GRV should be flag\n") nopan=0 color=1 line=1 curcol=1 keepgr=tloc=-1 nvec=bvec=super=0 vjmp=50 entries=1 segments=1 fchooser_flag=0 vsz[0] = 300 vsz[1] = 200 glist = new List() tmpfile = new File() oglist = glist // save old glist for after superimpose llist=new List() gcomms=new List() printlist=llist tvec=new Vector(0) ind=tvec.c vec=tvec.c vrtmp=tvec.c tmpvec=tvec.c rvvec_name = "vec" ddir = "data/" printStep=gvmarkflag=gveraseflag=mff=0 remote=0 entries=segments=shift=0 tloc=vloc=vjmp=x=y=luprd=0 wvloc[0]=50 wvloc[1]=50 wvloc[2]=800 wvloc[3]=150 onum=objnum(this) for ii=0,3 { szstr[ii] = new String() } if (sfunc.substr(osname,"inux")==1) grep="grep -a" else grep="grep" readtag = "^//[:pbCM ]" // regexp used to identify header in mixed binary files { szstr[0].s="Set xmin" szstr[1].s="Set xmax" szstr[2].s="Set ymin" szstr[3].s="Set ymax" } multi_files = 1 // set 0 to show individual segments of multi-seg files dec_runnum = 0 // whether to decrement runnum when saving a new file byte_store = 4 // store as ascii (0), byte (1), int (2), float (3), double (4) tvec_bytesize = 4 // always store tvecs with more precision outvecint = 0 // dump vectors every outvecint time if not 0 outvect = 0 // time for next vec dump labelm = 1 // set to 0 to turn off labeling attr0=0 // default is a panel for reading files if (flag==0) { // make a sim-recording panel if (numarg()>1) printf("GRV WARNING: creating simpan, ignoring filename\n") attr0=1 attrnum=0 if (! isobj(panobjl,"List")) panobjl = new List() attrnum=panobjl.append(this)-1 if (attrnum!=0) printf("GRV WARNING: attr0 with attrnum=%d!\n",attrnum) if (show_panel) vecpanel() sprint(tstr,"printlist=%s.printlist",this) execute(tstr) sprint(s,"GRV[%d]:%s (sim vecs)",objnum(this),simname) return } panobjl=grv_.panobjl attrnum=panobjl.append(this)-1 if (flag==-2) nopan=1 if (flag==-1) { fchooser() // ask user for filename } else if (numarg()>=1) { if (argtype(1)==2) read_vfile($s1) } if (!nopan) attrpanl() } //** newfile() calls fchooser proc newfile () { localobj o o = apvb fchooser() attrpanl() } //** bst() selects byte_store func bst () { if (numarg()>=1) byte_store=$1 if (numarg()>=2) tvec_bytesize=$2 return byte_store } //* attrpanl() gives attributes for a set of graphs proc attrpanl () { local ii,jj sfunc.tail(filename,"data.*/",grvecstr) apvb=new VBox() apvb.intercept(1) xpanel(temp_string_) xvarlabel(filename) if (sfunc.len(mesg)>40) sfunc.left(mesg,40) xvarlabel(mesg) xvalue("Color(-1=multi)","color",1,"if (color==0) curcol=0",0,1) xvalue("Line","line",1,"",0,1) xpanel() xpanel("",1) xbutton("Superimpose: ","tog(&super) if (super==0) gnum=-1 sprint(mesg,\"super=%d\",super)") xbutton("Where?","sprimp()") xbutton("Restore","glist=oglist sprint(mesg,\"Restore graph list\")") xpanel() xpanel("",1) xbutton("Limits","wvpanl()") xbutton("Erase","geall()") xbutton("Mark","togmark()") if (attr0) xbutton("Panel","pbrgr(\"Graph\",\"gv\")") else { xbutton("New file","newfile()") } xpanel() xpanel("",1) xmenu("Graphs") xbutton("Erase/redraw","gveraseflag=-(gveraseflag-1) if (gveraseflag==1) super=1 else super=0 sprint(mesg,\"Erase=%d\",gveraseflag)") xbutton("Erase graphs","geall()") xbutton("Remove graphs","remgrs()") xbutton("Clean graph list","collapsegrs()") xbutton("Erase axes","setrange(3)") xbutton("Draw axes","setrange(0)") xbutton("Label graphs","lblall()") sprint(tstr,"execute(\"disptray(%d)\")",onum) xbutton("Make tray",tstr) xbutton("View = plot","for ltr(Xo,glist) Xo.exec_menu(\"View = plot\")") xbutton("Crosshair","for ltr(Xo,glist) Xo.exec_menu(\"Crosshair\")") xbutton("New view","for ltr(Xo,glist) Xo.exec_menu(\"NewView\")") xbutton("Zoom","for ltr(Xo,glist) Xo.exec_menu(\"Zoom in/out\")") xbutton("Delete Text","for ltr(Xo,glist) Xo.exec_menu(\"Delete\")") xbutton("Move Text","for ltr(Xo,glist) Xo.exec_menu(\"Move Text\")") xbutton("Change Text","for ltr(Xo,glist) Xo.exec_menu(\"Change Text\")") xmenu() // sprint(temp_string_,"remote",attrnum) // sprint(temp_string2_,"grall(%d)",attrnum) // xvalue("Graph all",temp_string_,0,temp_string2_) if (attr0) redo_printlist() else xbutton("Show full panel","rpanel()") xpanel() apvb.intercept(0) if (attr0) { sprint(s,"GRV[%d] %s SIM CONTROL",objnum(this),simname) } else { if (sfunc.len(filename)>0) filname(filename,grvecstr) sprint(s,"GRV[%d] %s:%s",objnum(this),simname,grvecstr) } apvb.map(s) } //** sprimp() superimpose on another sim proc sprimp () { super=1 sprint(tstr,"SUPERIMPOSE %s ON?",s) ovb=new VBox() ovb.intercept(1) xpanel(tstr) xvalue("Superimpose on Graph[#]","gnum",1) for ltr(Xo,panobjl) { sprint(temp_string2_,"glist=%s.glist sprint(mesg,\"Using graph list from %s\") ovb.unmap() ovb=nil",Xo,Xo) xbutton(Xo.s,temp_string2_) } xpanel() ovb.intercept(0) ovb.map(tstr) ovb.dismiss_action("ovb.unmap ovb=nil") } //** fchooser() finds file and then create panel from it using rpanel proc fchooser () { if (fchooser_flag == 0) { // create panel first time only if (setfilt2(filter)) { // do nothing } else if (strm(filter,"\\*")) { // do nothing } else sprint(filter,"*%s*",datestr) tmpfile.chooser("","Read from a file",filter,"Open","Cancel",ddir) } fchooser_flag = 1 if (tmpfile.chooser()) { // find out whether this is a vector file or not tmpfile.getname(filename) if (strm(filename,"\.mf")) read_mf() else read_vfile() } } //** newpan() create a new panel and call fchooser from there proc newpan () { tmpobj=new GRV(-1) } //** read_vfile() creates a panattr object from information in a file // (uses grep to avoid loading big file) // assumes file in tmpfile func read_vfile () { local flag, ii, sz, loc, mult, sze, cloc, segs if (numarg()>=2) if (strcmp(filename,$s1)==0) return 2 // check if file is already active if (attr0) { if (!boolean_dialog("Look at file data instead of sim?","YES","NO")) { printf("Read file cancelled\n") return 0 } } else { attr0=0 } if (numarg()>=1) filename=$s1 else tmpfile.getname(filename) if (strm(filename,"\.mf$")) return read_mf(filename) sprint(s,"GRV[%d] %s: %s",objnum(this),simname,filename) clear() // grab hold of the different lines using grep file_with_dot(filename,temp_string_) // put .filename into temp_string_ if (!tmpfile.ropen(temp_string_)) { print "E1: Can't open ",temp_string_ // avoid grep error return 0 } else flag = 1 // signifies that .file exists to use as key while ((numr = tmpfile.gets(tstr)) != -1) { // throw out the leading '//' // read the line if (sfunc.head(tstr,"//[^b]",temp_string2_)==0) { read_vinfo() // a line giving info about the file (eg comment) } else { // NB: code in v60:516 to pickup byte_store value if (flag && entries > 1) { // a .file with MULTI segs tmpfile.seek(-numr,1) // backup to beginning of line read_vdotfile() } else if (segments > 1) { // mult segs: different times for same var tmpfile.seek(-numr,1) // backup to beginning of line segments = read_vsegs() //**** NEEDS to be recovered from grvec.hoc442 } else { // read each line in for itself if ( sscanf(tstr,"//b%1ld %g %s %ld %ld",&bvec,&nvec,tstr2,&sze,&loc)!=5) { if (sscanf(tstr,"//b%1ld %s %ld %ld",&bvec,tstr2,&sze,&loc)!=4) { printf("**** GRV read_vfile() parse ERR on %s in %s",tstr,filename) } else if (printStep==-2) nvec=-2 else nvec=-1 // guess } if (nvec==2) { printf("read_vfile forward compat. **** WARNING ****\n\t****consider edit of %s dot file to change 2 to -2\n",filename) nvec=-2 } if (strcmp(tstr2,"CVODE1.0 tvec")==0) { tvec.resize(0) printStep=-1 tloc = loc // where to find tvec later } else { tmpobj = new vfile_line(tstr2,sze,loc,nvec) // name size loc num tmpobj.ty=bvec llist.append(tmpobj) tmpobj = nil } } } } if (llist.count==0) { printf("grvec.hoc::read_vfile ERR no vecs read from %s\n",filename)} if (entries==1) entries = llist.count if (! flag && segments>1) write_vsegs() // create key .file if (! tmpfile.ropen(filename)) { print "E3: Can't open ",filename return 0 } if (printStep==-1) rtvec() // code for cvode_active() mff=0 return 1 } //** rtvec() reads tvec if it exists, returns -1 if it doesn't func rtvec () { if (tloc > -1) { tmpfile.seek(tloc) tvec.vread(tmpfile) return 1 } else { return 0 } } proc write_vsegs () { print "NEEDS to be ported from grvec.hoc442" } //** read_vinfo() proc read_vinfo () { if (strm(tstr,"//printStep")) { sfunc.tail(tstr," ",tstr) // just take end of string following space sscanf(tstr,"%g",&printStep) // printstep==-1 means cvode } else if (strm(tstr,"^//:")) { // a comment sfunc.tail(tstr,"//: *",tstr) sfunc.head(tstr,"\n",comment) // chop final newline mesg=comment } else if (strm(tstr,"^//CPU")) { // the machine type for byte storage sfunc.tail(tstr," ",tstr) if (! strm(tstr,uname)) { printf("%s written from %s\n",filename,tstr) } } else if (strm(tstr,"^//MULTI")) { // multiple lines for each entry sfunc.tail(tstr," ",tstr) if (sscanf(tstr,"%d %d",&entries,&segments)==2) { if (! multi_files) printf("**************** GRV read_vinfo ERRa\n") } else segments=1 } else { printf("Line:\t%s\n\tnot recognized in %s\n",tstr,filename) } } //** read_vdotfile() read .file in abbreviated format (see write_vsegs) proc read_vdotfile() { local loc,entries,segments,ii entries=entries segments=segments for i=1,entries { // read this abbreviated file version (much faster) tmpfile.scanstr(temp_string_) loc = tmpfile.scanvar() tmpobj = new vfile_line(temp_string_,-1,loc,segments) // don't set size llist.append(tmpobj) for ii=1,segments-1 { tmpobj.loc[ii] = tmpfile.scanvar() } } } //** rpanel() creates a panel from information in llist proc rpanel () { local ii if (llist.count > 8) { rlist() return } sprint(temp_string_,"%s ",simname) xpanel(temp_string_) xlabel(filename) for ii=0,llist.count-1 { sprint(temp_string2_,"rv(%d)",ii) xbutton(llist.object(ii).name,temp_string2_) } xbutton("Attributes","attrpanl()") sprint(temp_string_,"lpvec(filename,vrtmp,%g)",printStep) xbutton("Print last vec",temp_string_) xbutton("Erase","ge()") xpanel() } //** rlist(): like rpanel() but puts up a browser list instead of a panel proc rlist () { sprint(tstr,"%d items on list: Enter regexp for subset or \"All\"",llist.count) if (llist.count>50 || numarg()>=1) { if (numarg()>=1) regexp=$s1 else if (!string_dialog(tstr,regexp)) return if (! strm(regexp,"[Aa][Ll][Ll]")) { if (! isobj(tmplist,"List")) tmplist = new List() tmplist.remove_all for ltr(Xo,llist) { Xo.ix=ii1 if (strm(Xo.name,regexp)) tmplist.append(Xo) } tmplist.browser(filename,"name") tmplist.accept_action("rv(tmplist.object(hoc_ac_).ix)") printf("%d selected\n",tmplist.count) return } } llist.browser(filename,"name") llist.accept_action("rv(hoc_ac_)") } //** rvlist(): like rpanel() but puts up a browser list instead of a panel proc rvlist () { local flag,rdstr rdstr = 1 flag = $1 if (numarg()==2) { recstr=$s2 rdstr=0 } if (flag==0) { llist.browser(filename,"name") llist.accept_action("rvec(hoc_ac_)") } else if (flag==1) { // proc(vec) if (rdstr) string_dialog("Procedure name: proc, called as proc(vec)",recstr) llist.browser(recstr,"name") sprint(temp_string_,"rv_readvec(hoc_ac_,%s) execute1(\"%s(%s)\")",rvvec_name,recstr,rvvec_name) llist.accept_action(temp_string_) print ":",recstr,":",temp_string_,":",rvvec_name } else if (flag==2) { // vec.command if (rdstr) string_dialog("comm: print vec.comm",recstr) llist.browser(recstr,"name") sprint(temp_string_,"{rvec(hoc_ac_) print %s.%s}",rvvec_name,recstr) llist.accept_action(temp_string_) } } //* rv() reads line of vector file into IV graph via vector // rv(llist_ind1[,llist_ind2]) // rvaltdisp(tvec,vec,name) func rvaltdisp () { return 0 } // if returns 1 means there is an alternate display for rv obfunc rv () { local inx,inx2 localobj o // open the file and go to correct position if (numarg() == 0) { print "rv(ind1,ind2) reads into vrtmp bzw vec" return this} inx = $1 if (attr0) {return gv(inx)} o=llist.object(inx) if (numarg()>1) inx2 = $2 else inx2 = -1 // to graph one vec against another rv_readvec(inx,vrtmp) rv2(vrtmp,tvec) // create a new plot if necessary and set color if (vrtmp.size==0) { // assume this is a spike train in tvec nvplt(ind,vrtmp) ind.resize(tvec.size) ind.fill(0) ind.mark(graphItem,tvec,symb,line,curcol) } else if (inx2>-1) { // only make sense if they share the same tvec rv_readvec(inx2,vec) nvplt(vec,vrtmp) if (numarg() >= 3) { vec.mark(graphItem,vrtmp,$s3,line,curcol) } else { vec.mark(graphItem,vrtmp,symb,line,curcol) } } else if (o.num==-2) { nvplt(vrtmp,tvec) if (gvmarkflag) { if (! rvaltdisp(tvec,vrtmp,llist.object(inx).name)) { vrtmp.mark(graphItem,tvec,symb,line,curcol,4) } } else vrtmp.line(graphItem,tvec,curcol,line) } else if (o.num==-1) { printf("rv() PROBLEM: CVODE global read not implemented\n") } else { if (o.num==0) { printf("rv WARNING: taking printstep %g for %s\n",printStep,o.name) o.num=printStep } nvplt(vrtmp,o.num) if (gvmarkflag) { vrtmp.mark(graphItem,o.num,symb,line,curcol,4) } else vrtmp.line(graphItem,o.num,curcol,line) } // too much fussing with labels if (sfunc.substr(filename,"batch")!=-1 || \ sfunc.substr(filename,"data")==-1) { grvecstr = filename } else sfunc.tail(filename,"data",grvecstr) if (sfunc.len(llist.object(inx).name)>40) { grvecstr=llist.object(inx).name } else { sprint(grvecstr,"%s:%s",grvecstr,llist.object(inx).name) } rv3(grvecstr) if (super == 0 && labelm) { graphItem.label(0,0.9,grvecstr) } else if (labelm) graphItem.label(0.0,0.95,grvecstr) return graphItem } //* gv(vnum) graphs vector obfunc gv () { local a,inx,lin localobj o,v1,vtmp inx=-1 lin=line a=allocvecs(vtmp) if (numarg()==0) { inx = hoc_ac_ } else { if (argtype(1)==0) inx = $1 if (argtype(1)==2) { for ltr(Xo,printlist) if (strm(Xo.name,$s1)) inx=ii1 if (inx==-1) {print $s1," not found" return this}} } if (numarg()>=2) { color=curcol=$2 } if (numarg()>=3) { lin=$3 } o = printlist.object(inx) vtmp.copy(o.vec) rv2(o.vec) // alters vtmp if (o.vec.size==0) { // assume that this is spk trace if (o.tvec.size==0) { printf("\tNO SPIKES IN %s\n",printlist.object(inx).name) } else { nvplt(o.tvec) ind.resize(o.tvec.size) ind.fill(1) ind.mark(graphItem,o.tvec,symb,lin,curcol) } } else { if (o.tvflag!=0) { // o.tvec should point to tvec if tvflag==-1 nvplt(o.vec,o.tvec) if (gvmarkflag) { o.vec.mark(graphItem,o.tvec,symb,lin,curcol) } else { o.vec.line(graphItem,o.tvec,curcol,lin) } } else { if (o.pstep==0) { printf("gv WARNING: vitem.pstep not set with tvflag==0 (%s)\n",o) o.pstep=printStep } nvplt(o.vec,o.pstep) if (gvmarkflag) { o.vec.mark(graphItem,o.pstep,symb,lin,curcol) } else { o.vec.line(graphItem,o.pstep,curcol,lin) } } if (labelm) { grvecstr=printlist.object(inx).name rv3(grvecstr) graphItem.label(0.,0.9,grvecstr) } } o.vec.copy(vtmp) // in case has been changed by rv2() dealloc(a) return graphItem } // go(n) will goto location in the data file obfunc go () { localobj o if (argtype(1)==0) { inx=$1 o=llist.object(inx) } else o=$o1 tmpfile.seek(o.loc) return o } // rv_readvec(index,vec) // read vector #index from file into vector vec func rv_readvec () { local inx,ii,n,bvec localobj o if (argtype(1)==0) { inx=$1 o=llist.object(inx) } else o=$o1 n=o.num if (mff) {tstr=filename filename=o.f} tmpfile.getname(temp_string_) // may not be necessary? if (strcmp(temp_string_,filename)!=0 || tmpfile.isopen()==0) { // don't reopen file if there if (! tmpfile.ropen(filename)) { print "ERROR rv() can't read ",filename return 0 } } tmpfile.seek(o.loc) bvec=o.ty if (numarg()>=3) { if (n!=-2) { printf("ERROR rv() called with 2 vecs but only find 1 in %s %s %d\n",filename,o.name,inx) return 0 } if (bvec>5) { $o2.fread(tmpfile,o.size,bvec-5) $o3.fread(tmpfile,o.size,bvec-5) } else { $o2.vread(tmpfile) $o3.vread(tmpfile) } } else if (n==-2) { if (n==-2) { if (bvec>5) { tvec.fread(tmpfile,o.size,bvec-5) // no error check } else if (!tvec.vread(tmpfile)) { printf("rv_readvec tvec READ failure in %s %s %d\n",filename,o.name,inx) return 0 } if (bvec>5) { $o2.fread(tmpfile,o.size,bvec-5) // no error check } else if (! $o2.vread(tmpfile)) { printf("rv_readvec vec READ failure in %s %s %d\n",filename,o.name,inx) return 0 } } if (n==-2 && (tvec.size != $o2.size)) { printf("rv_readvec size mismatch in %s %s %d\n",filename,o.name,inx) return 0 } } else $o2.vread(tmpfile) // fixed dt if (segments>1) { // needs rewrite tmpvec = new Vector($o2.size) for ii=1,segments-1 { tmpfile.seek(llist.object(inx).loc[ii]) tmpvec.vread(tmpfile) $o2.copy(tmpvec,$o2.size) } tmpvec = nil } if (mff) filename=tstr // restore return n } //** vf2fwf() take a file in vformat and prints out as multiple fwrites proc vf2fwf () { local ii localobj f f=new File() f.wopen($s1) for ii=0,entries-1 { rv_readvec(ii,vrtmp) vrtmp.fwrite(f) printf("%d ",vrtmp.size) } f.close printf("\n dt=%g\n",printStep) } //** rvec(num[,vec]) writes to vec, or contents of rvvec_name or // to vector of same name if rvvec_name is empty proc rvec () { local flag,on flag=0 if (sfunc.len(rvvec_name)==0) flag=1 if (numarg()<1) on=hoc_ac_ else on=$1 if (numarg()>1) sprint(rvvec_name,"%s",$o2) if (sfunc.len(rvvec_name)==0) rvvec_name=llist.object(on).name printf("Copying %s to %s\n",llist.object(on).name,rvvec_name) sprint(temp_string_,"%s.rv_readvec(%d,%s)",this,on,rvvec_name) if (flag) rvvec_name="" // clear it again if (! execute1(temp_string_)) print "ERROR: Declare target as a vector" if (numarg()==4) $o4.copy(tvec) } //** rvl() reads line of vector file into IV graph via vector // rvl(name,pos[,pos2,pos3,etc]) proc rvl () { local i // open the file and go to correct position tmpfile.getname(temp_string_) if (strcmp(temp_string_,filename)!=0 || tmpfile.isopen()==0) { tmpfile.ropen(filename) } // only open if necessary if (tmpfile.isopen==0) { printf("ERROR: %s not found.\n",filename) return } if (numarg() == 3) { tmpfile.seek($3) tmpfile.gets(temp_string_) // throw away line vrtmp.vread(tmpfile) } else { tmpvec = new Vector() for i=3,numarg() { tmpfile.seek($i) tmpvec.vread(tmpfile) vrtmp.copy(tmpvec,vrtmp.size) } } tmpvec = nil nvplt(vrtmp) vrtmp.line(graphItem,printStep,curcol,line) // graph it and label the graph if (sfunc.substr(filename,"batch")!=-1) { grvecstr = filename } else { sfunc.tail(filename,"data",grvecstr) } sprint(grvecstr,"%s:%s",grvecstr,$s2) if (super==0 && labelm) { graphItem.label(0,0.9,grvecstr) } else if (labelm) graphItem.label(grvecstr) } //* utility programs (not all used or even all usable) //** nvplt() put up new voltage plot obfunc nvplt () { local xs,ys,flag,prstep prstep=10 if (super == 0) flag=1 else { if (gnum>-1) { sprint(tstr,"{Graph[%d]}",gnum) if (execute1(tstr,0)) { // Graph[gnum] exists if (Graph[gnum].view_count>0) { graphItem=Graph[gnum] flag=0 } } } else if (isobj(graphItem,"Graph")) if (graphItem.view_count() > 0) { flag=0 } else { flag=1 } // else need new graph } if (flag) { if (numarg()==2) if (argtype(2)==0) prstep=$2 else prstep=-1 if (size[1] != 0) { // xmax is set newpl(size[0],size[1],size[2],size[3]) } else if (prstep<0) { newpl(0,$o2.max,$o1.min,$o1.max) } else { newpl(0,$o1.size()*prstep,$o1.min,$o1.max) } } else if (gveraseflag) graphItem.erase_all if (color == -1) { curcol += 1 if (curcol == 0 || curcol>7) curcol = 1 } else curcol = color graphItem.color(curcol) g=graphItem return g } //** grrtsize() use view=plot and then pad a little proc grrtsize () { local h,w,frac if (numarg()>=1) tmpobj=$o1 else tmpobj=graphItem if (numarg()>=2) frac = $2 else frac=.05 tmpobj.exec_menu("View = plot") tmpobj.size(&x) w=frac*(x[1]-x[0]) h=frac*(x[3]-x[2]) x[0]-=2*w x[1]+=w x[2]-=4*h x[3]+=h // need extra padding on bottom tmpobj.size(x[0],x[1],x[2],x[3]) } //** newpl() proc newpl () { local w,h if (numarg()==5) newPlot($1,$2,$3,$4) // 5th arg is flag if (numarg()==8) {wvloc[0]=$5 wvloc[1]=$6 wvloc[2]=$7 wvloc[3]=$8} graphItem = new Graph(0) g=graphItem graphItem.xaxis() // view axis for x and y graphItem.view($1,$3,$2-$1,$4-$3,wvloc[0],wvloc[1],wvloc[2],wvloc[3]) glist.append(graphItem) } //** find_secname(variable,result): put secname into result proc find_secname () { localobj o if ((sfunc.head($s1,"\.[_A-Za-z0-9]+$",$s2))==0) { // strip off stuff after terminal . printf("grvec.hoc:find_secname ERR: no section found: %s\n",$s1) err() } if ( strm($s1,"\.[_A-Za-z0-9]+[(][0-9.]+[)]$")) { // form eg v(0.5) sfunc.head($s1,"\.[_A-Za-z0-9]+[(][0-9.]+[)]$",$s2) } else { o=isit($s2) if (o.x) { // the stem is an obj o.o.get_loc() sectionname($s2) pop_section() } else { printf("grvec.hoc:f_s ERR0: Can't find sec: %s\n",$s1) err() } } } //** vecpanel() main panel proc vecpanel () { if (! attr0) {printf("vecpanel (main panel) can only be run from attr0\n") return } fchooser_flag = 0 // used to initialize the file chooser sprint(temp_string_,"%s Vectors",simname) xpanel(temp_string_) xbutton("Graph from file","newpan()") xbutton("Sim vectors","pbrgr(\"Graph\",\"gv\")") xbutton("Sim attributes","attrpanl(0)") xbutton("Save Sim","pvall()") xbutton("Panels","apbrowse()") redo_printlist() xpanel() } //** lpvec(title,vector,printstep) dumps a single vector onto the printer using jgraph proc lpvec () { local inx,ii tmpfile.wopen("lptmp") tmpfile.printf("newgraph\nnewcurve pts\n") for ii = 0,$o2.size-1 { tmpfile.printf("%g ",ii*$3) $o2.printf(tmpfile,"%g",ii,ii) } tmpfile.printf("marktype none\nlinetype solid\ntitle : %s\n",$s1) tmpfile.close() system("jgraph -P lptmp > lptmp2") system("lpt lptmp2") } //** remgrs() -- clears glist proc remgrs () { local ii for ltr(Xo,glist) Xo.unmap if (keepgr!=-1) { for (ii=glist.count-1;ii>0;ii-=1) glist.remove(ii) // leave #1 } else glist.remove_all } //** clear() -- clears llist proc clear () { entries=1 segments=1 comment = "" llist.remove_all() } //** ll() same as external llist proc ll () { if (numarg()==1) { if (attr0==1) { for ltr(XO,printlist) if (strm(XO.name,$s1)) print ii1,XO.name,XO.vec.size } else for ltr(XO,llist) if (strm(XO.name,$s1)) print ii1,XO.name,XO.size } else { if (attr0==1) { for ltr(XO,printlist) print ii1,XO.name,XO.vec.size } else for ltr(XO,llist) print ii1,XO.name,XO.size } } //* read_pclamp(file,vscale,tscale): read physiol data file, similar to read_file() proc read_pclamp () { local ii,cols,pt,length,pstep,tscale,vscale if (! tmpfile.ropen($s1)) { printf("\tERROR: can't open file \"%s\"\n",$s1) } if (numarg()>=2) vscale=$2 else vscale=1 if (numarg()>=3) tscale=$3 else tscale=1e3 printlist.remove_all() method("implicit") printStep=0.1 tmpfile.gets(temp_string_) length=1 while (! strm(temp_string_,"^\"Time")) { length += 1 tmpfile.gets(temp_string_) // first word in line was not a number so next line } temp_string2_ = temp_string_ // column def line cols = count_substr(temp_string_,"[(]") // destructive function pt = tmpfile.tell() length = file_len($s1) - length vrtmp.scanf(tmpfile,length,1,cols) // tvec pstep=vrtmp.x[1]-vrtmp.x[0] pstep*=tscale // typically gives it in s statt ms print "Reading ", cols, " columns; ", length, " lines; tstep=",pstep for ii=2,cols { // pick up all of the columns tmpfile.seek(pt) vrtmp.scanf(tmpfile,length,ii,cols) vrtmp.mul(vscale) // correct for a common scaling npl("col",ii,vrtmp,pstep) } if (1) { sprint(temp_string2_,"%s:%s",$s1,temp_string2_) file_with_dot($s1,filename,"v") // put vfilename into name print "Saving to ",filename pvplist(filename,temp_string2_) } } //* read_file(file,cols[,length]): read multicolumn file // see also read_pclamp() above func read_file () { local ii,cols,pt,length if (numarg()==0) { print "\tread_file(\"file\",cols)" print "\t(must set tstop and printStep.)" return 0 } printStep=10 if (cvode_status()!=0) print "WARNING: Turn off cvode." if (numarg()==3) { length = $3 } else { length=tstop/printStep } cols = $2 if (! tmpfile.ropen($s1)) { printf("\tERROR: can't open file \"%s\"\n",$s1) return 0} // printlist.remove_all() tmpfile.scanstr(temp_string_) pt = 0 // skip over a comment line; note that this will skip extra line if comment line is // just one word long while (sfunc.head(temp_string_,"[^-+0-9.e]",temp_string2_) != -1) { tmpfile.gets(temp_string_) // first word in line was not a number so next line pt = tmpfile.tell() // location at next line tmpfile.scanstr(temp_string_) // get first word here print temp_string2_ } for ii=1,cols { // pick up all of the columns tmpfile.seek(pt) vrtmp.scanf(tmpfile,length,ii,cols) npl("col",ii,vrtmp) } return 1 } //* read_rfile(file): read multirow file // use col2row to transpose columnar file first proc read_rfile() { local num if (numarg()==0) { print "\tread_rfile(\"file\")" return } if (! tmpfile.ropen($s1)) { printf("\tERROR: can't open file \"%s\"\n",$s1) return} printlist.remove_all() while (tmpfile.scanstr(temp_string_) != -1) { // read lines num = tmpfile.scanvar() // pick up number of items in col vrtmp.scanf(tmpfile,num) npl(temp_string_,vrtmp) } } //* redo_printlist() menu allows removal or addition of inidividual items proc redo_printlist () { xmenu("Printlist") xbutton("Save Sim","pvall()") xbutton("Add var to printlist","redolist(0)") xbutton("Clear printlist","printlist.remove_all()") xbutton("Remove item from printlist","redolist(1)") xbutton("Vector.op","redolist(2)") xbutton("Proc(vector)","redolist(6)") xbutton("Link XO->vec,YO->tvec","redolist(7)") xbutton("Graph vector","redolist(4)") xbutton("Save printlist","redolist(5)") xbutton("Archive to file:","pbrgr(\"Archive\",\"pv\")") xbutton("Add all obj's of this type to printlist","redolist(3)") xmenu() } //* redolist() set of functions for altering the printlist called by redo_printlist() proc redolist () { local ii,flag if (! isobj(printlist,"List")) printlist = new List() flag = $1 rdstr = 1 if (numarg()==2) { recstr=$s2 rdstr=0 } if (flag==0) { if (! isobj(scob,"SymChooser")) scob = new SymChooser() if (scob.run()) { scob.text(temp_string_) npl(temp_string_) } } else if (flag==1) { // remove item printlist.browser("Double click on item to remove","name") printlist.accept_action("printlist.remove(hoc_ac_)") } else if (flag==2) { // .op if (rdstr) string_dialog("Enter operation to be run on vec",recstr) temp_string_ = "\"%s.%s = %g\\n\"" sprint(temp_string_,"printf(%s,printlist.object(hoc_ac_).name,\"%s\",x=printlist.object(hoc_ac_).vec.%s)",temp_string_,recstr,recstr) printlist.browser(recstr,"name") printlist.accept_action(temp_string_) } else if (flag==3) { // put another set of things on list if (! isobj(scob,"SymChooser")) scob = new SymChooser() if (rdstr) string_dialog("String to be used as suffix for all items on list",recstr) scob.run() scob.text(temp_string_) tmplist = new List(temp_string_) record(tmplist,recstr) } else if (flag==4) { // show it pbrgr("Graph","gv") } else if (flag==5) { fchooser_flag = 0 tmpfile.chooser("a","Add printlist to file") if (tmpfile.chooser()==1) { tmpfile.printf("\nproc make_printlist() { \n") tmpfile.printf(" printlist.remove_all()\n") for ii=0,printlist.count-1 { tmpfile.printf(" npl(\"%s\")\n",printlist.object(ii).name) } tmpfile.printf("}\nmake_printlist()\n") tmpfile.close() } } else if (flag==6) { // proc(vec) if (rdstr) string_dialog("Enter procedure name \"proc\",called as proc(vec,var,num)",recstr) printlist.browser(recstr,"name") sprint(temp_string_,"%s(printlist.object(hoc_ac_).vec,printlist.object(hoc_ac_).name,hoc_ac_)",recstr) printlist.accept_action(temp_string_) } else if (flag==7) { // XO is pointer to vec printlist.browser("XO","name") sprint(temp_string_,"{tmpobj=printlist.object(hoc_ac_) print hoc_ac_,tmpobj.name XO=tmpobj.vec YO=tmpobj.tvec}") printlist.accept_action(temp_string_) } } //** mkmenu(title,action,proc) makes a menu from printlist proc mkmenu () { local ii xmenu($s1) for ii=0,printlist.count-1 { sprint(temp_string_,"%s %s",$s2,printlist.object(ii).name) sprint(temp_string2_,"%s(%d)",$s3,ii) xbutton(temp_string_,temp_string2_) } sprint(temp_string_,"mkpanel(\"%s\",\"%s\",\"%s\")",$s1,$s2,$s3) xbutton("Leave up",temp_string_) xmenu() } //** pbrgr(browser name,action) is used to put up a browser // note action given without '()' proc pbrgr () { if (printlist.count == 1) { gv(0) } else if (printlist.count <= 8) { mkpanel("Vector",$s1,$s2) } else { sprint(temp_string_,"%s:%s",simname,$s1) printlist.browser(temp_string_,"name") sprint(temp_string2_,"%s()",$s2) printlist.accept_action(temp_string2_) } } //** mkpanel(title,action,proc) makes a panel from printlist proc mkpanel () { local ii sprint(temp_string_,"%s:%s",simname,$s1) xpanel(temp_string_) for ii=0,printlist.count-1 { sprint(temp_string_,"%s %s",$s2,printlist.object(ii).name) sprint(temp_string2_,"%s(%d)",$s3,ii) xbutton(temp_string_,temp_string2_) } xpanel() } //** remprl() -- remove printlist item by name proc remprl () { local flag flag=0 if (numarg()==2) flag=1 else print "LISTING ONLY; rerun with 2 args to remove" for (ii=printlist.count-1;ii>=0;ii-=1) { Xo=printlist.object(ii) if (strm(Xo.name,$s1)) if (flag) printlist.remove(ii) else print Xo.name } } // for ltr(XO,glist) { print XO,XO.view_count } //** wvpanl() proc wvpanl () { local ii sfunc.tail(filename,"data.*/",grvecstr) sprint(temp_string_,"%s:%s (WVPANL)",simname,grvecstr) xpanel(temp_string_) sprint(temp_string_,"%d Vectors",llist.count) xlabel(temp_string_) for ii=0,3 { sprint(temp_string_,"size[%d]",ii) sprint(temp_string2_,"chrange(%d)",ii) xvalue(szstr[ii].s,temp_string_,0,temp_string2_,0,1) } xvalue("Shift L/R","shift",0,"chrange(-2)",0,1) xmenu("Other") xbutton("Clear/Set to G0","chrange(-1)") xbutton("View=plot","viewplot()") xbutton("0,tstop,-90,50","setrange(0,tstop,-90,50)") // xbutton("Clean graph list","collapsegrs()") xbutton("Attributes","attrpanl()") xmenu() xpanel() if (glist.count>0) for ii=0,3 if (size[ii]==0) size[ii]=glist.object(0).size(ii+1) } //** chrange() changes range for a set of graphs (called from attrpanl) proc chrange () { local cnt, flag, ii, sz1, sz2, sz3, sz4 if (numarg()==1) { flag = $1 } else { flag = -1 } cnt = glist.count() for (ii=cnt-1;ii>=0;ii=ii-1) if (glist.object(ii).view_count() == 0) glist.remove(ii) cnt = glist.count() // check again after removing any with no views if (cnt==0) { for ii=0,3 size[ii]=0 return } // flag -1 means set everything from the first graph if (flag==-1) for ii=0,3 size[ii] = glist.object(0).size(ii+1) if (flag==-2) for ii=0+luprd,1+luprd size[ii] += shift // shift right or left if (flag==5) { size[0]=0 size[1]=tstop } // just set x // for each of the graphs for ltr(Xo,glist) { sz1=Xo.size(1) sz2=Xo.size(2) sz3=Xo.size(3) sz4=Xo.size(4) if (flag==0) Xo.size(size[0],sz2,sz3,sz4) if (flag==1) Xo.size(sz1,size[1],sz3,sz4) if (flag==2) Xo.size(sz1,sz2,size[2],sz4) if (flag==3) Xo.size(sz1,sz2,sz3,size[3]) if (flag==-1 || flag==4) Xo.size(size[0],size[1],size[2],size[3]) if ((flag==-2 && !luprd) || flag==5) Xo.size(size[0],size[1],sz3,sz4) if (flag==-2 && luprd) Xo.size(sz1,sz2,size[2],size[3]) } for ii=0,3 if (size[ii]==0) size[ii]=glist.object(0).size(ii+1) } //** grall() graphs all of the lines from the file // use vector $o2 as indices for vectors (see tposvec) proc grall () { local cnt,ii,min,max,gr,skip,iskp,vind,sind,a if (numarg()==0) {printf("grall(min,max,gr_offset,skipgr,iskp]): graph vectors.\n") return } sind=vind=0 cnt = llist.count() min=0 max=cnt-1 // will reset max if is vector with numarg()==2 // with 2 args, vector $o2 gives indices for vectors (see tposvec) if (numarg()>=1) { if (argtype(1)==0) { min=$1 } else { // a vector of indices or a string for prdr/vrdr a=allocvecs(1) if (argtype(1)==1) { vind=1 mso[a].copy($o1) } else sind=1 } } if (numarg()>1) { max=$2 if (max<0) max+=llist.count } if (numarg()>2) gr=$3 else gr=0 if (numarg()>3) skip=$4 else skip=1 if (numarg()>4) iskp=$5 else iskp=1 if (iskp==0) iskp=1 if (super==1 && glist.count==0) { remgrs() print "Creating plot" skip=0 newPlot(0,tstop,-100,100) glist.append(graphItem)} if (super==0 && glist.count==0) size[1]=0 if (sind) { // for vrdr(aa,$s2,1,1) aa.x(0).append(ii1) vind=1 } if (vind) { min=0 max=mso[a].size-1 } for (ii=min;ii<=max;ii+=iskp) { if (super == 1) { if (gr >= glist.count()) break graphItem = glist.object(gr) gr=gr+skip } if (vind) rv(mso[a].x[ii]) else rv(ii) } if (vind) dealloc(a) } // go through tmplist selected in rlist and graph onto glist proc grsel () { localobj o for ii=0,tmplist.count-1 { rv_readvec((o=tmplist.o(ii)),vrtmp) if (ii-1) { printf("Graphing %s\n",printlist.object(grrcnt).name) graphItem.erase_all() rv(grrcnt) graphItem.exec_menu("View = plot") } graphItem.size(size[0],size[1],size[2],size[3]) } else if (keystate==2 && type==2) { grrcnt=-1 } else if (keystate==2 && type==1) { x+=1 // slow it down five-fold if (x>5) { grrcnt=(grrcnt+1)%printlist.count printf("%d: %s\n",grrcnt,printlist.object(grrcnt).name) x=0 } } else if (keystate==0 && type==2) { x=x0 y=y0 } else if (keystate==0 && type==3) { graphItem.size(x,x0,y,y0) // resize to chosen square } } //** remgrs() gets rid of all of the graphs (called from attrpanl) proc remgrs () { local ii,cnt if (isobj(graphItem,"Graph")) { graphItem.unmap graphItem = nil } for ltr (Xo,glist) Xo.unmap() glist.remove_all } //** collapsegrs () take off of glist graphs that have been closed on screen proc collapsegrs () { local ii for (ii=glist.count-1;ii>=0;ii-=1) { if (glist.object(ii).view_count() == 0) { glist.remove(ii) } } } //** viewplot() set the world for each graph correctly proc viewplot () { local cnt,ii,flag,sz1,sz2,sz3,sz4 if (numarg()==1) flag=$1 else flag=-1 if (flag==0) { sz1=sz3=1e10 sz2=sz4=-1e10 } for ltr(Xo,glist) { Xo.size(&x[0]) if (flag==0) { if (x[0]sz2) sz2=x[1] if (x[2]sz4) sz4=x[3] } else if (flag==9) { Xo.size(0,tstop,x[2],x[3]) } else { Xo.size(x[0],x[1],x[2],x[3]) } } if (flag==9) { size[0]=0 size[1]=tstop } if (flag==0) for ltr(Xo,glist) Xo.size(sz1,sz2,sz3,sz4) } //** nvwall() changes the size of the graphs proc nvwall () { local cnt,ii,sz1,sz2,sz3,sz4,wd,ht if (numarg()==2) { wd=$1 ht=$2 } else { wd=vsz[0] ht=vsz[1] } cnt = glist.count() for (ii=cnt-1;ii>=0;ii=ii-1) { if (glist.object(ii).view_count()==0) {glist.remove(ii) } else { sz1 = glist.object(ii).size(1) sz2 = glist.object(ii).size(2) sz3 = glist.object(ii).size(3) sz4 = glist.object(ii).size(4) glist.object(ii).unmap() vloc = vloc+vjmp if (vloc > 700) { vloc = 0 } glist.object(ii).view(sz1,sz3,sz2-sz1,sz4-sz3,0,vloc,wd,ht) } } } //** geall() erases all of the graphs proc geall () { local cnt,ii cnt = glist.count() for ii=0,cnt-1 { glist.object(ii).erase_all() } } //** lblall(label,#,xloc,yloc) put label on all of the graphs // arg3 tells which single graph to put it on proc lblall () { local cnt,ii,min,max,lx,ly if (numarg()==0) { printf("lblall([,loc])\n") return } cnt = glist.count() if (numarg()>1) { min=max=$2 } else { min=0 max=cnt-1 } if (numarg()==5) { lx=$3 ly=$4 } else { lx=0.1 ly=0.8 } if (numarg()>1) { if (sfunc.len($s1)>0) { temp_string_ = $s1 }} for ii=min,max { glist.object(ii).color(color) glist.object(ii).label(lx,ly,temp_string_) } } //** relbl() put appropriate label on all of the graphs proc relbl () { local cnt,ii,min,max,lx,ly if (numarg()==0) { printf("relbl([str])\n") return } cnt = glist.count() if (numarg()==4) { lx=$3 ly=$4 } else { lx=0.1 ly=0.8 } if (numarg()>1) glist.object(0).label($s2) for ii=0,glist.count-1 { Xo=glist.object(0) Yo=llist.object(0) Xo.color(0) Xo.label(0.,.9,Yo.name) Xo.color(color) Xo.label(lx,ly,Yo.vec.label) } } //** toggle functions proc tog (){if (numarg()==0) print super=1-super else print $&1=1-$&1} proc togmark () { if (gvmarkflag==0) { gvmarkflag=1 if (line<4) line+=1 } else { gvmarkflag=0 if (line>6) line-=1 } sprint(tstr,"gvmarkflag=%d",gvmarkflag) // set external gvmarkflag as well execute(tstr) sprint(mesg,"mark=%d",gvmarkflag) } //* panobjl stuff proc apbrowse () { panobjl.browser("attrpanls","s") panobjl.accept_action("panobjl.object(hoc_ac_).attrpanl()") } //** po(NUM) set global panobj to that number proc po () { sprint(tstr,"panobj=GRV[%d]",$1) execute(tstr) } proc apkill () { panobjl.browser("attrpanls","s") panobjl.accept_action("panobjl.remove(hoc_ac_)") } //* printlist stuff //** record(list,what,vecptr) from items in $o1 object(ii).$s2 in vectors // $o1 is the list arg $s2 is the thing to be recorded [eg soma.v(0.5)] // optional $3 is the name of an object belonging to list items that will // serve as a pointer to the recording vector proc record () { local ii, dur, na3 if (isobj($o1,"List")) for ltr(Xo,$o1) { sprint(recstr,"%s.%s",Xo,$s2) npl(recstr) if (numarg()==3) { sprint(temp_string_,"%s.%s=printlist.object(printlist.count-1).vec",Xo,$s3) execute(temp_string_) // only way to get call by ref for object } } else forsec $o1 { // assume sectionlist sprint(recstr,"%s.%s",secname(),$s2) npl(recstr) if (numarg()==3) { sprint(temp_string_,"%s.%s=printlist.object(printlist.count-1).vec",Xo,$s3) execute(temp_string_) // only way to get call by ref for object } } } //** npl(name) adds this item to the printlist // npl(name,vec) adds this vec to the printlist // npl(name,vec,step) adds this vec to the printlist with printStep step // npl(name,vec,tvec) adds this vec to the printlist // npl(var,name) use name instead of variable name // npl(var,ptr) provide an objref to point to the vec // npl(name,num,vec)??adds this vec to the printlist under name_num0,name_num1,etc proc npl () { local dur,nflag,tvflag,prstep // METHOD DEPENDENT if (! isobj(printlist,"List")) printlist = new List() tvflag=nflag=0 prstep=0.05 if (argtype(3)==0) { vite = new vitem($s1,$o2.size) vite.vec.copy($o2) vite.pstep=$3 printlist.append(vite) return } else if (cvode_status()==0.0) { sprint(tstr,"%s.printStep=printStep",this) execute(tstr) prstep=printStep } else if (cvode_status()==1.1) { tvflag=1 } else if (cvode_status()==1.0) { // ?? printf("WARNING: Method 'global' is not currently supported for recording via grvec\n") } if (outvecint == 0) dur = tstop else dur = outvecint grvecstr = $s1 repl_mstr(grvecstr," ","",temp_string2_) // no longer splits on '/' // eg npl(name,ii,vec) if (numarg()>=4) if ($4<=0) tvflag=1 else { tvflag=0 prstep=$4 } if (numarg()>=3) { // allows formation of tags on the fly if (argtype(3)==0) { if ($3<=0) tvflag=1 else { tvflag=0 prstep=$3 } } else if (argtype(2)==0) { sprint(temp_string_,"%s%s",grvecstr,":%d") sprint(temp_string_,temp_string_,$2) vite = new vitem(temp_string_,$o3.size) vite.vec.copy($o3) if (numarg()==4) if (argtype(4)==1) { vite.tvec.copy($o4) vite.tvflag=1 vite.pstep=0 } else if (argtype(4)==0) { vite.pstep=$4 } else printf("Arg 4 unrecognized in npl?\n") printlist.append(vite) return } else if (argtype(2)==1) { vite = new vitem(grvecstr,$o2.size,1) vite.vec.copy($o2) vite.tvec.copy($o3) printlist.append(vite) return } } if (numarg()>=2) { // second arg is a vector to store if (argtype(2)==1) { vite = new vitem(grvecstr,$o2.size) vite.tvflag=tvflag vite.pstep=prstep vite.vec.copy($o2) printlist.append(vite) return } else if (argtype(2)==2) { // give explicit name for the thing to store nflag=1 } } if (cvode_status()==1.0) { if (tvec.buffer_size==0){tvec.resize(dur/prstep+10) tvec.resize(0)} tvec.record(&t) } else if (isobj(tvec,"Vector")) if (tvec.size!=0) { tvec.resize(0) tvec.play_remove() } if (nflag) { if (tvflag) { vite = new vitem($s2,dur/prstep+10,1) } else { vite = new vitem($s2,dur/prstep+10,prstep) } } else { if (tvflag) { vite = new vitem(grvecstr,dur/prstep+10,1) } else { vite = new vitem(grvecstr,dur/prstep+10,prstep) } } if (numarg()==2) if (argtype(2)==1) $o2=vite.vec // allow user to assign a pointer printlist.append(vite) if (tvflag) { vite.vec.resize(dur/prstep+10) vite.tvec.resize(dur/prstep+10) find_secname(grvecstr,temp_string_) // with lvardt, need to assign in proper context sprint(temp_string_,"%s {cvode.record(&%s,%s.vite.vec,%s.vite.tvec)}",temp_string_,grvecstr,this,this) } else if (cvode_status()==1.0) { // don't give an explicit prstep vite.vec.resize(dur/prstep+10) sprint(temp_string_,"%s.vite.vec.record(&%s)",this,grvecstr) } else { sprint(temp_string_,"%s.vite.vec.record(&%s,%g)",this,grvecstr,prstep) } if (! execute1(temp_string_)) print "Unable to excute ",temp_string_ vite=nil } //** store cvode state in a double in form active.local func cvode_status () { return cvode.active() + cvode.use_local_dt()/10 } proc ulv () { } //** pvall() dumps all vectors to output_file // Save logic: // 1) Interactive mode: you're watching simulations while printing out // data. You see something you like and save it - the runnum in the // index file then corrsponds to the number on the data file, it is // subsequently augmented // 2) Batch mode: you're running very long sims and saving directly to // vector files. You put together a simulation you want and save it // immediately rather than waiting for the sim to return (in 1 or 2 // days). To correspond, the data file (v*) must then be numbered // 'runnum-dec_runnum' proc pvall () { if (numarg()>=1) { comment = $s1 // a comment } else if (sfunc.len(comment)==0) { sprint(tstr,"%s.comment=comment",this) execute(tstr) sprint(tstr,"Use: %s ?",comment) if (!boolean_dialog(tstr)) return } if (numarg()>=2) output_file=$s2 else { sprint(output_file,"%sv%s.%02d",ddir,datestr,runnum-dec_runnum) while (tmpfile.ropen(output_file)) { runnum = runnum+1 printf("%s found, trying %sv%s.%02d\n",output_file,ddir,datestr,runnum-dec_runnum) sprint(output_file,"%sv%s.%02d",ddir,datestr,runnum-dec_runnum) } } printf("Saving to %s\n",output_file) pvplist(output_file,comment) sprint(output_file,"%sv%s.%02d",ddir,datestr,runnum) comment="" } //** pvplist(file,comment,tback) print out the printlist with comment at head proc pvother () {} // user can dump other vectors at top with prvec() proc pvplist () { local inx,tmin,tmax,tback localobj oq,xo output_file=$s1 if (! pvplist0()) return // open file(s) pvplist1($s2) // print string header if (numarg()==3) if ($3>1) { tback=$3 tmax=printlist.o(0).tvec.max if (tmax>tback) { tmin=tmax-tback oq=new NQS() for ltr(xo,printlist) { oq.setcols(xo.tvec,xo.vec) oq.select(0,">",tmin) oq.cpout() oq.resize(0) } } } pvout() if (numarg()<3) { // leave for appending if $3==1 tmpfile.close() tf1.close() } else if ($3>1) { tmpfile.close() tf1.close() } } //** pvclose() -- close files used for writing proc pvclose () { tmpfile.close() tf1.close() } //** pvplist0() -- open output_file and ancillary dot file if needed func pvplist0 () { localobj st st=new String2() file_with_dot(output_file,st.s) // put .filename into st.s if (numarg()==0) { if (tmpfile.ropen(st.s)) { printf("WARNING: removing %s\n",st.s) sprint(st.t,"rm %s",st.s) system(st.t) } if (tmpfile.wopen(st.s)==0) { print "Can't open ",st.s return 0} if (! isojt(tf1,tmpfile)) tf1=new File() tf1.wopen(output_file) } else { if (tmpfile.aopen(st.s)==0) { print "Can't open ",st.s," to append" return 0} if (! isojt(tf1,tmpfile)) tf1=new File() tf1.aopen(output_file) } return 1 } //** prplist1() proc pvplist1 () { tmpfile.printf("//: %s\n",$s1) // comment if (cvode_status()==1.1) { tmpfile.printf("//printStep -2\n") } else if (cvode_status()==1.0) { tmpfile.printf("//printStep -1\n") } else { sprint(tstr,"%s.printStep=printStep",this) execute(tstr) tmpfile.printf("//printStep %g\n",printStep) } if (byte_store) tmpfile.printf("//CPU %s\n",uname) } //** pvnext() append another printlist set to same file proc pvnext () { local ii if ($1==0) { pvplist(output_file,comment,1) return } pvplist0(0) // open for appending pvout() printf("Append to %s\n",output_file) tmpfile.close() tf1.close } //** pvout() called by pvplist() and pvnext(), actually puts out the vecs proc pvout () { // METHOD DEPENDENT pvout2() if (cvode_status()==1.0 && tvec.max>0) { tmpfile.printf("//b%d 1 %s %d %d\n",tvec_bytesize,"CVODE1.0 tvec",tvec.size,tf1.tell) tvec.vwrite(tf1,tvec_bytesize) } for ltr(Xo,printlist) { // no whitespace allowed if (Xo.code==2) continue if (sfunc.len(Xo.vec.label)>0) sprint(temp_string_,"%s__(%s)",Xo.vec.label,Xo.name) else { temp_string_=Xo.name } pvpone(Xo) } } //** dir2pr(item#[,OUTFILE,OUTCOMMENT]) read the files in dir and add one item to printlist // see also collect.hoc for batch use proc dir2pr () { local ix,ps printlist.remove_all ix=$1 for ltr(Xo,dir) { read_vfile(Xo.s) rv_readvec(ix,vrtmp) ps=llist.o(ix).num // pstep: need if want to save a fixed step entry grv_.npl(comment,vrtmp,tvec) } if (numarg()==3) { grv_.pvplist($s2,$s3) read_vfile($s2) } } //** dir2mf(FILENAME,COMMENT) read the files in dir and create a master file proc dir2mf () { local ix,ps,n localobj f f=new File() f.wopen($s1) f.printf("//: %s\n",$s2) for ltr(Xo,dir) { read_vfile(Xo.s) n=-1 for ltr(Yo,llist) if (dir2mf2(n+=1)) { // repl_mstr(comment," ",";",temp_string2_) // no spaces allowed // sprint(temp_string_,"%s_%s",Yo.name,comment) f.printf("//b%d %g %s %d %d %s\n",bvec,Yo.num,Yo.name,Yo.size,Yo.loc,filename) } } f.close() } //** read_mf() reads a master file // assumes file in tmpfile func read_mf () { local ii,sz,loc,mult,sze,cloc,segs localobj o if (attr0) { if (!boolean_dialog("Look at file data instead of sim?","YES","NO")) { printf("Read file cancelled\n") return 0 } } else { attr0=0 } if (numarg()==1) filename=$s1 else tmpfile.getname(filename) sprint(s,"GRV[%d] %s: %s",objnum(this),simname,filename) clear() if (!tmpfile.ropen(filename)) { print "E1: Can't open ",filename return 0 } while ((numr = tmpfile.gets(tstr)) != -1 && (sfunc.head(tstr,"//[^b]",temp_string2_)==0)) { read_vinfo() // a line giving info about the file (eg comment) } tmpfile.seek(-numr,1) // back up ii=0 while ((numr = tmpfile.gets(tstr)) != -1) { if (((ii+=1)%10000)==0) printf("%d ",ii) if (sscanf(tstr,"//b%1ld %g %s %ld %ld %s",&bvec,&nvec,tstr2,&sze,&loc,tstr)!=6) { printf("**** GRV read_mf() parse ERR on %s in %s",tstr,filename) return 0 } llist.append(new vfile_line(tstr2,sze,loc,nvec,tstr)) // name size loc num } if (llist.count==0) { printf("grvec.hoc::read_mf ERR nothing read from %s\n",filename) return 0 } entries=llist.count mff=1 return 1 } //** prvec(name,vec,byte_flag[,file]) proc prvec () { local bflag if (numarg()>3) { tmpfile.aopen($s4) } bflag = $3 tmpfile.printf("//b%d 1 %s %d %d\n",bflag,$s1,$o2.size,tf1.tell()) $o2.vwrite(tf1,bflag) if (numarg()>3) { tmpfile.close() } } //** pv() dumps a single vector into output_file proc pv () { local inx sprint(output_file,"%sv%s.%02d",ddir,datestr,runnum-dec_runnum) if (numarg()==0) { inx = hoc_ac_ } else { inx = $1 } printf("Printing %s to %s\n",printlist.object(inx).name,output_file) // string_dialog("Name for saved vector",printlist.object(inx).name) if (tmpfile.ropen(output_file)) { // file exists already file_with_dot(output_file,temp_string_) // put .filename into temp_string_ tmpfile.aopen(temp_string_) tf1.aopen(output_file) printf("Appending to %s\n",output_file) } else { pvplist0() pvplist1(comment) } pvpone() tmpfile.close() tf1.close } //** pvpone() -- write out a vector or vector pair to the file proc pvpone () { // METHOD DEPENDENT if (byte_store) { if ($o1.tvflag==1 && isassigned($o1.tvec)) { tmpfile.printf("//b%d -2 %s %d %d\n",byte_store,temp_string_,$o1.vec.size,tf1.tell) $o1.tvec.vwrite(tf1,tvec_bytesize) } else if ($o1.pstep>0) { tmpfile.printf("//b%d %g %s %d %d\n",byte_store,$o1.pstep,temp_string_,$o1.vec.size,tf1.tell) } else { tmpfile.printf("//b%d -1 %s %d %d\n",byte_store,temp_string_,$o1.vec.size,tf1.tell) } $o1.vec.vwrite(tf1,byte_store) } } //** cpplitem([num]) copy X0 to new item in printlist, optional arg can be pos or neg proc cpplitem () { local num,cnt cnt = printlist.count if (numarg()>0) {if ($1>=0) num=$1 else num=cnt+$1} else num=cnt-1 if (num>cnt-1 || num<0) { printf("%d!: Only %d items (0-%d) in list.\n",num,cnt,cnt-1) return } if (numarg()>1) grvecstr=$s2 else sprint(grvecstr,"Copy_of_%s",printlist.object(num).name) npl(grvecstr,printlist.object(num).vec) print printlist.count-1,":XO -> ",grvecstr XO = printlist.object(printlist.count-1).vec } //** chgplname([num],STR) change name of item in printlist proc chgplname () { local num,cnt cnt = printlist.count if (numarg()>0) {if ($1>=0) num=$1 else num=cnt+$1} else num=cnt-1 if (num>cnt-1 || num<0) { printf("%d!: Only %d items (0-%d) in list.\n",num,cnt,cnt-1) return } printlist.object(num).name=$s2 } // new_pri(NAME,TVEC,VEC) quick and dirty new_printlist_item proc new_pri () { vite = new vitem($s1,$o2.size) if (numarg()==3) { vite.tvec.copy($o2) vite.vec.copy($o3) } else vite.vec.copy($o2) printlist.append(vite) vite=nil } //* prlexp(sz) expands all the vectors in printlist to size sz proc prlexp () { sz = $1 tvec.resize(sz) for ltr(Xo,printlist) { Xo.vec.resize(sz) } } //* iterators for printlist and files //** rvtr() read vector iterator // usage 'for rvtr(vec) XO.vec.printf' where # is attrpanl# iterator rvtr () { local i,flag,s4flag if (numarg()>=2) {$&2=0} else {i1 = 0} if (numarg()==3) s4flag=1 else s4flag=0 flag=1 for i = 0, entries-1 { tstr = llist.object(i).name if (s4flag) {if (strm(tstr,$s3)) flag=1 else flag=0} if (flag) { rv_readvec(i,$o1) if (numarg()>=2) { $&2=i } else { i1=i } iterator_statement // rvtr(vec) -- name in .tstr, tvec in .tvec } } } //** vrdr(vlist[,REGEXP or INDV,flag,&y]) -- used for llist // similar to rvtr() but does interpolation // use regexp eg for prdr("PYR2.8") { etc } // optional flag to NOT interpolate // indv gives set of llist nums to search through (can use with "" as regexp) // sets 4 vectors in vlist: voltage,times,interp v, interp t iterator vrdr () { local flag,a,ii localobj rxp,v1,tv1,v2,tv2,ipt if (numarg()==0) printf("\t**** HELP:: vrdr(vlist[,REGEXP or INDV,flag,&y]) ****\n") curcol=0 rxp=new String() a=allocvecs(ipt) if (!isojt($o1,llist)) $o1=new List() if ($o1.count==4) { // use the list we're given for ii=0,3 if (!isojt($o1.o(ii),vrtmp)) { printf("vrdr: Nonvector in vlist:%s\n",$o1.o(ii)) return } } else { $o1.remove_all for ii=0,3 $o1.append(new Vector()) } v1=$o1.o(0) tv1=$o1.o(1) v2=$o1.o(2) tv2=$o1.o(3) ipt.indgen(0,llist.count-1,1) if (numarg()>=2) if (argtype(2)==1) { ipt.copy($o2) } else if (argtype(2)==2) { rxp.s=$s2 } else { printf("vrdr() ERR arg 2 should be vector or string\n") } if (numarg()>=3) flag=$3 else flag=0 if (numarg()>=4) {$&4=0} else {ii1 = 0} if (!flag) { if (tvec.max != tstop) printf("WARNING: tvec set?: %g %g\n",tstop,tvec.max) tv2.copy(tvec) // tvec must be preassigned for interpolation } tmpfile.ropen(filename) for (ii1=0;ii1=4) { $&4+=1 } } } tmpfile.close dealloc(a) } //** prdr() -- used for printlist // use regexp eg for prdr("PYR2.8") { etc } // optional flag to NOT interpolate // ind=tvec, vec1=original trace, vec interpolated on tvec // note that i1 here gives list number, not sequential // eg for panobj.prdr("V$",1) gv(i1) iterator prdr () { local flag if (numarg()>1) flag=$2 else flag=0 if (numarg()==3) {$&3=0} else {i1 = 0} v1=tv1=v2=tv2=allocvecs(4) tv1+=1 v2+=2 tv2+=3 if (!flag) { if (tvec.max != tstop) printf("WARNING: tvec set?: %g %g\n",tstop,tvec.max) mso[tv2].copy(tvec) // tvec must be preassigned for interpolation } curcol=0 if (attr0) for (ii1=0;ii1=3) { $&3+=1 } } } dealloc(v1) } //* outvec() routines for printing out in sections - NOT DEBUGGED //** outvec_init([output_file,comment]) proc outvec_init() { local segs if (numarg()>0) { output_file = $s1 } else { sprint(output_file,"%sv%s.%02d",ddir,datestr,runnum-dec_runnum) while (tmpfile.ropen(output_file)) { runnum = runnum+1 // don't allow an overwrite sprint(output_file,"%sv%s.%02d",ddir,datestr,runnum-dec_runnum) } } if (numarg()>1) { comment = $s2 } print "\nOutput to ",output_file if (print_flag) { print "WARNING: print_flag=1 --> 0\n" print_flag = 0 } if (outvecint==0 || outvecint>tstop) { printf("WARNING: outvecint being set to tstop\n") outvecint = tstop } outvect = outvecint segs = int(tstop/outvecint) if (tstop/outvecint > segs) { segs=segs+1 } tmpfile.wopen(output_file) if (strcmp(comment,"")!=0) { tmpfile.printf("//: %s\n",comment) } tmpfile.printf("//printStep %g\n",printStep) tmpfile.printf("//MULTI %d %d\n",printlist.count,segs) tmpfile.close() } //** outvecs() : print out the vectors and reset them for recording proc outvecs () { local ii if (t outvect-outvecint+2*dt) { tmpfile.aopen(output_file) for ii=0,printlist.count-1 { tmpfile.printf("//b%d 1 %s %d %d\n",byte_store,printlist.object(ii).name,t-outvecint,tmpfile.tell()) printlist.object(ii).vec.vwrite(tmpfile,byte_store) tmpfile.printf("\n") } tmpfile.close() } } //* endtemplate; assignments: endtemplate GRV printStep=0.1 grv_ = new GRV(0) {panobj=grv_ printlist=grv_.printlist panobjl=grv_.panobjl} //* external routines //** new_printlist_item(name) adds this item to the printlist // new_printlist_item(name,vec) adds this vec to the printlist // new_printlist_item(name,vec,tvec) adds this vec to the printlist // new_printlist_item(var,name) use name instead of variable name // new_printlist_item(var,ptr) provide an objref to point to the vec // new_printlist_item(name,num,vec)??adds this vec to the printlist under name_num0,name_num1,etc proc new_printlist_item () { local dur,nflag,tvflag if (! isassigned(grv_)) { grv_ = new GRV(0) printlist=grv_.printlist } if (numarg()==1) { grv_.npl($s1) } else if (numarg()==2) { if (argtype(2)==1) { grv_.npl($s1,$o2) } else if (argtype(2)==2) { grv_.npl($s1,$s2) } else grv_.npl($s1,$2) } else if (numarg()==3) { if (argtype(2)==1) { grv_.npl($s1,$o2,$o3) } else if (argtype(2)==0) { grv_.npl($s1,$2,$o3) } } } //** llist() print out contents of a list proc llist () { local done localobj o,st,xo st=new String() o=panobj if (numarg()==2) st.s=$s2 if (numarg()>=1) { if (argtype(1)==1) { if (isobj($o1,"List")) { if ($o1.count==0) {print "empty list" return} if (isobj($o1.object(0),"String2")) { for ltr(xo,$o1) if (strm(xo.s,st.s)) print xo.s,xo.t } else if (isobj($o1.object(0),"String")) { for ltr(xo,$o1) if (strm(xo.s,st.s)) print xo.s } else if (isobj($o1.object(0),"Vector")) { done=0 if (name_declared("oform")) if (oform(vec)!=NOP) { for ltr(xo,$o1) print xo,oform(xo) done=1 } if (!done) for ltr(xo,$o1) print xo,xo.size } else if (isobj($o1.object(0),"Union")) { for ltr(xo,$o1) if (strm(xo.s,st.s)) print xo,xo.s,xo.t,xo.u,xo.v } else for ltr(xo,$o1) print xo return } else o=$o1 } else if (argtype(1)==2) st.s=$s1 } if (o.attr0) { for ltr(xo,printlist) if (strm(xo.name,st.s)) print i1,xo.name,xo.vec.size } else for ltr(xo,o.llist) if (strm(xo.name,st.s)) print i1,xo.name,xo.size } //** cpprl(PRINTLIST,TMPLIST) copies printlist vitem's to tmplist proc cpprl () { localobj xo,yo $o2.remove_all for ltr(xo,$o1) { $o2.append((yo=new vitem(xo.name,xo.vec.size))) yo.tvflag=xo.tvflag yo.pstep=xo.pstep yo.o=xo.o yo.vec.copy(xo.vec) if (yo.tvflag) {yo.tvec=new Vector() yo.tvec.copy(xo.tvec)} } } //** abbreviated proc calls proc gvpwpl () { pwman_place(500,500) } proc vp () { grv_.vecpanel } obfunc gvnew () { if (numarg()==1) { if (argtype(1)==0) { panobj=new GRV($1) } else if (argtype(1)==2) { panobj=new GRV($s1) } else if (argtype(1)==1) { $o1=new GRV(-2) panobj=$o1 } } else if (numarg()==2) { if ($2>0) { panobj=panobjl.object($2) panobj.read_vfile($s1) } else panobj=new GRV($s1,$2) // file,flag } else panobj=new GRV(1) // default return panobj } proc ap () { local ii,attr0,nopan localobj o nopan=ii=0 if (numarg()==0) { o=panobj } else if (numarg()>=1) { if (argtype(1)==0) { ii=$1 o=grv_.panobjl.object(ii) if (ii<0 || ii>=grv_.panobjl.count) { printf("**** ap(%d) ERR panobj #%d not found -- run gvnew() \n",ii,ii) return } } else o=$o1 } if (numarg()>=2) if (argtype(2)==0) if ($2==-2) nopan=1 attr0=o.attr0 o.attrpanl() if (!nopan) if (attr0) o.pbrgr("Graph","gv") else o.rpanel() panobj=o } proc disptray () { print "Must load boxes.hoc to get trays" } //** gg() graph vectors and functions directly //** gs(#) select graph (by setting g and graphItem to this Graph# proc gs () { if (argtype(1)==1) { g=$o1 graphItem=g } else if (numarg()==2) { g[$1]=Graph[$2] } else { g=Graph[$1] graphItem=g } } // gg(g[i],vec) gg(vec,step) gg(vec,ind) gg(g,"FUNC","min,max") [color,line,symbol] gvmarkflag=0 obfunc gg () { local gp,na,newgr,clr,a,stp,i,tmp localobj ty,ts,abs,ord,o,go if (argtype(1)==2) if (strc($s1,"help")) { printf("eg gg(g[i],vec) gg(vec,step) gg(vec,ind) gg(g,'FUNC','min,max') [color,line,symbol]\n") return nil } a=allocvecs(ty,abs,ord) ts=new String2() na=numarg() newgr=1 ty.resize(10) ty.fill(-1) for i=1,na ty.x[i]=argtype(i) i=1 clr=panobj.color lne=panobj.line if (ty.x[i]==0) { gp=$i i+=1 } else gp=0 if (gp<100) { if (isassigned(g[gp])) if (g[gp].view_count>0) newgr=0 if (newgr) g[gp]=new Graph() go=graphItem=g[gp] graphList[0].append(g[gp]) panobj.glist.append(g[gp]) } else { graphItem=go=new Graph() graphList[0].append(go) panobj.glist.append(go) } if (gvmarkflag) ts.t="mark" else ts.t="line" if (na==1 && ty.x[0]==0) { return // gg(#) just put up the graph } else if (na==i && ty.x[i]==1) { sprint(ts.t,"%s.%s(%s,1",$oi,ts.t,go) // gg(vec) } else if (ty.x[i]==2) { // gg("FUNC","min,max,step") min=0 max=10 stp=0 ts.s=$si i+=1 if (ty.x[i]==2) { split($si,abs,"[,:/]") min=abs.x[0] max=abs.x[1] if (abs.size==3) stp=abs.x[2] i+=1 } if (stp==0) stp=(max-min)/200 abs.indgen(min,max,stp) ord.copy(abs) if (!name_declared(ts.s)) { // look for an x that will become $1 if (!strm(ts.s,"[$]1")) { printf("gg ERR Can't find '$1' in %s\n",ts.s) return nil } sprint(ts.s,"func _gg_f(){return %s}",ts.s) execute1(ts.s) print ts.s ts.s="_gg_f" } ord.apply(ts.s) sprint(ts.t,"%s.%s(%s,%s",ord,ts.t,go,abs) } else if (ty.x[i]==1 && ty.x[i+1]==0) { // gg(vec,step) o=$oi i+=1 if (isobj(o,"List")) { tmp=$i i+=1 if (int($i)!=$i) { // a timestep sprint(ts.t,"%s.%s(%s,%g",o.o(tmp),ts.t,go,$i) i+=1 } else { sprint(ts.t,"%s.%s(%s,%s",o.o(tmp),ts.t,go,o.o($i)) i+=1 } } else { // vector sprint(ts.t,"%s.%s(%s,%g",o,ts.t,go,$i) i+=1 } } else if (ty.x[i]==1 && ty.x[i+1]==1) { // gg(vec,ind) o=$oi i+=1 sprint(ts.t,"%s.%s(%s,%s",o,ts.t,go,$oi) i+=1 } if (ty.x[i]==0) { clr=$i i+=1 } if (ty.x[i]==0) { lne=$i i+=1 } if (ty.x[i]==2) { symb=$si i+=1 } if (sfunc.len(ts.t)>4) { if (gvmarkflag) { sprint(ts.s,"%s,\"%s\",%d,%d,4)",ts.t,symb,lne,clr) } else { sprint(ts.s,"%s,%d,%d)",ts.t,clr,lne) } execute(ts.s) } dealloc(a) return graphItem } //*** ge() erases IV graph proc ge () { if (numarg()==0) graphItem.erase_all() else g[$1].erase_all } //** gv() calls internal gv proc gv () { local inx,na // EXTERNAL VERSION -- same name in template na=numarg() if (argtype(1)==0) { inx = $1 } else if (argtype(1)==2) { for ltr(XO,printlist) if (strm(XO.name,$s1)) inx=i1 if (inx==-1) {print $s1," not found" return } } if (na==1) grv_.gv(inx) else if (na==2) grv_.gv(inx,$2) else if (na==3) grv_.gv(inx,$2,$3) } //** restore_printlist() restores the plist from a file in an attrnum objref vite proc restore_printlist () { local cnt,ii,attrnum,savlvar localobj aa,st printf("NOT WORKING\n") st=new String() attrnum=$1 printlist.remove_all panobj=grv_.panobjl.object(attrnum) for panobj.vrdr(aa,"",1) { vite= new vitem(st.s,aa.o(0).size) vite.vec.copy(aa.o(0)) printlist.append(vite) } } //** dirname(full,path) filname(full,file) splits up path/file // eg filname("/home/billl/nrniv/thal/params.hoc",temp_string_) // temp_string_ => params.hoc obfunc dirname () { localobj st st=new String2() if (argtype(1)==1) st.s=$o1.s else st.s=$s1 st.t=st.s sfunc.head(st.s,"[^/]+$",st.s) sfunc.tail(st.t,st.s,st.t) if (numarg()==2) $s2=st.s return st } //** filname() obfunc filname () { localobj st st=new String2() if (argtype(1)==1) st.s=$o1.s else st.s=$s1 sfunc.head(st.s,"[^/]+$",st.t) sfunc.tail(st.s,st.t,st.s) if (numarg()==2) $s2=st.s return st } //** filsuf() obfunc filsuf () { localobj st st=new String2() if (argtype(1)==1) st.s=$o1.s else st.s=$s1 sfunc.tail(st.s,"\\.",st.s) if (numarg()==2) $s2=st.s return st } //** filstem() // allows composition: filstem(filname(aa)).s obfunc filstem () { localobj st st=new String2() if (argtype(1)==1) st.s=$o1.s else st.s=$s1 sfunc.head(st.s,"\\.",st.s) if (numarg()==2) $s2=st.s return st } //** file_with_dot(filename,[result,prefix]): put .filename into result obfunc file_with_dot () { localobj st st=dirname($s1) if (numarg()==3) { sprint(st.s,"%s%s%s",st.s,$s3,st.t) } else sprint(st.s,"%s.%s", st.s, st.t) if (numarg()>=2) $s2=st.s return st } //* using grvec to save vectors proc grvclr () { printlist.remove_all() } //* grvsv,grvwr,etc //* grvsv(name,vec[,dt or tvec]) save a named vector proc grvsv () { local ddt,tvf localobj st,dv,tv st=new String() tvf=0 ddt=1 if (argtype(1)==2) st.s=$s1 if (argtype(2)==1) dv=$o2 if (argtype(3)==-1){tvf=0 ddt=0.025 } else if (argtype(3)==1) {tv=$o3 tvf=1 } else if (argtype(3)==0) ddt=$3 if (ddt==1) ddt=1.00001 // since dt of 1 is used as a flag (bad hack) if (tvf) printlist.append(new vitem(st.s,dv,tv)) else printlist.append(new vitem(st.s,dv,ddt)) } // grvwr(filename[,comment]) // comment appends date,user,hg tip proc grvwr () { localobj st st=new String2() if (argtype(2)==2) st.t=$s2 system("date",st.s) chop(st.s) sprint(st.t,"%s:%s",st.t,st.s) system("echo $USER",st.s) chop(st.s) sprint(st.t,"%s:%s",st.t,st.s) system("hg tip --template '{rev}:{node}:{date|isodate}'",st.s) // mysteriously adds a newline?? if (sfunc.len(st.s)>2) {chop(st.s) sprint(st.t,"%s:%s",st.t,st.s)} GRV[0].pvplist($s1,st.t) } //** datasource=grvrd("filename"[,showflag]); with showflag puts up attribute panel; returns a datasource obfunc grvrd () { local showflag showflag= 0 // default don't show if (argtype(2)==0) showflag=1 if (showflag) panobj=new GRV($s1) else panobj=new GRV($s1,-2) return panobj } //** grvlist([GRV]) // list names and sizes proc grvlist () { local x localobj xo,po po=panobj if (po.llist.count()==0) return if (argtype(1)==1) if (isobj($o1,"GRV")) po=$o1 printf("# name size\n") if (eqobj(po.llist,printlist)) { for ltr(xo,po.llist,&x) print x,xo.name,xo.vec.size } else for ltr(xo,po.llist,&x) print x,xo.name,xo.size } //** vec=grvrv(datasource,num OR name, datavec, timevec) // read data vec(s) from a datasource // all arguments are optional but order of args not // datasource defaults to current datasource given by 'panobj' object pointer // num or dataname defaults to 0 (first vector in datasource) // if vec1 is missing routine creates a vector, fills with datavec and returns // vec2 if missing is ignored -- in order to pick up vec2 must also give a vector for vec1 // examples: grvrv(3) grvrv(vec,tvec) grvrv("dataname",vec,tvec) obfunc grvrv () { local i,num,x localobj po,st,v1,v2,xo i=1 st=new String2() po=panobj if (argtype(i)==1) if (isobj($oi,"GRV")) {po=$oi i+=1} if (argtype(i)==0) {num=$i i+=1} else num=0 if (argtype(i)==2) { st.s=$si i+=1 // name will overwrite num if redundantly given as num,name for ltr(xo,po.llist,&x) if (strm(xo.name,st.s)) {num=x break} if (x==po.llist.count) printf("grvrv(): %s NOT FOUND in datasource %s; returning first item\n",st.s,po) } if (num>=po.llist.count || num<0) { printf("grvrv(): %d not in datasource %s (max %d); returning first item\n",num,po,po.llist.count-1) num=0 } if (argtype(i)==-1) { v1=new Vector(1e3) } else { // pick up 1 or 2 vectors or vector names if (argtype(i)==1) { v1=$oi i+=1 // vector if (isobj(v1,"NULLobject")) { v1=new Vector(1e3) } else if (!isobj(v1,"Vector")) {printf("grvrv ERRA: arg %d should be a vector\n",i) err()} } if (argtype(i)==1) {v2=$oi i+=1 // vector if (isobj(v2,"NULLobject")) { v2=new Vector(1e3) } else if (!isobj(v2,"Vector")) {printf("grvrv ERRA: arg %d should be a vector\n",i) err()} } } if (i!=numarg()+1) printf("grvrv ERRB: some args not parsed (%d %d)\n",i,numarg()) tstr=po.llist.o(num).name // name of that data item if (v2==nil) po.rv_readvec(num,v1) else po.rv_readvec(num,v2,v1) return v1 } //** vec=grvnq(datasource,num OR name, nq) // read data vec(s) from a datasource // all arguments are optional but order of args not // datasource defaults to current datasource given by 'panobj' object pointer // num or dataname defaults to 0 (first vector in datasource) obfunc grvnq () { local i,num,x,a localobj po,st,oq,xo,v1,v2 i=1 st=new String2() po=panobj if (argtype(i)==1) if (isobj($oi,"GRV")) {po=$oi i+=1} if (argtype(i)==0) {num=$i i+=1} else num=0 a=allocvecs(v1,v2) if (argtype(i)==2) { st.s=$si i+=1 // name will overwrite num if redundantly given as num,name for ltr(xo,po.llist,&x) if (strm(xo.name,st.s)) {num=x break} if (x==po.llist.count) printf("grvnq(): %s NOT FOUND in datasource %s; returning first item\n",st.s,po) } if (num>=po.llist.count || num<0) { printf("grvnq(): %d not in datasource %s (max %d); returning first item\n",num,po,po.llist.count-1) num=0 } if (argtype(i)!=1) { oq=new NQS("t","ind") } else oq=$oi if (i!=numarg()+1) printf("grvnq ERRB: some args not parsed (%d %d)\n",i,numarg()) tstr=po.llist.o(num).name // name of that data item if (po!=panobjl.o(0)) po.rv_readvec(num,v2,v1) else { v1.copy(printlist.o(num).vec) v2.copy(printlist.o(num).tvec) } oq.v[0].append(v2) oq.v[1].append(v1) return oq } //* misc routines //** fexists() func fexists () { localobj o o=new File() return o.ropen($s1) } //** ftype() func ftype () { local ty localobj st ty=0 st=new String2() sprint(st.t,"stat -c %%F %s 2>&1",$s1) system(st.t,st.s) chop(st.s) if (strm(st.s,"\n")) { return 10 // more than 1 file -- ie * used } else if (strm(st.s,"No such")) { return -1 } else if (strm(st.s,"directory")) { return 0 } else if (strm(st.s,"symbolic")) { return 8 } else if (strm(st.s,"regular")) { return 2 } else { // not identified printf("File %s is a %s\n",$s1,st.s) return -2 } } //** file_len() uses wc func file_len () { local x localobj st st=new String() sprint(st.s,"wc -l \"%s\"",$s1) system(st.s,st.s) sscanf(st.s,"%d",&x) return x } func cvode_status () { return cvode.active() + cvode.use_local_dt()/10 } proc pvall () { local n localobj o o=panobjl.o(0) if (! o.attr0) { printf("pvall() ERR %s not attr0==0\n",o) } else { n=numarg() if (n==1) o.pvall($s1) else if (n==2) o.pvall($s1,$s2) else o.pvall() } } //** procbutt() put up a single proc in a button proc procbutt () { xpanel($s1) xbutton($s1,$s1) xpanel(500,500) } // mdl2view(g,X,Y) converts world coordinates to view coordinates // eg {XO=mdl2view(g,12,533.7) g.label(XO.x,XO.x[1],"AA",2,2,0.5,0.5,1)} // translate from world coordinates into view coordinates // view coordinates are different from Graph model coordinates // 3 coordinate systems: view, world, panel -- ie the 0,1 used by g.label obfunc mdl2view () { local a,ii,x0,y0 localobj o,v1,g g=$o1 x0=$2 y0=$3 if (argtype(4)==1) v1=$o4 else { v1=new Vector(4) for ii=0,3 v1.x[ii]=g.size(ii+1) } o=new Union() o.x= (x0-v1.x[0])/(v1.x[1]-v1.x[0]) o.x[1]=(y0-v1.x[2])/(v1.x[3]-v1.x[2]) o.x[2]=o.x[0]*0.8+0.1 o.x[3]=o.x[1]*0.8+0.1 // scale and move over to where graph usually is return o } //* cart2north() -- identify 0-360 degree N up for cartesian vector // cart2north(x0,y0,x1,y1[,vec]) -- with vec also return amplitude in vec.x[1] // cart2north(delx,dely[,vec]) func cart2north () { local theta,delx,dely,i if (numarg()<4) {delx=$1 dely=$2 i=3} else {delx=$3-$1 dely=$4-$2 i=5} theta=atan2(dely,delx) theta*=(180/PI) if (theta<0) theta+=360 if (theta>=0 && theta<90) { theta= abs(theta-90) } else if (theta>=90 && theta<=360) theta = abs(450 - theta) if (numarg()==i) revec($oi,theta,sqrt(dely*dely+delx*delx)) return theta } //** rmallgrs() gets rid of all extant graphs proc rmallgrs () { local ii,cnt localobj xo,glist glist=new List("Graph") for ltr (xo,glist) xo.unmap() } proc stopper () { xpanel("STOP") xbutton("STOP","stoprun=1") xbutton("FINI","finish()") xbutton("CONT","time(\"cvode.solve(tstop)\")") xbutton("RUN","time()") xpanel() } if (name_declared("PythonObject") && fexists("grvec.py")) nrnpython("execfile('grvec.py')")