The solution

The solution to these problems is to give each NetStim its own random number generator.


"How?" you might very well ask.

By creating an instance of the Random class for every instance of the NetStim class, and using the NetStim class's noiseFromRandom to associate the two. You can probably figure out how to do this on your own if I just point you to a good example, like NEURON/common/netstim.hoc in the source code for entry 83319 from ModelDB

But for the impatient, here's a quick example. Promise to check out the ModelDB entry after you understand this one.

Outline of the solution

In essense the solution is this simple:

  create a new NetStim instance
  create a new Random instance
  make the NetStim get its event times from the Random
Until enough NetStims have been created
Run a simulation and show results

But of course the actual implementation is somewhat more complex, because there are many details to attend to. These include

  • Specifying the basic properties of the NetStim (interval, number, start, noise).
  • Specifying the distribution that governs the values returned by the Random instances. Always use Random.negexp(1), because the NetStim instance will scale these random values by a factor that depends on its interval and noise parameters.
  • If we're going to all this trouble, we might as well use the MCellRan4 random number generator, which is a higher quality generator than the Random class's default ACG (this would be a good time to read about the Random class and MCellRan4 in the programmer's reference).
  • Instrumentation and simulation control. As in the previous example, instrumentation will consist of using the NetCon class's record() method to capture spike times and cell ids to a pair of Vectors. Also as before, simulation control will use a custom myrun() function that pulls together the standard run system's run() with a bit more code that prints out the spike times and cell ids, but this time there will also be a graph that shows a raster plot of the spikes generated by the NetStims. And this time, instead of the seed() procedure used in the first example, we will use a special restart() procedure that allows us to reset all of the Random instances to the start of their random number streams, as an aid to being able to perform reproducibile simulations without having to exit and restart NEURON after each run.