// Created 02/07/06 12:59:28 by /usr/site/scripts/loadfiles //================================================================ // INSERTED prebatch.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ //================================================================ // INSERTED /usr/site/nrniv/local/hoc/setup.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ // variables normally controlled by SIMCTRL // load_file("setup.hoc") {load_file("stdgui.hoc")} show_panel=0 proc setup () {} strdef simname, filename, output_file, datestr, uname, comment, section, osname objref tmpfile,nil,graphItem,sfunc tmpfile = new File() simname = "sim" // helpful if running multiple simulations simultaneously runnum = 2 // updated at end of run datestr = "99aug01" // updated at end of day output_file = "data/99aug01.01" // assumes a subdir called data comment = "current comment for saving sim" uname = "i686" // keep track of type of machine for byte compatibility if (unix_mac_pc()==1) osname = "Linux" else if (unix_mac_pc()==2) { osname = "Mac" } else if (unix_mac_pc()==3) osname = "PC" printStep = 0.25 // time interval for saving to vector graph_flag=0 batch_flag=1 xwindows = 0 // can still save but not look without xwindows sfunc = hoc_sf_ // from stdlib.hoc // load_file("nrnoc.hoc") // END /usr/site/nrniv/local/hoc/setup.hoc //================================================================ {datestr="06feb06" runnum=1} //================================================================ // INSERTED /usr/site/nrniv/simctrl/hoc/nrnoc.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ proc nrnoc () {} // Users should not edit nrnoc.hoc or default.hoc. Any local // changes to these files should be made in local.hoc. // key '*&*' is picked up by to indicate command for emacs proc elisp () { printf("*&* %s\n",$s1) } // if (not exists(simname)) { strdef simname, output_file, datestr, comment } // Simctrl.hoc will automatically load stdgraph.hoc which automatically // loads stdrun.hoc strdef temp_string_, user_string_ // needed for simctrl /* Global variable default values. NOTE that stdrun.hoc, stdgraph.hoc and simctrl.hoc all contain variable definitions and thus default.hoc should be loaded after these files */ //================================================================ // INSERTED /usr/site/nrniv/simctrl/hoc/default.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ /* This file contains various global defaults for hoc ** Users should not edit nrnoc.hoc or default.hoc. Any local changes to these files should be made in local.hoc. ----------------------------------------------------------------*/ /*------------------------------------------------------------ Object defaults ------------------------------------------------------------*/ /*** Define a "nil" object ***/ objectvar nil /*------------------------------------------------------------ String defaults ------------------------------------------------------------*/ /*** "Section" is used if errors are found in the initializiations ***/ strdef section /*** Misc defines used by graphic routines ***/ temp_string_ = "t" tempvar = 0 /*------------------------------------------------------------ Simulation defaults ------------------------------------------------------------*/ /* To be consistent w/the nmodl values */ FARADAY = 96520. /* Hoc default = 96484.56 */ PI = 3.14159 /* Hoc default = 3.1415927 */ /* 0=off, 1=on */ print_flag = 0 /* Write to output file */ graph_flag = 1 /* Plot output */ iv_flag = 1 /* Using Interviews plotting */ batch_flag = 0 /* Using batch_run() */ compress_flag = 0 /* Compress output file when saved */ stoprun = 0 /* 0=running, 1=stopped */ iv_loaded = 0 /* Load initial iv stuff on once */ init_seed = 830529 run_seed = 680612 t = 0 /* msec */ dt = .01 /* msec */ tstop = 100 /* msec */ printStep = 0.1 /* msec */ plotStep = 0.1 /* msec */ flushStep = 0.1 /* msec */ eventStep = 50 /* Number of nstep's before a doEvent */ secondorder = 0 celsius = 6.3 /* degC */ v_init = -70 /* (mV) */ global_ra = 200 /* (ohm-cm) specific axial resisitivity */ /*** Ion parameters ***/ ca_init = 50e-6 /* mM */ na_init = 10 /* mM */ k_init = 54.4 /* mM */ // END /usr/site/nrniv/simctrl/hoc/default.hoc //================================================================ /* Allows arrays of strings */ objref hoc_obj_[2] //================================================================ // INSERTED /usr/site/nrniv/simctrl/hoc/simctrl.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ // Graphic routines for neuremacs simulation control proc sim_panel () { xpanel(simname) xvarlabel(output_file) xbutton("Init", "stdinit()") xbutton("Init & Run", "run()") xbutton("Stop", "stoprun=1") xbutton("Continue till Tstop", "continueRun(tstop)") xvalue("Continue till", "runStopAt", 1, "{continueRun(runStopAt) stoprun=1}", 1, 1) xvalue("Continue for", "runStopIn", 1, "{continueRun(t + runStopIn) stoprun=1}", 1,1) xbutton("Single Step", "steprun()") xvalue("Tstop", "tstop", 1, "tstop_changed()", 0, 1) graphmenu() sim_menu_bar() misc_menu_bar() xpanel() } proc misc_menu_bar() { xmenu("Miscellaneous") xbutton("Label Graphs", "labelgrs()") xbutton("Label With String", "labelwith()") xbutton("Label Panel", "labelpanel()") xbutton("Parameterized Function", "load_template(\"FunctionFitter\") makefitter()") xmenu() } proc sim_menu_bar() { xmenu("Simulation Control") xbutton("File Vers", "elisp(\"sim-current-files\")") xbutton("File Status...", "elisp(\"sim-rcs-status\")") xbutton("Sim Status", "elisp(\"sim-portrait\")") xbutton("Load Current Files", "elisp(\"sim-load-sim\")") xbutton("Load Templates", "elisp(\"sim-load-templates\")") xbutton("Load File...", "elisp(\"sim-load-file\")") xbutton("Save Sim...", "elisp(\"sim-save-sim\")") xbutton("Set File Vers...", "elisp(\"sim-set-file-ver\")") xbutton("Read Current Vers From Index", "elisp(\"sim-read-index-file\")") xbutton("Read Last Saved Vers", "elisp(\"sim-read-recent-versions\")") xbutton("Output to sim buffer", "elisp(\"sim-direct-output\")") xmenu() } proc labelpanel() { xpanel(simname,1) xvarlabel(output_file) xpanel() } proc labels () { labelwith($s1) labelgrs() } proc labelgrs () { local i, j, cnt for j=0,n_graph_lists-1 { cnt = graphList[j].count() - 1 for i=0,cnt labelgr(graphList[j].object(i)) } } proc labelwith () { local i, j, cnt temp_string_ = user_string_ // save the old one if (numarg() == 1) { /* interactive mode */ user_string_ = $s1 } else { string_dialog("write what?", user_string_) } for j=0,n_graph_lists-1 { cnt = graphList[j].count() - 1 for i=0,cnt { graphList[j].object(i).color(0) graphList[j].object(i).label(0.5,0.9,temp_string_) graphList[j].object(i).color(1) graphList[j].object(i).label(0.5,0.9,user_string_) } } } proc labelgr () { local i $o1.color(0) // white overwrite for (i=0;i<10;i=i+1) { // erase every possible runnum for this date sprint(temp_string_,"%s %d%d",datestr,i,i) $o1.label(0.1,0.7,temp_string_) } $o1.color(1) // back to basic black sprint(temp_string_,"%s %02d",datestr,runnum) $o1.label(0.1,0.7,temp_string_) } // END /usr/site/nrniv/simctrl/hoc/simctrl.hoc //================================================================ proc run () { stdinit() if (using_cvode_ && cvode.use_local_dt) { cvode.solve(tstop) } else { continueRun(tstop) } finish() } proc continueRun () { local eventCount eventCount=0 eventslow=1 stoprun = 0 if (cvode_active()) cvode.event($1) while (t < $1 && stoprun == 0) { advance() outputData() if (graph_flag) { fastflushPlot() doEvents() } } } proc advance () { fadvance() } proc stdinit() { realtime=0 startsw() t = 0 stoprun = 0 if (batch_flag == 1) { } init() if (graph_flag == 1) { if (iv_flag == 1) { initPlot() } else { initGraph() } } if (print_flag == 1) { initPrint() } } proc init () { cvode_simgraph() initMech() initMisc1() // Initialize state vars then calculate currents // If user hand-set v in initMisc1() then v_init should be > 1000, // else all compartments will be set to v_init if (v_init < 1000) { finitialize(v_init) } else { finitialize() } print ina // Set ca pump and leak channel for steady state setMemb() initMisc2() if (cvode_active()) cvode.re_init() else fcurrent() frecord_init() } // Initialization of mechanism variables // NOTE: if any changes are made to the NEURON block of any local mod // file, the user must add the necessary inits to initMisc1() proc initMech () { forall { if ((!ismembrane("pas")) && (!ismembrane("Passive"))) { // Allow for either pas or Passive mod file usage // errorMsg("passive not inserted") } if (ismembrane("na_ion")) { nai = na_init nai0_na_ion = na_init } if (ismembrane("k_ion")) { ki = k_init ki0_k_ion = k_init } if (ismembrane("ca_ion")) { cai = ca_init cai0_ca_ion = ca_init } } } //* setMemb complex -- multiple names for passive mech //** declarations iterator scase() { local i for i = 1, numarg() { temp_string_ = $si iterator_statement }} objref paslist,pasvars[3],XO double pasvals[2],x[1] paslist = new List() for ii=0,2 pasvars[ii]= new String() for scase("fastpas","pas","Pass","Passive") paslist.append(new String(temp_string_)) //** getval(),setval() -- return/set the hoc value of a string func retval () { return getval($s1) } func getval () { sprint(temp_string2_,"x=%s",$s1) execute(temp_string2_) return x } proc setval () { sprint(temp_string2_,"%s=%g",$s1,$2) execute(temp_string2_) } //** findpas() // assumes that we are starting in a live section since looks for pass mech there qx_=0 proc findpas () { for ii=0,paslist.count-1 { XO=paslist.object(ii) if (ismembrane(XO.s)) { // print XO.s,"found" pasvars[2].s=XO.s sprint(pasvars[0].s,"g_%s(qx_)",XO.s) for scase("e","erev","XXXX") { // look for the proper prefix sprint(temp_string_,"%s_%s",temp_string_,XO.s) if (name_declared(temp_string_)==1) break } if (name_declared(temp_string_)==0) { // not found printf("SetMemb() in nrnoc.hoc: Can't find proper 'erev' prefix for %s\n",XO.s) } else { sprint(pasvars[1].s,"%s(qx_)",temp_string_) } } } } proc setMemb () { findpas() // assume that passive name is the same in all sections forall for (qx_,0) { // will eventually want 'for (x)' to handle all the segments if (ismembrane(pasvars[2].s)) { for ii=0,1 pasvals[ii]=getval(pasvars[ii].s) setmemb2() for ii=0,1 setval(pasvars[ii].s,pasvals[ii]) } } } func setother () {return 0} // callback stub proc setmemb2 () { local iSum, ii, epas, gpas gpas=pasvals[0] epas=pasvals[1] // Setup steady state voltage using leak channel iSum = 0.0 if (ismembrane("na_ion")) { iSum += ina(qx_) } if (ismembrane("k_ion")) { iSum += ik(qx_) } if (ismembrane("ca_ion")) { iSum += ica(qx_) } iSum += setother() if (iSum == 0) { // Passive cmp so set e_pas = v epas = v } else { if (gpas > 0) { // Assume g set by user, calc e epas = v + iSum/gpas } else { // Assume e set by user, calc g if (epas != v) { gpas = iSum/(epas - v) } else { gpas=0 } } if (gpas < 0) errorMsg("bad g", gpas) if (epas < -100 || epas > 0) { printf(".") // printf("%s erev: %g %g %g\n",secname(),e_pas,ina,ik) } } pasvals[0]=gpas pasvals[1]=epas } proc finish () { /* Called following completion of continueRun() */ finishMisc() if (graph_flag == 1) { if (iv_flag == 1) { flushPlot() doEvents() } else { graphmode(-1) plt(-1) } } if (print_flag == 1) { wopen("") } } /*------------------------------------------------------------ User definable GRAPHICS and PRINTING routines ------------------------------------------------------------*/ proc outputData() { // Default procedure - if outputData() doesn't exist in the run file if (graph_flag == 1) { if (iv_flag == 1) { Plot() rt = stopsw() if (rt > realtime) { realtime = rt fastflushPlot() doNotify() if (realtime == 2 && eventcount > 50) { eventslow = int(eventcount/50) + 1 } eventcount = 0 }else{ eventcount = eventcount + 1 if ((eventcount%eventslow) == 0) { doEvents() } } } else { graph(t) } } if (print_flag == 1) { if (t%printStep <= printStep) { printOut() } } } proc printOut() { /* Default procedure - if printOut() doesn't exist in the run file */ } proc initGraph() { /* Default procedure - if initGraph() doesn't exist in the run file */ graph() } proc initPrint() { /* Default procedure - if initPrint() doesn't exist in the run file */ wopen(output_file) } /*------------------------------------------------------------ User definable BATCH RUN routines ------------------------------------------------------------*/ proc nextrun() { // Called from finishmisc() following completion of batch in an autorun wopen("") runnum = runnum + 1 sprint(output_file,"data/b%s.%02d", datestr, runnum) } // commands for emacs proc update_runnum() { runnum = $1 sprint(output_file,"data/%s.%02d", datestr, runnum) print "^&^ (progn (sim-index-revert)(setq sim-runnum ",runnum,"))" } proc nrn_write_index() { printf("&INDEX& %s\n",$s1) } proc nrn_update () { elisp("nrn-update") } proc nrn_message () { printf("!&! %s\n",$s1) } /*------------------------------------------------------------ User definable INITIALIZATION and FINISH routines ------------------------------------------------------------*/ // Default procedure - if initMisc1() doesn't exist in the run file // Initializations performed prior to finitialize() // This should contain point process inits and inits for any changes // made to the NEURON block of any local mod file proc initMisc1() { } // Default procedure - if initMisc2() doesn't exist in the run file // Initializations performed after finitialize() proc initMisc2() { } // Default procedure - if finishMisc() doesn't exist in the run file proc finishMisc() { } /*------------------------------------------------------------ Miscellaneous routines ------------------------------------------------------------*/ proc errorMsg() { /* Print warning, assumes arg1 is string and arg2 if present is a variable value */ sectionname(section) if (numarg() == 0) { printf("ERROR in errorMsg(): Needs at least 1 argument.\n") } else if (numarg() == 1) { printf("ERROR: %s in section %s.\n", $s1, section) } else { printf("ERROR: %s in section %s (var=%g).\n", $s1, section, $2) } } proc clear() { /* Clear non-interviews plot window */ plt(-3) } func mod() { local x, y /* Mod function for non-integers */ x=$1 y=$2 return (x/y - int(x/y)) } proc whatSection() { print secname() } proc print_pp_location() { local x //arg1 must be a point process x = $o1.get_loc() sectionname(temp_string_) printf("%s located at %s(%g)\n", $o1, temp_string_, x) pop_section() } //* set method with method() proc method () { local prc if (numarg()==0) { if (cvode_active() && cvode_local()) { printf("\tlocal atol=%g\n",cvode.atol) } else if (cvode_active()) { printf("\tglobal atol=%g\n",cvode.atol) } else if (secondorder==2) { printf("\tCrank-Nicholson dt=%g\n",cvode.atol) } else if (secondorder==0) { printf("\timplicit dt=%g\n",cvode.atol) } else { printf("\tMethod unrecognized\n") } return } if (numarg()==2) prc = $2 else prc=0 finitialize() if (strcmp($s1,"global")==0) { cvode_active(1) cvode.condition_order(2) if (prc) cvode.atol(prc) } else if (strcmp($s1,"local")==0) { cvode_local(1) cvode.condition_order(2) if (prc) cvode.atol(prc) } else if (strcmp($s1,"implicit")==0) { secondorder=0 cvode_active(1) cvode_active(0) if (prc) dt=prc } else if (strcmp($s1,"CN")==0) { secondorder=2 cvode_active(1) // this turns off local cvode_active(0) if (prc) dt=prc } else { printf("Integration method %s not recognized\n",$s1) } } //* Load local modifications to nrnoc.hoc and default.hoc //================================================================ // INSERTED /usr/site/nrniv/simctrl/hoc/local.hoc // $Header: /home/cvsroot/netmod/parscalebush/prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ // // This file contains local modifications to nrnoc.hoc and default.hoc // // Users should not edit nrnoc.hoc or default.hoc. Any local // changes to these files should be made in this file. // ------------------------------------------------------------ //* MODIFICATIONS TO NRNOC.HOC // The procedures declared here will overwrite any duplicate // procedures in nrnoc.hoc. // ------------------------------------------------------------ //*MODIFICATIONS TO DEFAULT.HOC // // Vars added here may not be handled properly within nrnoc.hoc //------------------------------------------------------------ //** String defaults //** Simulation defaults long_dt = .001 // msec objref sfunc,tmpfile sfunc = hoc_sf_ // needed to use is_name() tmpfile = new File() // check for existence before opening a user's local.hoc file proc write_comment () { tmpfile.aopen("index") tmpfile.printf("%s\n",$s1) tmpfile.close() } func asin () { return atan($1/sqrt(1-$1*$1)) } func acos () { return atan(sqrt(1-$1*$1)/$1) } objref mt[2] mt = new MechanismType(0) proc uninsert_all () { local ii forall for ii=0,mt.count()-1 { mt.select(ii) mt.selected(temp_string_) if (strcmp(temp_string_,"morphology")==0) continue if (strcmp(temp_string_,"capacitance")==0) continue if (strcmp(temp_string_,"extracellular")==0) continue if (sfunc.substr(temp_string_,"_ion")!=-1) continue mt.remove() // print ii,temp_string_ } } condor_run = 0 // define for compatability // END /usr/site/nrniv/simctrl/hoc/local.hoc //================================================================ if (xwindows && graph_flag) { nrnmainmenu() } // pwman_place(50,50) if (myid == 0) print "Init complete.\n" // END /usr/site/nrniv/simctrl/hoc/nrnoc.hoc //================================================================ //================================================================ // INSERTED init.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ //================================================================ // INSERTED /usr/site/nrniv/local/hoc/grvec.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ // argtype: 0:double; 1:obj; 2:str; 3:double pointer objref g[10],printlist,grv_,panobj,panobjl //================================================================ // INSERTED /usr/site/nrniv/local/hoc/decvec.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ proc decvec() {} //* Declarations objref ind, tvec, vec, vec0, vec1, tmpvec, vrtmp, veclist, veccollect objref tmpobj, XO, YO, rdm, dir strdef filename dir = new List() tmpfile = new File() if (! name_declared("datestr")) load_file("setup.hoc") //================================================================ // INSERTED /usr/site/nrniv/local/hoc/declist.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ //* Declarations strdef mchnms objref tmplist,tmplist2,tmpobj,stack,SO,aa,XO,YO if (! name_declared("datestr")) load_file("setup.hoc") tmplist = new List() stack = new List() proc declist() {} //* Templates //** template String2 begintemplate String2 public s,t,x,append,prepend,exec strdef s,t proc init() { if (numarg() == 1) { s=$s1 } if (numarg() == 2) { s=$s1 t=$s2 } if (numarg() == 3) { s=$s1 t=$s2 x=$3 } } proc append () { local i if (argtype(1)==2) sprint(t,"%s%s",s,$s1) for i=2,numarg() sprint(t,"%s%s",t,$si) } proc prepend () { local i if (argtype(1)==2) sprint(t,"%s%s",$s1,s) for i=2,numarg() sprint(t,"%s%s",$si,t) } proc exec () { if (numarg()==1) sprint(t,"%s%s",$s1,s) execute(t) } endtemplate String2 //** template DBL begintemplate DBL public x proc init () { if (numarg()==1) x=$1 else x=0 } endtemplate DBL //** template Union // USAGE: XO=new Union(val) where val can be a number string or object // XO=new Union(list,index) will pick up a string or object from list // XO=new Union(vec,index) will pick up a number from vector // XO=new Union(&dbl,index) will pick up a number from double array // Union allows storage of a double, string or object // It is useful as a localobj in an obfunc since it will permit returning anything // It also makes it easy to pick up any kind of value out of a list, vector or array begintemplate Union public ty,x,s,o strdef s objref o[2] double x[2] external sfunc,tstr // 1arg -- store a num, string or obj // 2arg -- pick up type out of list proc init() { local ii x=x[1]=0 ty=-1 if (numarg() == 1) { ty = argtype(1) if (ty==0) { x=$1 } else if (ty==2) { s=$s1 } else if (ty==1) { o=$o1 } else printf("Union ERR: argtype not recognized %d\n",ty) } else if (numarg()==2) { ii=$2 if (argtype(1)==1) { if (isobj($o1,"Vector")) { if (ii<0 || ii>=$o1.size) { printf("Union ERR: vec index (%d) out of bounds for %s\n",ii,$o1) return } ty=0 x=$o1.x[ii] o=$o1 } else if (isobj($o1,"List")) { if (ii<0 || ii>=$o1.count) { printf("Union ERR: list index (%d) out of bounds for %s\n",ii,$o1) return } if (isobj($o1.object(ii),"String")) { // will handle String2 ty=2 s=$o1.object(ii).s o=$o1.object(ii) x=ii } else { ty=1 o=$o1.object(ii) x=ii } } } else if (argtype(1)==3) { ty=0 x=$&1[ii] // could check - but no + bound checking possible } } } func isobj () { sprint(tstr,"%s",$o1) if (sfunc.substr(tstr,$s2)==0) return 1 else return 0 } endtemplate Union //* Iterators //** list iterator ltr // usage 'for ltr(tmplist) { print XO }' :: 1 arg, assumes XO as dummy // usage 'for ltr(YO, tmplist) { print YO }' 2 arg, specify dummy // usage 'for ltr(XO, tmplist, &x) { print XO,x }' :: 3 args, define counter (else i1 default) // :: note that x, i1 must be globally defined // usage 'for ltr(XO, tmplist, 5) { print XO,x }' :: 3 args, only print out 0-5 iterator ltr () { local i,min,max,ifl min=0 max=1e9 ifl=0 // iterator flag if (numarg()==3) { if (argtype(3)==3) {ifl=1 $&3=0} if (argtype(3)==0) max=$3 } if (numarg()==4) { min=$3 max=$4 } if (! ifl) i1=0 if (numarg()==1) { for i = 0, $o1.count-1 { XO = $o1.object(i) iterator_statement i1+=1 } tmpobj=$o1 XO=nil } else { if (max==1e9) max=$o2.count()-1 else if (max<0) { min=$o2.count+max max=$o2.count-1 } else if (max>$o2.count-1) max=$o2.count-1 for i = min, max { $o1 = $o2.object(i) iterator_statement if (ifl) { $&3+=1 } else { i1+=1 } } tmpobj=$o2 $o1 = nil } } //** list iterator ltrb -- backwards list iterator // usage 'for ltrb(tmplist) { print XO }' :: 1 arg, assumes XO as dummy // usage 'for ltrb(YO, tmplist) { print YO }' 2 arg, specify dummy // usage 'for ltrb(XO, tmplist, &x) { print XO,x }' :: 3 args, define counter (else i1 default) // :: note that x, i1 must be defined iterator ltrb () { local i if (numarg()==1) { i1=$o1.count-1 for (i=$o1.count()-1;i>=0;i-=1) { XO = $o1.object(i) iterator_statement i1-=1 } tmpobj=$o1 XO=nil } else { if (numarg()==3) $&3=$o2.count-1 else i1=$o2.count-1 for (i=$o2.count()-1;i>=0;i-=1) { $o1 = $o2.object(i) iterator_statement if (numarg()==3) { $&3-=1 } else { i1-=1 } } tmpobj=$o2 $o1 = nil } } //** list iterator ltr2 // usage 'for ltr2(XO, YO, list1, list2) { print XO,YO }' iterator ltr2() { local i,cnt if (numarg()==5) $&5=0 else i1=0 cnt=$o4.count if ($o3.count != $o4.count) { print "ltr2 WARNING: lists have different lengths" if ($o3.count<$o4.count) cnt=$o3.count } for i = 0, cnt-1 { $o1 = $o3.object(i) $o2 = $o4.object(i) iterator_statement if (numarg()==5) { $&5+=1 } else { i1+=1 } } $o1=nil $o2=nil } //** list pairwise iterator ltrp // usage 'for ltrp(XO, YO, list) { print XO,YO }' takes them pairwise iterator ltrp() { local i if (numarg()==4) {$&4=0} else {i1 = 0} for (i=0;i<$o3.count()-1;i+=2) { $o1 = $o3.object(i) $o2 = $o3.object(i+1) iterator_statement if (numarg()==4) { $&4+=1 } else { i1+=1 } } $o1=nil $o2=nil } //** list iterator sltr // usage 'for sltr(XO, string) { print XO }' iterator sltr() { local i tmplist = new List($s2) if (numarg()==3) {$&3=0} else {i1=0} for i = 0, tmplist.count() - 1 { $o1 = tmplist.object(i) iterator_statement if (numarg()==3) { $&3+=1 } else { i1+=1 } } $o1 = nil } //* Procedures //** rel(LIST,o1,o2,...) -- like revec() makes a list of objects proc rel () { local i if (!isassigned($o1)) $o1=new List() $o1.remove_all for i=2,numarg() $o1.append($oi) } //** rcsopen(file,vers) -- version open func rcshead () { local x localobj s s=new String() sprint(s.s,"head -1 %s",$s1) system(s.s,s.s) sscanf(s.s,"%*[^,],v 1.%d",&x) return x } proc rcsopen () { local vers localobj s vers=$2 s=new String() if (rcshead($s1)==vers) { xopen($s1) } else { sprint(s.s,"cp -f %s %s.tmp",$s1,$s1) system(s.s) sprint(s.s,"co -f -r1.%d %s",vers,$s1) system(s.s) xopen($s1) } } //** lrm(LIST,STR) will remove item with string from LIST proc lrm () { local cnt cnt=0 if (argtype(2)==2) { for ltrb(XO,$o1) if (strm(XO.s,$s2)) { $o1.remove(i1) cnt+=1 } printf("%s found %d time\n",$s2,cnt) } else { $o1.remove($o1.index($o2)) } } //** lrepl(LIST,#,OBJ) will replace item at location # with OBJ proc lrepl () { $o1.remove($2) $o1.insrt($2,$o3) } //** lswap(list,#1,#2) swap items on a list proc lswap () { local a,b if ($2<$3) {a=$2 b=$3} else {a=$3 b=$2} $o1.insrt(a,$o1.object(b)) $o1.remove(b+1) $o1.insrt(b+1,$o1.object(a+1)) $o1.remove(a+1) } //** proc shl() show a list proc shl () { if (numarg()==1) tmpobj=$o1 else tmpobj=tmplist if (tmpobj.count==0) return if (isstring(tmpobj.object(0),tstr)) { for ltr(XO,tmpobj) print XO.s } else for ltr(XO,tmpobj) print XO } //** lfu() = ltr follow-up, pick out a single item from the last ltr request // lfu(list,num[,obj]) proc lfu () { if (numarg()==1) { if (argtype(1)==0) XO=tmpobj.object($1) if (argtype(1)==1) tmpobj=$o1 } if (numarg()==2) { if (argtype(1)==1 && argtype(2)==0) {tmpobj=$o1 XO=$o1.object($2)} if (argtype(1)==0 && argtype(2)==1) {$o2=tmpobj.object($1)} } if (numarg()==3) { if (argtype(1)==1 && argtype(2)==0 && argtype(3)==1) { tmpobj=$o1 $o3=$o1.object($2) } } if (numarg()==4) { $o2=tmpobj.object($1) $o4=tmpobj.object($3) } } //** listedit() allows you to remove things by clicking proc listedit () { if (numarg()==0) { print "listedit(list,str) gives browser(list,str) for removing items" return} if (numarg()==1) { if (! isstring($o1.object(0),temp_string_)) {print "Give name for string of object?" return } sprint(temp_string_,"proc ledt1 () {sprint(temp_string_,%s,hoc_ac_,%s.object(hoc_ac_).%s)}","\"%d:%s\"",$o1,"s") } else { sprint(temp_string_,"proc ledt1 () {sprint(temp_string_,%s,hoc_ac_,%s.object(hoc_ac_).%s)}","\"%d:%s\"",$o1,$s2) } execute1(temp_string_) $o1.browser("Double click to remove",temp_string_,"ledt1()") sprint(temp_string_,"%s.remove(hoc_ac_)",$o1) $o1.accept_action(temp_string_) } //** crac() create and access proc crac () { execute("create acell_home_") execute("access acell_home_") } //** listXO() connects stuff to XO from a list proc listXO () { if (numarg()==1) { $o1.browser("Double click") sprint(temp_string_,"print hoc_ac_,\":XO -> \",%s.object(hoc_ac_) XO = %s.object(hoc_ac_)",$o1,$o1) $o1.accept_action(temp_string_) } else if (numarg()==2) { $o1.browser($s2) sprint(temp_string_,"XO = %s.object(hoc_ac_) print %s.object(hoc_ac_).%s",$o1,$o1,$s2) $o1.accept_action(temp_string_) } else if (numarg()==3) { $o1.browser($s2) sprint(temp_string_,"XO = %s.object(hoc_ac_) print %s.object(hoc_ac_).%s,%s.object(hoc_ac_).%s",$o1,$o1,$s2,$o1,$s3) $o1.accept_action(temp_string_) } } //** lcatstr(list,s1,s2,...) make new List("s1") new List("s2") ... in one list proc lcatstr() { local i if (numarg()<3) { print "lcatstr(l1,s1,s2,...) puts new Lists into l1" return } $o1 = new List($s2) for i=3,numarg() { tmplist2 = new List($si) for ltr(XO,tmplist2) { $o1.append(XO) } } } //** sublist() places a sublist in LIST0 from LIST1 index BEGIN to END inclusive proc sublist () { local ii $o1.remove_all for ii=$3,$4 { $o1.append($o2.object(ii)) } } //* catlist() concats LIST2...LISTN on end of LIST1 proc catlist () { local i for i = 2, numarg() { for ltr(YO,$oi) { $o1.append(YO) } } } //* mechlist() creates a LIST of all this CELL type's TEMPLATE type // list, cell, template // make a list of mechanisms belonging to a certain template proc mechlist () { local num,ii // mchnms = "" // not a good storage since runs out of room if (numarg()==0) { print "mechlist(list, cell, template)" return} $o1 = new List($s2) num = $o1.count for ii=0,num-1 { sprint(temp_string_,"%s.append(%s.%s)",$o1,$o1.object(ii),$s3) execute(temp_string_) sprint(mchnms,"%s/%d/%s.%s",mchnms,ii,$o1.object(ii),$s3) } for (ii=num-1;ii>=0;ii=ii-1) { $o1.remove(ii) } } //* lp() loop through a list running command in object's context // assumes list in tmplist // with 1 args run $o1.object().obj_elem // with 2 args run comm($o1.object().obj_elem) proc lp () { for ii=0,tmplist.count-1 { printf("%s ",tmplist.object(ii)) if (numarg()==2) { sprint(temp_string_,"%s(%s.%s)",$s2,tmplist.object(ii),$s1) } else { sprint(temp_string_,"%s.%s",tmplist.object(ii),$s1) } execute(temp_string_) } } //* prlp() loop through a list printing object name and result of command proc prlp () { tmpobj=tmplist if (numarg()>0) if (argtype(1)==1) tmpobj=$o1 for ltr(XO,tmpobj) { printf("%d %s ",i1,XO) if (numarg()>1) { sprint(temp_string_,"print %s.%s",XO,$s2) execute(temp_string_) } else { print "" } } } //* String functions //** repl_str(str,stra,strb): replace stra with strb in string // will only replace first string match proc repl_str() { localobj scr scr=new String() if (sfunc.head($s1,$s2,scr.s) == -1) { print $s2," not in ",$s1 return } sfunc.tail($s1,$s2,scr.s) sprint(scr.s,"%s%s",$s3,scr.s) sfunc.head($s1,$s2,$s1) sprint($s1,"%s%s",$s1,scr.s) } //** find_str(str,left,right,dest): pull out dest flanked by left and right proc find_str() { if (sfunc.tail($s1,$s2,$s4) == -1) { print $s2," not in ",$s1 return } sfunc.head($s4,$s3,$s4) } //** repl_mstr(str,stra,strb,scratch): replace stra with strb in string // multiple replace proc repl_mstr() { localobj scr scr=new String() while (sfunc.head($s1,$s2,scr.s) != -1) { sfunc.tail($s1,$s2,scr.s) sprint(scr.s,"%s%s",$s3,scr.s) sfunc.head($s1,$s2,$s1) sprint($s1,"%s%s",$s1,scr.s) } } //** clean_str(str,scratch,s1,s2,s3,...) // remove serial $si from string proc clean_str () { local i for i=3,numarg() { while (sfunc.head($s1,$si,$s2) != -1) { sfunc.tail($s1,$si,$s2) sfunc.head($s1,$si,$s1) sprint($s1,"%s%s",$s1,$s2) } } } //** aaaa() (or $o2) becomes a list of strings from file $s1 proc aaaa () { local flag if (numarg()==2) { tmpfile.ropen($s1) aa=$o2 flag=0 } else if (numarg()==1) { tmpfile.ropen($s1) flag=1 } else { tmpfile.ropen("aa") flag=1 } if (flag==1) if (isobj(aa,"List")) { aa.remove_all() } else { aa=new List() } while (tmpfile.gets(temp_string_)>0) { chop(temp_string_) tmpobj=new String(temp_string_) aa.append(tmpobj) } tmpobj=nil } //* Object identification //** objid() find information about object -- replaces var2obj, canobj, objnum obfunc objid () { local flag localobj xo xo=new Union() if (argtype(1)==1) sprint(xo.s,"tmpobj=%s",$o1) else sprint(xo.s,"tmpobj=%s",$s1) execute(xo.s) // change variable name to object name xo.o=tmpobj sprint(xo.s,"%s",xo.o) sscanf(xo.s,"%*[^[][%d]",&xo.x) return xo } //** var2obj() and canobj() -- find true object names // var2obj("tstr"[,"objvar"]) replaces variable name with actual name of the object // default into XO; optional second arg allows to place somewhere else // eg tstr="TC[0].ampa" var2obj(tstr) -> AMPA[0] proc var2obj () { local flag if (numarg()==1) flag=1 else flag=0 if (flag) sprint($s1,"XO=%s",$s1) else sprint($s1,"%s=%s",$s2,$s1) execute($s1) // change variable name to object name if (flag) sprint($s1,"%s",XO) else sprint($s1,"%s",$s2) printf("var2obj() PLEASE REPLACE WITH objid()\n") } //** objnum(OBJ) -- find object number func objnum () { local x localobj st st=new String() if (argtype(1)==1) sprint(st.s,"%s",$o1) else st.s=$s1 if (sscanf(st.s,"%*[^[][%d]",&x) != 1) x=-1 return x } //** strnum(str,"PRE") -- pull number out of a string func strnum () { local x localobj st st=new String2($s1) sfunc.tail(st.s,$s2,st.t) if (sscanf(st.t,"%d",&x) != 1) x=-99e99 return x } //** canobj(obj[,"OBJVAR"]) -- default will assign to XO // canonical object -- return canonical identity for an object // eg canobj(tc,"YO") -- figure out what tc is and assign it to YO proc canobj () { local flag if (numarg()==1) flag=1 else flag=0 if (flag) sprint(tstr,"XO=%s",$o1) else sprint(tstr,"%s=%s",$s2,$o1) execute(tstr) // change variable name to object name sprint(tstr,"%s",$o1) printf("canobj() PLEASE REPLACE WITH objid()\n") } //* push() and pop() for objects -- returns proc push () { local i for i=1,numarg() stack.append($oi) } //** pop() proc pop () { local i if ((numarg()>0 && stack.count=1) { for i=1,numarg() { $oi=stack.object(stack.count-1) stack.remove(stack.count-1) } } else { SO=stack.object(stack.count-1) stack.remove(stack.count-1) } } //* time() strdef tmstr tmstr="run()" func time () { local tti prtime() system("date") if (numarg()==1) execute1($s1) else execute1(tmstr) tti=prtime() if (tti<60) print tti,"s" else print tti/60,"m" system("date") return tti } // END /usr/site/nrniv/local/hoc/declist.hoc //================================================================ if (myid == 0) print "Loading decvec" {symnum = 7 colnum = 9} func cg () { return $1%colnum+1 } // skip white color objref clrsym[colnum+1] for ii=0,colnum { clrsym[ii]=new String2() } // black->red->blue->green->orange->brown->violet->yellow->grey {clrsym[0].s="white" clrsym[1].s="black" clrsym[2].s="red" clrsym[3].s="blue" clrsym[4].s="green" clrsym[5].s="orange" clrsym[6].s="brown" clrsym[7].s="violet" clrsym[8].s="yellow" clrsym[9].s="grey"} {clrsym[0].t="o" clrsym[1].t="t" clrsym[2].t="s" clrsym[3].t="O" clrsym[4].t="T" clrsym[5].t="S" clrsym[6].t="+"} { MSONUM=100 MSOSIZ=100 msomax=0 msoptr=0 objref mso[MSONUM] } double x[4],y[4] xx=0 // declare a scalar ind = new Vector(100) tvec = new Vector(100) vec = new Vector(100) vec0 = new Vector() vec1 = new Vector() vrtmp = new Vector() veclist = new List() veccollect = new List() rdm = new Random() {rdm.MCellRan4()} if (!(xwindows && name_declared("xwindows"))) { xwindows=0 objref graphItem strdef temp_string_, temp_string2_ } strdef xtmp,space // do not create a file here //if (wopen("xtmp")) xtmp = "xtmp" else xtmp="/tmp/xtmp" // scratch file to save system output to //* stuff that doesn't belong here //** dired([list,]file) - put together list of files matching 'file', calls 'ls -1 file' // dired([list,]file,1) file name to read for list of files // dired([list,]file,2) clear dir first; if list isn't present assume 'dir' proc dired () { local f,fs1 f=fs1=0 if (numarg()==0) { print "dired([list,]filename[,flag])\t\ adds the filename to list (use wildcards) (flag:1 read file;flag:2 clear list)" return } if (argtype(1)==2) fs1=1 // list name not give, assume 'dir' if (fs1 && numarg()==2) { if ($2==2) dir.remove_all if ($2==1) { tmpfile.ropen($s1) f=1 } } if (numarg()==3) { if ($3==2) $o1.remove_all if ($3==1) { tmpfile.ropen($s2) f=1 } } if (!f) { if (fs1) { sprint(temp_string_,"ls -1R %s > %s",$s1,xtmp) // list in order of creation time } else { sprint(temp_string_,"ls -1R %s > %s",$s2,xtmp) // list in order of creation time } system(temp_string_) tmpfile.ropen(xtmp) } while (tmpfile.scanstr(temp_string_) != -1) { tmpobj=new String() tmpobj.s=temp_string_ if (fs1) dir.append(tmpobj) else $o1.append(tmpobj) tmpfile.gets(temp_string_) // get rid of the rest of the line } if (fs1) printf("%d files in dir\n",dir.count) else printf("%d files in %s\n",$o1.count,$o1) } // lsdir([dir]) proc lsdir () { if (numarg()==1) { for ltr($o1) {sprint(tstr,"ls -l %s",XO.s) system(tstr)} } else for ltr(dir) {sprint(tstr,"ls -l %s",XO.s) system(tstr)} } //** lbrw(list,action) is used to put up a browser // note action given without '()' proc lbrw () { $o1.browser($s2,"s") sprint($s2,"%s()",$s2) $o1.accept_action($s2) } //** l2v(S1,S2) makes a list(S1) and puts all the XO.S2 into vec // eg l2v("IClamp","amp") proc l2v () { tmpobj=new List($s1) if (numarg()==3) YO=$o3 else YO=vec YO.resize(tmpobj.count) YO.resize(0) for ltr(tmpobj) { sprint(tstr,"YO.append(%s.%s)",XO,$s2) execute(tstr) } } //* vector iterator vtr // usage 'for vtr(&x, vec) { print x }' iterator vtr () { local i if (numarg()==3) {$&3=0} else {i1 = 0} if (numarg()==1) { for i = 0,$o1.size()-1 { x = $o1.x[i] iterator_statement i1+=1 } } else { for i = 0,$o2.size()-1 { $&1 = $o2.x[i] iterator_statement if (numarg()==3) { $&3+=1 } else { i1+=1 } } } } //* vector iterator vtr2, treat two vectors as pairs // usage 'for vtr2(&x, &y, vec1, vec2) { print x,y }' iterator vtr2 () { local i,pairwise,noi1 noi1=pairwise=0 if (numarg()==3) { pairwise=1 i1=0 } if (numarg()==4) if (argtype(4)==3) { pairwise=1 $&4=0 noi1=1} if (pairwise) if ($o3.size%2!=0) { print "vtr2 ERROR: vec not even sized." return } if (! pairwise) { if ($o3.size != $o4.size) { print "vtr2 ERROR: sizes differ." return } if (numarg()==5) {$&5=0 noi1=1} else {i1 = 0} } for i = 0,$o3.size()-1 { $&1 = $o3.x[i] if (pairwise) $&2=$o3.x[i+=1] else $&2=$o4.x[i] iterator_statement if (noi1) { if (pairwise) $&4+=1 else $&5+=1 } else i1+=1 } } //** viconv(TARG,OLD_INDS,NEW_INDS) proc viconv () { local a,b if (numarg()==0) { printf("viconv(TARG,OLD_INDS,NEW_INDS)\n") return } a=b=allocvecs(2) b+=1 if ($o2.size!=$o3.size) {printf("OLD_INDS %d != NEW_INDS %d\n",$o2.size,$o3.size) return} mso[b].resize($o1.size) for vtr2(&x,&y,$o2,$o3) { // x -> y mso[a].indvwhere($o1,"==",x) mso[b].indset(mso[a],y) } $o1.copy(mso[b]) dealloc(a) } //* iterator lvtr, step through a list and a vector together // usage 'for lvtr(XO, &x, list, vec) { print XO,x }' iterator lvtr() { local i if ($o3.count < $o4.size) { printf("lvtr ERROR: vecsize > listsize: list %d,vec %d.\n",$o3.count,$o4.size) return } if ($o3.count != $o4.size) { printf("lvtr WARNING: sizes differ: list %d,vec %d.\n",$o3.count,$o4.size) } if (numarg()==5) {$&5=0} else {i1 = 0} for i = 0, $o4.size()-1 { $o1 = $o3.object(i) $&2 = $o4.x[i] iterator_statement if (numarg()==5) { $&5+=1 } else { i1+=1 } } } //* other iterators: case, scase, ocase iterator case () { local i i1 = 0 for i = 2, numarg() { $&1 = $i iterator_statement i1+=1 } } iterator scase () { local i,min i1 = 0 if (argtype(1)==1) min=2 else min=1 for i = min, numarg() { if (min==1) temp_string_=$si else $o1=new String($si) iterator_statement i1+=1 } } iterator scas () { local i,flag i1 = 0 if (argtype(1)==2) flag=1 else flag=0 for i = 2, numarg() { if (flag) $s1=$si else $o1=new String($si) iterator_statement i1+=1 } } // scasf() allows choice of string for saving iterator scasf() { local i i1 = 0 for i = 2, numarg() { $s1 = $si iterator_statement i1+=1 } } // eg for scase2("a","b","c","d","e","f") print tmpobj.s,tmpobj.t iterator scase2() { local i i1 = 0 if (numarg()%2==1) {print "ERROR: scase2 needs even number of args" return } for i = 1, numarg() { tmpobj=new String2() tmpobj.s=$si i+=1 tmpobj.t=$si iterator_statement i1+=1 } } iterator ocase() { local i i1 = 0 if (isassigned($o1)) { for i = 1, numarg() { XO = $oi iterator_statement i1+=1 } } else { for i = 2, numarg() { $o1 = $oi iterator_statement i1+=1 } } } //* strm(STR,REGEXP) == regexp string match func strm () { return sfunc.head($s1,$s2,"")!=-1 } func strc () { return strcmp($s1,$s2)==0 } //** count_substr(str,sub): count occurences of substring in str func count_substr () { local cnt cnt = 0 while (sfunc.tail($s1,$s2,$s1) != -1) { cnt += 1} return cnt } //* nind(targ,data,ind) fill the target vector with data NOT index by ind (opposite of v.index) proc nind () { if (! eqobj($o1,$o2)) $o1.copy($o2) $o1.indset($o3,-1e20) $o1.where($o1,">",-1e20) } //* vlk(vec) // vlk(vec,max) // vlk(vec,min,max) // prints out a segment of a vector vlk_width=20 space=" " proc vlk () { local i,j,min,max,dual,wdh,nonl j=dual=0 nl=1 wdh=vlk_width if (numarg()==1) { min=0 max=$o1.size-1 } if (numarg()==2) { if (argtype(2)==0) { if ($2==0) { nl=min=0 max=$o1.size-1 // vlk(vec,0) flag to suppress new lines } else if ($2>0) { min=0 max=$2-1 } else { min=$o1.size+$2 max=$o1.size-1 } } else { dual=1 min=0 max=$o1.size-1 } } if (numarg()==3) { if (argtype(2)==0) if ($3>-1) { min=$2 max=$3 } if (argtype(2)==1) { dual=1 if ($3>=0) { min=0 max=$3 } else { min=$o1.size+$3 max=$o1.size-1 } } } if (numarg()==4) { min=$3 max=$4 dual=1 } if (min<0) min=0 if (max>$o1.size-1) { max=$o1.size-1 printf("vlk: max beyond $o1 size\n") } if (dual) if (max>$o2.size-1) { max=$o2.size-1 printf("vlk: max beyond $o2 size\n") } for i=min,max { if (dual) printf("%g:%g%s",$o1.x[i],$o2.x[i],space) else printf("%g%s",$o1.x[i],space) if ((j=j+1)%vlk_width==0 && nl && strcmp(space," ")==0) { print "" } } if (nl) print "" } //** vlkp(SRC,PVEC) uses indices in PVEC to print out values in SRC proc vlkp () { local i,j,wdh j=0 nl=1 wdh=vlk_width if (numarg()==2) { for vtr(&x,$o1) { printf("%g%s",$o2.x[x],space) if ((j=j+1)%vlk_width==0 && nl && strcmp(space," ")==0) { print "" } } } else { for vtr(&x,$o1) { for i=2,numarg() printf("%g%s",$oi.x[x],space) print "" } } if (nl) print "" } //* vprf() prints 1,2 or 3 vectors in parallel to output file proc vprf () { local x2 if (! tmpfile.isopen()) { print "Writing to temp file 'temp'" tmpfile.wopen("temp") } if (numarg()==1) { for vtr(&x,$o1) { tmpfile.printf("%g\n",x) } } else if (numarg()==2) { for vtr2(&x,&y,$o1,$o2) { tmpfile.printf("%g %g\n",x,y) } } else if (numarg()==3) { for vtr2(&x,&y,$o1,$o2,&ii) { x2=$o3.x[ii] tmpfile.printf("%g %g %g\n",x,y,x2) } } tmpfile.close } //* vpr() prints 1,2 or 3 vectors in parallel to STDOUT proc vpr () { local x2 if (numarg()==1) { for vtr(&x,$o1) { printf("%g ",x) } } else if (numarg()==2) { for vtr2(&x,&y,$o1,$o2) { printf("%g:%g ",x,y) } } else if (numarg()==3) { for vtr2(&x,&y,$o1,$o2,&ii) { x2=$o3.x[ii] printf("%g:%g:%g ",x,y,x2) } } print "" } //* readvec(vec) read from line proc readvec () { $o1.resize(0) while (read(xx)) $o1.append(xx) vlk($o1) } //* popvec(), savenums, readnums, vecsprint, savevec, savestr // vrsz(), vcp(), zvec(), resize, copy, empty proc pushvec () { local i // same as .append, retained for compatability for i=2, numarg() $o1.append($i) } //** insvec(VEC,IND,VAL1[,VAL2,...]) insert values into the vector proc insvec () { local ix,i,a // insert values into a vector a=allocvecs(1) ix=$2 for i=3, numarg() mso[a].append($i) $o1.insrt(ix,mso[a]) dealloc(a) } //** revec() clear vector then append proc revec () { local i // clear vector then append if (! isobj($o1,"Vector")) $o1 = new Vector() $o1.resize(0) if (numarg()>1) if (argtype(2)==1) { for i=2,numarg() $oi.resize(0) } else { for i=2,numarg() if (argtype(i)==0) $o1.append($i) else $o1.append($&i) } } //** unvec(VEC,&a,&b,...) put values from vector back into doubles (via pointers) proc unvec () { local i if ($o1.size!=numarg()-1) { printf("unvec WARNING resizing %s to %d\n",$o1,numarg()-1) $o1.resize(numarg()-1) } for i=2,numarg() $&i=$o1.x[i-2] } //** wevec(VEC,wt0,wt1,...) returned weighted sum func wevec () { local i,sum if ($o1.size!=numarg()-1) { printf("wevec SIZE ERR %d %d\n",$o1.size,numarg()-1) return } sum=0 for i=2,numarg() sum+=$o1.x[i-2]*$i return sum } //** vrsz(VEC or NUM,VEC1,VEC2...,VECn or NUM) -- vector resize -- to size of first arg // optional final number is fill proc vrsz () { local i,sz,max,fill,flag max=numarg() if (argtype(1)==1) sz=$o1.size else sz=$1 if (argtype(max)==0) {i=max max-=1 fill=$i flag=1} else flag=0 for i=2, max { $oi.resize(sz) if (flag) $oi.fill(fill) } } //** vcp() -- copy vector segment with resizing proc vcp () { local i,sz $o1.resize($4-$3+1) $o1.copy($o2,$3,$4) } //** veccut(VEC,min,max) just keep a piece of the vector // veccut(VEC,min,max,tstep) generate indices from times using tstep proc veccut () { local a localobj v1 a=allocvecs(v1) if (numarg()==4) { min=round($2/$4) max=round($3/$4) } else { min=$2 max=$3 } v1.copy($o1,min,max) $o1.copy(v1) dealloc(a) } //** zvec() proc zvec () { local i // make vectors zero size for i=1, numarg() $oi.resize(0) } //* save and read series //** savenums(x[,y,...]) save numbers to tmpfile via a vector proc savenums () { local i,vv vv=allocvecs(1) for i=1, numarg() mso[vv].append($i) mso[vv].vwrite(tmpfile) dealloc(vv) } //** savedbls(&x,sz) save a double array of size sz proc savedbls () { local vv,i vv=allocvecs(1) mso[vv].from_double($2,&$&1) mso[vv].vwrite(tmpfile) dealloc(vv) } //** readnums(&x[,&y...]) recover nums from tmpfile via a vector func readnums () { local vv,i,cnt vv=allocvecs(1) cnt=0 if (mso[vv].vread(tmpfile)) { if (numarg()!=mso[vv].size) { printf("readnums WARNING: args=%d;vec.size=%d\n",numarg(),mso[vv].size) if (numarg()>mso[vv].size) { for i=1,mso[vv].size $&i = mso[vv].x[i-1] cnt=mso[vv].size } } if (cnt==0) { for i=1,numarg() $&i = mso[vv].x[i-1] cnt=numarg() } } else cnt=-1 dealloc(vv) return cnt } //** readdbls(&x,sz) read a double array of size sz func readdbls () { local vv,i,flag vv=allocvecs(1) flag=1 if (mso[vv].vread(tmpfile)) { mso[vv].v2d(&$&1) // seg error risk } else flag=0 dealloc(vv) return flag } //** wrvstr(str) save string to a file by converting to ascii proc wrvstr () { local vv,i vv=allocvecs(1) str2v($s1,mso[vv]) mso[vv].vwrite(tmpfile,1) dealloc(vv) } //** rdvstr(str) read string from a file via vread and conversion func rdvstr () { local vv,i,flag flag=1 vv=allocvecs(1) if (mso[vv].vread(tmpfile)) { if (numarg()==1) v2str(mso[vv],$s1) else v2str(mso[vv],tstr) } else flag=0 dealloc(vv) return flag } //** str2v() proc str2v () { localobj lo lo=new String() $o2.resize(0) lo.s=$s1 while (sfunc.len(lo.s)>0) { sscanf(lo.s,"%c%*s",&x) sfunc.right(lo.s,1) $o2.append(x) } } //** v2str() translates from vector to string proc v2str () { local ii,x $s2="" round($o1) for ii=0,$o1.size-1 { x=$o1.x[ii] sprint($s2,"%s%c",$s2,x) } } //* popvec() remove last entry func popvec () { local sz, ret sz = $o1.size-1 if (sz<0) return 1e9 ret = $o1.x[sz] $o1.resize[sz] return ret } //* chkvec (look at last entry) func chkvec () { if ($o1.size>0) return $o1.x[$o1.size-1] else return -1e10 } // vecsprint(strdef,vec) proc vecsprint () { local ii if ($o2.size>100) { return } for ii=0,$o2.size-1 { sprint($s1,"%s %g ",$s1,$o2.x[ii]) } } // savevec([list,]vec1[,vec2,...]) add vector onto veclist or other list if given as 1st arg // don't throw out vectors func savevec () { local i,flag,beg if (numarg()==0) { savevec(hoc_obj_[0],hoc_obj_[1]) return } if (isobj($o1,"List")) beg=2 else beg=1 for i=beg, numarg() { if (veccollect.count>0) { // grab a vector from garbage collection tmpvec=veccollect.object(veccollect.count-1) veccollect.remove(veccollect.count-1) } else tmpvec = new Vector($oi.size) tmpvec.copy($oi) if (beg==2) $o1.append(tmpvec) else veclist.append(tmpvec) tmpvec = nil } if (beg==2) return $o1.count-1 else return veclist.count-1 } proc prveclist () { if (tmpfile.ropen($s1)) { printf("%s exists; save anyway? (y/n) ",$s1) getstr(temp_string_) chop(temp_string_) if (strcmp(temp_string_,"y")!=0) return } if (! tmpfile.wopen($s1)) { print "Can't open ",$s1 return } if (numarg()==2) { for ltr(XO,$o2) XO.vwrite(tmpfile) } else { for ltr(XO,veclist) XO.vwrite(tmpfile) } tmpfile.close() } // rdveclist("FILENAME"[,list]) // rdveclist("FILENAME"[,NOERASE]) proc rdveclist () { local flag,a flag=0 a=allocvecs(1) if (numarg()==1) { flag=1 clrveclist() } else if (argtype(2)==1) $o2.remove_all else flag=1 if (! tmpfile.ropen($s1)) { print "Can't open ",$s1 return } while (mso[a].vread(tmpfile)) { if (flag) savevec(mso[a]) else savevec($o2,mso[a]) } tmpfile.close() tmpobj=veclist dealloc(a) } // rdvecs("FILENAME",vec1,vec2,...) proc rdvecs () { local i if (! tmpfile.ropen($s1)) { print "Can't open ",$s1 return } for i=2,numarg() if ($oi.vread(tmpfile)==0) printf("WARNING nothing to read into %s\n",$oi) tmpfile.close() } // svvecs("FILENAME",vec1,vec2,...) proc svvecs () { local i clrveclist() for i=2,numarg() savevec($oi) prveclist($s1) } // vpad(vec,howmany,val[,right]) proc vpad () { local a a=allocvecs(1) mso[a].resize($2) mso[a].fill($3) if (numarg()==4) $o1.append(mso[a]) else { mso[a].append($o1) $o1.copy(mso[a]) } dealloc(a) } // vtrunc(vec,howmany[,right]) proc vtrunc () { local a if (numarg()==3) $o1.resize($o1.size-$2) else { $o1.reverse $o1.resize($o1.size-$2) $o1.reverse } } proc rdxy () { local a a = allocvecs(1) revec(ind,vec) tmpfile.ropen("aa") mso[a].scanf(tmpfile) if (mso[a].size%2!=0) {print "rdxy ERR1 ",mso[a].size return} for vtr2(&x,&y,mso[a]) {ind.append(x) vec.append(y)} print ind.size," points read from aa into ind and vec" dealloc(a) } // closest(vec,num) -- return ind for vec member closest to num func closest () { local a,ret a=allocvecs(1) mso[a].copy($o1) mso[a].sub($2) mso[a].abs ret=mso[a].min_ind dealloc(a) return ret } // memb(TEST#,#1,#2,...) -- true if the TEST# is in the list func memb () { local na,i for i=2,numarg() if ($1==$i) return 1 return 0 } proc clrveclist () { for ltr(XO,veclist) { XO.resize(0) veccollect.append(XO) } veclist.remove_all() } // savestr(str1...) add string obj onto tmplist proc savestr () { local i if (argtype(1)==1) for i=2, numarg() $o1.append(new String($si)) else { for i=1, numarg() tmplist.append(new String($si)) } } // redund with v.count in vecst.mod func vcount () { local val,sum val=$2 sum=0 for vtr(&x,$o1) if (x==val) sum+=1 return sum } // tvecl() -- transpose veclist proc tvecl () { local cnt,sz,err,ii,p err = 0 cnt = veclist.count sz = veclist.object(0).size for ltr(XO,veclist) if (XO.size!=sz) err=i1 if (err) { print "Wrong size vector is #",i1 return } p = allocvecs(1,cnt) mso[p].resize(cnt) for ii=0,sz-1 { for jj=0,cnt-1 { XO=veclist.object(jj) mso[p].x[jj] = XO.x[ii] } savevec(mso[p]) } for (jj=cnt-1;jj>=0;jj-=1) { veccollect.append(veclist.object(jj)) veclist.remove(jj) } } //* vinsect(v1,v2,v3) -- v1 gets intersection (common members) of v2,v3 // replaced by v.insct() in vecst.mod proc vinsect () { $o1.resize(0) for vtr(&x,$o2) for vtr(&y,$o3) if (x==y) $o1.append(x) } //* vecsplit(vec,vec1,vec2[,vec3,...]) // splits vec into other vecs given proc vecsplit () { local num,ii,i num = numarg()-1 // how many for i=2,numarg() $oi.resize(0) for (ii=0;ii<$o1.size;ii+=num) { for i=2,numarg() if (ii+i-2<$o1.size) $oi.append($o1.x[ii+i-2]) } } //* vecsort(vec,vec1,vec2[,vec3,...]) // sorts n vecs including first vec by first one proc vecsort () { local i,inv,scr,narg narg=numarg() if (narg<2 || narg>10) {print "Wrong #args in decvec.hoc:vecsort" return} scr=inv=allocvecs(2) scr+=1 $o1.sortindex(mso[inv]) mso[scr].resize(mso[inv].size) sprint(temp_string_,"%s.fewind(%s,%s,%s",mso[scr],mso[inv],$o1,$o2) for i=3,narg sprint(temp_string_,"%s,%s",temp_string_,$oi) sprint(temp_string_,"%s)",temp_string_) execute(temp_string_) dealloc(inv) } //* vdelind() -- delete a single index proc vdelind () { local i,iin iin = $2 if (iin<0) iin=$o1.size+iin if (iin>$o1.size-1 || iin<0) { printf("vdelind Error: index %d doesn't exist.\n",iin) return } if (iin<$o1.size-1) $o1.copy($o1,iin,iin+1,$o1.size-1) $o1.resize($o1.size-1) } //* mkveclist(num[,sz]) recreate veclist to have NUM vecs each of size SZ (or MSOSIZ) proc mkveclist () { local ii,num,sz,diff num=$1 diff = num-veclist.count if (numarg()==2) { sz=$2 } else { sz = MSOSIZ } if (diff>0) { for ii=0,diff-1 { tmpvec = new Vector(sz) veclist.append(tmpvec) } } else if (diff<0) { for (ii=veclist.count-1;ii>=num;ii=ii-1) { veclist.remove(ii) } } for ltr(XO,veclist) { XO.resize(sz) } } //* allocvecs // create temp set of vectors on mso // returns starting point on mso // eg p = allocvecs(3) // or p = allocvecs(v1,v2,v3) // where v1..v3 are localobj // access these vectors by mso[p+0] ... [p+2] func allocvecs () { local i,ii,llen,sz,newv,aflg,lflg localobj o if (numarg()==0) { print "p=allocvecs(#) or p=allocvecs(v1,v2,...), access with mso[p], mso[p+1]..." return 0 } sz=MSOSIZ lflg=0 if (argtype(1)==0) { aflg=0 newv=$1 if (numarg()==2) if (argtype(2)==0) sz=$2 else {lflg=1 o=$o2} if (numarg()==3) {sz=$2 lflg=1 o=$o3} // append to list in arg3 if (lflg) o.remove_all } else { aflg=1 if (argtype(numarg())==0) { i=numarg() sz=$i newv=i-1 } else newv=numarg() } llen = msoptr for ii=msomax,msoptr+newv-1 { // may need new vectors if (ii>=MSONUM) { print "alloc ERROR: MSONUM exceeded." return 0 } mso[ii] = new Vector(sz) } for ii=0,newv-1 { mso[msoptr].resize(sz) mso[msoptr].resize(0) msoptr = msoptr+1 } if (msomax0) printf("%d/%d (%g)\n",ret,$o1.size,ret/$o1.size*100) dealloc(a) return ret } //** civw(DEST,SRC1,STR1,x1[,y1]...) does compound indvwhere // overwrites tstr; DEST should be size 0 unless to be compounded // civw(DEST,0,...) will resize DEST to 0 func civw () { local i,a,b,c,f2,x,y,sz,min a=b=c=allocvecs(3) b+=1 c+=2 min=2 // if ($o1.size>0) print "Starting with previously set index vector" if (argtype(2)==0) { if ($2==0) { $o1.resize(0) min=3 if (argtype(3)==1) sz=$o3.size else { printf("ERR0: arg 3 should be obj when $2==0\n",i) return -1 } } else { printf("ERR0a: arg 2 should be 0 if a number -- zero sizes ind vector\n") return -1 } } else if (argtype(2)==1) sz=$o2.size else { printf("ERR0b: arg 2 should be obj\n",i) return -1 } for (i=min;i<=numarg();) { mso[c].copy($o1) if (argtype(i)!=1) { printf("ERR1: arg %d should be obj\n",i) return -1} if ($oi.size!=sz) { printf("ERR1a: all vecs should be size %d\n",sz) return -1} mso[a].copy($oi) i+=1 // look in a if (argtype(i)!=2) { printf("ERR2: arg %d should be str\n",i) return -1} tstr=$si i+=1 if (strm(tstr,"[[(]")) f2=1 else f2=0 // opstring2 needs 2 args if (argtype(i)!=0) { printf("ERR3: arg %d should be dbl\n",i) return -1} x=$i i+=1 if (f2) { if (argtype(i)!=0) { printf("ERR4: arg %d should be dbl\n",i) return -1} y=$i i+=1 } if (f2) mso[b].indvwhere(mso[a],tstr,x,y) else { // the engine mso[b].indvwhere(mso[a],tstr,x) } $o1.resize(sz) // make sure it's big enough for insct -- shouldn't need if (mso[c].size>0) $o1.insct(mso[b],mso[c]) else $o1.copy(mso[b]) if ($o1.size==0) break } dealloc(a) return $o1.size } //* vecconcat(vec1,vec2,...) // destructive: concatenates all vecs onto vec1 proc vecconcat () { local i if (numarg()<2) { print "vecconcat(v1,v2,...) puts all into v1" return } for i=2,numarg() { $o1.copy($oi,$o1.size) } } //** vecelim(v1,v2) eliminates items in v1 given by index vec v2 proc vecelim () { for vtr(&x,$o2) { $o1.x[x]= -1e20 } $o1.where($o1,"!=",-1e20) } //** redundout(vec) eliminates sequential redundent entries // destructive func redundout () { local x,ii,p1 p1=allocvecs(1) $o1.sort mso[p1].resize($o1.size) mso[p1].redundout($o1) $o1.copy(mso[p1]) dealloc(p1) return $o1.size } //** uniq(src,dest[,cnt]) uses redundout to return random values of a vector // like redundout except nondestructive obfunc uniq () { local a localobj v1,vret a=allocvecs(v1) v1.copy($o1) v1.sort if (numarg()==3) { $o2.redundout(v1,0,$o3) } else if (numarg()==2) { $o2.redundout(v1) } else { vret=new Vector(v1.size) vret.redundout(v1) } dealloc(a) if (numarg()==1) return vret else return $o2 } //** complement(ind,max) for indices -- return values from 0..max that are not in ind proc complement () { local a,b,max a=b=allocvecs(2) b+=1 max=$2 mso[a].indgen(0,max,1) mso[b].resize(mso[a].size) mso[b].cull(mso[a],$o1) $o1.copy(mso[b]) dealloc(a) } proc albetname () { local ii ii=$1 if (ii>17575) printf("albetname WARN: out of names\n") // 26^3-1 if (numarg()==3) { sprint($s2,"%c%c%c%s",ii/26/26%26+97,ii/26%26+97,ii%26+97,$s3) } else sprint($s2,"%c%c%c", ii/26/26%26+97,ii/26%26+97,ii%26+97) } // vecconv() convert $o1 by replacing instances in $o2 by corresponding instances in $o3 proc vecconv () { local a,b a=b=allocvecs(2) b+=1 vrsz($o1,mso[b]) for vtr2(&x,&y,$o2,$o3) { // x -> y mso[a].indvwhere($o1,"==",x) mso[b].indset(mso[a],y) } $o1.copy(mso[b]) } //** veceq() like vec.eq but don't have to be same size and shows discrepency func veceq () { local sz1,sz2,eq,beg,ii,jj,kk sz1=$o1.size sz2=$o2.size if (numarg()==3) beg=$3 else beg=0 if (sz1!=sz2) printf("%s %d; %s %d\n",$o1,sz1,$o2,sz2) ii=0 jj=beg while (ii=0 && (ii+kk)=0 && (jj+kk)=1) { sfunc.left($s1,ln1-1) return 1 } else { print "ERR: chop called on empty string" } return 0 } // lchop(STR[,BEGIN]) -- chop from the left func lchop () { local ln1,match ln1=sfunc.len($s1) if (numarg()==2) { sprint($s2,"^%s",$s2) // just look for initial chars if ((match=sfunc.tail($s1,$s2,temp_string2_))==-1) { return 0 } else { sfunc.right($s1,match) return match } } else if (sfunc.len($s1)>=1) { sfunc.right($s1,1) return 1 } else { print "ERR: chop called on empty string" } return 0 } proc concat () { local i for i=2,numarg() sprint($s1,"%s%s",$s1,$si) } proc concat () { local i for i=2,numarg() sprint($s1,"%s%s",$s1,$si) } // eg split("534, 43 , 2, 1.4, 34",vec[,"/"]) // split("13, 3*PI/2*tau/2, 32+7, 6, 9.2, 42/3",vec) // optional 3rd str is what to split on; default is comma func split () { local vf,x localobj s if (numarg()==0) { printf("eg split(\"534 43 2 1.4 34\",vec,\" \") split(\"a,b,c,d,e\",tmplist)") return -1 } s = new String2() if (isobj($o2,"Vector")) vf=1 else vf=0 if (vf) revec($o2) else $o2.remove_all s.t=$s1 while (sfunc.len(s.t)>0) { if (vf) { if (strm(s.t,"^[^,]+[+*/-]")) { sfunc.head(s.t,",",s.s) if (sfunc.len(s.s)==0) s.s=s.t sprint(s.s,"%s.append(%s)",$o2,s.s) execute(s.s) } else if (sscanf(s.t,"%lf",&x)) { $o2.append(x) // throw out non-numbers } // else printf("split WARNING non-number: %s\n",s.t) } else { if (numarg()==3) sfunc.head(s.t,$s3,s.s) else { sfunc.head(s.t,",",s.s) } if (sfunc.len(s.s)==0) s.s=s.t // the end $o2.append(new String(s.s)) } if (numarg()==3) sfunc.tail(s.t,$s3,s.t) else { sfunc.tail(s.t,",",s.t) } } if (vf) return $o2.size else return $o2.count } // extract("STR","PARAM=") looks for PARAM= in STR and returns value that follows func extract () { localobj o o=new Union() sfunc.tail($s1,$s2,o.s) sscanf(o.s,"%lf",&o.x) return o.x } // intervals(TRAIN,OUTPUT) proc intervals () { local a if ($o1.size<=1) { printf("%s size <2 in intervals()\n",$o1) return } $o2.deriv($o1,1,1) } // downcase(tstr[,UPCASE]) proc downcase () { local len,ii,let,diff,min,max diff=32 min=65 max=90 if (numarg()==2) { diff=-diff min=97 max=122 } // if flag -> upcase len = sfunc.len($s1) for ii=1,len { sscanf($s1,"%c%*s",&x) sfunc.right($s1,1) if (x>=min&&x<=max) { sprint($s1,"%s%c",$s1,x+diff) } else sprint($s1,"%s%c",$s1,x) // just rotate the letter } } // newlst() puts a newline in the middle of a string proc newlst () { local l if (numarg()>1) l=$2 else l=int(sfunc.len($s1)/2) temp_string_=$s1 temp_string2_=$s1 sfunc.left(temp_string_,l) sfunc.right(temp_string2_,l) sprint($s1,"%s\n%s",temp_string_,temp_string2_) } //* rdcol(file,vec,col#,cols): read multicolumn file func rdcol () { local col,cols,length if (numarg()==0) { print "\trdcol(\"file\",vec,col#,cols) // col#=1..." return 0} col=$3 cols=$4 length=0 if (! tmpfile.ropen($s1)) { printf("\tERROR: can't open file \"%s\"\n",$s1) return 0} while (tmpfile.gets(temp_string_) != -1) length+=1 // count lines print length tmpfile.seek() $o2.scanf(tmpfile,length,col,cols) if ($o2.size!=length) printf("rdcol ERR: only read %d statt %d\n",$o2.size,length) return length } //* hist(g,vec,min,max,bins) {clr=1 hflg=0 ers=1} // clr:color, hflg=1 draw lines; 2 draw boxes; 3 fill in; ers=erase // style determined by hflg // hflg==0 lines with dots // hflg==0.x offset lines with dots // hflg==1 outlines but not down to zero // hflg==2 outlines with lines down to zero // hflg==3 just dots proc hist () { local a,b,c,min,max,wid,bins,ii,jj,offset if (numarg()==5) {min=$3 max=$4 bins=$5 } else if (numarg()==4) { min=0 max=$3 bins=$4 } else if (numarg()==3) { min=$o2.min-.1 max=$o2.max+.1 bins=$3 } else if (numarg()==2) { min=$o2.min-.1 max=$o2.max+.1 bins=int(max-min) } else { printf("hist(g,vec,min,max,bins)\n") return } wid=(max-min)/bins a=b=c=allocvecs(3) b+=1 c+=2 offset=0 if (ers) $o1.erase_all() mso[c].hist($o2,min,bins,wid) // c has values mso[a].resize(2*mso[c].size()) mso[a].indgen(0.5) mso[a].apply("int") mso[b].index(mso[c], mso[a]) mso[a].mul(wid) mso[a].add(min) mso[b].rotate(1) mso[b].x[0] = 0 mso[b].append(mso[b].x[mso[b].size-1],0) mso[a].append(max,max) if (hflg==1 || hflg==2) { mso[b].line($o1, mso[a],clr,4) if (hflg==2) for vtr(&x,mso[a]) drline(x,0,x,mso[b].x[i1],$o1,clr,4) } else if (int(hflg)==0 || hflg==3) { if (hflg%1!=0) offset=hflg*wid // use eg -0.5+ii/8 to move back to integer mso[a].indgen(min,max-wid,wid) mso[a].add(wid/2+offset) print mso[a].min,mso[a].max // mso[c].mark($o1,mso[a],"O",6,clr,2) // this will place points where 0 count for jj=0,mso[a].size-1 if (mso[c].x[jj]!=0) { if (hflg!=3) drline(mso[a].x[jj],0,mso[a].x[jj],mso[c].x[jj],$o1,clr,4) $o1.mark(mso[a].x[jj],mso[c].x[jj],"O",6,clr,2) // don't place points with 0 count } } $o1.flush() $o1.size(min,max,0,mso[b].max) dealloc(a) } //** drline(x0,y0,x1,y1,OPT graph or color) proc drline () { local color,line if (numarg()==0) { print "drline(x0,y0,x1,y1,OPT graph)" return } if (numarg()>4) { if (argtype(5)==0) { color=$5 if (numarg()>5) line=$6 } else { graphItem = $o5 if (numarg()>5) color=$6 if (numarg()>6) line=$7 }} graphItem.beginline(color,line) graphItem.line($1,$2) graphItem.line($3,$4) graphItem.flush() } //* rdmuniq(vec,n,rdm) -- augment vec by n unique vals from rdm // draw n numbers without replacement, only makes sense with discrete distribution // could do something like // mso[a].setrand($o3) mso[d].copy(mso[a]) // mso[b].indsort(mso[a]) mso[a].sort() mso[c].redundout(mso[a],1) // to get indices of unique values but then have to back index to original proc rdmuniq () { local n,num,flag,xx,loop,a a=allocvecs(1) n=$2 num=0 flag=1 loop=0 mso[a].resize(n*4) // hopefully will get what we want while (flag) { mso[a].setrand($o3) for ii=0,mso[a].size-1 { xx=mso[a].x[ii] if (! $o1.contains(xx)) { $o1.append(xx) num+=1 } if (num==n) { flag=0 break } } loop+=1 if (loop==10) { print "rdmunq ERR; inf loop" flag=0 break } } dealloc(a) } // rdmord (vec,n) randomly ordered numbers 0->n-1 in vec // eg rdmord(ind,ind.size); check: for ii=0,ind.size-1 if (ind.count(ii)!=1) print ii proc rdmord () { local n,a localobj v1 a=allocvecs(v1) n=$2 rdm.uniform(0,100) v1.resize(n) v1.setrand(rdm) v1.sortindex($o1) dealloc(a) } // shuffle(VSRC[,VDEST]) randomly rearrange elements of vec proc shuffle () { local a localobj v1,v2 a=allocvecs(v1,v2) rdmord(v1,$o1.size) v2.index($o1,v1) if (numarg()==2) $o2.copy(v2) else $o1.copy(v2) dealloc(a) } // sample(vec,beg,end,vals) pick out n integer values from given range // sample(vec,end,vals) -- assumes 0 proc sample () { local min,max,vals min=0 if (numarg()==4) {min=$2 max=$3 vals=$4} else {max=$2 vals=$3} $o1.indgen(min,max,1) shuffle($o1) $o1.resize(vals) } // round() round off to nearest integer func round () { local ii if (argtype(1)==1) { if ($o1.size==0) return 1e9 for ii=0,$o1.size-1 { if ($o1.x[ii]>0) $o1.x[ii]=int($o1.x[ii]+0.5) else $o1.x[ii]=int($o1.x[ii]-0.5) } return($o1.x[0]) } else { if ($1>0) return int($1+0.5) else return int($1-0.5) } } // filevers() pulls out version of file from first line func filevers () { localobj f1,s1,lx1 f1=new File() s1=new String() lx1=new Union() if (! f1.ropen($s1)) { printf("filevers ERR, can't open %s\n",$s1) return 0 } f1.gets(s1.s) if (sscanf(s1.s,"%*s $Id: %*s %*d.%d",&lx1.x)!=1) { printf("filevers ERR, sscanf failed %s: %s",$s1,s1.s) } f1.close return lx1.x } //* hocfind(FILENAME) searches through HOC_LIBRARY_PATH and locates file obfunc hocfind () { local done localobj f1,s1,s2 f1=new File() s1=new String() s2=new String() done=0 system("echo -n $HOC_LIBRARY_PATH",s1.s) sprint(s1.s,"%s ",s1.s) // to look at last item while (sfunc.len(s1.s)>2) { sfunc.head(s1.s,"[ :]",s2.s) sprint(s2.s,"%s/%s",s2.s,$s1) if (f1.ropen(s2.s)) {done=1 break} sfunc.tail(s1.s,"[ :]",s1.s) } if (!done) if (f1.ropen($s1)) {sprint(s2.s,"./%s",$s1) done=1} if (!done) s2.s="NOT FOUND" return s2 } //* usefiles(F1[,F2,...]) list of files returns string with list of files and versions obfunc usefiles () { local i localobj s1,s2 s2=new String() s2.s="Using " for i=1,numarg() { s1=hocfind($si) sprint(s2.s,"%s %s%d",s2.s,$si,filevers(s1.s)) } return s2 } // END /usr/site/nrniv/local/hoc/decvec.hoc //================================================================ gnum=-1 if (! name_declared("show_panel")) show_panel=1 proc file_with_dot(){} // stubs to declare later, otherwise external barfs proc filname(){} proc 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 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 strdef name,f double loc[1] proc init () { segs=1 if (numarg()>4) if (argtype(5)==0) segs=$5 else 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 begintemplate vitem external cvode public tvec,vec,name,tvflag,pstep,o,code objref tvec,vec,o // o not set here but used for Acells strdef 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 } vec=new Vector($2) if (numarg()==3) { // sloppy -- what if pstep=1?? if (argtype(3)==0) if ($3==1) tvflag=1 else {tvflag=0 pstep=$3} } if (numarg()==4) if ($4==1) tvflag=1 else {tvflag=0 pstep=$4} if (tvflag==1) tvec=new Vector($2) } endtemplate vitem //* main template: GRV // the attributes of a particular set of graphs including line colors, // world coordinates, ... // 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 public glist,oglist,llist,tvec,size,shift,vsz,vjmp,tloc,vloc,remote public entries,segments,clear 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 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 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 strdef comment,recstr,grvecstr,readtag,rvvec_name,grep,tstr,tstr2,ddir strdef temp_string_,temp_string2_,output_file,s,filename,mesg,regexp external sfunc,osname,vfile_line,vitem,uname,nil,simname,gnum,XO,YO,graphList external isobj,isit,mso,msoptr,allocvecs,dealloc,tstop,method,cvode,show_panel,rv2,rv3 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 // 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 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() 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=ojtnum(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,"",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 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 sprint(temp_string_,"*%s*",datestr) tmpfile.chooser("","Read from a file",temp_string_,"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 proc read_vfile () { local flag, ii, sz, loc, mult, sze, cloc, segs if (numarg()>=2) if (strcmp(filename,$s1)==0) return // 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 } } else { attr0=0 } if (numarg()>=1) filename=$s1 else tmpfile.getname(filename) if (strm(filename,"\.mf$")) {read_mf(filename) return} 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_,temp_string2_) // put .filename into temp_string_ if (!tmpfile.ropen(temp_string_)) { print "E1: Can't open ",temp_string_ // avoid grep error return } 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 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 } if (printStep==-1) rtvec() // code for cvode_active() mff=0 } //** 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) // 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,"O",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,"O",line,curcol) } } else if (o.num==-2) { nvplt(vrtmp,tvec) if (gvmarkflag) { if (! rvaltdisp(tvec,vrtmp,llist.object(inx).name)) { vrtmp.mark(graphItem,tvec,"O",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,"O",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 inx,clr,lin localobj o,v1 inx=-1 lin=line clr=color 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) { clr=$2 } if (numarg()>=3) { lin=$3 } o = printlist.object(inx) // rv2(o.vec) this damages the actual data -- bad -- want eg 'obfunc gv2()' for this 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,"O",lin,clr) } } else { if (o.tvflag==1) { nvplt(o.vec,o.tvec) if (gvmarkflag) { o.vec.mark(graphItem,o.tvec,"O",lin,clr) } else { o.vec.line(graphItem,o.tvec,clr,lin) } } else if (o.tvflag==-1) { // global cvode -- using global tvec nvplt(o.vec,tvec) if (gvmarkflag) { o.vec.mark(graphItem,tvec,"O",lin,clr) } else { o.vec.line(graphItem,tvec,clr,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,"O",lin,clr) } else { o.vec.line(graphItem,o.pstep,clr,lin) } } if (labelm) { grvecstr=printlist.object(inx).name rv3(grvecstr) graphItem.label(0.,0.9,grvecstr) } } 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 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) 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 } $o2.vread(tmpfile) $o3.vread(tmpfile) } else { if (n==-2) if (! tvec.vread(tmpfile)) { printf("rv_readvec tvec READ failure in %s %s %d\n",filename,o.name,inx) return 0 } 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 } } 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,...]) 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) } //** file_with_dot(filename,result,scratch): put .filename into result proc file_with_dot() { if (sfunc.substr($s1,"/") == -1) { sprint($s2,".%s",$s1) } else { sfunc.tail($s1,".*/",$s3) sfunc.head($s1,"/[^/]+$",$s2) sprint($s2,"%s/.%s",$s2,$s3) } } //** find_secname(variable,result): put secname into result proc find_secname () { 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 if (isit($s2)) { // the stem is an obj Xo.get_loc() // isit sets Xo 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 () { for ltr(Xo,glist) Xo.unmap glist.remove_all } //** clear() -- clears llist proc clear () { entries=1 segments=1 comment = "" llist.remove_all() } //* 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_v($s1,filename,tstr) // put vfilename into name print "Saving to ",filename pvplist(filename,temp_string2_) } } //** file_with_v(filename,result,scratch): put vfilename into result proc file_with_v() { if (sfunc.substr($s1,"/") == -1) { sprint($s2,".%s",$s1) } else { sfunc.tail($s1,".*/",$s3) sfunc.head($s1,"/[^/]+$",$s2) sprint($s2,"%s/v%s",$s2,$s3) } } //* 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 (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+=6 } else { gvmarkflag=0 if (line>6) line-=6 } 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,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,... proc npl () { local dur,nflag,tvflag,prstep // METHOD DEPENDENT if (! isobj(printlist,"List")) printlist = new List() tvflag=nflag=0 prstep=0.05 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) { // ?? } 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)) { printf("COMMENT: ") getstr(tstr) sfunc.head(tstr,"\n",comment) // chop final newline } } 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) print out the printlist with comment at head proc pvother () {} // user can dump other vectors at top with prvec() proc pvplist () { local inx output_file=$s1 if (! pvplist0()) return // open file(s) pvplist1($s2) // print string header pvout() if (numarg()<3) { // else leave for appending 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,st.t) // 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() } //** pvout() called by pvplist() and pvnext(), actually puts out the vecs proc pvout () { // METHOD DEPENDENT pvout2() if (cvode_status()==1.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 secname() // a section must exist 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 secname() // a section must exist 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 proc 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 } } 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 } 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) } 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) entries=llist.count mff=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_,temp_string2_) // 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) { 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# // not debugged for presence of tvec in cvode iterator rvtr () { local i,flag,s4flag if (numarg()>=2) {$&2=0} else {i1 = 0} if (numarg()==3) s4flag=1 else s4flag=0 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) iterator_statement if (numarg()>=2) { $&2+=1 } else { i1+=1 } } } } //** vrdr(vlist[,REGEXP or INDV,flag,&y]) -- used for llist // similar to rvtr() but does interpolation // use regexp eg for prdr("PYR2.8") { ... } // 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,nw localobj rxp,v1,tv1,v2,tv2,ipt if (numarg()==0) printf("\t**** HELP:: vrdr(vlist[,REGEXP or INDV,flag,&y]) ****\n") rxp=new String() a=allocvecs(v1,tv1,v2,tv2,ipt) if (!isojt($o1,llist)) $o1=new List() if ($o1.count==4) { // use the list we're given nw=0 printf("vrdr() WARNING: reusing veclist -- could interfere with allocvecs\n") for ii=0,3 if (!isojt($o1.o(ii),vrtmp)) { printf("vrdr: Nonvector in vlist:%s\n",$o1.o(ii)) return } v1=$o1.o(0) tv1=$o1.o(1) v2=$o1.o(2) tv2=$o1.o(3) } else { nw=1 $o1.remove_all for ii=0,3 $o1.append(mso[a+ii]) } 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 {i1 = 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 (i1=0;i1=4) { $&4+=1 } } } if (nw) $o1.remove_all dealloc(a) tmpfile.close } //** prdr() -- used for printlist // use regexp eg for prdr("PYR2.8") { ... } // optional flag to NOT interpolate // ind=tvec, vec1=original trace, vec interpolated on tvec // note that i1 here gives list number, not sequential 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 } for (i1=0;i10) { 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,... 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 () { if (numarg()>=1) { if ($o1.count==0) {print "empty list" return} if (isobj($o1.object(0),"String2")) { for ltr(XO,$o1) print XO.s,XO.t } else for ltr(XO,$o1) print XO.s } else for ltr(XO,printlist) print i1,XO.name } //** cpprl(PRINTLIST,TMPLIST) copies printlist vitem's to tmplist proc cpprl () { $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 localobj o ii=0 if (numarg()==1) ii=$1 if (ii<0 || ii>=grv_.panobjl.count) { printf("**** ap(%d) ERR panobj #%d not found -- run gvnew() \n",ii,ii) return } o=grv_.panobjl.object(ii) attr0=o.attr0 o.attrpanl() 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 (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] strdef symb symb = "O" gvmarkflag=0 obfunc gg () { local gp,na,newgr,clr,a,stp,i,tmp localobj ty,ts,abs,ord,o 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 (isassigned(g[gp])) if (g[gp].view_count>0) newgr=0 if (newgr) g[gp]=new Graph() graphItem=g[gp] graphList[0].append(g[gp]) panobj.glist.append(g[gp]) 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,g[gp]) // 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) ord.apply(ts.s) sprint(ts.t,"%s.%s(%s,%s",ord,ts.t,g[gp],abs) } else if (ty.x[i]==1 && ty.x[i+1]==0) { // gg(vec,step) o=$oi i+=1 sprint(ts.t,"%s.%s(%s,%g",o,ts.t,g[gp],$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,g[gp],$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,1)",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) } //** file_with_dot(filename,result,scratch): put .filename into result proc file_with_dot() { if (sfunc.substr($s1,"/") == -1) { sprint($s2,".%s",$s1) } else { sfunc.tail($s1,".*/",$s3) sfunc.head($s1,"/[^/]+$",$s2) sprint($s2,"%s/.%s",$s2,$s3) } } //** restore_printlist() restores the plist from a file in an attrnum objref vite proc restore_printlist () { local cnt,ii,attrnum,savlvar localobj aa printf("NOT WORKING\n") attrnum=$1 printlist.remove_all panobj=grv_.panobjl.object(attrnum) for panobj.vrdr(aa,"",1) { vite= new vitem(tstr,aa.o(0).size) vite.vec.copy(aa.o(0)) printlist.append(vite) } } //** file_len(fname): retrieve file length; uses global x func file_len () { sprint(temp_string_,"wc %s",$s1) sassign(temp_string_,temp_string_) sscanf(temp_string_,"%ld",&x) return x } //** 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 if (numarg()==2) { sfunc.head($s1,"[^/]+$",$s2) } else { st=new String() sfunc.head($s1,"[^/]+$",st.s) return st } } obfunc filname () { local loc localobj st if (numarg()==2) { loc=sfunc.head($s1,"[^/]+$",$s2) // end of directory string $s2=$s1 sfunc.right($s2,loc) } else { st=new String() loc=sfunc.head($s1,"[^/]+$",st.s) // end of directory string st.s=$s1 sfunc.right(st.s,loc) return st } } // file_len() uses wc func file_len () { local x sprint(tstr,"wc -l \"%s\"",$s1) system(tstr,tstr) sscanf(tstr,"%d",&x) return x } func cvode_status () { return cvode.active() + cvode.use_local_dt()/10 } //* xgetargs, etc. //** xgetargs(panel_name,command,arg1[,arg2,...],defaults) // eg xgetargs("Random session","newrand","# of patts","patt size ","overlap ","5,33,7") strdef mesg objref argv,argvl proc xgetargs () { local i,args args=numarg()-3 i=numarg() argv = new Vector(args) if (! isobj(argvl,"List")) argvl=new List() argvl.append(argv) argv.resize(0) sprint(temp_string_,"argv.append(%s)",$si) execute(temp_string_) if (argv.size!=args) argv.resize(args) xpanel($s1) mesg="" xvarlabel(mesg) for i=3,numarg()-1 { sprint(temp_string_,"%s.x[%d]",argv,i-3) xvalue($si,temp_string_) } sprint(temp_string_,"xgetexec(\"%s\",%d,%s)",$s2,args,argv) xbutton($s1,temp_string_) xpanel() } proc xgetexec () { local i,args args = $2 if ($o3.size!=args) { mesg="Error-close & relaunch panel" return } sprint(temp_string_,"%s(",$s1) for i=0,args-2 sprint(temp_string_,"%s%g,",temp_string_,$o3.x[i]) sprint(temp_string_,"%s%g)",temp_string_,$o3.x[i]) // print temp_string_ execute(temp_string_) } //** procbutt() put up a single proc in a button proc procbutt () { xpanel($s1) xbutton($s1,$s1) xpanel(500,500) } // mdl2view(g,X,Y) converts model 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)} obfunc mdl2view () { local a,ii,x0,y0 localobj o,v1 x0=$2 y0=$3 o=new Union() a=allocvecs(v1) for ii=1,4 v1.append($o1.size(ii)) 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]) return o } // END /usr/site/nrniv/local/hoc/grvec.hoc //================================================================ //================================================================ // INSERTED /usr/site/nrniv/local/hoc/nqs.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ // primarily edited in nrniv/place if (!name_declared("VECST_INSTALLED")) { printf("NQS ERROR: Need vecst.mod nmodl package compiled in special.\n") } if (!VECST_INSTALLED) install_vecst() if (! name_declared("datestr")) load_file("setup.hoc") objref g[10] gvmarkflag=0 func file_len(){} strdef execstr,strform,dblform {strform="%s " dblform="%3.4g "} //* stubs for ancillary programs double sops[19] // AUGMENT TO ADD NEW OPSYM declared("whvarg","whkey","varstr","nqsdel","chsel2","grsel2") //* NQS template // potential to overwrite XO,tmpfile,i1 begintemplate NQS public cob,out,up // operate on this or out public s,comment,file,v,m,x,ind,scr,fcd,fcds,fcdo,fcdl,this,sstr // strings and vecs public objl,verbose,tmplist,vlist,nval,sval,oval,selcp,rxpstr,slorflag,stub,chunk,rdpiece public sv,rd,append,pr,prn,zvec,resize,size,fi,sets,set,setcol,gets,get,fetch,tog // routines public cp,copy,mo,aind,it,qt,ot,appi,eq,fcdseq,fcdoeq,sort,select,stat,rdcols,map,apply,applf public spr,pad,delect,fill,uniq,gr,clear,strdec,coddec,odec,join,fillin,fillv,otl,selall public unuselist,useslist,renamecol,delrow,elimrepeats,grow,shuffle,fewind,listvecs,loose public percl,psel,svsetting,getrow,getcol,resize2,find,family,delcol,delcols,keepcols,selone public sethdrs,gethdrs objref v[1],s[1],is[4],x,nil,ind,scr[3],fcd,fcds,fcdo,fcdl,this,objl objref cob,out,up,Xo,Yo,oval,tmplist,otl,vlist strdef comment,file,sstr,sstr2,sstr3,sstr4,tstr,sval double m[1] external readnums,savenums,readdbls,savedbls,rdvstr,wrvstr,sfunc,repl_mstr,isobj,rdmord external vlk,Union,String,tmpfile,strm,XO,execstr,i1,allocvecs,dealloc,mso,strform,dblform external eqobj,isnum,chop,isassigned,whvarg,whkey,sops,batch_flag,g,varstr,gvmarkflag external file_len,nqsdel,chsel2,grsel2 external myid //** init() proc init () { local i,ii,flag,scnt,na,fl,rdflag nval=fl=scnt=flag=rdflag=0 // flag set if creating the internal NQS ni=0 selcp=verbose=1 svsetting=3 loose=1e-4 for ii=2,3 is[ii]=new String() is[2].s="INDEX" is[3].s="SCRATCH" na=numarg() for i=1,na scnt+=(argtype(i)==2) // string count if (na==0) scnt=-1 if (na==1) if (argtype(1)==2) rdflag=1 if (na>=1) if (argtype(1)==0) { fl=1 // 1 arg taken care of if ($1==1e-9) { flag=1 up=$o2 fl=2 m=up.m if (m>0) { objref v[m],s[m] for ii=0,m-1 {v[ii]=new Vector() s[ii]=up.s[ii]} } fcd=up.fcd fcds=up.fcds fcdl=up.fcdl fcdo=up.fcdo // finish creation of .out here } else { m=$1 objref v[m],s[m] for ii=0,m-1 { v[ii]=new Vector() s[ii]=new String2() } } } if (fl!=1 && na==scnt) { // all strings fl=2 // all args taken care of m=na objref v[m],s[m] for ii=0,m-1 {i=ii+1 v[ii]=new Vector() s[ii]=new String($si) } } if (fl!=2 && na>=2) if (argtype(2)==0) { fl==2 // all args taken care of for ii=0,m-1 v[ii].resize($2) } if (fl!=2) { // if first arg is not a string these other can be if (na>=2) file=$s2 if (na>=3) comment=$s3 if (na>=4) x.x[0]=$4 } if (!flag) { // fcd gives field codes according to values used for argtype() fcds=new List() fcd=new Vector(m) tmplist=new List() vlist=new List() fcd.resize(m) fcd.fill(0) // field codes to have a field that's string based } x=new Vector(m) ind=x.c for ii=0,2 scr[ii]=x.c scr.resize(0) ind.resize(0) objl=new List() cob=this v0sz=slorflag=0 chunk=100 if (!flag) { out=new NQS(1e-9,this) if (rdflag) rd($s1) } } //** tog() toggle flag that determines whether actions are on out or this proc tog () { if (numarg()==0) { if (eqobj(cob,out)) { cob=this print "Operate on full db" } else { cob=out print "Operate on output of select" } } else if (numarg()==1) { if (argtype(1)==0) { // just give information if (eqobj(cob,out)) { print "Using output db" } else { print "Using full db" } } else if (argtype(1)==2) { // out,output,selected to choose these if (strm($s1,"[Oo][Uu][Tt]") || strm($s1,"[Ss][Ee][Ll]")) { cob=out } else cob=this } } } //** sethdrs() set the column names to given args // sethdrs(#,"NAME") sethdrs("NAME1","NAME2",...) sethdrs(nq) -- copy from nq proc sets () { printf("sets() changed to sethdrs()\n") } proc sethdrs () { local i,nm nm=numarg() // out.s should always be a pointer to s but early on was keeping different copies: if (! eqobj(s,out.s)) printf("sets INTERRA\n") if (nm==2 && argtype(1)==0) { s[$1].s=$s2 } else if (nm==1) { if ($o1.m!=m) resize($o1.m) for i=0,m-1 s[i].s=$o1.s[i].s } else { if (nm>m) { if (batch_flag) { printf("NQS sets WARNING resized table from %d to %d\n",m,nm) } else if (! boolean_dialog("Resize TABLE?","YES","NO")) return printf("resizing TABLE: %d -> %d\n",m,nm) resize(nm) } for i=1,nm { s[i-1].s=$si } } } // gethdrs() print the strings proc gets () { printf("gets() changed to gethdrs()\n") } proc gethdrs () { local ii,jj,kk,mm localobj o if (numarg()==1) { // set the strings o=new String("%s%c") for ii=0,m-1 { jj=ii%26 kk=int(ii/26)+1 for mm=1,kk sprint(s[ii].s,o.s,s[ii].s,65+jj) } } for ii=0,m-1 printf("%s(%d) ",s[ii].s,ii) } //* selone(COL,VAL[,FLAG]) -- uses vec.selone when just working with one col and one value func selone () { local val,niflag if (numarg()==3) niflag=$3 else niflag=0 // use if searching repeatedly through same vec tog("DB") // start at full db if (argtype(1)==2) fl=fi($s1) else fl=$1 if (fl==-1) return val=$2 // if (!v[fl].ismono) {printf("NQS selone: must sort on %s before using\n",s[fl].s) return -1} if (niflag) ni=ind.slone(v[fl],val,ni) else ni=ind.slone(v[fl],val) if (selcp) { if (ind.size==0) { printf("None selected\n") } else { out.ind.copy(ind) aind() cob=out } } else cob=this return ind.size } //* select() -- based loosely on SQL select func select () { local ii,i,tmp,tmp1,ret,isv,key,arg,vc,selcpsav,savind,union,not,rxpflg localobj o if (numarg()==0) { out.cp(this,2) cob=out return v.size } tog("DB") // start at full db if (size(1)==-1) { printf("NQS:select ERR0: cols not all same size\n") return -1 } // key holds OPs; arg holds ARGs; vc holds COL NAMEs key=arg=vc=allocvecs(3) arg+=1 vc+=2 selcpsav=selcp i=1 not=rxpflg=union=savind=0 tmplist.remove_all vlist.remove_all if (argtype(i)==0) if ($1==-1) {selcp=0 i+=1} // else is a number identifying a vector if (argtype(i)==2) { // check first string for &&, ||, ! if (strcmp($si,"&&")==0) { savind=1 union=0 i+=1 } else if (strcmp($si,"||")==0) { savind=1 union=1 i+=1 } else if (strcmp($si,"!")==0) { savind=0 not=1 i+=1 } else if (strcmp($si,"&&!")==0) {savind=1 not=1 i+=1 } else if (strcmp($si,"||!")==0) {savind=1 union=1 not=1 i+=1 } } else if (argtype(i)==1) { i+=1 if (isobj($o1,"Vector")) { ind.copy($o1) savind=1 union=0 // assume && } else { printf("NQS:select ERR0a: first vec obj should be ind vector\n") dealloc(key) return -1 } } if (savind) scr.copy(ind) else scr.resize(0) for (;i<=numarg();) { if (argtype(i)==2) { if (strcmp($si,"IND_")==0) { if ((vn=fi($si,"NOERR"))!=-1) { printf("NQS:select() WARNING: IND_ is a reserved word: ?%s\n",s[vn].s) } vn=-1e9 scr[1].indgen(0,v.size-1,1) tmplist.prepend(scr[1]) } else if ((vn=fi($si))<0) { dealloc(key) return -1 } sstr=$si // save for join: use with "NAME",EQW,OTHER_NQS } else if (argtype(i)==0) { vn=$i // can avoid repeated string search sstr=s[vn].s } else {printf("NQS:select ERR1: arg %d should be col name or num\n",i) dealloc(key) return -1} mso[vc].append(vn) i+=1 if (argtype(i)==0) { if ((isv=isvarg($i))==-1) { mso[key].append(EQU) // if arg2 is a regular number presume that op is EQU arg2 mso[arg].append($i,0) i+=1 continue } else { lk=$i } } else if (argtype(i)==2) { isv=isvarg(lk=whvarg($si)) if (isv==-1) { if (strcmp($si,"~")==0) { mso[key].append(EBE) // approximately equal -- generate a range i+=1 tmp=$i*(1-loose) tmp1=$i*(1+loose) if (tmpmso[arg].x[mso[arg].size-1]) { tmp=mso[arg].x[mso[arg].size-2] mso[arg].x[mso[arg].size-2]=mso[arg].x[mso[arg].size-1] mso[arg].x[mso[arg].size-1]=tmp } // pad so every OP sees 2 ARGS for ii=0,2-isv-1 { mso[arg].append(0) } } ind.resize(v.size) for ii=0,mso[vc].size-1 { vn=mso[vc].x[ii] if (vn==-1e9) { // code for EQW case with NQS arg vlist.append(tmplist.object(tmplist.count-1)) tmplist.remove(tmplist.count-1) // pop } else if (vn<0) { i=-vn // code for EQV case where vector is in the arg list vlist.append($oi) } else vlist.append(v[vn]) } if (tmplist.count!=0) { printf("NQS:select ERR5 %s.tmplist not empty\n",this) return -1 } if (slorflag) { ind.slor(mso[key],mso[arg],vlist) } else { ind.slct(mso[key],mso[arg],vlist) } if (not==1) complement() // ind->!ind if (savind) { if (union==1) { scr.append(ind) scr.sort ind.resize(scr.size+ind.size) ind.redundout(scr) } else { mso[key].resize(scr.size+ind.size) mso[key].insct(scr,ind) ind.copy(mso[key]) } } ret=ind.size if (selcp) { if (ind.size==0) { printf("None selected\n") } else { out.ind.copy(ind) aind() cob=out } } else cob=this dealloc(key) selcp=selcpsav slorflag=0 return ret } //** selall() proc selall () { local ii if (numarg()==2) { for ii=0,m-1 out.v[ii].where(v[ii],$s1,$2) } else { for ii=0,m-1 out.v[ii].where(v[ii],$s1,$2,$3) } tog("SEL") } //** complement() ind -> !ind proc complement () { local a,b a=b=allocvecs(2) b+=1 mso[a].indgen(0,size(1)-1,1) mso[b].resize(mso[a].size) mso[b].cull(mso[a],ind) ind.copy(mso[b]) dealloc(a) } //** delect([NQS]) // move the selected rows from the out db [or other] back to the main db // the assumption is that you have operated on some of the fields and now want to // put the rows back // ind must not have been altered since it will be used to replace the items func delect () { local beg,ii,flag scr.resize(v.size) if (numarg()==1) flag=1 else flag=0 if (flag) { if (m!=$o1.m){ printf("NQS:delect ERRa m mismatch: %s:%d vs %s:%d\n",this,m,$o1,$o1.m) return -1 } ind.copy($o1.ind) } else if (!out.ind.eq(ind) || ind.size!=out.v.size) { printf("NQS:delect ERR ind size mismatch\n") return -1 } for (beg=0;beg=ALL*(m+1)) { op/=(m+1) break } // m is is field key 1-5 if (op=1) { err=1 printf("NQS fi ERR: regexp matches more than once: %d %s\n",ii,s[ii].s) } else { num+=1 ret=ii flag=1 } } if (err) printf("NQS WARNING; ambiguous regexp; fi() returning pointer for: %d %s\n",ret,s[ret].s) if (flag) { if (numarg()==2 && noerr==0) { if (argtype(2)==1) { if (ret==-2) $o2=scr else if (ret==-3) {printf("NQS:fi ERRa copy what?\n") return ret } else $o2=v[ret] } else if (argtype(2)==0) { if ($2<0 || $2>=v[ret].size) { printf("NQS:fi ERR index out of bounds: %d %d\n",$2,v[ret].size) return -1 } if (ret==-2) ret=scr.x[$2] else if (ret==-3) {printf("NQS:fi ERRb what?\n") return ret } else ret=v[ret].x[$2] } else { printf("NQS:fi WARNING 2nd arg ignored\n") } } return ret } else { if (!noerr) printf("NQS.fi() ERR '%s' not found\n",$s1) return -1 } } //** find(STR) find the vector associated with a COL label obfunc find () { local fl if (eqobj(cob,out) && verbose) printf(" *Selected* ") fl=fi($s1) if (fl==-2) { return scr } else if (fl==-3) { return ind } else return cob.v[fl] } //** set("name",IND,VAL) proc set () { local fl,ix,i if (eqojt(cob,out)) { printf("NQS set() ERR: attempting to set a value in Selected db\n") return } if (argtype(1)==2) fl=fi($s1) else fl=$1 ix=$2 if (fl==-1) return if (ix<0) ix=v[fl].size+ix // 2 LINE 'SET' MACRO i=3 // arg 3 will be the value if (argtype(i)==0) nval=$i else if (argtype(i)==1) oval=$oi else if (argtype(i)==2) sval=$si v[fl].x[ix]=newval(argtype(i),fl) } //** setcol("name",VEC) proc setcol () { local fl if (eqobj(cob,out) && verbose) { printf("NQS setcol() ERR: attempting to set column in Selected db\n") return } if (argtype(1)==2) fl=fi($s1) else fl=$1 if (fl==-1) return if (v[fl].size!=0) { printf("NQS setcol() ERR: clear() column before setting\n") return } v[fl].copy($o2) } //** newval(typ,col#) -- check if a value is already on the list and if not put it there // usuall preceded by eg: // if (argtype(i)==0) nval=$i else if (argtype(i)==1) oval=$oi else if (argtype(i)==2) sval=$si func newval () { local ret,typ,fl,ii typ=$1 fl=$2 if (fcd.x[fl]!=typ && fcd.x[fl]!=-1) { printf("nqs::newval() ERRa %d statt %d\n",typ,fcd.x[fl]) return ERR } if (typ==0 || typ==-1) { return nval } else if (typ==1) { // object handling for (ii=0;iifcdo.count-1) { printf("nqs::getval() ERR fcdo index OOB %d, %d\n",ix,fcdo.count) return ERR } else if (ix<0) { printf("nqs::getval() WARNING empty obj ptr\n\t") } else oval = fcdo.object(ix) } else if (typ==2) { // string handling if (ix==-1) { sval="NULL" } else if (ix<0 || ix>fcds.count-1) { printf("nqs::getval() ERR index OOB %d, %d\n",ix,fcds.count) return ERR } else sval=fcds.object(ix).s } else if (typ==-1) { // string from external list if (fcdl.count<=fl) {printf("NQS getval ERRa\n") return -1} if (! isobj(fcdl.object(fl),"List")) {printf("NQS getval ERRb\n") return -1} if (fcdl.object(fl).count<=ix) {printf("NQS getval ERRc\n") return -1} if (ix==-1) sval="XX" else { if (! isobj (fcdl.object(fl).object(ix),"String")) {printf("NQS getval ERRd\n") return -1} sval=fcdl.object(fl).object(ix).s } } return typ } //*** useslist() connects a list of strings to fcdl to use when printing // fcdl: list of lists to make it easy to attach lists from outside proc useslist () { local fl,ii if (argtype(1)==2) fl=fi($s1) else fl=$1 if (fl==-1) return if (! isobj(fcdl,"List")) {fcdl=new List() out.fcdl=fcdl} if (fcdl.count!=m) for ii=fcdl.count,m-1 fcdl.append(fcdl) // use fcdl as placeholder fcdl.remove(fl) fcdl.insrt(fl,$o2) // replace:fcdl.object(fl)=$o2 fcd.x[fl]=-1 } //*** unuselist() connects a list of strings to fcdl to use when printing // fcdl: list of lists to make it easy to attach lists from outside proc unuselist () { local fl,ii if (argtype(1)==2) fl=fi($s1) else fl=$1 if (fl==-1) return fcd.x[fl]=0 } //*** listvecs(LIST) put the vecs in the list for use with eg uncode() proc listvecs () { local ii if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (!isassigned($o1)) $o1=new List() $o1.remove_all for ii=0,m-1 $o1.append(cob.v[ii]) } //*** prtval() use %g or %s to print values proc prtval () { local typ,flag typ=$1 if (typ==0) sstr=dblform else sstr=strform if (numarg()==2) sprint(sstr,"%s%s",sstr,$s2) if (numarg()==3) sprint(sstr,"%s%s%s",$s2,sstr,$s3) if (typ==0) { printf(sstr,nval) } else if (typ==1) { printf(sstr,oval) } else if (typ==2) { printf(sstr,sval) } else if (typ==10) { for ii=0,4 printf("%d ",scr.x[ii]) } else if (typ==-1) { printf(sstr,sval) } // special code for externally provided list } //** get("name",[IND]]) if omit IND take ind from first ind.x[0] obfunc get () { local ty,fl,ix,outf localobj lo outf=0 if (argtype(1)==0) { fl=$1 sstr2=s[fl].s } else if (argtype(1)==2) { fl=fi($s1) sstr2=$s1 } if (fl==-1) { return -1 } if (eqobj(cob,out)) { outf=1 if (verbose) printf(" *Selected* ") } if (numarg()==1) { if (outf) ix=0 else ix=ind.x[0] } else ix=$2 if (ix<0 || ix>=cob.v[fl].size) { printf("NQS::get ERR ix %d out of range for %s (%s)\n",ix,sstr2,cob) return -1 } ty=fcd.x[fl] if (ty==0) lo=new Union(cob.v[fl].x[ix]) if (ty==1) lo=new Union(fcdo,cob.v[fl].x[ix]) if (ty==2) lo=new Union(fcds,cob.v[fl].x[ix]) if (ty==-1) lo=new Union(fcdl.object(fl),cob.v[fl].x[ix]) return lo } //** fetch(COLA,VAL,COLB) does fast select where COLA is VAL and returns value in COLB // only works with VAL as number func fetch () { local fl1,fl2,max,i localobj st if (numarg()==3) { if (argtype(1)==2) fl1=fi($s1) else fl1=$1 if (argtype(3)==2) fl2=fi($s3) else fl2=$3 if ((i=v[fl1].indwhere("==",$2))<0) { printf("fetch ERR %d not found in %s\n",$2,s[fl1].s) return -1 } return v[fl2].x[i] } else { st=new String("select(") for i=1,numarg()-1 { if (argtype(i)==0) sprint(st.s,"%s%g,",st.s,$i) else sprint(st.s,"%s\"%s\",",st.s,$si) } chop(st.s) sprint(st.s,"%s)",st.s) execute(st.s,this) i=numarg() if (argtype(i)==0) fl2=$i else fl2=fi($si) if (out.v.size!=1) printf("NQS fetch WARNING -- %d lines found\n",out.v.size) if (out.v.size>0) return out.v[fl2].x[0] else return -1 } } //** stat("COL","operation") // stat("COL",VEC) // save into a vector: max,min,mean,sdev proc stat () { local i,vn if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (numarg()==0) { for i=0,m-1 { printf("%s:\t",s[i].s) stat(i) } // recursive call return } if (argtype(1)==0) vn=$1 else vn=fi($s1) if (vn<0||vn>=m) return i=2 if (cob.size(1)<2) { printf("NQS:stat small NQS: %d\n",cob.size(1)) return } if (vn==-2) { sprint(sstr2,"%s",scr) } else if (fcd.x[vn]==10) { scr.resize(cob.v.size) field=$i i+=1 cob.v[vn].uncode(scr,field) sprint(sstr2,"%s",scr) } else { sprint(sstr2,"%s",cob.v[vn]) } if (numarg()=m) { if (argtype(i)==2) printf("(%s)",$si) printf("NQS::qt() ERR %d not found\n",val) return }} scr[1].copy(fcd) // scr[1] gives codes for col's for (i=1;i<=na;i+=2) { // can't do iteration over externally defined strings (eg -1) see useslist() if (scr.x[int(i/2)]<0) continue if (scr[1].x[scr.x[int(i/2)]]!=0) { if (argtype(i)==3) { printf("NQS::qt() WARNING using list index statt str for col %s\n",s[scr.x[int(i/2)]].s) scr[1].set(scr.x[int(i/2)],0) } } if (scr[1].x[scr.x[int(i/2)]]==2 && argtype(i)!=2) { printf("NQS::qt() ERR %s is strdec but arg %d not string\n",s[scr.x[int(i/2)]].s,i) return } if (scr[1].x[scr.x[int(i/2)]]==1 && argtype(i)!=1) { printf("NQS::qt() ERR %s is odec but arg %d not obj\n",s[scr.x[int(i/2)]].s,i) return } } for (i1=0;i1 // anything quoted can use either ' or \" // eg sp.spr(".c.mul(DELD).add(DEL)") proc spr () { local ii,vn if (numarg()==0) { printf("eg spr(\".copy(.c.mul().add(5))\") \ntakes a compound expression utilizing column names in slant brackets <>\nanything quoted can use either ' slash quote.\n") return } else sstr=$s1 if (eqobj(cob,out) && verbose) printf(" *Selected* ") while (sfunc.tail(sstr,"<",sstr2)!=-1) { sfunc.head(sstr2,">",sstr2) if (strcmp(sstr2,"SCR")==0) { sprint(sstr3,"%s",cob.scr) } else if ((vn=fi(sstr2))==-1) return else { sprint(sstr3,"%s",cob.v[vn]) } sprint(sstr2,"<%s>",sstr2) repl_mstr(sstr,sstr2,sstr3,sstr4) } repl_mstr(sstr,"'","\"",sstr4) execute(sstr) } //** sort () sort according to one index func sort () { local beg,ii,vn if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (argtype(1)==0) vn=$1 else vn=fi($s1) if (vn<0||vn>=m) return -1 cob.v[vn].sortindex(cob.ind) if (numarg()==2) if ($2==-1) cob.ind.reverse fewind() return vn } //** percl ("FIELD",n %ile) check whether the first n% of the vector are in the top n %ile // usage -- reverse sort according to 1 field and then ask if other field is in top n %ile func percl () { local beg,ii,vn,nile,sz if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (argtype(1)==0) vn=$1 else vn=fi($s1) if (vn<0||vn>=m) return -1 sz=cob.v[vn].size nile=int($2*sz/100) scr[1].copy(cob.v[vn]) scr[1].sort() scr.resize(0) scr.copy(scr[1],sz-nile-1,sz-1) scr.reverse() // the top n-ile percentile scr[2].resize(0) scr[2].copy(cob.v[vn],0,nile) // the first set of values from NQS // scr[1].insct(scr,scr[2]) // find all common values for ii=0,scr[2].size-1 if (scr.contains(scr[2].x[ii])) return ii // which one is top of scr[2] return -1 } // family("COLA",val,"COLB","COLC") // pick out rows that have are same as row with "COLA" val except that COLB COLC // etc. can be anything func family () { local a,i,ii,vn,va,nile,sz,om localobj key,arg tog("DB") // start at full db a=allocvecs(key,arg) sz=size(1) tmplist.remove_all arg.resize(0) key.resize(0) if (select(-1,$s1,$2)!=1) printf("WARNING: NQS family found more than 1 %s=%g\n",$s1,$2) va=fi($s1) scr.resize(0) scr.append(va) for i=3,numarg() scr.append(fi($si)) for i=0,m-1 if (! scr.contains(i)) { tmplist.append(v[i]) key.append(EQU) arg.append(v[i].x[ind.x[0]],0) } ind.resize(v.size) ind.slct(key,arg,tmplist) // run select function if (ind.size>0) { out.ind.copy(ind) aind() cob=out } else printf("None selected\n") dealloc(a) return ind.size } // psel(%ile,"COLA","COLB","COLC") // psel("COLA",%ileA,"COLB",%ileB,"COLC",%ileC) // neg %ile means bottom -- eg 10 is largest 10% and -10 is smallest 10% // return top percentile in these columns func psel () { local a,i,ii,vn,nile,sz,om localobj key,arg tog("DB") // start at full db a=allocvecs(key,arg) om=numarg()-1 sz=size(1) tmplist.remove_all arg.resize(0) key.resize(0) if (argtype(1)==0) { if (int($1*sz/100)==0) { printf("NQS psel(): ERROR: unable %d%% of %d\n",$1,sz) return -1 } key.resize(om) if ($1>0) { nile=sz-int($1*sz/100) key.fill(GTE) } else { nile=-int($1*sz/100) key.fill(LTE) } for i=2,numarg() { if (argtype(i)==0) vn=$i else vn=fi($si) if (vn<0||vn>=m) return -1 tmplist.append(v[vn]) scr[1].copy(v[vn]) scr[1].sort() arg.append(scr[1].x[nile],0) // 2nd arg for GTE ignored printf("%s:%g ",$si,scr[1].x[nile]) } } else for i=1,numarg() { tstr=$si vn=fi($si) i+=1 if (int($i*sz/100)==0) { printf("NQS psel(): WARNING: ignoring %d%% of %d\n",$i,sz) continue } if (vn<0||vn>=m) return -1 tmplist.append(v[vn]) scr[1].copy(v[vn]) scr[1].sort() if ($i>0) { nile=sz-int($i*sz/100) key.append(GTE) } else { nile=-int($i*sz/100) key.append(LTE) } arg.append(scr[1].x[nile],0) // 2nd arg for GTE ignored printf("%s:%g ",tstr,scr[1].x[nile]) } ind.resize(v.size) ind.slct(key,arg,tmplist) // run select function if (ind.size>0) { out.ind.copy(ind) aind() cob=out } else printf("None selected\n") print "" dealloc(a) return ind.size } //** uniq(COLNAME) will pick out unique row (1st) for the chosen column func uniq () { local vn if (! eqobj(cob,out)) {printf("Only run NQS:uniq() on prior selected set.\n") return -1} vn=sort($s1) cob.ind.resize(cob.v.size) cob.ind.redundout(cob.v[vn],1) fewind() return vn } //** elimrepeats(COLA[,COLB,...]) func elimrepeats () { local a,b,i,ii,indflag localobj sl,tl,v1 if (eqobj(cob,out)) {printf("NQS ERR: run elimrepeats on full db\n") return 0.} if (size(1)==0) { print "NQS:elimirepeats Empty NQS" return 0.} a=allocvecs(v1) b=1 indflag=0 sl=new List() tl=new List() if (numarg()==0) { for ii=0,m-1 { sl.append(v[ii]) v1.append(ii) } b=numarg()+1 } else if (argtype(1)==0) if ($1==-1) {b=2 indflag=1} for i=b,numarg() { if ((ii=fi($si))==-1) return 0 else { sl.append(v[ii]) v1.append(ii) } } for ii=0,m-1 if (!v1.contains(ii)) tl.append(v[ii]) for (ii=v1.size-1;ii>=0;ii-=1) sort(v1.x[ii]) // sort them in the reverse order of calling ii=ind.mredundout(sl,indflag,tl) dealloc(a) return ii } //** shuffle() proc shuffle () { local a,b,i,ii,indflag localobj sl,tl,v1 if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (size(1)==0) { print "NQS:shuffle Empty NQS" return 0.} rdmord(ind,cob.v.size) fewind() } //** fewind () -- index all of the vecs in place using fewing proc fewind () { cob.scr.resize(cob.v.size) for (beg=0;beg1) begin=$2 else begin=0 if (begin+$o1.size>m) { printf("NQS append ERR1: vec %s too large; doing nothing: %d>%d",$o1,begin+$o1.size,m) } else { for i=begin,begin+$o1.size-1 v[i].append($o1.x[i-begin]) } } else if (isobj($o1,"NQS")) { // another NQS to add onto end if ($o1.m != m) { printf("NQS append ERR1a, %s size (%d)!= %s size (%d)?\n",this,m,$o1,$o1.m) return } for ii=0,m-1 v[ii].append($o1.v[ii]) ind.append($o1.ind) } else { printf("NQS append ERR1b, what is %s?\n",$o1) } return } if (argtype(1)==2) if ((ii=fi($s1,"NOERR"))!=-1) { // a field name for i=1,numarg() { i+=1 if (argtype(i)==0) nval=$i else if (argtype(i)==1) oval=$oi else if (argtype(i)==2) sval=$si v[ii].append(newval(argtype(i),ii)) } return } if (numarg()>m) { print "NQS append ERR2: args>m; doing nothing" return } if (numarg()<=m) { if (numarg()m-ix) { print "NQS appi ERR1: vec too large; doing nothing\t" } else { for i=ix,$o2.size-1 v[i].append($o2.x[i]) } } else { if (numarg()-1>m-ix) { print "NQS appi ERR2: args>m; doing nothing" return } for i=2,numarg() { if (argtype(i)==0) nval=$i else if (argtype(i)==1) oval=$oi else if (argtype(i)==2) sval=$si v[ix+i-2].append(newval(argtype(i),ix+i-2)) } } } //** map(FUNC,arg1,...) map $s1 command to other args, replacing strings with vectors as found // eg nqs.map("gg",0,"volt","cai",2) proc map () { local i,agt,wf if (numarg()==0) { printf("map(FUNC,arg1,...) apply function to args using names for columns.\n") return } if (eqobj(cob,out) && verbose) printf(" *Selected* ") sprint(sstr,"%s(",$s1) // the command wf=0 for i=2,numarg() { // the args agt=argtype(i) if (agt==0) { sprint(sstr,"%s%g,",sstr,$i) } else if (agt==1) { sprint(sstr,"%s%s,",sstr,$oi) } else if (agt==2) { if ((vn=fi($si))==-1) { sprint(sstr,"%s\"%s\",",sstr,$si) printf("NQS.map WARNING: including raw string: %s\n",$si) wf=1 } else if (vn==-2) { // code for scr vector sprint(sstr,"%s%s,",sstr,cob.scr) } else { sprint(sstr,"%s%s,",sstr,cob.v[vn]) } } else { printf("argtype %d for arg %d not implemented for NQS:map\n",agt,i) return } } chop(sstr) sprint(sstr,"%s)",sstr) if (wf && !batch_flag) if (boolean_dialog(sstr,"CANCEL","EXECUTE")) return execute(sstr) } //*** gr() use map to graph // need to assign .crosshair_action so can do visual select procedure proc gr () { local i,nm,gn,col,lne,f3d,y,x,done localobj symb nm=numarg() gn=0 f3d=-1 gvmarkflag=col=2 lne=4 done=0 symb=new String() if (nm==0) { print "gr(\"Y\"[,\"X\",Z,g#,col,line])" return } else if (nm==1) { map("gg",0,$s1,1,col,lne) done=1 } else if (nm==2) { map("gg",0,$s1,$s2,col,lne) done=1 } i=3 if (! done) { if (argtype(i)==2) f3d=fi($si) else i-=1 i+=1 if (i<=nm) gn=$i i+=1 if (i<=nm) col=$i i+=1 if (i<=nm) lne=$i if (f3d!=-1) { if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (!gvmarkflag) {printf("NQS gr ERR: 3D and gvmarkflag=0\n") return} y=fi($s1) x=fi($s2) if (lne==1) lne=2 else lne-=2 // will augment below if (x==-1 || y==-1) {printf("NQS gr ERR: %s,%s not fi()\n",$s1,$s2) return} for i=0,cob.v.size-1 { if (i%9==0) lne+=2 g[gn].mark(cob.v[x].x[i],cob.v[y].x[i],"o",lne,cob.v[f3d].x[i]%9+1,4) } } else map("gg",gn,$s1,$s2,col,lne) } g[gn].color(col) g[gn].label(0.05,0.95,$s1) if (nm>=2) g[gn].label(0.85,0.05,$s2) g[gn].color(1) setgrsel(g[gn],fi($s1),fi($s2)) setchsel(g[gn],fi($s1),fi($s2)) } //** grsel(): 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 proc setgrsel () { $o1.menu_remove("Selector") sprint(tstr,"proc p(){grsel($1,$2,$3,$4,%d,%d)}",$2,$3) execute1(tstr,this) $o1.menu_tool("Selector", "p") } proc setchsel () { sprint(tstr,"proc q(){chsel($1,$2,$3,%d,%d)}",$2,$3) execute1(tstr,this) $o1.crosshair_action("q") } grsbegx=grsbegy=1e9 proc grsel () { local type, x0, y0, keystate, fl1,fl2,sel type=$1 x0=$2 y0=$3 keystate=$4 fl1=$5 fl2=$6 if (type==3) { if (grsbegx==1e9) { // no drag was done if ((sel=select(fl2,"~",x0,fl1,"~",y0))!=0) { pr() } else print "Can't find ",s[fl2].s,"~ ",x0,s[fl1].s,"~ ",y0 } else { // consider a rectangle order(&grsbegx,&x0) order(&grsbegy,&y0) if ((sel=select(fl2,"[]",grsbegx,x0,fl1,"[]",grsbegy,y0))!=0) { if (keystate==0) { grsel2() } else if (keystate==3) { // CTL or SHIFT alone are being used by fvwm2 pr() // print grsbegx,x0,grsbegy,y0 } } else printf("Can't find %s %g-%g; %s %g-%g\n",s[fl2].s,grsbegx,x0,s[fl1].s,grsbegy,y0) grsbegx=grsbegy=1e9 } } else if (type==1 && grsbegx==1e9) {grsbegx=x0 grsbegy=y0 } } // order(&x,&y) returns the values in order proc order () { local tmp if ($&2<$&1) { tmp=$&2 $&2=$&1 $&1=tmp } } proc chsel () { local ascii, x0, y0, fl1,fl2,sel x0=$1 y0=$2 ascii=$3 fl1=$4 fl2=$5 if ((sel=select(fl2,"~",x0,fl1,"~",y0))!=0) { if (ascii==32) { chsel2() } else pr() } else print "Can't find ",s[fl2].s,"~ ",x0,s[fl1].s,"~ ",y0 } //** apply function or .op to every selected vector -- ignore return val, see applf proc apply () { local i,fl if (numarg()==0) { printf("apply(FUNC,COL1,...) apply function or .op to every selected vector.\n") printf("must be function, not proc, since will return value.\n") return } if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (numarg()==1) for i=0,m-1 { // apply to all vectors if (strm($s1,"^\\.")) sprint(sstr,"%s%s" ,cob.v[i],$s1) else { sprint(sstr,"%s(%s)",$s1,cob.v[i]) } execute(sstr) } else for i=2,numarg() { if ((fl=fi($si))==-1) return if (strm($s1,"^\\.")) sprint(sstr,"%s%s" ,cob.v[fl],$s1) else { sprint(sstr,"%s(%s)",$s1,cob.v[fl]) } execute(sstr) } } //** applf(FUNC,COL) function or .op which returns a value func applf () { local a,fl,ret localobj v1 if (numarg()==0) { printf("apply(FUNC,COLNAME) apply function or .op to selected vector.\n") printf("must be function, not proc, since will return value.\n") return -1 } a=allocvecs(v1) v1.resize(1) if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (argtype(2)==2) { if ((fl=fi($s2))==-1) return -1 } else fl=$2 if (strm($s1,"^\\.")) sprint(sstr,"%s.x[0]=%s%s" ,v1,cob.v[fl],$s1) else { sprint(sstr,"%s.x[0]=%s(%s)",v1,$s1,cob.v[fl]) } execute(sstr) ret=v1.x[0] dealloc(a) return ret } //** fill(NAME,val[,NAME1,val1 ...]) // fill each selected vector with next arg func fill () { local i,fl,fl2,x if (numarg()==0) { printf("fill(NAME,val[,NAME1,val1 ...])\n\tfill each selected vector with val\nval can be num, vector, or other col name\n") return -1} if (eqobj(cob,out) && verbose) printf(" *Selected* ") for i=1,numarg() { fl=fi($si) i+=1 if (fl==-1) return -1 field=0 if (fcd.x[fl]==10) { // code field field=$i i+=1 } if (argtype(i)==0) { if (field>0) cob.v[fl].uncode(field,$i) else cob.v[fl].fill($i) } else if (argtype(i)==1) { if (!isobj($oi,"Vector")){ printf("NQS:fill() ERRa: only fill with vector: %s\n",$oi) return -1} if ($oi.size!=cob.v.size){ printf("NQS:fill() ERRb: wrong vec size: %d!=%s:%d\n",cob.v.size,$oi,$oi.size) return -1} if (field>0) cob.v[fl].uncode(field,$oi) else cob.v[fl].copy($oi) } else if (argtype(i)==2) { fl2=fi($si,"NOERR") if (fl2== -1) { // add this string to this field? if (fcd.x[fl]==2) { sval=$si x=newval(2,fl) cob.v[fl].fill(x) } else { printf("NQS:fill() ERRc: trying to fill field %s with string %s\n",s[fl].s,$si) return -1 } } else if (field>0) { cob.v[fl].uncode(field,cob.v[fl2]) } else cob.v[fl].copy(cob.v[fl2]) i+=1 } } return cob.v[fl].size } //** fillin(NAME,val[,NAME1,val1 ...]) // fill in place according to indices in ind -- use with selcp=0 proc fillin () { local i,fl if (numarg()==0) { printf("fillin(NAME,val[,NAME1,val1 ...])\n\tfill selected vectors in place\n") printf("\tuse after select(-1,...) eg selcp==0\n") return } scr.resize(0) for (i=2;i<=numarg();i+=2) scr.append($i) tmplist.remove_all for (i=1;i<=numarg();i+=2) { if (argtype(i)==2) { if ((fl=fi($si))==-1) return } else fl=$i tmplist.append(v[fl]) } ind.sindv(tmplist,scr) } //** fillv(NAME,v1[,NAME1,v2 ...]) // fill from vectors v1,v2,..., places in ind -- use with selcp=0 proc fillv () { local i,fl if (numarg()==0) { printf("fillv(NAME,vec1[,NAME1,vec2 ...])\n\tfill selected vectors from vectors\n") printf("\tuse after select() with selcp==0\n") return } tmplist.remove_all vlist.remove_all for (i=1;i<=numarg();i+=2) { if (argtype(i)==2) { if ((fl=fi($si))==-1) return } else fl=$i tmplist.append(v[fl]) } for (i=2;i<=numarg();i+=2) vlist.append($oi) ind.sindx(tmplist,vlist) } //** pr() print out vectors // eg pr("COLA","COLB",3,7) func pr () { local ii,i,min,max,na,flag,jj,e if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (m==0) {print "EMPTY" return 0} flag=min=0 max=cob.v.size-1 na=numarg() if (na>=2) { if (argtype(na-1)==0) { i=na na-=2 max=$i i-=1 min=$i flag=1 // took care of numbers }} if (!flag && na>=1) { if (argtype(na)==0) { i=na na-=1 if ($i>=0) max=$i else min=max+$i // allow printing the end } } // reuse flag -- means printing only certain cols flag=0 if (na>=1) if (argtype(1)==2 || argtype(1)==1) flag=1 // column names if (max>size(1)){ max=size(1)-1 printf("NQS:pr WARNING: %d rows requested but %s size=%d\n",max,this,size(1)) } if (min>size(1)){printf("NQS:pr ERROR: %s size=%d < min %d\n",this,size(1),min) return 0} print "" if (flag) { scr[1].resize(0) if (argtype(1)==1) scr[1].copy($o1) else for i=1,na scr[1].append(fi($si)) for i=0,scr[1].size-1 { ii=scr[1].x[i] if (ii==-1) return -1 if (ii<0) printf("is[-ii].s\t") else printf("%s(%d)\t",s[ii].s,ii) } print "" for jj=min,max { for i=0,scr[1].size-1 { ii=scr[1].x[i] if (ii==-2) { printf("%g\t",cob.scr.x[jj]) } else if (ii==-3) { printf("%g\t",cob.ind.x[jj]) } else { prtval((e=getval(ii,cob.v[ii].x[jj])),"\t") if (e==ERR) return ERR } } print "" } } else { for ii=0,m-1 printf("%4.4s ",s[ii].s) print "" for jj=min,max { for ii=0,m-1 { prtval(e=getval(ii,cob.v[ii].x[jj])," ") if (e==ERR) return ERR} print "" } } return max-min+1 } //** prn() print out single index from vectors proc prn () { local jj,ii,ix,max,e ix=$1 if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (numarg()==2) max=$2 else max=ix for jj=ix,max { if (jj<0 || jj>=cob.v[0].size) { printf("prn: Index out of range (%d)\n",cob.v[0].size) return } for ii=0,m-1 { printf("%s:",s[ii].s) prtval(e=getval(ii,cob.v[ii].x[jj])," ") if (e==ERR) return } print "" } } //** zvec() -- clear -- resize all the vectors to 0 proc clear () { if (numarg()==1) zvec($1) else zvec() } proc zvec () { local ii cob=this // fcds.remove_all fcds.append(new String("`EMPTY'")) if (isassigned(fcdo)) fcdo.remove_all for ii=0,m-1 { if (numarg()==1) { v[ii].resize($1) v[ii].fill(0) }// resize the buffer if desirable v[ii].resize(0) } } //** pad() -- bring all vectors up to same length (of v[0]) func pad () { local sz,ii cob=this sz=-1 if (numarg()==1) sz=$1 else for ii=0,m-1 if (v[ii].size>sz) sz=v[ii].size for ii=0,m-1 { // if (v[ii].size>sz) printf("NQS.pad WARNING: neg padding %d\n",ii) v[ii].resize(sz) } return sz } //** size() -- return num of vectors and size of each vector func size () { local ii,sz if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (numarg()==1) { sz=cob.v.size // with 1 arg don't print anything for ii=1,m-1 if (cob.v[ii].size!=sz) sz=-1 // generate err return sz } if (m==0) { print "0 x 0" return 0 } // empty printf("%d x %d",m,cob.v.size) for ii=1,m-1 printf(",%d",cob.v[ii].size) print "" return cob.v.size } //** resize(#cols[,#rows]) -- augment or dec the number of vectors // resize("LABEL1","LABEL2",...) // resize("LABEL1",VEC1,"LABEL2",VEC2) ... put on some vecs of same size func resize () { local oldsz,newsz,i,ii,jj,vsz,na,appfl na=numarg() vsz=-1 if (na==1) { if (argtype(1)==0) { newsz=$1 appfl=0 } else if (argtype(1)==2) { newsz=m+1 appfl=2 } } else { if (argtype(1)==0 && argtype(2)==0) { newsz=$1 appfl=0 vsz=$2 } else if (argtype(1)==2 && argtype(2)==2) { newsz=m+na appfl=2 } else { if (int(na/2)!=na/2) { print "NQS Resize ERR: require even # of args" return -1} newsz=m+numarg()/2 appfl=1 } } oldsz=m if (m==newsz) { printf("No resize -- same size: %s\n",this) return m } else if (newsz>m) { tmplist.remove_all vlist.remove_all for ii=0,m-1 { tmplist.append(v[ii]) tmplist.append(s[ii]) tmplist.append(out.v[ii]) } objref v[newsz],s[newsz] if (isassigned(out)) out.resize2(newsz) // create vectors for .out jj=-1 for ii=0,m-1 { v[ii]=tmplist.object(jj+=1) out.s[ii]=s[ii]=tmplist.object(jj+=1) out.v[ii]=tmplist.object(jj+=1) } for ii=m,newsz-1 { v[ii]=new Vector() out.s[ii]=s[ii]=new String() out.v[ii]=new Vector() } out.m=m=newsz tmplist.remove_all } else { for (ii=m-1;ii>=newsz;ii-=1) { out.v[ii]=v[ii]=nil out.s[ii]=s[ii]=nil } out.m=m=newsz } x.resize(m) x.fill(0) fcd.resize(m) out.x.resize(m) out.x.fill(0) out.fcd=fcd if (vsz>=1) for ii=0,m-1 v[ii].resize(vsz) if (appfl==1) { // append for (ii=1;ii<=na;ii+=2) { i=ii if (argtype(i)!=2) { printf("NQS RESIZE ERR: arg %d should be str\n",i) return -1} s[oldsz+(ii-1)/2].s=$si i+=1 if (argtype(i)==0) { if ($i>0) v[oldsz+(ii-1)/2].resize($i) } else if (argtype(i)==1) { v[oldsz+(ii-1)/2].copy($oi) } else { printf("NQS RESIZE ERR2: arg %d should be num or obj\n",i) return -1} } } else if (appfl==2) { for (i=1;i<=na;i+=1) { if (argtype(i)!=2) { printf("NQS RESIZE ERR3: arg %d should be str\n",i) return -1} s[oldsz+i-1].s=$si } } cob=this return m } // for resizing the vector for .out proc resize2 () { local newsz newsz=$1 objref v[newsz],s[newsz] } // grow(NQS) append NQS of same size to this one func grow () { local ii if (m!=$o1.m) { printf("%s,%s off different size: %d %d\n",this,$o1,m,$o1.m) return 0 } if (eqobj(cob,out)) {printf("NQS ERR: run grow on full db\n") return 0.} for ii=0,m-1 v[ii].append($o1.v[ii]) return v.size } //** keepcols("LABEL1",...) func keepcols () { local i,fl scr.resize(0) for i=1,numarg() { if (argtype(i)==2) { if ((fl=fi($si))==-1) return -1 } else fl=$i scr.append(fl) } for (i=m-1;i>=0;i-=1) if (! scr.contains(i)) delcol(i) return m } //** delcols("LABEL1",...) func delcols () { local i,fl scr.resize(0) for i=1,numarg() { if (argtype(i)==2) { if ((fl=fi($si))==-1) return -1 } else fl=$i scr.append(fl) } for (i=m-1;i>=0;i-=1) if (scr.contains(i)) delcol(i) return m } //** delcol("LABEL1") func delcol () { local oldsz,ii tog("DB") // start at full db if (argtype(1)==2) { if ((fl=fi($s1))==-1) return -1 } else fl=$1 for (ii=fl;ii=cob.v.size) {printf("delrow %d OOR (%d)\n",kk,cob.v.size-1) return -1} for ii=0,m-1 cob.v[ii].remove(kk) } else { // remove selected tog("DB") if (ind.size>1) { sprint(sstr,"Remove %d rows from main table?",ind.size) if (!boolean_dialog(sstr,"OK","Cancel")) { print "Cancelled" return -1 } } for ii=0,m-1 for (jj=ind.size-1;jj>=0;jj-=1) { kk=ind.x[jj] v[ii].remove(kk) } } return v.size } //** getrow(#,VEC) obfunc getrow () { local ii localobj v1 if (eqobj(cob,out) && verbose) printf(" *Selected* ") if (numarg()==2) v1=$o2 else v1=new Vector() v1.resize(0) for (ii=0;ii=2) aflag=$2 if (numarg()>=3) cd1=$3 // 1:flag for not compressing if (aflag) { tmpfile.aopen(file) } else { if (tmpfile.ropen(file)) { if (batch_flag) { printf("NQS sv WARNING overwriting %s\n",file) } else if (!boolean_dialog("File exists","Overwrite","Cancel")) { print "Cancelled" return } } if (! tmpfile.wopen(file)) { printf("NQSsvERR: can't open file\n") return } } mso[a].resize(m) mso[a].fill(0) if (cd1==0) for i=0,m-1 if (v[i].ismono(0)) { // will be saved without full vectors cd1=2 // 2 flag for using compression mso[a].x[i]=1 } if (isassigned(fcdo)) foc=fcdo.count else foc=-1 // only save an object list if all of the objects are vecs for i=0,foc-1 if (!isojt(fcdo.object(i),v)) {foc=0 break} if (isassigned(fcdo)) if (fcdo.count>0 && foc==0) { printf("NQS:sv() WARNING: Can't save objlist for %s (eg %s)\n",this,fcdo.object(0)) } savenums(m,fcds.count,(cnt=fcd.count(-1)),foc,size(1),cd1,0,0,0) // extra for codes wrvstr(file) wrvstr(comment) for i=0,m-1 wrvstr(s[i].s) fcd.vwrite(tmpfile) for i=0,fcds.count-1 wrvstr(fcds.object(i).s) for i=0,foc-1 if (isojt(fcdo.object(i),v)) fcdo.object(i).vwrite(tmpfile,3) if (cnt>0) for i=0,fcd.size-1 if (fcd.x[i]==-1) { savenums(fcdl.object(i).count) for j=0,fcdl.object(i).count-1 wrvstr(fcdl.object(i).object(j).s) } for i=0,m-1 { if (cd1==2 && mso[a].x[i]==1) { savenums(-1e9,v[i].size,v[i].x[0]) } else if (fcd.x[i]==10) { v[i].vwrite(tmpfile,4) // must save CODE fully } else { v[i].vwrite(tmpfile,svsetting) } } x.vwrite(tmpfile) tmpfile.close dealloc(a) } //** rd(FNAME[,FLAG]) read format saved by sv() // flag==2 - only read header func rd () { local n,hflag,cd1,cd2,cd3,cd4,ii hflag=0 if (numarg()>=1) if (argtype(1)==2) { if (!tmpfile.ropen($s1)) { printf("NQSrdERR: can't open file\n") return 0 } } // else continue reading from current point in file if (numarg()>=2) hflag=$2 // only read header if (m!=0) resize(0) cnt=fc=foc=0 // backward compatible -- if only 2 vals then cnt=0, cd1-4 unused at present n=readnums(&ii,&fc,&cnt,&foc,&v0sz,&cd1,&cd2,&cd3,&cd4) if (n<9) v0sz=cd1=cd2=cd3=cd4=-1 if (cd1==2 && hflag==1) {printf("NQSrdERR0: can't do partial reads on compressed\n") return 0 } if (ii!=m) resize(ii) rdvstr(file) rdvstr(comment) if (sfunc.len(file)==0) file=$s1 for i=0,m-1 rdvstr(s[i].s) fcd.vread(tmpfile) fcds.remove_all if (isassigned(fcdl)) fcdl.remove_all for i=0,fc-1 { fcds.append(Xo=new String()) rdvstr(Xo.s) } if (foc>=0) { fcdo=new List() out.fcdo=fcdo } for i=0,foc-1 { fcdo.append(Xo=new Vector()) Xo.vread(tmpfile) } // assume vecs for now if (cnt>0) for i=0,fcd.size-1 if (fcd.x[i]==-1) { readnums(&cnt) Yo=new List() for j=0,cnt-1 {Xo=new String() Yo.append(Xo) rdvstr(Xo.s)} useslist(i,Yo) } if (hflag==1) { // v0sz will tell size of all vectors tell=tmpfile.tell tmpfile.seek(0,2) tellend=tmpfile.tell() if (v0sz==-1) { printf("NQSrdERRA: can't do seeks since v's not same size\n") return 0 } } else { v0sz=-1 // indicates that the everything has been read in for i=0,m-1 { v[i].vread(tmpfile) if (v[i].x[0]==-1e9) { v[i].resize(v[i].x[1]) v[i].fill(v[i].x[2]) } } x.vread(tmpfile) } if (foc==0) for ii=0,fcd.size-1 if (fcd.x[ii]==1) v[ii].fill(-1) // clear obj pointers out.cp(this,0) // leave vectors empty return 1 } //** rdpiece() read a section of each vector func rdpiece () { local ii,ix,end,jump,loc,bswap ix=$1 if (numarg()>=2) bswap=$2 else bswap=0 tmpfile.seek(tell+8) // start of first one if (ix<0) {printf("NQS:rdpiece ERR: no room: neg index\n") return 0} if (ix*chunk>v0sz) return 0 if ((ix+1)*chunk>v0sz) end=v0sz-ix*chunk else end=chunk for ii=0,m-1 { loc=tell+8+ii*(v0sz*4+8)+ix*4*chunk tmpfile.seek(loc) if (loc+end*4>tellend){printf("NQS:rdpiece ERRA: ran out: %d %d",loc+end,tellend) return 0} v[ii].fread2(tmpfile,end,3+bswap) } return 1 } //** func rdcols() // reads columns of ascii with labels at the top func rdcols () { local ii,cols,li,errflag,num,hflag errflag=0 if (! tmpfile.ropen($s1)) { printf("\trdcols ERR0: can't open file \"%s\"\n",$s1) return 0} if (tmpfile.scanstr(sstr)==-1) {printf("\trdcols ERR1: file \"%s\"\n",$s1) return 0} if (isnum(sstr)) hflag=0 else hflag=1 // hflag=0 -> no header if (!hflag) printf("No Header for %s\n",$s1) cols=0 if (hflag) { while (! isnum(sstr)) { cols+=1 tmpfile.scanstr(sstr) } } else cols=m // assume that NQS was set up ahead li=file_len($s1) printf("%d cols; %d lines of data in %s.\n",cols,li,$s1) tmpfile.ropen($s1) if (hflag) tmpfile.gets(sstr) // remove first line num=scr.scanf(tmpfile,li*cols) if (num!=li*cols) { // err not reached since scanf dumps out printf("WARNING: expected %d vals; found %d\n",li*cols,num) errflag=3 } if (tmpfile.scanstr(sstr)>-1) { printf("WARNING: %s found after reading in %d vals\n",sstr,li*cols) errflag=4 } resize(cols) tmpfile.seek(0) for ii=0,cols-1 { if (hflag) tmpfile.scanstr(s[ii].s) v[ii].resize(li) v[ii].copy(scr,0,ii,li*cols-1,1,cols) // v[ii].mcol(scr,ii,cols) } if (errflag) { printf("rdcols ERR%d\n",errflag) return 0 } return cols } //** func svcols(filename) // currently only saves numeric columns func svcols () { local ii,jj,cols,li,errflag,num errflag=0 if (! tmpfile.wopen($s1)) { printf("\trdcols ERR0: can't open file \"%s\"\n",$s1) return 0} sstr2="\t" // delimiter for ii=0,m-1 tmpfile.printf("%s%s",s[ii].s,sstr2) tmpfile.printf("\n") for ii=0,size(1)-1 { for jj=0,m-1 { getval(jj,v[jj].x[ii]) tmpfile.printf("%g%s",nval,sstr2) } tmpfile.printf("\n") } tmpfile.close return ii } //** join(nqs2,"PIVOT"[,"COLA",...]) // [selected fields of] nqs2 will be appended to this // index field should only appear once in nqs2 func join () { local vn,vn1,vn2,i,ii,jj,kk,val localobj al,bl al=new List() bl=new List() if ((vn1=fi($s2))==-1 || (vn2=$o1.fi($s2))==-1) { printf("NQS::join() %s not found in both %s %s\n",$s2,$o1,this) return -1 } if (!v[vn1].ismono) { print "Sorting A..." sort(vn1) } if (!$o1.v[vn2].ismono){print "Sorting B..." $o1.sort(vn2) } if (!$o1.v[vn2].ismono(2)){ printf("Pivot B has repeats\n") return -1 } scr.resize($o1.m) scr.fill(-1) if (numarg()>2) for i=3,numarg() { if ((vn=$o1.fi($si))==-1) return -1 scr.x[vn]=resize($si)-1 // index for this } else for ii=0,$o1.m-1 if (! strcmp($o1.s[ii].s,$s2)==0) { if ($o1.fcd.x[ii]!=0) {printf("NQS:join ERRA not double field\n") return -1} scr.x[ii]=resize($o1.s[ii].s)-1 // index for this } pad() for jj=0,scr.size-1 { kk=scr.x[jj] if (kk!=-1) { al.append(v[kk]) bl.append($o1.v[jj]) } } v[vn1].join($o1.v[vn2],al,bl) return m } //** cp(NQS[,VEC_COPY]) copy 1 NQS to another // default: VEC_COPY==1; side effect of NO_VEC_COPY is no fcd,fcds creation proc copy () { if (numarg()==2) cp($o1,$2) else cp($o1) } proc cp () { local ii,csz,veccp,outcp csz=$o1.m outcp=0 if (numarg()==2) veccp=$2 else veccp=1 if (m!=csz) if (isassigned(out)) resize(csz) else { resize2(csz) outcp=1 } objl.remove_all for ii=0,$o1.objl.count-1 { objl.append($o1.objl.object(ii)) } file=$o1.file comment=$o1.comment if (outcp) for ii=0,m-1 { s[ii]=up.s[ii] v[ii]=new Vector() } else for ii=0,m-1 { s[ii].s=$o1.s[ii].s if (veccp) v[ii].copy($o1.v[ii]) // 2nd arg to not copy vectors } if (veccp==1) { // full copy fcd.copy($o1.fcd) for ii=0,$o1.fcds.count-1 fcds.append($o1.fcds.object(ii)) if (isobj($o1.fcdl,"List")) { fcdl=new List() out.fcdl=fcdl for ii=0,$o1.fcdl.count-1 fcdl.append($o1.fcdl.object(ii)) } if (isobj($o1.fcdo,"List")) { fcdo=new List() out.fcdo=fcdo for ii=0,$o1.fcdo.count-1 fcdo.append($o1.fcdo.object(ii)) } } else if (! isassigned(fcd)) { // use pointers for .out fcd=$o1.fcd fcds=$o1.fcds fcdl=$o1.fcdl tmplist=$o1.tmplist } x.copy($o1.x) x.resize(m) scr.copy($o1.scr) ind.copy($o1.ind) } //** eq(NQS) -- just check the vecs func eq () { local ii,jj,af,ix localobj v1 if (numarg()==2) af=1 else af=0 // af is flag for approx eq if ($o1.m!=m) { printf("# of cols differ %d vs %d\n",m,$o1.m) return 0 } for ii=0,m-1 if (strcmp($o1.s[ii].s,s[ii].s)!=0) { printf("%d col names differ: %s vs %s",ii,s[ii].s,$o1.s[ii].s) return 0 } for ii=0,m-1 if ($o1.v[ii].size != v[ii].size) { printf("%d col lengths differ: %d vs %d",ii,v[ii].size,$o1.v[ii].size) return 0 } if (af) { a=allocvecs(v1) for ii=0,m-1 { v1.copy(v[ii]) v1.sub($o1.v[ii]) v1.abs() if (v1.max>1e-5) { ix=v1.max_ind printf("%s cols differ: \n",s[ii].s,ix,v[ii].x[ix],$o1.v[ii].x[ix]) } } dealloc(a) } else for ii=0,m-1 if (! $o1.v[ii].eq(v[ii])) { printf("%s cols differ at ",s[ii].s) for jj=0,v[ii].size-1 if ($o1.v[ii].x[jj] != v[ii].x[jj]) { printf("element %d: %g vs %g",jj,v[ii].x[jj],$o1.v[ii].x[jj]) return 0 } } if (! fcdseq($o1)) return 0 if (! fcdoeq($o1)) return 0 return 1 } //** fcdseq() -- check that string lists are identical in two NQSs -- this is // sufficient but not nec for comparing string columns for JOIN // in order to use JOIN must share same fcds by setting up with strdec(NQS,...) // (could break out separate lists for each str column -- tried in nqs.hoc220; // but separate lists would be problem: two columns might require same indices if // either could be used to for "JOIN" to another nqs func fcdseq () { local ii,jj,cnt cnt=fcds.count if (eqobj(fcds,$o1.fcds)) { printf("%s %s already share string list fcds\n",this,$o1) return 1 } if (cnt!=$o1.fcds.count) { printf("DIFFERING (1) string lists (fcds) %d %d\n",fcds.count,$o1.fcds.count) return 0 } for ii=0,cnt-1 if (!strcmp(fcds.object(ii).s,$o1.fcds.object(ii).s)==0) { printf("DIFFERING (2) string lists (fcds) %d:%s vs %s",ii,fcds.object(ii).s,$o1.fcds.object(ii).s) return 0 } if (numarg()==2) return 1 // just check fcds and not fcd and fcdl if (! fcd.eq($o1.fcd)) { printf("DIFFERING (3) col keys (fcd) ") vlk(fcd) vlk($o1.fcd) return 0 } if (! isassigned(fcdl) && isassigned($o1.fcdl)) { printf("DIFFERING (4) uselists() string lists: absent in %s\n",this) return 0 } if (isassigned(fcdl)) { if (! isassigned($o1.fcdl)) { printf("DIFFERING (5) uselists() string lists absent in %s\n",$o1) return 0 } if (fcdl.count!=$o1.fcdl.count) { printf("DIFFERING (6) uselists() list list counts %d vs %d",fcdl.count,$o1.fcdl.count) return 0 } for ii=0,fcdl.count-1 if (fcd.x[ii]==-1) { if (!isobj(fcdl.object(ii),"List") || !isobj($o1.fcdl.object(ii),"List")) { printf("DIFFERING (7) uselists() string lists (fcdl.obj) %d:%s vs %s",ii,\ fcdl.object(ii),$o1.fcdl.object(ii)) return 0 } if (fcdl.object(ii).count != $o1.fcdl.object(ii).count) { printf("DIFFERING (8) uselists() string lists counts (fcdl.obj) %d:%d vs %d",ii,\ fcdl.object(ii).count,$o1.fcdl.object(ii).count) return 0 } for jj=0,fcdl.object(ii).count-1 { if (!strcmp(fcdl.object(ii).object(jj).s,$o1.fcdl.object(ii).object(jj).s)==0) { printf("DIFFERING (9) uselists() string lists (fcdl.obj) %d,%d:%s vs %s",ii,jj,\ fcdl.object(ii).object(jj).s,$o1.fcdl.object(ii).object(jj).s) return 0 } } } } return 1 } //** fcdoeq() -- check that object lists are identical in two NQSs func fcdoeq () { local ii,jj,cnt if (! isassigned(fcdo) && ! isassigned($o1.fcdo)) return 1 if (! isassigned(fcdo)) { printf("No object list in %s\n",this) return 0 } if (! isassigned($o1.fcdo)) { printf("No object list in %s\n",$o1) return 0 } cnt=fcdo.count if (cnt!=$o1.fcdo.count) { printf("DIFFERING (1) object lists (fcdo) %d %d\n",fcdo.count,$o1.fcdo.count) return 0 } for ii=0,cnt-1 if (!isojt(fcdo.object(ii),v) || !isojt($o1.fcdo.object(ii),v)) { printf("DIFFERING (2) obj lists (fcdo) -- non vector found %s,%s (%s,%s)",fcdo.object(ii),$o1.fcdo.object(ii),this,$o1) return 0 } for ii=0,cnt-1 if (! fcdo.object(ii).eq($o1.fcdo.object(ii))) { printf("DIFFERING (2) obj lists (fcdo) -- vectors differ %s,%s (%s,%s)",fcdo.object(ii),$o1.fcdo.object(ii),this,$o1) return 0 } return 1 } //** strdec() -- declare these columns to be strings func strdec () { local i,min min=1 if (eqobj(cob,out)) { printf("strdec() ERR: string fields can only be declared at top level\n") return 0} if (numarg()==0) { printf("strdec(NAME[,NAME1 ...])\n\tdeclare these field to be string fields\n") return 0} out.fcd=fcd if (argtype(1)==1) { if (fcds.count>0) if (! fcdseq($o1,1)) { // just check fcds and not fcd, fcdl printf("Pre-existing string lists differ; unable to join %s %s\n",this,$o1) return 0 } fcds=$o1.fcds // share string list to allow JOIN on a string field min=2 } for i=min,numarg() { fl=fi($si) if (fl>-1) { fcd.x[fl]=2 sval="`EMPTY'" newval(2,fl) // don't want to put on more than one } } return 1 } //** coddec() -- declare these columns to be strings func coddec () { local i,min min=1 if (eqobj(cob,out)) { printf("coddec() ERR: CODE fields can only be declared at top level\n") return 0} if (numarg()==0) { printf("coddec(NAME[,NAME1 ...])\n\tdeclare these field to be code fields\n") return 0} out.fcd=fcd for i=min,numarg() { fl=fi($si) if (fl>-1) fcd.x[fl]=10 } return 1 } //** odec() -- declare these columns to be objects func odec () { local i,min min=1 if (eqobj(cob,out)) { printf("odec() ERR: object fields can only be declared at top level\n") return 0} if (numarg()==0) { printf("odec(NAME[,NAME1 ...])\n\tdeclare these field to be object fields\n") return 0} out.fcd=fcd for i=min,numarg() { fl=fi($si) if (fl>-1) fcd.x[fl]=1 } if (! isobj(fcdo,"List")) { fcdo=new List() out.fcdo=fcdo } return 1 } //** mo([flag][,STAT1,...]) -- create global objectvars that point to the vectors // first time use flag=1 to create new global objrefs, else just shift them // flag=1 reassign objl but don't care if they already exist // flag=2 don't print out the assignments // flag=3 reassign objl; make sure they're unique // flag=4 clear the vectors // should we also create a set of global scalars to assign to in an iterator? proc mo () { local ii,flag,i,hf if (numarg()>=1) flag=$1 else flag=0 // flag:create objrefs if (flag==1 || flag==3) { if (objl.count>0) { if (flag==3) if (batch_flag) { printf("NQS mo(3) WARNING: Renamed object pointers.\n") } else if (! boolean_dialog("New name object pointers?","YES","NO")) return if (flag==1) if (batch_flag) { printf("NQS mo(1) WARNING: Rassigned object pointers.\n") } else if (! boolean_dialog("Reassign object pointers?","YES","NO")) return } objl.remove_all for ii=0,m-1 if (sfunc.len(s[ii].s)>0) { sstr=s[ii].s repl_mstr(sstr,"[^A-za-z0-9]","",execstr) sprint(sstr,"%sv",sstr) if (flag==3) { // make sure it's unique hf=0 while (name_declared(sstr)) { hf=1 if (myid == 0) printf("%s exists ... ",sstr) sprint(sstr,"%sv",sstr) } if (myid == 0) if (hf) printf(" -> %s\n",sstr) } else if (myid == 0) if (name_declared(sstr)) printf("%s reassigned: ",sstr) if (myid == 0) printf("%s -> v[%d] (%s)\n",sstr,ii,s[ii].s) sprint(execstr,"objref %s",sstr) execute(execstr) sprint(execstr,"%s=%s",sstr,v[ii]) execute(execstr) objl.append(new String(sstr)) } sprint(execstr,"objref indv") execute(execstr) sprint(execstr,"indv=%s",ind) execute(execstr) } else { if (objl.count==0) { printf("Must create vecs with mo(1)\n") } else if (objl.count>m) { printf("STAT:mo ERR: wrong objref count in objl: %d vs %d\n",objl.count,m) return } else { if (objl.count %s.v[%d] (%s)\n",Xo.s,this,ii,s[ii].s) if (flag==4) {sprint(execstr,"%s=nil",Xo.s) } else sprint(execstr,"%s=%s",Xo.s,v[ii]) execute(execstr) } } sprint(execstr,"objref indv") execute(execstr) if (flag!=4) { sprint(execstr,"indv=%s",ind) execute(execstr) } } if (numarg()>1) for i=2,numarg() { // propagate the objl to other STATs $oi.objl.remove_all for ii=0,objl.count-1 $oi.objl.append(objl.object(ii)) } } //* endtemplate endtemplate NQS //* ancillary routines //* sopset() returns symbolic arg associated with a string proc sopset() { local i for i=1,19 { sops[i-1]=$i } // AUGMENT TO ADD NEW OPSYM } sopset(ALL,NEG,POS,CHK,NOZ,GTH,GTE,LTH,LTE,EQU,EQV,EQW,NEQ,SEQ,RXP,IBE,EBI,IBI,EBE) // ADD NEW OPSYM NAME proc sofset () { for scase(XO,"ALL","NEG","POS","CHK","NOZ","GTH","GTE","LTH","LTE","EQU","EQV","EQW","NEQ","SEQ","RXP","IBE","EBI","IBI","EBE") for j=1,5 { sprint(tstr,"%s%d=%s*%d",XO.s,j,XO.s,j+1) execute(tstr) } } sofset() //** whvarg func whvarg () { local ret ret=-1 // ADD NEW OPSYM STRING // ALL NEG POS CHK NOZ GTH GTE LTH LTE EQU EQV EQW NEQ SEQ RXP IBE EBI IBI EBE for scase("ALL","<0",">0","CHK","!=0",">",">=","<","<=","==","EQV","EQW","!=","=~","~~","[)","(]","[]","()") { if (strcmp($s1,temp_string_)==0) {ret=i1 break} } if (ret==-1) return ret else return sops[ret] } //** whkey(KEY,STR) // place name of KEY from vecst.mod in temp_string_ func whkey () { local key for scase("ALL","NEG","POS","CHK","NOZ","GTH","GTE","LTH","LTE","EQU","EQV","EQW","NEQ","SEQ","RXP","IBE","EBI","IBI","EBE") { // ADD NEW OPSYM NAME sprint(tstr,"x=%s",temp_string_) execute(tstr) if (x==$1) { $s2=temp_string_ break } } return x } //** varstr(tstr) -- make a variable out of string by removing nonalphanumeric characters func varstr () { local a,z,A,Z,a0,a9,a_,len,ii,sflag a=97 z=122 A=65 Z=90 a0=48 a9=57 a_=95 // ascii codes if (numarg()==2) sflag=1 else sflag=0 len = sfunc.len($s1) for ({x=0 ii=0};ii=a&&x<=z)||(x>=A&&x<=Z));ii+=1) { // allowed first char sscanf($s1,"%c%*s",&x) sfunc.right($s1,1) } if (ii==len) { printf("varstr() ERR: no useable characters") return 0} sprint($s1,"%c%s",x,$s1) for (;ii<=len;ii+=1) { sscanf($s1,"%c%*s",&x) sfunc.right($s1,1) if ((x>=a&&x<=z)||(x>=A&&x<=Z)||(x>=a0&&x<=a9)||(x==a_)) { // allowed chars sprint($s1,"%s%c",$s1,x) } } if (sflag) { sprint($s1,"strdef %s",$s1) execute($s1) sfunc.right($s1,7) // strip leading "strdef" } else { sprint($s1,"%s=0",$s1) execute($s1) sfunc.left($s1,sfunc.len($s1)-2) // strip the =0 } return 1 } strdef h1 h1="Select operators: \nALL <0 >0 CHK !=0 > >= < <= == EQV EQW != =~ ~~ [) (] [] ()\nALL NEG POS CHK NOZ GTH GTE LTH LTE EQU EQV EQW NEQ SEQ RXP IBE EBI IBI EBE\nmost are obvious; those that are not\nEQV: value equal to same row value another column (takes string arg)\nEQW: value found in other vector (takes vector or NQS arg)\nSEQ: string equal (takes string)\nRXP: regular expression comparison (takes string)\nIBE,EBI...: I=inclusive, E=exclusive for ranges\n" proc nqshelp () { if (numarg()==0) { } else { if (strcmp($s1,"select")==0) { // ed=new TextEditor(h1,9,160) ed.map printf("%s",h1) } } } //* nqsdel(NQS_objref) fully delete an nqs proc nqsdel () { $o1.out.cob=nil $o1.out=nil $o1.cob=nil $o1=nil } // END /usr/site/nrniv/local/hoc/nqs.hoc //================================================================ //================================================================ // INSERTED /usr/site/nrniv/local/hoc/boxes.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ // load_file("boxes.hoc") proc boxes () {} // factor(num) finds the factors that are closest together // NB: must be at top since declared external in template BX func factor () { local num, srt, ii num = $1 srt = int(sqrt(num)) for (ii=srt;iinum/ii) ii=num/ii // return smaller factor return ii } // template for putting up trays and decks begintemplate BX public mktray,mkdeck,name,boxes,glist,map,unmap,closebox public min,max,attrnum,rows,cols,trnum,gl,stub,label external factor objref boxes[3], ob, gitem,gl,XO,nil double min[1],max[1],trnum[1] strdef temp_string_,name proc init () { min = -1 max = -1 trnum=$1 gl = new List() } //mktray(panattr) graph out from llist of a panattr proc mktray () { local ci, ri, gi, m1, m2, bi ob = $o1 cols=$3 rows=$2 if (numarg()==6) {xs=$4 ys=$5} else {xs=100 ys=50} ri = 0 // count the rows gi = 0 // count the graphs boxes[0] = new VBox() boxes[0].dismiss_action("closebox()") boxes[0].intercept(1) name="" xpanel("",1) xvarlabel(name) xpanel() for ri=0,rows-1 { boxes[2] = new HBox() boxes[2].intercept(1) for ci=0,cols-1 { gitem = new Graph(0) gitem.view(0,-100,1000,50,0,0,xs,ys) gl.append(gitem) ob.glist.append(gitem) gi = gi+1 } boxes[2].intercept(0) boxes[2].map("") } boxes[0].intercept(0) if (strcmp(name,"")==0) name=ob.filename sprint(name,"%d:%s",trnum,name) boxes[0].map(name) } proc map() { boxes[0].map() } proc unmap() { boxes[0].unmap() } proc closebox () { local ii for (ii=gl.count-1;ii>=0;ii-=1) { XO=gl.object(ii) XO.unmap } ob.glist.remove_all gl.remove_all boxes[0].unmap boxes[0]=nil boxes[2]=nil } proc mkdeck () { local rows, cols, ci, ri, gi, m1, m2 ob = $o1 if (min==-1 || max==-1) { m1 = 0 m2 = ob.llist.count()-1 } else { m1=min m2=max } cnt = m2-m1+1 cols=factor(cnt) rows=cnt/factor(cnt) ri = 0 // count the rows gi = 0 // count the graphs boxes[0] = new VBox() boxes[0].intercept(1) xpanel("",1) xbutton("Next","boxes[1].flip_to(decknum=decknum+1)") xbutton("Previous","boxes[1].flip_to(decknum=decknum-1)") xpanel() boxes[1] = new Deck() boxes[1].intercept(1) for ri=0,rows-1 { boxes[2] = new HBox() boxes[2].intercept(1) for ci=0,cols-1 { ob.rv(gi+m1) gi = gi+1 } boxes[2].intercept(0) boxes[2].map("") } boxes[1].intercept(0) boxes[1].map("") boxes[0].intercept(0) boxes[0].map("Deck") decknum = 0 boxes[1].flip_to(decknum) if (! ob.attr0) { for ii = 0,gi-1 { ob.glist.object(ii).label(0.3,0.5,ob.llist.object(ii).name) } } } endtemplate BX objref boxer, boxerl boxerl = new List() proc mktray () { local i,na,namef localobj o if (numarg()==0) { print "mktray(attrnum,rows,cols[,xsize,ysize,label])" print "Create a tray for attr panel ATTRNUM to superimpose upon." return } boxer = new BX(boxerl.count) boxerl.append(boxer) trnum=boxer.trnum if (argtype(numarg())==2) { namef=1 na=numarg()-1 i=numarg() } else { namef=0 na=numarg() } if (na==2) o=panobj else if (argtype(1)==0) o=GRV[$1] else o=$o1 o.super = 1 if (na==5) { boxer.mktray(o,$2,$3,$4,$5) } else if (na==3) { boxer.mktray(o,$2,$3) } else if (na==2) { boxer.mktray(o,$1,$2) printf("Mapping trays to %s\n",o) } if (namef) boxer.name=$si } proc rmtray () { local ix ix=$1 if (boxerl.count<=1) boxerl.remove_all else { for (ii=boxerl.count-1;ii>=0;ii-=1) { if (boxerl.object(ii).attrnum==attrnum) boxerl.remove(ii) }} remgrs(attrnum) GRV[ix].super=0 } proc trsz () { if (boxerl.count>0) for ltr (XO,boxerl) printf("%d:%d x %d\n",XO.attrnum,XO.rows,XO.cols) } proc mktrpanl () { xgetargs("Make Tray","mktray","Which","rows","cols","xsize","ysize","0,2,3,100,50") } //* disptray() redisp() redispv() proc disptray () { local ix,ii,jj,kk if (numarg()==0) {print "disptray(ix[,cols])" return} ix=$1 ii=GRV[ix].llist.count if (numarg()==2) jj=$2 else jj=factor(ii) kk=GRV[ix].glist.count mktray(GRV[ix],round(ii/jj),jj,100,50) GRV[ix].grall(0,ii-1) for ltr(XO,GRV[ix].glist) if(i1>=kk) { XO.size(&x[0]) XO.size(x[0],x[1],x[2],x[3]) } } proc redisp () { local supsav panobj=$o1 if (numarg()>=2) trnum=$2 supsav=panobj.super panobj.super=1 for ltr(graphItem,boxerl.object(trnum).gl) { graphItem.erase_all() panobj.rv(i1) } panobj.super=supsav } // for bxit () {} go through all the graphs in tray trnum // for bxit (g1,g2,g3,g4) {} go through selected graphs // for bxit (-1,g1,g2) {} go through g1-g2 bxn=-1 proc bxop () { g=boxerl.object(trnum).gl.object($1) graphItem=g} proc bxinc () { if (bxn>=boxerl.object(trnum).gl.count) bxn=0 else bxn+=1 g=boxerl.object(trnum).gl.object(bxn) graphItem=g } iterator bxit () { local i,ii i1=0 if (numarg()>0) { if (numarg()==3 && $1==-1) { for ii = $2, $3 { g=boxerl.object(trnum).gl.object(ii) graphItem=g iterator_statement i1+=1 } } else { for i = 1, numarg() { if (numarg()==1) XO=$o1.object(ii) g=boxerl.object(trnum).gl.object($i) graphItem=g iterator_statement i1+=1 } } } else { for ii=0,boxerl.object(trnum).gl.count-1 { g=boxerl.object(trnum).gl.object(ii) graphItem=g iterator_statement i1+=1 } } } // redispv(VEC,ATTRNUM,TRNUM) -- all args optional proc redispv () { local supsav panobj=$o1 if (numarg()>=2) trnum=$2 supsav=panobj.super panobj.super=1 for bxit() { g.erase_all() if (numarg()>0) panobj.rv($o1.x[i1]) else panobj.rv(vec.x[i1]) } panobj.super=supsav } proc bxcomm () { if (numarg()==1) boxerl.object(boxerl.count-1).name=$s1 else { boxerl.object(boxerl.count-1).name=comment } } //* gin() search through param strings to graph particular members of llist // eg regexp="SPCX SPTC SPSM " then 'gin(1)' to create regexp: 'SPCX.+%sSPTC.+%sSPSM.+%s' // gin("5","","") will find examples with SPCX=5 and graph SPTC against SPSM // ginpr() will search through llist and just print out the file names // meant to be used after running dir2pr() to get a summary file strdef regexp proc gin () { local i,a a=allocvecs(1) revec(mso[a]) tstr=regexp for i=1,numarg() repl_str(tstr,"%s",$si,temp_string2_) // replace sprint for ltr(XO,panobj.llist,&y) if (strm(XO.name,tstr)) mso[a].append(y) if (mso[a].size!=boxer.rows*boxer.cols) { printf("gin() ERR: %d!=%dx%d\n",mso[a].size,boxer.rows,boxer.cols) dealloc(a) return } geall(1) for bxit() panobj.rv(mso[a].x[i1]) tstr=regexp repl_mstr(tstr,".\\+%s","=%s,",temp_string2_) chop(tstr) for i=1,numarg() repl_str(tstr,"%s",$si,temp_string2_) sprint(tstr,"%s: %s",panobj.filename,tstr) bxcomm(tstr) print tstr dealloc(a) } proc ginpr () { local base,i if (numarg()==0) { print "Set regexp to begin: eg\n\tregexp=\"SMTC SPSM NSTC \" (space at end)" print "Then call ginpr(regexp) to reset regexp" print "Then call eg ginpr(\"0.015\",\"\",\"\") to list or gin(...) to graph" return } if (numarg()==1) { regexp=$s1 repl_mstr(regexp," ",".+%s,",tstr) chop(regexp,",") print regexp return } base=1 tstr=regexp // where they start numbering for i=1,numarg() repl_str(tstr,"%s",$si,temp_string2_) // replace sprint for ltr(XO,panobj.llist,&y) if (strm(XO.name,tstr)) printf("%03d %s\n",base+y,XO.name) } // END /usr/site/nrniv/local/hoc/boxes.hoc //================================================================ //================================================================ // INSERTED /usr/site/nrniv/local/hoc/syncode.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ proc syncode () {} // mo(1) will assign these objref NCv,CODEv,PRv,POv,DISTv,DELv,WT0v,WT1v,CTYP,STYP,cp,svs objref ivspks,vspks,wvspks,ncl[1][1] objref sp[3], c[1], nc[1], cells[10] // enough room for 10 cell types objref vite Incol=2 //* setup //================================================================ // INSERTED /usr/site/nrniv/local/hoc/labels.hoc // $Id: prebatch_.hoc,v 1.2 2006/02/08 11:59:39 hines Exp $ objref PRIDv,POIDv,PRv,POv,DISTv,WT0v,WID0v,DEL0v,NC0v // mo(1) will assign these objref WT1v,WID1v,DEL1v,NC1v // mo(1) will assign these objref CPLA,CTYP,snsm,STYP,TPA //* utility functions // plmin(val,var) func plmin() { return $1 + $2*(2*u_rand() - 1) } //* cell types: CTYPi=20 // number of cell types CTYP=new List() for scase(XO,"NU","SM","DP","SU","IN","TC","RE","NS","BU","RF") { sprint(tstr,"%s=%d",XO.s,i1) execute(tstr) CTYP.append(new String2(XO.s)) } CPLAi=7 // count of cell templates CMP1=0 // single cmp real nrn CMP2=1 // 2 cmp real nrn MCMP=2 // multi cmp real nrn -- lots of different ones IF1=3 // basic acell -- eg intfire1 IF4=4 // 4 state var acell IFV=5 // invlfire STM=6 // nstim CPLA=new List() for scase("CMP1","CMP2","MCMP","IntFire1","INTF","INVLF","NStim") CPLA.append(new String(temp_string_)) TPAi=4 REAL=0 ARTC=1 SOMA=2 DEND=3 TPA=new List() for scase("REAL","ARTC","SOMA","DEND") TPA.append(new String(temp_string_)) ncells=0 objref nm nm=new List() STYPi= 9 AM = 0 NM = 1 GA = 2 GB = 3 GB2 = 4 IC = 5 // ICLAMP EX = 6 // AMPA+NMDA IX = 7 // GABAA+GABAB E2 = 8 // Exp2Syn STYP=new List() for scase("AMPA","NMDA","GABAA","GABAB","GABAB2","IClamp","AMPA/NMDA","GABAA/GABAB2","Exp2Syn") { STYP.append(new String2(temp_string_)) } for scase("ampa","nmda","gabaa","gabab","gabab2","inj","ampa/nmda","gabaa/gabab2","exp2syn") { STYP.object(i1).t=temp_string_ } objref SYNM[STYPi] // array is preferable since don't have to fill in every entry for scase(XO,"AM","NM","GA","GB","EX","IX","E2") { sprint(tstr,"x=%s",XO.s) execute(tstr) SYNM[x]=XO } objref ZTYP ZTYP=new List() for scase(XO,"DG","CA3","CA1","SUB","PSUB","MEC","LEC") { sprint(tstr,"%s=%d",XO.s,i1) execute(tstr) ZTYP.append(XO) } // END /usr/site/nrniv/local/hoc/labels.hoc //================================================================ ncl = new List() sp = new NQS() strdef syn1,syn2 thresh = -20 // for ltr(XO,cvode.netconlist("", "", "")) print XO.precell,XO.postcell,XO.syn //* synapse linking -- old routines not using NQS //** geolink(s1,s2,s3) s1 for presyns and s2 for postsyns, connect s3's // only checks for INTF as a possible pre/post point process // connects a layer to another assuming 1 dim netgeom proc geolink() { local i,ii,a,sav,nowrap,noself if (numarg()==0) { print "\tgeolink(s1,s2,s3,DEFCON)" print " make connections from s1 to s2 connecting onto s3 type PPs." print " DEFCON struct defines connection" return } // default to yes wrap; yes within-column connect unless $s1==$s2 nowrap = !$o4.wrap noself=!$o4.self if (strcmp($s1,$s2)==0) $o4.self=0 tmpobj=new List($s1) // object containing a receive/event PP need fflag=1 and intf as name of PP if (tmpobj.object(0).fflag) { // presynaptic object flag sprint(temp_string_,"ncl.append(new NetCon(XO.intf, YO.%s))",$s3) } else { sprint(temp_string_,"XO.soma ncl.append(new NetCon(&v(.5), YO.%s))",$s3) } for ltr (XO,tmpobj,&y) { // presyn list $o4.grot(y) for lvtr (YO,&x,new List($s2),$o4.scr) { // postsyn list and vector if (x==1) { // connect print "connecting ",XO," to ",YO execute(temp_string_) } } } XO=nil YO=nil } //** glink() same as geolink but takes lists statt strings proc glink() { local i,ii,a,sav,nowrap,noself if (numarg()==0) { print "\tgeolink(l1,l2,DEFCON)" print " make connections from items in l1 to items in l2." print " DEFCON struct defines connection" return } // default to yes wrap; yes within-column connect unless $s1==$s2 nowrap = !$o4.wrap noself=!$o4.self // object containing a receive/event PP need fflag=1 and intf as name of PP if ($o1.object(0).fflag) { // presynaptic object flag sprint(temp_string_,"ncl.append(new NetCon(XO.intf, YO.%s))",$s3) } else { sprint(temp_string_,"XO.soma ncl.append(new NetCon(&v(.5), YO.%s))",$s3) } for ltr (XO,$o1,&y) { // presyn list $o4.grot(y) for lvtr (YO,&x,$o2,$o4.scr) { // postsyn list and vector if (x==1) { // connect // print "connecting ",XO," to ",YO execute(temp_string_) } } } XO=nil YO=nil } //** synlink(s1,s2,s3,[gmax,del]) s1 for presyns and s2 for postsyns, connect s3's // eg synlink("PYR","INH","AMPA") // provides full connectivity proc synlink() { local gm,dl if (numarg()==0) { print "\tsynlink(s1,s2,s3)" print " make connections from all of type s1 to one of type s2 " print " only connecting onto s3 type PPs." print " Matching done with regexps." return } if (numarg()==5) { gm=$4 dl=$5 } else { gm=0 dl=1 } tmplist = new List($s3) // list of postsyn point processes for ltr (XO,new List($s1)) { // presyn list for ltr (YO,tmplist) { if (pp_loc(YO,$s2,syn2)) { sfunc.head(syn2,"\\.",syn2) sprint(syn1,"%s",XO) if (strcmp(syn1,syn2)!=0) { // don't allow self connects print "connecting ",XO," to ",syn2 XO.soma ncl.append(new NetCon(&v(.5), YO, thresh, gm, dl)) } } } } } // run NQS.mo(1) first to set up PRIDv ... vectors //** simple netconnect routines: netconn(), netgen() proc netconn () { local pre,post,syn,pri,poi pre=$1 post=$2 if (numarg()==5) { syn=$3 pri=$4 poi=$5 } else { syn=0 pri=$3 poi=$4 } cells[pre].object(pri).conn(cells[post].object(poi).syns[syn]) } proc netgen () { ncl.append(new NetCon($o1, $o2)) } //** syncopy() copies from one set of syns to another for colocalization proc syncopy () { if (numarg()==0) { printf("syncopy(to_type,[]): copy from type, post/type, pre/post/type\n") return } sprint(temp_string_,"XO.precell.soma ncl.append(new NetCon(&v(.5),XO.postcell.%s",$s1) if (numarg()==1) tmplist = cvode.netconlist("", "" , $s2) if (numarg()==2) tmplist = cvode.netconlist("", $s2, $s3) if (numarg()==3) tmplist = cvode.netconlist($s2, $s3, $s4) for ltr(XO,tmplist) execute(temp_string_) } //** syn1to1(PRE,POST,SYN) proc syn1to1 () { local pre,post,syn pre=$1 post=$2 if (numarg()==3) syn=$3 else syn=0 if (cells[pre].count !=cells[post].count) { printf("\tERROR: 1-to-1 connectivity requires same # of %s (=%d) and %s (=%d).\n",\ CTYP.object(pre).s,cells[pre].count,CTYP.object(post).s,cells[post].count) return } for ltr2(XO,YO,cells[pre],cells[post]) { printf("SRC: %s -> TRG: %s (%s)\n",XO,YO,YO.syns(syn)) XO.conn(YO.syns[syn]) } } //* synconn() synapse linking -- NQS routines //** synconn(preid,postid,pre#,post#,%div) // eg synconn(PYRi,PYRi,AMPAi,pmat[PYR][PYR]) // provides % connectivity based on C/pre==%div==%conv==D/post // S==C*post==D*pre %conv=S/(post*pre)=C/pre=D/post objref convec,convec1,convec2 // vectors to count how much div is from each nrn convec = new Vector(1e3) convec1 = convec.c // a scratch vector convec2 = convec.c // copy of convec to blot out self-connect and redundent connects proc synconn () { local preid,posid,pdiv,con,div,ii,jj,prn,pon,targ,sz,styp1,styp2 if (numarg()==0) { print "\tsynconn(preid,postid,prn,pon,pdiv)" return } preid=$1 posid=$2 prn=$3 pon=$4 pdiv=$5 CODEv=sp.v[sp.fi("CODE")] PRv=sp.v[sp.fi("PR")] POv=sp.v[sp.fi("PO")] sz=PRv.size if (pdiv==1) { if (preid==posid) div=pon-1 else div=pon con=div } else { con=int(pdiv*prn+1) div=int(pdiv*pon) } if (isobj(CTYP,"List")) { printf("%s->%s:\tdiv=%d,conv=%d (%d syns)\n",CTYP.object(preid).s,CTYP.object(posid).s,div,con,prn*div) } else { printf("%d->%d:\tdiv=%d,conv=%d (%d syns)\n",preid,posid,div,con,prn*div) } if (prn*div==0) return sp.pad(sz+prn*div) if (pdiv==1) { convec.indgen(0,pon-1,1) for ii=0,prn-1 { if (preid==posid) {convec.indgen(0,pon-1,1) convec.remove(ii)} POv.copy(convec,sz+ii*div) PRv.fill(ii,sz+ii*div,sz+(ii+1)*div-1) } } else { convec.resize(pon) convec.fill(0) // counter for convergence for ii=0,prn-1 { // sources convec2.copy(convec) if (preid==posid) convec2.x[ii]=1e10 // block self-connect for jj=1,div POv.set(sz+ii*div+jj-1,pickpost(pon,con)) // pick desired target PRv.fill(ii,sz+ii*div,sz+(ii+1)*div-1) } } CODEv.fill(mkcodf(preid,posid,0,0,0),sz,PRv.size-1) } //** synconn2() uses elimrepeats() and shuffle methods proc synconn2 () { local preid,posid,pdiv,con,div,ii,jj,prn,pon if (numarg()==0) { print "\tsynconn2(preid,postid,prn,pon,pdiv)" return } preid=$2 posid=$3 prn=$4 pon=$5 pdiv=$6 $o1.clear() PRv=$o1.v[$o1.fi("PR")] POv=$o1.v[$o1.fi("PO")] con=int(pdiv*prn+1) div=int(pdiv*pon) if (prn*div==0) return printf("%s->%s:\tdiv=%d,conv=%d (%d syns)\n",CTYP.object(preid).s,CTYP.object(posid).s,div,con,prn*div) if (pdiv==1) { $o1.pad(prn*div) convec.indgen(0,pon-1,1) for ii=0,prn-1 { POv.copy(convec,ii*div) PRv.fill(ii,ii*div,(ii+1)*div-1) } } else { $o1.pad(1.5*prn*div) rdm.discunif(0,prn-1) PRv.setrand(rdm) rdm.discunif(0,pon-1) POv.setrand(rdm) $o1.elimrepeats("PR","PO") $o1.shuffle() $o1.pad(prn*div) } $o1.fill("CODE",1,preid) $o1.fill("CODE",2,posid) } //** synconn3() doesn't worry about eliminating repeats proc synconn3 () { local preid,posid,pdiv,con,div,ii,jj,prn,pon if (numarg()==0) { print "\tsynconn2(preid,postid,prn,pon,pdiv)" return } preid=$2 posid=$3 prn=$4 pon=$5 pdiv=$6 $o1.clear() PRv=$o1.v[$o1.fi("PR")] POv=$o1.v[$o1.fi("PO")] con=int(pdiv*prn+1) div=int(pdiv*pon) if (prn*div==0) return printf("%s->%s:\tdiv=%d,conv=%d (%d syns)\n",CTYP.object(preid).s,CTYP.object(posid).s,div,con,prn*div) $o1.pad(prn*div) rdm.discunif(0,prn-1) PRv.setrand(rdm) rdm.discunif(0,pon-1) POv.setrand(rdm) $o1.fill("CODE",1,preid) $o1.fill("CODE",2,posid) } //*** pickpost() tries to reduce divergence variance // pickpost(postlist,maxcon,YO) // maxcon == -1 means to ignore convergence // MUST do convec.resize() and convec.fill(0) before using func pickpost () { local ran, maxcon, maxpo, min, indx maxcon = $2 // max convergence to be allowed maxpo = $1 // number of postsyn choices min = convec2.min // convec should start all 0's if (min >= maxcon) { // all full up printf("Pickpost full WARNING: %d %d\n",min,maxcon) vlk(convec2) } convec1.indvwhere(convec2,"==",min) // look for all the smallest to fill up first inx = convec1.x[rdm.discunif(0,convec1.size-1)] convec.x[inx]+=1 convec2.x[inx]=1e10 // block from reconnecting here return inx } //** smap() // excitatory cells project to AMPA and inhibitory cells to GABA // assumes PRIDv ... defined by sp.mo(1) objref pro,poo // pre and post pointers prdx=podx=prx=pox=delx=w0x=w1x=0 func smap () { local ii,ct,sy,conv localobj nc,ty ty=new Union() ct=cp.fi("PRID") sy=cp.fi("STYP") sp.resize("NC") sp.odec("NC") sp.pad() sp.mo(1) for ii=0,PRv.size-1 { uncodf(CODEv.x[ii],&prdx,&podx) prx=PRv.x[ii] pox=POv.x[ii] delx=DELv.x[ii] w0x=WT0v.x[ii] w1x=WT1v.x[ii] pro=c[prdx].object(prx) poo=c[podx].object(pox) NCv.x[ii]=sp.fcdo.append(nc=smap1(prdx))-1 for kk=0,nc.wcnt-1 nc.weight[kk]=0 x=cp.fetch(ct,prdx,sy) syntyp(x,ty) nc.weight[ty.x]=w0x if (ty.x[1]>-1) nc.weight[ty.x[1]]=w1x nc.delay=delx } return ii } //*** smap1(SYN#) poo has postsyn and pro has pre obfunc smap1 () { localobj si if (poo.fflag) { YO=poo } else { YO=poo.po[$1] if (isobj(YO,"List")) { snsr($1,poo) YO=YO.object(YO.count-1) } } if (pro.fflag) { si=new NetCon(pro, YO) } else { pro.soma si=new NetCon(&v(0.5),YO) } return si } //*** snsr() handles situation where multiple PPs must be hung onto postsyn objref proc snsr () { printf("PROBLEM: replace snsr() which uses an execute\n") if (isobj($o2.po[$1],"List")) { sprint(tstr,"%s.soma %s.po[%d].append(new %s(0.5))",$o2,$o2,$1,STYP.object($1).s) } else { sprint(tstr,"%s.soma %s.po[%d] = new %s(0.5)",$o2,$o2,$1,STYP.object($1).s) } execute(tstr) } //** umbrella(preid,postid,max,width[,shift]) // set lateral projections from pre to post out to width // sets direct connection (jj==ii) iff preid!=posid proc umbrella () { local ii,jj,preid,posid,width,sh,max,sz,styp1,styp2 preid=$1 posid=$2 max=$3 width=$4 if (numarg()>=5) sh=$5 else sh=0 sz=PRv.size styp1=styp2=-1 if (width) { for ii=0,max-1 for jj=ii-width+sh,ii+width+sh { if (jj>=0 && jj=5) sh=$5 else sh=0 sz=PRv.size styp1=styp2=-1 if (width) { for ii=0,max-1 for jj=ii-width+sh,ii+width+sh { if (preid!=posid || jj!=ii) { ja=jj if (jj<0) ja=-jj if (jj>max-1) ja=2*max-jj-2 PRv.append(ja) POv.append(ii) PRIDv.append(preid) POIDv.append(posid) } } } else { // just within column connections for ii=0,max-1 { PRv.append(ii) POv.append(ii) PRIDv.append(preid) POIDv.append(posid) } } sp.pad() // WID0v.fill(styp1,sz,PRv.size-1) // WID1v.fill(styp2,sz,PRv.size-1) } //** nqdiv(PRID,POID,PR,PO0[,PO1,...]) // nqdiv(PRID,POID,PR,POBEG,..,POEND) proc nqdiv () { local i,beg,end if (numarg()==0) { print "nqdiv(PRID,POID,PR,PO0[,PO1,...])\nnqdiv(PRID,POID,PR,POBEG,\"..\",POEND)" return } if (numarg()==6 && argtype(5)==2) { beg=$4 end=$6 for i=beg,end sp.append("CODE",EQU1,$1,"CODE",EQU2,$2,"PR",$3,"PO",i) } else for i=4,numarg() sp.append("CODE",EQU1,$1,"CODE",EQU2,$2,"PR",$3,"PO",$i) sp.pad() } //** nqconv(POID,PRID,PO,PR0[,PR1,...]) // nqconv(POID,PRID,PO,PRBEG,..,PREND) proc nqconv () { local i,beg,end if (numarg()==0) { print "nqconv(POID,PRID,PO,PR0[,PR1,...])\nnqconv(POID,PRID,PO,PRBEG,\"..\",PREND)" return } if (numarg()==6 && argtype(5)==2) { beg=$4 end=$6 for i=beg,end sp.append("PRID",$2,"POID",$1,"PR",i,"PO",$3) } else for i=4,numarg() sp.append("PRID",$2,"POID",$1,"PR",$i,"PO",$3) sp.pad() } //** proc nq1to1(PRID,POID,num) proc nq1to1 () { umbrella($1,$2,$3,0) } //* direct weight setting routines //** scale gmax proc synscgmax () { for ltr(XO,cvode.netconlist("" , "", $s1)) { XO.weight *= $2 } } //** set/get gmax proc synsetgmax () { if (numarg()==0) { print "synsetgmax(pre,post,type,wt)" } else if (numarg()==2) {for ltr(XO,cvode.netconlist("" , "", $s1)) XO.weight=$2 } else if (numarg()==3) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) XO.weight=$3 } else if (numarg()==4) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) XO.weight=$4 } else { print "ERROR: too many args" } if (i1==0) printf("WARNING: nothing set in synsetgmax(%s ...)\n",$s1) } // synnormgmax() -- like synsetgmax except normalizes the wt by convergence proc synnormgmax () { for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) { XO.weight=$4/cvode.netconlist($s1,XO.postcell,$s3).count } } proc syngetgmax () { if (numarg()==1) { if (strcmp($s1,"help")==0) { printf("type,post/type,pre/post/type\n") } else { for ltr(XO,cvode.netconlist("" , "", $s1)) printf("%g ",XO.weight) } } else if (numarg()==2) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) printf("%g ",XO.weight) } else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) printf("%g ",XO.weight) } else for ltr(XO,cvode.netconlist("","","")) printf("%g ",XO.weight) print "" } //** set/get delay proc synsetdel () { if (numarg()==2) {for ltr(XO,cvode.netconlist("" , "", $s1)) XO.delay=$2 } else if (numarg()==3) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) XO.delay=$3 } else if (numarg()==4) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) XO.delay=$4 } else { print "ERROR: too many args" } if (i1==0) printf("WARNING: nothing set in synsetdel(%s ...)\n",$s1) } proc syngetdel () { if (numarg()==1) {for ltr(XO,cvode.netconlist("" , "", $s1)) printf("%g ",XO.delay) } else if (numarg()==2) {for ltr(XO,cvode.netconlist("" , $s1, $s2)) printf("%g ",XO.delay) } else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) printf("%g ",XO.delay) } else for ltr(XO,cvode.netconlist("","","")) printf("%g ",XO.delay) print "" } //** set/get thresh proc synsetthr () { if (numarg()==1) {for ltr(XO,cvode.netconlist("" , "", "")) XO.threshold=$1 } else if (numarg()==2) {for ltr(XO,cvode.netconlist($s1 , "", "")) XO.threshold=$2 } else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1, "", $s2)) XO.threshold=$3 } else if (numarg()==4) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) XO.threshold=$4 } else { print "ERROR: too many args" } if (i1==0) printf("WARNING: nothing set in synsetthr(%s ...)\n",$s1) } proc syngetthr () { if (numarg()==1) {for ltr(XO,cvode.netconlist($s1 , "", "")) printf("%g ",XO.threshold) } else if (numarg()==2) {for ltr(XO,cvode.netconlist($s1, "", $s2)) printf("%g ",XO.threshold) } else if (numarg()==3) {for ltr(XO,cvode.netconlist($s1 , $s2, $s3)) printf("%g ",XO.threshold) } else for ltr(XO,cvode.netconlist("","","")) printf("%g ",XO.threshold) print "" } //** synremove: remove post, pre/post, pre/post/type; synshow proc synremove () { if (numarg()==0) { printf("synremove: remove post, pre/post, pre/post/type\n") return } if (numarg()==1) tmplist = cvode.netconlist("", $s1 , "") if (numarg()==2) tmplist = cvode.netconlist("", $s1, $s2) if (numarg()==3) tmplist = cvode.netconlist($s1 , $s2, $s3) if (tmplist.count>0) for ltr(XO,tmplist) ncl.remove(ncl.index(XO)) tmplist = nil // need to remove these references too if (numarg()==1) tmplist = cvode.netconlist("", $s1 , "") if (numarg()==2) tmplist = cvode.netconlist("", $s1, $s2) if (numarg()==3) tmplist = cvode.netconlist($s1 , $s2, $s3) if (tmplist.count>0) for ltr(XO,tmplist) printf("ERROR: %s removed from ncl but still exists\n",XO) tmplist = nil } proc synshow () { sprint(temp_string_,"x=XO.%s",$s2) for ltr(XO,cvode.netconlist("" , "", $s1)) { execute(temp_string_) printf("%g ",x) } print "" } //* weight setting routines using NQS //** stwt(PREID,POSTID,WT0[,WT1,norm]) // stwtnorm() causes dividing by individual convergence values proc stwt () { local w0,w1 if (sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2) ==0) { printf("WARNING NO CONNECTS FROM %d TO %d\n",$1,$2) return } w0=$3 if (numarg()>=5) { w0=$3/$5 w1=$4/$5 } else if (numarg()>=4) { w1=$4 } if (numarg()>=4) sp.fillin("WT0",w0,"WT1",w1) else sp.fillin("WT0",w0) } //** strwt(PREID,POSTID,WT0,WT1,psdev[,norm]) proc strwt () { local w0,w1,psdev cnt=sp.select("CODE",EQU1,$1,"CODE",EQU2,$2) if (cnt==0) {printf("WARNING NO CONNECTS FROM %d TO %d\n",$1,$2) return } if (numarg()>=6) { w0=$3/$6 w1=$4/$6 } else { w0=$3 w1=$4 } psdev=$5 rdm.lognormal(w0,psdev*psdev*w0*w0) sp.out.v[sp.fi("WT0")].setrand(rdm) if (w1!=0) { rdm.lognormal(w1,psdev*psdev*w1*w1) sp.out.v[sp.fi("WT1")].setrand(rdm) } sp.delect() } //** strwt2(NQS,WT0,WT1,psdev[,norm]) proc strwt2 () { local w0,w1,psdev if (numarg()>=5) { w0=$2/$5 w1=$3/$5 } else { w0=$2 w1=$3 } psdev=$4 rdm.lognormal(w0,psdev*psdev*w0*w0) $o1.v[$o1.fi("WT0")].setrand(rdm) if (w1!=0) { rdm.lognormal(w1,psdev*psdev*w1*w1) $o1.v[$o1.fi("WT1")].setrand(rdm) } } //** strdel(PREID,POSTID,del,psdev) proc strdel () { local del0,psdev if (numarg()==4) { cnt=sp.select("CODE",EQU1,$1,"CODE",EQU2,$2) if (cnt==0) {printf("WARNING NO CONNECTS FROM %d TO %d\n",$1,$2) return } del0=$3 psdev=$4 rdm.lognormal(del0,psdev*psdev*del0*del0) sp.out.v[sp.fi("DEL")].setrand(rdm) sp.delect() } else { del0=$2 psdev=$3 rdm.lognormal(del0,psdev*psdev*del0*del0) $o1.v[sp.fi("DEL")].setrand(rdm) } } //** clrwt(PRID,POID,%clr) proc clrwt () { local n n=round($3*sp.select("CODE",EQU1,$1,"CODE",EQU2,$2)) sp.out.v[sp.fi("WT0")].fill(0,0,n) sp.delect() } //** chksp() confirm correspondance between sp and ncl -- defunct if using multiple ncl proc chksp () { local prid,poid,pr,po for ltr(XO,ncl,&x) { prid=sp.v[0].x[x] poid=sp.v[1].x[x] pr=sp.v[2].x[x] po=sp.v[3].x[x] if (XO.pre.id!=pr || XO.pre.type!=prid || XO.syn.id!=po || XO.syn.type!=poid) { printf("%d %d %d %d %d %d %d %d\n",XO.pre.id,pr,XO.pre.type,prid,XO.syn.id,po,XO.syn.type,poid) }} } //** swtmap() -- redund code to permit it to run relatively fast // no longer overloaded to set delay, delmap() or to clr clrwts() proc swtmap () { local ii,ct,sy,conv localobj nc,ty ty=new Union() ct=cp.fi("PRID") sy=cp.fi("STYP") if (PRv.size!=$o1.count) { printf("swtmap ERR: size discrepency: %d vs %d\n",PRv.size,$o1.count) return } for ii=0,PRv.size-1 { prdx=PRIDv.x[ii] podx=POIDv.x[ii] prx=PRv.x[ii] pox=POv.x[ii] delx=DELv.x[ii] w0x=WT0v.x[ii] w1x=WT1v.x[ii] nc=$o1.object(ii) poo=nc.syn x=cp.fetch(ct,prdx,sy) syntyp(x,ty) nc.weight[ty.x]=w0x if (ty.x[1]>-1) nc.weight[ty.x[1]]=w1x nc.delay=delx } } //** wmul(PRID,POID,SYNID,MUL) multiplies set of syns by a factor // resets from weights stored in sp proc wmul () { local prx,pox,sox,fac,a,err,num localobj v1 prx=$1 pox=$2 sox=$3 fac=$4 err=0 a=allocvecs(v1) if (cp.fetch("PRID",prx,"STYP")==EX && !(sox==AM || sox==NM)) err=1 if (cp.fetch("PRID",prx,"STYP")==IX && !(sox==GA || sox==GB)) err=1 if (err) { printf("cell/syn discrepancy: %d -> %d\n",prx,sox) return } if (Incol==2) num=sp.select("CODE",EQU1,prx,"CODE",EQU2,pox) else { num=sp.select("CODE",EQU1,prx,"CODE",EQU2,pox,"CODE",EQU3,Incol) } if (num==0) { printf("wmul WARN: no syns selected:%d %d\n",prx,pox) return } if (sox==0 || sox==2) { v1.copy(sp.out.v[sp.fi("WT0")]) } else { v1.copy(sp.out.v[sp.fi("WT1")]) // O is AM and 2 is GA } v1.mul(fac) vwtmap(v1,sp,sox) dealloc(a) } //** wset(PRID,POID,SYNID,WT) resets weights to gaussian dist similar to strwt() // uses sp to determine how many weights are needed proc wset () { local num,prx,pox,sox,wet,a,err,psdev localobj v1 prx=$1 pox=$2 sox=$3 wet=$4 if (numarg()==5) psdev=$5*$5 else psdev=0 err=0 a=allocvecs(v1) if (cp.fetch("PRID",prx,"STYP")==EX && !(sox==AM || sox==NM)) err=1 if (cp.fetch("PRID",prx,"STYP")==IX && !(sox==GA || sox==GB)) err=1 if (err) { printf("cell/syn discrepancy: %d -> %d\n",prx,sox) return } if (Incol==2) num=sp.select(-1,"CODE",EQU1,prx,"CODE",EQU2,pox) else { num=sp.select(-1,"CODE",EQU1,prx,"CODE",EQU2,pox,"CODE",EQU3,Incol) } v1.resize(num) if (psdev) { rdm.normal(wet,psdev*wet*wet) v1.setrand(rdm) } else v1.fill(wet) vwtmap(v1,sp,sox) dealloc(a) } //** wbim(PRID,POID,SYNID,PSDEV,%A,WTA,%B,WTB,...) bimodal weight setting routines // uses sp to determine how many weights are needed proc wbim () { local fsz,i,prx,pox,sox,wet,a,err,psdev,pcw,ptot localobj v1,v2 prx=$1 pox=$2 sox=$3 psdev=$4*$4 pcw=$5 wet=$6 ptot=0 err=0 a=allocvecs(v1,v2) if (cp.fetch("PRID",prx,"STYP")==EX && !(sox==AM || sox==NM)) err=1 if (cp.fetch("PRID",prx,"STYP")==IX && !(sox==GA || sox==GB)) err=1 if (err) { printf("cell/syn discrepancy: %d -> %d\n",prx,sox) return } fsz=sp.select(-1,"CODE",EQU1,prx,"CODE",EQU2,pox) for i=5,numarg() { pcw=$i i+=1 wet=$i // if (pcw*fsz != int(pcw*fsz)){ printf("wbim WARNING: %d->%d non-int %gx%g=%g\n",prx,sox,pcw,fsz,pcw*fsz) } v2.resize(int(pcw*fsz)) rdm.normal(wet,psdev*wet*wet) v2.setrand(rdm) v1.append(v2) ptot+=pcw // keep track of percent filled } if (ptot!=1) printf("wbim WARNING: %d->%d only %g filled\n",prx,pox,ptot) if (v1.size!=fsz) { printf("wbim WARNING: %d->%d size error %d->%d\n",prx,sox,v1.size,fsz) v1.resize(fsz) } vwtmap(v1,sp,sox) dealloc(a) } //** vwtmap(VEC,NQS) -- copy weights from a vector onto ncl // vwtmap(NQS,VEC) -- copy weights from ncl into vector func vwtmap () { local wix if (numarg()==3) wix=$3 else wix=0 if (isojt($o2,sp)) { // copy from vector to sp.fcdo weights if ($o1.size!=$o2.ind.size){ printf("vwtmap ERR: size discrepency: %d vs %d\n",$o1.size,$o2.ind.size) return 0} for ii=0,$o1.size-1 $o2.fcdo.o[$o2.ind.x[ii]].weight[wix]=$o1.x[ii] return $o1.size } else { // copy from ncl weights to vector if ($o1.ind.size!=$o2.size){printf("vwtmap WARNING: resizing vec\n") $o2.resize($o1.ind.size)} for ii=0,$o2.size-1 $o2.x[ii]=$o1.o[$o1.ind.x[ii]].weight[wix] return $o2.size } } //** wtstat(WIX) -- check id of weights directly from the ncs // assume that have already been selected in sp.out proc wtstat () { local wix,a,sz,fnc localobj v1 a=allocvecs(v1) if (!eqojt(sp.cob,sp.out)) print "WARNING: no sp.select() done" sz=sp.size(1) fnc=sp.fi("NC") v1.resize(sz) v1.resize(0) if (numarg()==1) wix=$1 else wix=0 // for sp.qt(XO,"NC") v1.append(XO.weight[wix]) // 5x slower for ii=0,sz-1 v1.append(sp.fcdo.o(sp.out.v[fnc].x[ii]).weight[wix]) stat(v1) dealloc(a) } // need to set delays proc delmap () { local ii,deli,nc0,nc1 nc0=$o1.fi("NC0") nc1=$o1.fi("NC1","NOERR") deli=$o1.fi("DEL") for ii=0,$o1.v.size-1 { ncl.object($o1.v[nc0].x[ii]).delay=$o1.v[deli].x[ii] if (nc1!=-1) if ($o1.v[nc1].x[ii]!=-1) { ncl.object($o1.v[nc1].x[ii]).delay=$o1.v[deli].x[ii] } } } // clrwtmap proc clrwts () { local ii,jj,nc0,wt0,deli,nc1,wt1,typ,sy2,wid0,wid1,clr nc0=$o1.fi("NC0") wt0=$o1.fi("WT0") deli=$o1.fi("DEL") wid0=$o1.fi("WID0") typ=$o1.fi("TYPE") nc1=$o1.fi("NC1","NOERR") wt1=$o1.fi("WT1","NOERR") wid1=$o1.fi("WID1","NOERR") tobj=ncl.object($o1.v[nc0].x[ii]) for ii=0,$o1.v.size-1 { tobj=ncl.object($o1.v[nc0].x[ii]) for jj=0,tobj.wcnt-1 tobj.weight[jj]=0 // clear tobj.delay=1 tobj.threshold=0 if (nc1!=-1) if ($o1.v[nc1].x[ii]!=-1) for jj=0,tobj.wcnt-1 tobj.weight[jj]=0 // clear } } // swtchk(sp,"WT0","NC0") compare weights to sp weights func swtchk () { local ii,jj,nc0,wt0,n nc0=$o1.fi($s3) wt0=$o1.fi($s2) n=0 for ii=0,$o1.v.size-1 { if ($o1.v[nc0].x[ii]==-1) continue tobj=ncl.object($o1.v[nc0].x[ii]) if ($o1.v[wt0].x[ii]==tobj.weight) n+=1 else { printf("Mismatch %d: %g %g\n",ii,$o1.v[wt0].x[ii],tobj.weight) } } tobj=nil return n/ii } // synchk() look for internal consistency proc synchk () { for ltr(XO,cvode.netconlist("","","")) if (isassigned(XO.postcell) && XO.weight<0) { printf("Error for %s with wt %g\n",XO.syn,XO.weight) } } //** getwt() useful in eg sp.spr(".c.apply('getwt')") func getwt () { return NetCon[$1].weight } spnormflag = 0 // set this flag to normalize weights by number of projections //** actumb(PRID,POID,WIDTH) -- clears umbrella and then set sp.ind to chosen umbrella proc actumb () { local width,flag,divisor width=$3 if (width==-1) flag=1 else flag=0 sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2) if (! flag) { // width=-1 is flag for full connection if (sp.fi("WT1")!=-1) sp.fillin("WT0",0,"WT1",0) else sp.fillin("WT0",0) sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2,"DIST","()",-width,width) } if (! spnormflag) { // just set the values if (sp.fi("WT1")!=-1 && numarg()==5) sp.fillin("WT0",$4,"WT1",$5) else sp.fillin("WT0",$4) } else { // need to calculate convergence for individual cells here } } //** inline(PRID,POID,WT) sets the in-column weights proc inline () { local a sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2,"PR",EQV,"PO") if (numarg()==4) sp.fillin("WT0",$3,"WT1",$4) else sp.fillin("WT0",$3) } // stwtnorm(PREID,POSTID,WT0[,WT1,CONVVEC]) func stwtnorm () { local cv,a,b,ret a=b=allocvecs(2) b+=1 if (sp.select("CODE",EQU1,$1,"CODE",EQU2,$2)==0) { printf("WARNING NO CONNECTS FROM %d TO %d\n",$1,$2) return 0 } sp.uniq("PO") // only retains unique values of PO => cv>0 mso[a].copy(sp.out.v[sp.fi("PO")]) for vtr(&x,mso[a]) { cv=sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2,"PO",x) // do select without copy to out mso[b].append(cv) if (cv>0) { if (numarg()==4) sp.fillin("WT0",$3/cv,"WT1",$4/cv) else sp.fillin("WT0",$3/cv) } } ret=mso[b].mean // mean convergence if (numarg()==4) if (argtype(4)==1) $o4.copy(mso[b]) if (numarg()==5) if (argtype(5)==1) $o5.copy(mso[b]) dealloc(a) return ret } // wtnorm(PREID,POSTID) -- normalize the values according to convergence func wtnorm () { local cv,a,b,ret,wt0,wt1 wt0=sp.fi("WT0") wt1=sp.fi("WT1") if (sp.select(-1,"CODE",EQU1,$1,"CODE",EQU2,$2)==0) { printf("WARNING NO CONNECTS FROM %d TO %d\n",$1,$2) return } a=b=allocvecs(2) b+=1 sp.uniq("PO") // only retains unique values of PO => cv>0 mso[a].copy(sp.out.v[sp.fi("PO")]) for vtr(&x,mso[a]) { cv=sp.select("CODE",EQU1,$1,"CODE",EQU2,$2,"PO",x) mso[b].append(cv) if (cv>0) { sp.out.v[wt0].div(cv) if (wt1>-1) sp.out.v[wt1].div(cv) sp.delect() } } ret=mso[b].mean // mean convergence dealloc(a) return ret } proc setdist () { sp.spr("DIST",".c.sub().apply('abs')") } proc stwtvar() { local a,idr if (numarg()==5) idr=1 else idr=0 a=allocvecs(1) mso[a].resize(sp.ind.size) rdm.uniform($3*(1-$4),$3*(1+$4)) mso[a].setrand(rdm) if (spnormflag) mso[a].div(sp.ind.size) sp.wt[idr].indset(sp.ind,mso[a]) dealloc(a) } //** snc() -- set the actual netcons to the params in sp DEL=DELD=1 proc snc () { local ii for ii=0,sp.size-1 { nc[sp.nc.x[ii]].threshold=0 nc[sp.nc.x[ii]].weight=sp.wt.x[ii] nc[sp.nc.x[ii]].delay=DEL+DELD*sp.dist.x[ii] if (sp.nc[1].x[ii]>-1) { nc[sp.nc[1].x[ii]].weight=sp.wt[1].x[ii] nc[sp.nc[1].x[ii]].delay=DEL+DELD*sp.dist.x[ii] } } } //** snci() -- take a vec of indices (eg sp.ind) as arg proc snci () { local ii,jj for jj=0,$o1.size-1 { ii=$o1.x[jj] nc[sp.nc.x[ii]].weight=sp.wt.x[ii] nc[sp.nc.x[ii]].delay=DEL+DELD*sp.dist.x[ii] if (sp.nc[1].x[ii]>-1) { nc[sp.nc[1].x[ii]].weight=sp.wt[1].x[ii] nc[sp.nc[1].x[ii]].delay=DEL+DELD*sp.dist.x[ii] } } } //* informational procs //** proc print_pp_location(PP), from doc/html/refman/nocmodl.html proc print_pp_location() { local x //arg1 must be a point process x = $o1.get_loc() sectionname(section) printf("%s located at %s(%g)\n", $o1, section, x) pop_section() } //** pp_loc(PP,LOC,SCRATCH) returns true if point process PP is located in LOC (regexp match) func pp_loc () { local x //arg1 must be a point process x = 0 $o1.get_loc() if (numarg()==3) { sectionname($s3) } ifsec $s2 { x = 1 } pop_section() return x } //* ndivo, ncono, sdivo, scono: objects; ndivs, ncons, sdivs, scons: strings //** for use with INTF iterator divr () { local ii for ii=0,ncl.count-1 { XO=ncl.object(ii) if (object_id(sfunc.obj(XO.pre.p))==object_id(cells[$1].object($2))) { iterator_statement } } } iterator conr () { local ii for ii=0,ncl.count-1 { XO=ncl.object(ii) if (object_id(sfunc.obj(XO.syn.p))==object_id(cells[$1].object($2))) { iterator_statement } } } //** iterators // eg for syt("ns[0]","ns[1]") print XO,YO,nco iterator syt () { local num,err err=0 canobj($o1,"XO") canobj($o2,"YO") // canobj -- canonical object if ((num=cvode.netconlist(XO,"",YO).count)!=1) { printf("syt() ERROR num==%d (%s,%s)\n",num,XO,YO) err=1 } if (!err) { nco=cvode.netconlist(XO,"",YO).object(0) iterator_statement } XO=nil YO=nil nco=nil } // nca makes list backwards -- syn, then postcell, then precell iterator nca () { local ii tmplist.remove_all if (numarg()==0) { cvode.netconlist("", "", "",tmplist)} if (numarg()==1) { cvode.netconlist("", "", $s1,tmplist)} if (numarg()==2) { cvode.netconlist("", $s2, $s1,tmplist)} if (numarg()==3) { cvode.netconlist($s3, $s2, $s1,tmplist)} for ii=0,tmplist.count-1 { XO=tmplist.object(ii) iterator_statement } } func wtvec () { revec(vec) for nca($s1) vec.append(XO.weight) vlk(vec) return vec.size } func dlyvec () { revec(vec) for nca($s1) vec.append(XO.delay) vlk(vec) return vec.size } iterator pri () { local ii tmplist.remove_all for ii=0,cvode.netconlist("", $s1, "").count-1 { nco=cvode.netconlist("", $s1, "").object(ii) iterator_statement } } iterator poi () { local ii for ii=0,cvode.netconlist($s1,"","").count-1 { nco=cvode.netconlist($s1,"","").object(ii) iterator_statement } } iterator syi () { local ii for ii=0,cvode.netconlist("","",$s1).count-1 { nco=cvode.netconlist("","",$s1).object(ii) iterator_statement } } proc sdivo () {for ltr(XO,cvode.netconlist($o1, "", "")) prsxo() } func ndivo () { return cvode.netconlist($o1, "", "").count } func ncono () { return cvode.netconlist("", $o1, "").count } proc scono () {for ltr(XO,cvode.netconlist("", $o1, "")) prsxo() } func ndivs () { if (numarg()==1) return cvode.netconlist($s1, "", "").count else { return cvode.netconlist("" , "", "").count } } func ncons () { return cvode.netconlist("", $s1, "").count } proc sdivs () { for ltr(XO,cvode.netconlist($s1, "", "")) prsxo() } proc scons () { if (numarg()==0) for ltr(XO,cvode.netconlist("", "", "")) prsxo() if (numarg()==1) for ltr(XO,cvode.netconlist("", $s1, "")) prsxo() if (numarg()==2) for ltr(XO,cvode.netconlist("", $s1, $s2)) prsxo() if (numarg()==3) for ltr(XO,cvode.netconlist($s1, $s2,$s3)) prsxo() } // print pre,post,syntype,threshold,weight,delay proc prsxo () { if (isobj(XO.precell,"NULLobject")) { printf("%s:%s->%s (%s) (t%g,w%g,d%g)\n",XO,XO.pre,XO.postcell,XO.syn,XO.threshold,XO.weight,XO.delay) } else { printf("%s:%s->%s (%s) (t%g,w%g,d%g)\n",XO,XO.precell,XO.postcell,XO.syn,XO.threshold,XO.weight,XO.delay) } } //* grvec addendum -- new_printlist_... //** new_printlist_nc(obj,id[,NAME]) records spikes from obj to vitem in printlist // with NAME creates a new vitem warn_flag=1 obfunc new_printlist_nc () { local id,thresh,yoset localobj xo,yo id=$2 thresh=-20 yoset=0 if (!isojt(ncl,tmplist)) ncl=new List() if (numarg()>=3) { if (argtype(3)==2) { printlist.append(yo=new vitem($s3,0,1)) yoset=1 } else if (argtype(3)==0) { thresh=$3 } else printf("new_printlist_nc arg 3 should be name or thresh\n") } if (numarg()>=4) thresh=$4 if (!yoset) if (printlist.count==0) { printlist.append(yo=new vitem("SPKS",0,1)) } else { yo=printlist.object(printlist.count-1) // continue with the last one } xo=cvode.netconlist($o1, "", "") if (xo.count==0) { if (! warn_flag) printf(".") else { warn_flag=0 // only warn first time printf("WARNING (new_printlist_nc) creating NetCon for %s ",$o1) } if ($o1.fflag) { xo=new NetCon($o1, nil) } else { $o1.soma xo=new NetCon(&v(x), nil) } xo.threshold=thresh ncl.append(xo) } else { xo=xo.object(0) if (xo.threshold!=thresh && isassigned(xo.precell)) { printf("Warning: new_printlist_nc resetting thresh for %s\n",xo) xo.threshold=thresh } } xo.record(yo.tvec,yo.vec,id) return yo } //** proc new_printlist_nc2(VITEM,CELL,ID#) -- don't bother looking for an existing synapse proc new_printlist_nc2 () { local id,thresh,yoset localobj xo id=$3 thresh=-20 yoset=0 if ($o2.fflag) { xo=new NetCon($o2, nil) } else { $o2.soma xo=new NetCon(&v(x), nil) } xo.threshold=thresh ncl.append(xo) xo.record($o1.tvec,$o1.vec,id) } //** fipre(NETCON) find a presynaptic index for a netcon func fipre () { local nu if (isassigned($o1.pre)) { // a point-process return objnum($o1.pre) } else { if ($o1.preloc==-1) { printf("fipre() ERR: %s\n",$o1) err() } sscanf(secname(),"%*[^[][%d]",&x) // find number of the cell // eg grvecstr="PYR2 sINT sTC sRE" // use locations in this string as id if (sfunc.len(grvecstr)==0) { return x } else { sscanf(secname(),"%[^[]",tstr) nu=sfunc.substr(grvecstr,tstr)/5 return nu*50+x } pop_section() } } //** fspks (index,vec) put spike times for index in vec // fspks (index,vec,num) use printlist.object(num).vec // fspks (index,vec,spkvec,tvec) proc fspks () { local a,b,ix a=b=allocvecs(2) b+=1 if (numarg()==2) { ix=$1 XO=printlist.object(0).vec YO=printlist.object(0).tvec } if (numarg()==3) { ix=$1 XO=printlist.object($3).vec YO=printlist.object($3).tvec } if (numarg()==4) { ix=$1 XO=$o3 YO=$o4 } revec($o2) mso[a].indvwhere(XO,"==",ix) $o2.index(YO,mso[a]) dealloc(a) } // fspks1(index,vec) proc fspks1 () { local a,b,ix if (numarg()==2) { ix=$1 XO=printlist.object($1).vec YO=printlist.object($1).tvec } if (numarg()==4) { ix=$1 XO=$o3 YO=$o4 } $o2.resize(XO.size) $o2.xing(XO,YO,thresh) // times } //** spktimes(plist#,cell#) prints out spike times from a tvec/ivec printlist item func spktimes () { local sz,wh,a localobj va,vb,o a=allocvecs(va,vb) if (numarg()>=1) o=printlist.object($1) else o=printlist.object(0) sz=o.vec.size if (numarg()>=2) { wh=$2 va.indvwhere(o.vec,"==",wh) vb.index(o.tvec,va) sz=vb.size if (numarg()>=3) $o3.copy(vb) else vlk(vb) } else vlk(o.tvec,o.vec) dealloc(a) return sz } //** ceqi() cvode.event_queue_info(3,...) proc ceqi () { local flag,ii flag=$1 tmplist.remove_all revec(ind,vec) printf("\n\n\t**** t=%g ****\n\n",t) if (flag==3) { cvode.event_queue_info(3, ind, vec, tmplist) for ltr(XO,tmplist,100) printf("t=%g flag=%d nc=%s\n",ind.x[i1],vec.x[i1],XO) } else if (flag==2) { cvode.event_queue_info(2, ind, tmplist) for ltr(XO,tmplist,100) { printf("t=%g %s->%s:",ind.x[i1],XO.pre,XO.syn) for ii=0,XO.wcnt-1 printf("%g ",XO.weight[ii]) print "" } } else if (flag==0) { for ltr(XO,ncl,10) { printf("%s->%s:",XO.pre,XO.syn) for ii=0,XO.wcnt-1 printf("%g ",XO.weight[ii]) print "" } } } //** new_printlist_ac(obj,name[,NAME,num]) // adds params from an artificial cell with built-in vec dumping npacsz=1.2 proc new_printlist_ac () { local i,max,num,svloc,sz localobj lo vdt = vdt_INTF lo = new Union() if (numarg()>=4) num=$4 if (numarg()==4) { sprint(lo.s,"%s%d.%s",$s3,$4,$s2) } else { sprint(lo.s,"%s.%s",$o1,$s2) } sz=npacsz*tstop/vdt vite = new vitem(lo.s,sz) vite.o=$o1 if ($o1.recflag==0) { // record tvec vite.tvec=new Vector(sz) $o1.initrec("time",vite.tvec) } else { for ltr(YO,printlist) if (eqobj($o1,YO.o)) vite.tvec=YO.tvec if (!isassigned(vite.tvec)) printf("ERR INTF %s not found in printlist\n",$o1) } vite.tvflag=1 $o1.initrec($s2,vite.vec) printlist.append(vite) vite=nil } objref pfih psgchk = 1 proc psend () { local tt for ltr(XO,printlist) { if (strm(XO.var,"[()][()]$")) { revec(XO.vec,XO.tvec) for (tt=psgchk;tt<=tstop;tt+=psgchk) { sprint(tstr,"%s.append(%s)",XO.vec,XO.var) cvode.event(tt,tstr) sprint(tstr,"%s.append(t)",XO.tvec) cvode.event(tt,tstr) } } } } // eg new_printlist_fc("intf.M1()") // obsolete since intf.mod no longer defines M1(),M2(),... proc new_printlist_fc () { if (! isassigned(pfih)) { pfih = new FInitializeHandler("psend()") } if (! strm($s1,"\\(\\)$")){print "Should be func eg intf.M1()" return } XO = new vitem($s1,0) printlist.append(XO) } //* misc and commentary // con=absolute convergence number, div=absolute div number // con = %con * pre // div * pre = con * post = S (total synapses) // %div = div/post = S/(pre*post) = con/pre = %con // div = %con * post // maxdiv = int((1 + var) * div) //** vari returns randomly chosen $1+/-$2, $2 is a percent func frani () { return int(rdm.uniform($1,$2+1)) } func uvari () { return $1 - $1*$2 + (rdm.uniform(0,1) * 2 * $1*$2) } func gvari () { return $1 - (rdm.normal(0,1) * $1*$2) } //** clearsyns() proc clearsyns () { for ltr(XO,ncl) XO.active(0) ncl.remove_all for ltr(XO,new List("NetCon")) printf("**** CLEARSYN WARNING %s STILL EXISTS ****\n",XO) } // findstr() look thru list for a string and return the index func findstr () { local flag flag = -1 // failure for ltr(XO,$o2) { if (strcmp($s1,XO.s) == 0) flag=i1 } return flag } //** syntyp() reads syntyps out of cp directory proc syntyp () { local x x=$1 if (x==EX) {$o2.x=AM $o2.x[1]=NM // excit } else if (x==IX) {$o2.x=GA $o2.x[1]=GB // inhib } else $o2.x[1]=-1 } //** excitp(PRE) -> T if cell is excitatory func excitp () { if ($1==SU || $1==DP || $1==TC) return 1 if ($1==RE || $1==IN) return 0 printf("ID not classified in excitp\n") return -1 } //* Saving and reading //** svnet() rdnet() proc svnet () { local ii ii=0 if (numarg()==1) filename=$s1 else { sprint(filename,"data/%s%c.net",datestr,97+ii) while (tmpfile.ropen(filename)) sprint(filename,"data/%s%c.net",datestr,97+ii+=1) printf("nqsnet output to %s\n",filename) } XO=usefiles("nqs.hoc","syncode.hoc","nqsnet.hoc","labels.hoc") cp.comment=XO.s sp.comment=XO.s cp.sv(filename) sp.sv(filename,1) tmpfile.close() } proc rdnet () { filename=$s1 if (!isobj(cp,"NQS")) {cp=new NQS() sp=new NQS()} printf("reading network file %s\n",filename) cp.rd(filename) sp.rd() // continue reading tmpfile.close() } //** svstate() rdstate() rerun() proc svstate () { if (! isobj(svs,"SaveState")) svs=new SaveState() svs.save tmpfile.wopen($s1) svs.fwrite(tmpfile) } proc rdstate () { if (! isobj(svs,"SaveState")) svs=new SaveState() tmpfile.ropen($s1) svs.fread(tmpfile) svs.restore } proc initrr () { printf("WARNING: initrr() -- init for rerun() -- not defined\n") } proc rerun () { local tstp,told tstp=tstop if (numarg()>0) rdstate($s1) else svs.restore if (numarg()==1) if (argtype(1)==0) tstp=$1 if (numarg()>1) tstp=$2 told=t initrr() if (t!=told) { printf("ERROR: initrr() appears to have reset t (finitialize()?) (%d->%d)\n",told,t) return } sprint(tstr,"cvode.solve(%g)",t+tstp) time(tstr) finish() } // mkvspks(NUMCELLS,NUMGROUPS,INVL1,SPREAD,[APPEND]) // produces ivspks index vector and vspks time vector for inserting activations // groups are not stable -- they are reconstituted at each spiking time // NUMCELLS indices will be drawn from 0..NUMCELLS-1 // NUMGROUPS will give the separate groupings for simultaneous activation across a group // there will be NUMCELLS/NUMGROUPS cells in each group // INVL1 is the average interval in ms between the inputs // SPREAD is the +/- SPREAD/2 sloppiness in this interval // APPEND is a flag saying to add on to existing ivspks/vspks vectors proc mkvspks () { local gcnt,numc,numg,inv1,inv2,a,ii,j,apflg localobj iv,tv numc=$1 numg=$2 inv1=$3 inv2=$4 apflg=0 if (numarg()>=5) if ($5) apflg=1 // 5th arg is append flag if (!apflg) revec(ivspks,vspks) gcnt = int(numc/numg) // number of cells in each group a=allocvecs(iv,tv) for ({ii=20 j=0};ii=1-1e-8) printf("mkvspks ERR: j>=1\n") // should never happen } ivspks.sortindex(iv) tv.index(vspks,iv) vspks.copy(tv) tv.index(ivspks,iv) ivspks.copy(tv) ivspks.rnd() wvspks.resize(ivspks.size) dealloc(a) } // END /usr/site/nrniv/local/hoc/syncode.hoc //================================================================ // load_file("nqsnet.hoc") // END init.hoc //================================================================ // END prebatch.hoc //================================================================