Random numbers#
The LiteBIRD Simulation Framework can be used to generate random numbers, used for example for producing noise timelines. In order to do so, a seed and a Random Number Generator (RNG) are used.
Seed#
The random_seed is used to control the behavior of the RNG. The
seed can be None or an integer number. If you are not
interested in the reproducibility of your results, you can set
random_seed to None. However, this is not recommended, as if
you run many times a function or method that uses an RNG, e.g., for
producing noise timelines, then the outputs will be different, and
you will not be able to re-obtain these results again. If, instead,
you are interested in the reproducibility of your results, you can set
random_seed to an integer number. With this choice, if you run a
function or method multiple times using an RNG, then the outputs will
be the same, and you will obtain these results again by re-running
your script, as the random numbers produced by the generator will be
the same.
How should you set the random_seed? This parameter must be
passed to the constructor of a Simulation class. If you
create a Simulation instance without passing the seed, the
constructor will raise an error, and your script will fail. We
implemented this feature to avoid automatic settings of the seed and
unclear behavior of the generation of random numbers. If you run a
parallel script using MPI, you do not have to worry about setting a
different seed for different MPI ranks. The random number generator
ensures that the random numbers generated by the ranks will produce
orthogonal sequences. We want this behavior as we do not want
repetitions of, e.g., the same noise TOD if we split their computation
on different MPI ranks. For example, in this way, if you split the TOD
matrix of an Observation class by the time, you will not
encounter the same noise after the samples generated by a certain
rank; if you split the TOD matrix of an Observation class by
the detectors, each one will have a different noise timestream.
Regarding the reproducibility of the results in a parallel code, there is an important thing to bear in mind. If you set the seed to an integer number but run your script with a different number of MPI ranks, the outputs will be different! Think about a noise time stream of 4 samples. If you use 2 MPI ranks, then the first two samples will be generated by one RNG (rank 0), while the last two samples will be generated by a different RNG (rank 1). If you then run the same script with the same seed but with 4 MPI ranks, each of the samples will be generated by a different RNG, and only the first sample will be the same for the two runs, as it is always the first one generated by rank 0’s RNG.
The setting of the random_seed is as simple as this:
sim = lbs.Simulation(
base_path="/storage/output",
start_time=astropy.time.Time("2020-02-01T10:30:00"),
duration_s=3600.0,
name="My noise simulation",
description="I want to generate some noise and be able to reproduce my results",
random_seed=12345, # Here the seed for the random number generator is set
)
The Simulation constructor runs the
Simulation.init_random() method, which builds the RNG and seeds
it with random_seed. You can then use this RNG by calling
sim.random. There is also the possibility to change the random
seed after creating a Simulation instance. You can achieve
this by calling Simulation.init_random():
sim = lbs.Simulation(random_seed=12345)
[...]
sim.init_random(random_seed=42)
Random number generators#
The random number generator used by the Simulation.init_random()
method of the Simulation class is
PCG64.
After creating this RNG by calling Simulation.init_random()
(directly or from the Simulation constructor), you can use it
via sim.random:
sim = lbs.Simulation(random_seed=12345)
[...]
sim.add_noise(noise_type='white', random=sim.random)
You can also use your own RNG with the functions and methods of
litebird_sim:
sim = lbs.Simulation(random_seed=12345)
[...]
my_rng = ... # New RNG definition
sim.add_noise(noise_type='white', random=my_rng)
You should just make sure that your custom RNG implements the
normal method, so it can be used for white noise generation.