3. Run a segmented simulation and save its results

To implement recording and saving of a segmented simulation, I followed a pattern similar to what worked for a full run.

  1. Create a hoc file called cellrecord_segrun.hoc that contains statements that execute a user-specified number of simulation segments and save each segment's results to a separate file.
  2. Copy initcell_fullrun.hoc to initcell_segrun.hoc, and edit this new file to change the load_file("cellrecord_fullrun.hoc") statement to load_file("cellrecord_segrun.hoc").

Here is initcell_segrun.hoc

load_file("nrngui.hoc")

load_file("cellspec.hoc") // properties of model cell
load_file("cellrig.hoc") // basic instrumentation and simulation control
  // required to launch a simulation and see results
  // i.e. just an IClamp, graph, and RunControl

load_file("cellrecord_segrun.hoc") // sets up Vector recording,
  // executes series of short runs, and saves each to its own dat file.

Here is cellrecord_segrun.hoc. Note that it begins with the same Vector record() statements and proc xytofile() as its predecessor. The "new" stuff in this file are the declarations of the simulation parameters NSEGS and SEGDUR, and proc do_segments().

///// advanced instrumentation

// capture data to Vectors
objref tvec, vvec
tvec = new Vector()
vvec = new Vector()
tvec.record(&t)
vvec.record(&soma.v(0.5))

///// advanced simulation control

// $o1, $o2 Vectors of x & y values, respectively
// $s3 file name string
proc xytofile() { local i  localobj tfil
  print "writing to ", $s3
  tfil = new File()
  tfil.wopen($s3)
  tfil.printf("%d\n",$o1.size())
  for i=0,$o1.size()-1 tfil.printf("%g\t%g\n", $o1.x[i], $o2.x[i])
  tfil.close()
}

// execute NSEGS segments, each of duration SEGDUR
// save results to NSEGS files called segment00.dat..segmentnn.dat
// where nn is the two digit integer NSEGS-1

SEGDUR = 2 // duration of a segment
NSEGS = 3  // how many in a complete simulation

// run $1 segments, each of duration $2
// save results to $1 files called $s300.dat..$s3nn.dat

strdef tmpstr // for constructed file names

proc do_segments() { local i, j, tfin
  tfin = 0
  stdinit() // initialize the model before entering the loop
  for i=0,$1-1 { // iterate over the segments
/* doing this here will lose the datum at t = 0
    tvec.resize(0)
    vvec.resize(0)
*/
    tfin+=$2 // this segment's end time
    print "this run ends at ", tfin
    continuerun(tfin) // picks up where the previous simulation left off

    sprint(tmpstr, "%s%2.2d.dat", $s3, i) // construct name of file
      // to hold current segment's results
      // name is of the form $s3nn.dat, where nn is a two place integer
    xytofile(tvec, vvec, tmpstr) // save results to file
    // prepare for next pass
    // no need to capture last point of previous continuerun
    tvec.resize(0)
    vvec.resize(0)
  }
}

do_segments(NSEGS, SEGDUR, "segment") // generates segment00.dat..segmentnn.dat
  // where nn is a two digit integer equal to NSEGS - 1

The comments next to the last statement in cellrecord_segrun.hoc describe what will happen when initcell_segrun.hoc is executed.

The only aspect of cellrecord_segrun.hoc that is questionable is that the statements that assign values to SEGDUR and NSEGS are buried in the middle of the file. It would be best to put these assignment statements at the very beginning of initcell_segrun.hoc, where they will be most easily found in case someone ever wants to change segment duration or the number of segments.