RandomEngineRegistry.cc
Go to the documentation of this file.
1 
9 #include <map>
10 #include <string>
11 #include <sstream>
12 #include <stdio.h>
13 #include <fwk/RandomEngineRegistry.h>
14 #include <fwk/CentralConfig.h>
15 #include <utl/RandomEngine.h>
16 #include <utl/AugerException.h>
17 #include <utl/ErrorLogger.h>
18 #include <utl/Reader.h>
19 
20 #include <CLHEP/Random/Randomize.h>
21 
22 using namespace CLHEP;
23 using namespace utl;
24 using namespace std;
25 
26 
27 namespace fwk {
28 
29  void
30  RandomEngineRegistry::RegisterOne(const RandomEngineID id, RandomEngine* const engine)
31  {
32  const bool ok = fRegistry->insert(make_pair(id, engine)).second;
33  if (!ok) {
34  ostringstream msg;
35  msg << "Double insertion of random engine with id " << id;
36  WARNING(msg);
37  }
38  }
39 
40 
43  {
44  if (!fRegistry)
45  Init();
46 
47  Registry::iterator it = fRegistry->find(id);
48  if (it == fRegistry->end()) {
49  ostringstream msg;
50  msg << "Random engine with id " << id << " does not exist.";
51  ERROR(msg);
52  throw InvalidRandomEngineException(msg.str());
53  }
54  return *(it->second);
55  }
56 
57 
58  RandomEngineRegistry::~RandomEngineRegistry()
59  {
60  if (fRegistry)
61  for (const auto& r : *fRegistry)
62  delete r.second;
63  }
64 
65 
66  void
68  {
69  if (!fRegistry)
70  fRegistry = new Registry;
71  else {
72  string msg("Calling Init, "
73  "but RandomEngineRegistry already initialized.");
74  ERROR(msg);
75  throw InitSequenceException(msg);
76  }
77 
78  long seed[2] = { 0 };
79 
80  Branch topB = CentralConfig::GetInstance()->GetTopBranch("RandomEngineRegistry");
81 
82  if (topB) {
83  topB.GetChild("DetectorSeed").GetData(seed[0]);
84  topB.GetChild("PhysicsSeed").GetData(seed[1]);
85  } else {
86  WARNING("RandomEngine branch not found. Random seeds will be generated.");
87  }
88 
89  if (seed[0] == seed[1] && seed[0] > 0) {
90  ostringstream msg;
91  msg << "DetectorSeed = " << seed[0] <<" = PhysicsSeed: This can lead to unwanted correlations!";
92  ERROR(msg);
93  throw InvalidConfigurationException(msg.str());
94  }
95 
96  long randomSeed[2] = { 0 };
97  GenerateSeeds(randomSeed, 2);
98  for (int i = 0; i < 2; ++i)
99  if (seed[i] <= 0)
100  seed[i] = randomSeed[i];
101 
102  RandomEngine* const detectorengine = new RandomEngine(seed[0]);
103  RegisterOne(eDetector, detectorengine);
104  RegisterOne(ePhysics, new RandomEngine(seed[1]));
105 
106  ostringstream info;
107  info << "Seeds of random streams: "
108  "eDetector = " << seed[0] << ", "
109  "ePhysics = " << seed[1] << '.';
110  INFO(info);
111 
112  // set the default CLHEP engine for GEANT4 to be the eDetector engine
113  HepRandom::setTheEngine(&detectorengine->GetEngine());
114  }
115 
116 
117  void
118  RandomEngineRegistry::GenerateSeeds(long* const seed, const int n)
119  const
120  {
121  FILE* const fd = fopen("/dev/urandom", "r");
122  if (fd) {
123  int i;
124  for (i = 0; i < n; ++i) {
125  size_t len;
126  int s;
127  do {
128  len = fread(&s, sizeof(s), 1, fd);
129  } while (len && !s);
130  if (!len)
131  break;
132  seed[i] = abs(s);
133  }
134  fclose(fd);
135  if (i == n)
136  return;
137  }
138 
139  WARNING("Unable to open /dev/random, using current time instead.");
140  time_t s = time(nullptr);
141  for (int i = 0; i < n; ++i)
142  seed[i] = abs(int(s++));
143  }
144 
145 }
Branch GetTopBranch() const
Definition: Branch.cc:63
RandomEngineType & GetEngine()
Definition: RandomEngine.h:32
Base class for exceptions arising because configuration data are not valid.
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
bool ok(bool okay)
Definition: testlib.cc:89
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
Exception to use if sequence of initialisations violated.
int fd
Definition: dump1090.h:233
Class representing a document branch.
Definition: Branch.h:107
constexpr double s
Definition: AugerUnits.h:163
Wraps the random number engine used to generate distributions.
Definition: RandomEngine.h:27
double abs(const SVector< n, T > &v)
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
std::map< RandomEngineID, utl::RandomEngine * > Registry
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
RandomEngineID
Identifiers for all pre-defined random engines.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
Base class for exceptions in the RandomEngineRegistry.

, generated on Tue Sep 26 2023.