Allow to set the random noise generator seeds
For reproducibility, we should allow the user to set RNG seeds.
Currently, each noise generator uses one or more RNGs, therefore corresponding to several seeds. These should not be the same, as we don't want to introduce unwanted correlations. However, implementing a mechanism to set them all and as a user, setting them all do not seem like a good way to go. Instead, we suggest to use a primary seed from which all RNG seeds are generated, in a reproductible way.
One solution could be to
- Add a
seed
argument toInstrument.__init__
, which will be our primary seed. It should be saved as attribute on the instance and written to file as metadata inInstrument.write
. - Initialize a simple, light primary RNG with this primary seed to generate the necessary noise RNG seeds. Note that the order in which those are consumed (and therefore associated with the various noises) will change the results. Not sure how to deal with this, or if it's a problem. If we say that we only care about reproducibility per version, then it's not an issue because the code, and therefore how we generate these noise seeds, is fixed within a version. However, it might change between versions.
- Make sure to pass the primary RNG to the noise generating functions, so that they can use it to generate as many seeds they need to initialize their noise RNGs. We might want to save and write those to file -- though, theoretically it is not needed because we can always derive these noise seeds from the primary seed.
An even better way would be to use an explicit mapping from the primary seed to a specific noise seed. Maybe some formula like noise_seed = primary_seed * hash(noise_name) + RNG_index_for_this_noise mod big_number
. This would allow us to re-compute easily the noise seeds from the primary seed. It seems also more robust, because even if we add new noise sources (or even additional terms in an existing noise) or re-order the noise generation, it won't change the results.