Discussion of solution source code

The RanStream class

The RanStream class is defined by the code in ranstream.hoc. A RanStream instance is just an instance of the Random class, packaged with a couple of things that make it easy to use to generate statistically independent random event streams. In the context of the present problem, the most important of these are:
the public member r
This exposes the Random instance to hoc statements outside of this class. We'll use r when we associate a Random instance with a NetStim.
declaration of these items: an external called random_stream_offset_, a public parameter called stream, and a method called start()
Quoting from the Programmer's Reference documentation of mcell_ran4: SYNTAX
x = mcell_ran4(&highindex)
DESCRIPTION
 . . .  The highindex integer  . . .  is incremented by one on each call. Multiple independent streams are possible, each associated with a separate highindex with different starting values but the difference between highindex starting values should be greater than the length of each stream.

Note that ranstream.hoc starts with the statement
random_stream_offset_ = 1000
and that the RandomStream's proc init() calls func start(), which in turn contains the statement
return r.MCellRan4(stream*random_stream_offset_ + 1)

Which means this: if we create a bunch of RandomStream objects by executing these statements

objref rs1, rs2 . . .
rs1 = new RandomStream(0)
rs2 = new RandomStream(1)
 . . . 
then we can use each rsn's Random member to generate as many as 1000 random numbers before it starts to generate numbers that overlap those that were generated by rsn+1. So random_stream_offset_ specifies the maximum number of samples that can be drawn from any stream before statistical independence is compromised.

proc makenetstims()

random_stream_offset_ = MAXSTREAM
means that the value of the user-defined constant MAXSTREAM overwrites the default value of random_stream_offset_
the for loop
does, among other things, the following:
  1. creates an instance of the RandomStream class for each instance of the NetStim class that it creates
  2. uses the NetStim class's noiseFromRandom to associate the RandomStream's public Random member rs.r with the NetStim
  3. specifies that rs.r will use the negexp distribution
  4. and calls the RandomStream's start() method so that rs.r's highindex is initialized to the desired value
The "simulation control" code
proc restart()
calls the start() method of each RandomStream object with an argument that restores its Random object back to the beginning of its random number stream. This allows reproducible simulations to be executed without having to exit and restart NEURON.
proc myrun()
includes a bit of code that generates a raster plot that shows each cell's spike train. The model setup code uses the index in the list of NetStims as the cell ID number; these start at 0 which means that the first cell's raster marks would be drawn on top of the x axis where they would be easy to confuse with tick marks. For the sake of a nicer looking raster plot, the contents of the idvec are incremented by 1 before plotting. In other words, nslist.o(0)'s spike times are drawn at a y offset of 1, nslist.o(1)'s spike times are drawn at a y offset of 2, etc..

Is the slight esthetic improvement of the graph negated by the potential confusion about which marks in the raster plot belong to which element of nslist? Probably not--anyone who could follow the discussion up to this point is likely to be able to handle this too.