There are a few tricks that would help you solve your problem with a bit more elegance and flexibility.
Instead of changing run(), I'd leave it alone and declare a new proc
proc myrun() {
. . . do whatever needs doing before a run . . .
run()
. . . whatever needs doing after the run . . .
}
That avoids having to call stdinit() or continuerun(). That's one less line of code, which means I have fewer opportunities to make a mistake.
Also, since no data is written to the output file until _after_ completion of the run, I can put all of the file-related statements in a single block. That makes the code simpler, and simpler code is easier to debug. In fact, I think I'd split the file-related stuff into its own proc. Short procs are ease to read and understand. Also, I'd use a localobj to manage the file. That eliminates the need to declare a top-level variable, keeps code a bit cleaner and simpler.
Instead of using a Matrix to hold all of the output Vectors, I'd simply append them to a List. This eliminates the need to know in advance how many time points will be saved.
Here's a draft that implements these ideas:
Code: Select all
objref dlist
dlist = new List()
proc advance() { localobj tobj
fadvance()
update_csd()
tobj=csdvec.c // prevent future changes to csdvec
// from affecting contents of Vectors that are already in dlist
dlist.append(tobj)
}
proc save_results() { local i localobj fobj
// statements that open output file associated with fobj
for i=0,dlist.count()-1 { // for one row at a time
// statements that print the contents of dlist.o(i) in whatever format you like
}
// statement that closes output file
}
proc myrun() {
dlist = new List() // ensure that dlist is empty at start of new run
run()
save_results()
}
After I got all this working, I might go on to make one more change if I was thinking about using variable time step integration: instead of using a custom proc advance(), use events to control when the csdvec is generated and saved. This would ensure sampling at regular intervals.
Code: Select all
DT = 3.14159... // or whatever you want for the sampling interval
proc sample_csdvec() { localobj tobj
update_csd()
tobj=csdvec.c // prevent future changes to csdvec
// from affecting contents of Vectors that are already in dlist
dlist.append(tobj)
cvode.event("sample_csdvec()", t + DT) // execute sample_csdvec DT ms from now
}
// now we need to call sample_csdvec() at the start of the run
objref fih
fih = new FInitializeHandler("sample_csdvec(DT)") // execute sample_csdvec() at t = 0,
// right after the mechanism INITIAL blocks have been executed
objref dlist
dlist = new List()
// comment out the custom proc advance
// proc advance() { localobj tobj
// fadvance()
// update_csd()
// tobj=csdvec.c // prevent future changes to csdvec
// // from affecting contents of Vectors that are already in dlist
// dlist.append(tobj)
// }
proc save_results() { local i localobj fobj
// statements that open output file associated with fobj
for i=0,dlist.count()-1 { // for one row at a time
// statements that print the contents of dlist.o(i) in whatever format you like
}
// statement that closes output file
}
proc myrun() {
dlist = new List() // ensure that dlist is empty at start of new run
run()
save_results()
}
I think that should work--but typos and stupid or even clever mistakes are always possible.