Belle II Software  release-08-01-10
checkRandomNumbers.py
1 #!/usr/bin/env python3
2 
3 
10 
11 # this is a test executable, not a module so we don't need doxygen warnings
12 # @cond SUPPRESS_DOXYGEN
13 
14 """
15 Check that random numbers don't change and are consistent.
16 
17 This steering file runs through a set of exp/run combinations and prints
18 the first few random numbers in initialize(), beginRun(), event() and endRun().
19 
20 It also sets the framework to debugging output and shows the information used
21 to calculate the random generator state.
22 """
23 
24 import struct
25 import basf2
26 from ROOT import gRandom
27 
28 
29 def double_to_hex(double):
30  """Convert a double to a hex string representation"""
31  # we pack the float to a little-endian double end interpret it as
32  # little-endian unsigned 64 bit int
33  return "%016X" % struct.unpack("<Q", struct.pack("<d", double))[0]
34 
35 
36 class RandomTestModule(basf2.Module):
37  """Print some random numbers to check reproducibility"""
38 
39  def __init__(self, name):
40  """Make sure we can run in multiple processes"""
41  super().__init__()
42  self.set_property_flags(basf2.ModulePropFlags.PARALLELPROCESSINGCERTIFIED)
43 
44  self.name = name
45 
46  def get_numbers(self, name):
47  """Print the first 20 random numbers"""
48  numbers = [f"First 20 random values in {self.name}::{name}()"]
49  for row in range(5):
50  numbers.append(", ".join(double_to_hex(gRandom.Rndm()) for i in range(4)))
51  basf2.B2INFO("\n ".join(numbers))
52 
53  def initialize(self):
54  """Show random numbers in initialize"""
55  self.get_numbers("initialize")
56 
57  def beginRun(self):
58  """Show random numbers in beginRun"""
59  self.get_numbers("beginRun")
60 
61  def event(self):
62  """Show random numbers in event"""
63  self.get_numbers("event")
64 
65  def endRun(self):
66  """Show random numbers in endRun"""
67  self.get_numbers("endRun")
68 
69 
70 
71 main = basf2.Path()
72 # generate a few runs which look good in hex
73 main.add_module("EventInfoSetter", evtNumList=[3, 4, 5],
74  runList=[0x11121314, 0x21222324, 0x31323334],
75  expList=[0x123, 0x234, 0x345])
76 # We could add a single processing RandomBarrier to check random barrier
77 # transport in multi processing. But since output is unordered in multi
78 # processing we don't do this in the automatic test
79 # main.add_module("RandomBarrier").set_property_flags(0)
80 main.add_module("EventInfoPrinter")
81 main.add_module(RandomTestModule("test1"))
82 main.add_module("RandomBarrier")
83 main.add_module(RandomTestModule("test2"))
84 
85 
86 logging_framework = basf2.logging.package("framework")
87 # now the libraries are loaded so we can set the loglevel to debug, set the seed
88 # and start processing
89 logging_framework.set_log_level(basf2.LogLevel.DEBUG)
90 logging_framework.set_debug_level(200)
91 logging_framework.set_info(basf2.LogLevel.DEBUG, basf2.LogInfo.LEVEL | basf2.LogInfo.MESSAGE)
92 basf2.set_random_seed("this is the seed")
93 
94 basf2.process(main)
95 
96 # @endcond