//* $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<glist.count) graphItem=glist.o(ii) else {
printf("GRV grsel() glist exhausted\n")
return }
if (o.num==-2) { // guess should do mark
vrtmp.mark(graphItem,tvec,symb,line+2,curcol,4)
} else vrtmp.line(graphItem,o.num,curcol,line)
}
}
// tposvec(rows,cols): generate the indices for a transposed matrix of rows x cols
proc tposvec () { local rows,cols,i,j
rows=$2 cols=$3
$o1.resize($2*$3)
for (i=0;i<rows;i+=1) for (j=0;j<cols;j+=1) $o1.x[j*rows+i]=i*cols+j
}
// fliptb(rows,cols): generate the indices for a transposed matrix of rows x cols
proc fliptb () { local rows,cols,i,j,p
rows=$2 cols=$3
if ($o1.size != $2*$3) {print "Wrong size vector in fliptb()" return}
p = allocvecs(1) mso[p].resize(rows)
for (j=0;j<cols;j+=1) {
mso[p].copy($o1,j*rows,(j+1)*rows-1)
mso[p].reverse
$o1.copy(mso[p],j*rows)
}
}
//** setrange() sets the range
// setrange(x0,x1,y0,y1)
proc setrange () { local i,ii
if (numarg()==0){print "setrange(x0,x1,y0,y1)\n setrange(3) erases axes"}
if (numarg()==0) { for ltr(Xo,glist) Xo.size(0,tstop,-100,50)
} else if (numarg()==1) { for ltr(Xo,glist) Xo.xaxis($1)
} else if (numarg()==2) { for ltr(Xo,glist) Xo.size(0,tstop,$1,$2)
} else {
size[0]=$1
for ltr(Xo,glist) Xo.size($1,$2,$3,$4)
for i=1,4 size[i-1]=$i
}
for ii=0,3 if (size[ii]==0) size[ii]=glist.object(0).size(ii+1)
}
//* gxpan()
proc gxpan () { local x localobj xo,yo,g1
gcomms.remove_all
gcomms.append(new String2("Move","mvga"))
gcomms.append(new String2("Mag","magga"))
for ltr(xo,gcomms) for ltr(yo,glist) {
yo.menu_remove(xo.s)
yo.menu_tool(xo.s,xo.t)
}
gcomms.append(new String2("Crosshair",""))
xpanel("Manipulate graphs",1)
x=-1
for ltr(xo,gcomms) {sprint(tstr,"mvgaset(%d)",x+=1) xradiobutton(xo.s,tstr)}
xpanel()
}
proc mvgaset () { localobj yo
print $1,gcomms.o($1).s
for ltr(yo,glist) yo.exec_menu(gcomms.o($1).s)
}
proc mvga () { local type,x,y,keystate,sz1,sz2,sz3,sz4 localobj xo,yo
type=$1 x=$2 y=$3 keystate=$4 // 2 for press, 1 for dragging, and 3 for release
xo=glist.o(0)
sz1=xo.size(1) sz2=xo.size(2) sz3=xo.size(3) sz4=xo.size(4)
if (type == 2) {
begx=x begy=y
} else if (type==3) {
x-=begx y-=begy
size[0]=sz1-x size[1]=sz2-x size[2]=sz3-y size[3]=sz4-y
for ltr(xo,glist) xo.size(sz1-x,sz2-x,sz3-y,sz4-y)
}
}
proc magga () { local tmp,type,x,y,begx,begy,keystate,sz1,sz2,sz3,sz4 localobj xo,yo
type=$1 x=$2 y=$3 keystate=$4 // 2 for press, 1 for dragging, and 3 for release
xo=glist.o(0)
sz1=xo.size(1) sz2=xo.size(2) sz3=xo.size(3) sz4=xo.size(4)
if (type == 2) {
begx=x begy=y
} else if (type==3) {
if (x<begx) { tmp=x x=begx begx=tmp }
if (y<begy) { tmp=y y=begy begy=tmp }
size[0]=begx size[1]=x size[2]=begy size[3]=y
for ltr(xo,glist) xo.size(size[0],size[1],size[2],size[3])
}
}
//* grransel() -- graph range select
proc setgrransel () {
for ltr(Xo,glist) {
Xo.menu_remove("REVIEW")
sprint(tstr,"proc p%d(){grransel($1,$2,$3,$4,%d,%s)}",ii1,ii1,Xo)
execute1(tstr)
sprint(tstr,"p%d",ii1)
Xo.menu_tool("REVIEW", tstr)
Xo.exec_menu("REVIEW")
}
}
//** grransel(): CTL-hit == Crosshair
// SHT-hit == resize
// hit-drag-release == show in square
// SHT-hit-drag-release == show new thing there
// Type: press (2), drag (1), release (3)
// Keystate: META-SHT-CTL eg 101=5 is META-CTL
grrcnt=-1
// not debugged
proc grransel () { local type, x0, y0, keystate, ii, gr
type=$1 x0=$2 y0=$3 keystate=$4 gr=$5
graphItem=$o7 // = glist.object(gr)
if (keystate==1 && type==2) { graphItem.exec_menu("Crosshair") // CTL-MOUSE-1
} else if (keystate==3 && type==3) {
print grrcnt
if (grrcnt>-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]<sz1) sz1=x[0]
if (x[1]>sz2) sz2=x[1]
if (x[2]<sz3) sz3=x[2]
if (x[3]>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<llist.count;ii1+=1) {
if (ipt.contains(ii1) && strm(llist.object(ii1).name,rxp.s)) {
XO=llist.object(ii1)
if (mff) if (strcmp(filename,XO.f)!=0) { filename=XO.f tmpfile.ropen(filename) }
tmpfile.seek(XO.loc)
if (XO.num==-2) tv1.vread(tmpfile) else {
if (XO.num<=0) {printf("vrdr INTERR; ?printStep for interpolation\n") err()}
tv1.indgen(0,tstop+0.01,XO.num) }
v1.vread(tmpfile)
v2.resize(0)
if (XO.num==-2 && !flag) v2.interpolate(tv2,tv1,v1)
i1=ii1
iterator_statement
if (numarg()>=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<printlist.count;ii1+=1) {
XO=printlist.object(ii1)
if (strm(XO.name,$s1)) {
sprint(tstr,"tstr=\"%s\"",XO.name) execute(tstr) // set global tstr
mso[v1].copy(XO.vec)
if (isit(XO.tvec)) mso[tv1].copy(XO.tvec)
if (!flag && isit(XO.tvec)) mso[v2].interpolate(mso[tv2],XO.tvec,XO.vec)
i1=ii1
iterator_statement
if (numarg()==3) { $&3+=1 }
}
} else for (ii1=0;ii1<llist.count;ii1+=1) {
if (strm(llist.object(ii1).name,$s1)) {
XO=llist.object(ii1)
i1=ii1
iterator_statement
if (numarg()>=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 == 0) { return }
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")
printlist.object(ii).vec.play_remove()
sprint(temp_string_,"printlist.object(%d).vec.record(&%s,%g)",\
ii,printlist.object(ii).name,printStep)
execute(temp_string_)
}
tmpfile.close
outvect = outvect+outvecint
}
//** outvec_finish () : put out the last section if needed, update the output_file name
proc outvec_finish() {
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()
}