LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
NuRandomService_service.cc
Go to the documentation of this file.
1 
8 // NuRandomService header
10 
11 // Art include files
20 
21 // Supporting library include files
23 
24 // CLHEP libraries
25 #include "CLHEP/Random/RandomEngine.h" // CLHEP::HepRandomEngine
26 
27 // C++ include files
28 #include <iostream>
29 #include <iomanip>
30 
31 namespace rndm {
32 
33  //----------------------------------------------------------------------------
35  (fhicl::ParameterSet const& paramSet, art::ActivityRegistry& iRegistry)
36  : seeds(paramSet)
37  , state()
38  , verbosity(paramSet.get<int>("verbosity", 0))
39  , bPrintEndOfJobSummary(paramSet.get<bool>("endOfJobSummary",false))
40  {
42 
43  // Register callbacks.
48  iRegistry.sPreProcessEvent.watch (this, &NuRandomService::preProcessEvent );
49  iRegistry.sPreModule.watch (this, &NuRandomService::preModule );
50  iRegistry.sPostModule.watch (this, &NuRandomService::postModule );
51  iRegistry.sPostProcessEvent.watch (this, &NuRandomService::postProcessEvent );
52  iRegistry.sPreModuleEndJob.watch (this, &NuRandomService::preModuleEndJob );
53  iRegistry.sPostModuleEndJob.watch (this, &NuRandomService::postModuleEndJob );
54  iRegistry.sPostEndJob.watch (this, &NuRandomService::postEndJob );
55 
56  } // NuRandomService::NuRandomService()
57 
58 
59 
60  //----------------------------------------------------------------------------
62  (std::string moduleLabel, std::string instanceName) const
63  { return { moduleLabel, instanceName }; }
64 
66  (std::string instanceName /* = "" */) const
67  { return qualify_engine_label( state.moduleLabel(), instanceName); }
68 
69  //----------------------------------------------------------------------------
71  return getSeed(qualify_engine_label());
72  } // NuRandomService::getSeed()
73 
74 
75  //----------------------------------------------------------------------------
77  return getSeed(qualify_engine_label(instanceName));
78  } // NuRandomService::getSeed(string)
79 
80 
81  //----------------------------------------------------------------------------
83  EngineId ID(instanceName, EngineId::global);
84  LOG_DEBUG("NuRandomService")
85  << "NuRandomService::getGlobalSeed(\"" << instanceName << "\")";
86  return getSeed(ID);
87  } // NuRandomService::getGlobalSeed()
88 
89 
90  //----------------------------------------------------------------------------
92 
93  // We require an engine to have been registered before we yield seeds;
94  // this should minimise unexpected conflicts.
95  if (hasEngine(id)) return querySeed(id); // ask the seed to seed master
96 
97  // if it hasn't been declared, we declare it now
98  // (this is for backward compatibility with the previous behaviour).
99  // registerEngineID() will eventually call this function again to get the
100  // seed... so we return it directly.
101  // Also note that this effectively "freezes" the engine since no seeder
102  // is specified.
103  return registerEngineID(id);
104 
105  } // NuRandomService::getSeed(EngineId)
106 
107 
109  return seeds.getSeed(id); // ask the seed to seed master
110  } // NuRandomService::querySeed()
111 
112 
113  std::pair<NuRandomService::seed_t, bool> NuRandomService::findSeed(
114  EngineId const& id,
115  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
116  ) {
118  // try and read the seed from configuration; if succeed, it's "frozen"
119  bool const bFrozen = readSeedParameter(seed, pset, pnames);
120 
121  // if we got a valid seed, use it as frozen
122  if (bFrozen && (seed != InvalidSeed))
123  return { seed, true };
124 
125  // seed was not good enough; get the seed from the master
126  return { querySeed(id), false };
127 
128  } // NuRandomService::findSeed()
129 
130 
131  //----------------------------------------------------------------------------
133  art::EngineCreator& module, std::string type,
134  std::string instance /* = "" */
135  ) {
136  EngineId id = qualify_engine_label(instance);
138  module.createEngine(seed, type, instance);
139  mf::LogInfo("NuRandomService")
140  << "Seeding " << type << " engine \"" << id.artName()
141  << "\" with seed " << seed << ".";
142  return seed;
143  } // NuRandomService::createEngine(strings)
144 
145 
149  module.createEngine(seed);
150  mf::LogInfo("NuRandomService")
151  << "Seeding default-type engine \"" << id.artName()
152  << "\" with seed " << seed << ".";
153  return seed;
154  } // NuRandomService::createEngine()
155 
156 
158  art::EngineCreator& module, std::string type,
159  std::string instance,
160  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
161  ) {
162  EngineId id = qualify_engine_label(instance);
164  std::pair<seed_t, bool> seedInfo = findSeed(id, pset, pnames);
165  module.createEngine(seedInfo.first, type, instance);
166  mf::LogInfo("NuRandomService")
167  << "Seeding " << type << " engine \"" << id.artName()
168  << "\" with seed " << seedInfo.first << ".";
169  if (seedInfo.second) freezeSeed(id, seedInfo.first);
170  return seedInfo.first;
171  } // NuRandomService::createEngine(ParameterSet)
172 
173 
175  art::EngineCreator& module,
176  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
177  ) {
180  std::pair<seed_t, bool> seedInfo = findSeed(id, pset, pnames);
181  module.createEngine(seedInfo.first);
182  mf::LogInfo("NuRandomService")
183  << "Seeding default-type engine \"" << id.artName()
184  << "\" with seed " << seedInfo.first << ".";
185  if (seedInfo.second) freezeSeed(id, seedInfo.first);
186  return seedInfo.first;
187  } // NuRandomService::createEngine(ParameterSet)
188 
189 
191  (SeedMaster_t::Seeder_t seeder, std::string instance /* = "" */)
192  {
193  return registerEngineID(qualify_engine_label(instance), seeder);
194  } // NuRandomService::registerEngine(Seeder_t, string)
195 
196 
198  SeedMaster_t::Seeder_t seeder, std::string instance,
199  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
200  ) {
201  EngineId id = qualify_engine_label(instance);
202  registerEngineAndSeeder(id, seeder);
203  std::pair<seed_t, bool> seedInfo = findSeed(id, pset, pnames);
204  seedEngine(id); // seed it before freezing
205  if (seedInfo.second) freezeSeed(id, seedInfo.first);
206  seed_t const seed = seedInfo.first;
207  return seed;
208  } // NuRandomService::registerEngine(Seeder_t, string, ParameterSet, init list)
209 
210 
212  return registerEngine(SeedMaster_t::Seeder_t(), instance);
213  } // NuRandomService::declareEngine(string)
214 
215 
217  std::string instance,
218  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
219  ) {
220  return registerEngine(SeedMaster_t::Seeder_t(), instance, pset, pnames);
221  } // NuRandomService::declareEngine(string, ParameterSet, init list)
222 
223 
225  (SeedMaster_t::Seeder_t seeder, std::string instance /* = {} */)
226  {
227  return defineEngineID(qualify_engine_label(instance), seeder);
228  } // NuRandomService::defineEngine(string, Seeder_t)
229 
230 
231  //----------------------------------------------------------------------------
233  EngineId const& id,
234  SeedMaster_t::Seeder_t seeder /* = SeedMaster_t::Seeder_t() */
235  ) {
236  prepareEngine(id, seeder);
237  return seedEngine(id);
238  } // NuRandomService::registerEngine()
239 
240 
242  (EngineId const& id, SeedMaster_t::Seeder_t seeder)
243  {
244  if (!hasEngine(id)) {
246  << "Attempted to define engine '" << id.artName()
247  << "', that was not declared\n";
248  }
249 
250  if (seeds.hasSeeder(id)) {
252  << "Attempted to redefine engine '" << id.artName()
253  << "', that has already been defined\n";
254  }
255 
257 
258  seeds.registerSeeder(id, seeder);
259  seed_t const seed = seedEngine(id);
260  return seed;
261  } // NuRandomService::defineEngineID()
262 
263 
264  //----------------------------------------------------------------------------
265  void NuRandomService::ensureValidState(bool bGlobal /* = false */) const {
266  if (bGlobal) {
267  // registering engines may only happen in a service c'tor
268  // In all other cases, throw.
270  {
272  << "NuRandomService: not in a service constructor."
273  << " May not register \"global\" engines.\n";
274  }
275  }
276  else { // context-aware engine
277  // registering engines may only happen in a c'tor
278  // (disabling the ability to do that or from a beginRun method)
279  // In all other cases, throw.
281  // && (state.state() != NuRandomServiceHelper::ArtState::inModuleBeginRun)
282  )
283  {
285  << "NuRandomService: not in a module constructor."
286  << " May not register engines.\n";
287  }
288  } // if
289  } // NuRandomService::ensureValidState()
290 
291 
292  //----------------------------------------------------------------------------
294  // get all the information on the current process, event and module from
295  // ArtState:
297  seed_t const seed = seeds.reseedEvent(id, data);
298  if (seed == InvalidSeed) {
299  mf::LogDebug("NuRandomService")
300  << "No random seed specific to this event for engine '" << id << "'";
301  }
302  else {
303  mf::LogInfo("NuRandomService") << "Random seed for this event, engine '"
304  << id << "': " << seed;
305  }
306  return seed;
307  } // NuRandomService::reseedInstance()
308 
309 
310  void NuRandomService::reseedModule(std::string currentModule) {
311  for (EngineId const& ID: seeds.engineIDsRange()) {
312  if (ID.moduleLabel != currentModule) continue; // not our module? neeext!!
313  reseedInstance(ID);
314  } // for
315  } // NuRandomService::reseedModule(string)
316 
318 
319 
321  for (EngineId const& ID: seeds.engineIDsRange()) {
322  if (!ID.isGlobal()) continue; // not global? neeext!!
323  reseedInstance(ID);
324  } // for
325  } // NuRandomService::reseedGlobal()
326 
327 
328  //----------------------------------------------------------------------------
330  (EngineId const& id, seed_t seed)
331  {
332  // no check is performed to verify that the current module is the one
333  // specified in id.moduleLabel -- but that is required!
335  CLHEP::HepRandomEngine& engine = rng->getEngine(id.instanceName);
336  engine.setSeed(seed, 0); // the 0 is dummy... or so one hopes
337  } // NuRandomService::RandomNumberGeneratorSeeder()
338 
339 
340  //----------------------------------------------------------------------------
342  (EngineId const& id, SeedMaster_t::Seeder_t seeder)
343  {
344  // Are we being called from the right place?
345  ensureValidState(id.isGlobal());
346 
347  if (hasEngine(id)) {
349  << "NuRandomService: an engine with ID '" << id.artName()
350  << "' has already been created!\n";
351  }
352  seeds.registerNewSeeder(id, seeder);
353  } // NuRandomService::registerEngineAndSeeder()
354 
355 
356  //----------------------------------------------------------------------------
357  void NuRandomService::freezeSeed(EngineId const& id, seed_t frozen_seed)
358  { seeds.freezeSeed(id, frozen_seed); }
359 
360 
361  //----------------------------------------------------------------------------
363  (EngineId const& id, SeedMaster_t::Seeder_t seeder)
364  {
365  registerEngineAndSeeder(id, seeder);
366  return querySeed(id);
367  } // NuRandomService::prepareEngine()
368 
369 
370  //----------------------------------------------------------------------------
372  seed_t& seed, fhicl::ParameterSet const& pset,
373  std::initializer_list<std::string> pnames
374  ) {
375  for (std::string const& key: pnames)
376  if (pset.get_if_present(key, seed)) return true;
377  seed = InvalidSeed;
378  return false;
379  } // NuRandomService::readSeedParameter()
380 
381 
382  //----------------------------------------------------------------------------
383  // Callbacks called by art. Used to maintain information about state.
386  state.set_module(md);
387  } // NuRandomService::preModuleConstruction()
388 
390  state.reset_state();
391  } // NuRandomService::postModuleConstruction()
392 
395  state.set_module(md);
396  } // NuRandomService::preModuleBeginRun()
397 
399  state.reset_state();
400  } // NuRandomService::postModuleBeginRun()
401 
404  state.set_event(evt);
405  seeds.onNewEvent(); // inform the seed master that a new event has come
406 
407  LOG_DEBUG("NuRandomService") << "preProcessEvent(): will reseed global engines";
408  reseedGlobal(); // why don't we do them all?!?
409 
410  } // NuRandomService::preProcessEvent()
411 
414  state.set_module(md);
415 
416  // Reseed all the engine of this module... maybe
417  // (that is, if the current policy alows it).
418  LOG_DEBUG("NuRandomService") << "preModule(): will reseed engines for module '"
419  << md.moduleLabel() << "'";
421  } // NuRandomService::preModule()
422 
425  state.reset_state();
426  } // NuRandomService::postModule()
427 
429  state.reset_event();
430  state.reset_state();
431  } // NuRandomService::postProcessEvent()
432 
435  state.set_module(md);
436  } // NuRandomService::preModuleBeginRun()
437 
439  state.reset_state();
440  } // NuRandomService::preModuleBeginRun()
441 
443  if ((verbosity > 0) || bPrintEndOfJobSummary)
444  print(); // framework logger decides whether and where it shows up
445  } // NuRandomService::postEndJob()
446 
447  //----------------------------------------------------------------------------
448 
449 } // end namespace rndm
450 
state_type transit_to(state_type astate)
Records the new status of ART and returns the old one.
Definition: ArtState.h:63
seed_t querySeed(EngineId const &id)
Query a seed from the seed master.
void reset_module()
Records the status of ART.
Definition: ArtState.h:91
bool bPrintEndOfJobSummary
print a summary at the end of job
void reset_state()
Resets the status to "something else" (inOther)
Definition: ArtState.h:74
seed_t getGlobalSeed(std::string instanceName)
Returns a seed for the global engine with specified instance name.
int verbosity
Control the level of information messages.
void preModule(art::ModuleDescription const &md)
void postModule(art::ModuleDescription const &)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
#define DEFINE_ART_SERVICE(svc)
Definition: ServiceMacros.h:93
GlobalSignal< detail::SignalResponseType::FIFO, void(ModuleDescription const &)> sPreModuleConstruction
bool hasSeeder(EngineId const &id) const
Returns whether the specified engine has a valid seeder.
Definition: SeedMaster.h:281
GlobalSignal< detail::SignalResponseType::LIFO, void()> sPostEndJob
EventSeedInputData getEventSeedInputData() const
Definition: ArtState.h:128
void set_event(art::Event const &evt)
Records the specified event ID.
Definition: ArtState.h:77
static bool readSeedParameter(seed_t &seed, fhicl::ParameterSet const &pset, std::string pname)
seed_t defineEngineID(EngineId const &id, SeedMaster_t::Seeder_t seeder)
Set the seeder of an existing engine.
std::string moduleLabel() const
Getters.
Definition: ArtState.h:122
seed_t getSeed()
Returns a seed for the engine with default instance name.
seed_t seedEngine(EngineId const &id)
Calls the seeder with the specified seed and engine ID.
NuRandomService(const fhicl::ParameterSet &, art::ActivityRegistry &)
art::RandomNumberGenerator::seed_t seed_t
GlobalSignal< detail::SignalResponseType::LIFO, void(ModuleDescription const &)> sPostModuleConstruction
void freezeSeed(EngineId const &id, seed_t frozen_seed)
Forces NuRandomService not to change the seed of the specified engine.
void registerEngineAndSeeder(EngineId const &id, SeedMaster_t::Seeder_t seeder)
Registers an engine and its seeder.
void reseedModule()
Reseeds all the engines in the current module.
EngineId qualify_engine_label(std::string moduleLabel, std::string instanceName) const
Returns a fully qualified EngineId.
void postModuleBeginRun(art::ModuleDescription const &)
void postModuleConstruction(art::ModuleDescription const &)
base_engine_t & getEngine() const
GlobalSignal< detail::SignalResponseType::FIFO, void(ModuleDescription const &)> sPreModuleBeginRun
seed_t registerEngineID(EngineId const &id, SeedMaster_t::Seeder_t seeder=SeedMaster_t::Seeder_t())
Register an engine and seeds it with the seed from the master.
base_engine_t & createEngine(seed_t seed)
seed_t createEngine(art::EngineCreator &module, std::string type, std::string instance="")
Creates an engine with RandomNumberGenerator service.
SeedMaster_t::EngineId EngineId
type of random engine ID
void postProcessEvent(art::Event const &)
void registerNewSeeder(EngineId const &id, Seeder_t seeder)
Register the specified function to reseed the engine id.
Definition: SeedMaster.h:536
long seed
Definition: chem4.cc:68
void ensureValidState(bool bGlobal=false) const
void print() const
Prints to the framework Info logger.
std::function< void(EngineId const &, seed_t)> Seeder_t
type of a function setting a seed
Definition: SeedMaster.h:216
GlobalSignal< detail::SignalResponseType::LIFO, void(ModuleDescription const &)> sPostModule
typename PolicyImpl_t::EventData_t EventData_t
type of data used for event seeds
Definition: SeedMaster.h:255
void freezeSeed(EngineId const &id, seed_t seed)
Forces SeedMaster not to change the seed of a registered engine.
Definition: SeedMaster.h:548
NuRandomServiceHelper::ArtState state
in event processing by a module
Definition: ArtState.h:41
void preModuleConstruction(art::ModuleDescription const &md)
Identifier for a engine, made of module name and optional instance name.
Definition: EngineId.h:22
bool get_if_present(std::string const &key, T &value) const
Definition: ParameterSet.h:208
static constexpr seed_t InvalidSeed
An invalid seed.
seed_t defineEngine(SeedMaster_t::Seeder_t seeder, std::string instance={})
Defines a seeder for a previously declared engine.
std::pair< seed_t, bool > findSeed(EngineId const &id, fhicl::ParameterSet const &pset, std::initializer_list< std::string > pnames)
An art service to assist in the distribution of guaranteed unique seeds to all engines within an art ...
constexpr std::tuple_element_t< I, art::AssnsNode< L, R, D > > & get(art::AssnsNode< L, R, D > &t) noexcept
GlobalSignal< detail::SignalResponseType::FIFO, void(ModuleDescription const &)> sPreModuleEndJob
std::string const & moduleLabel() const
static void RandomNumberGeneratorSeeder(EngineId const &id, seed_t seed)
Seeder_t function setting the seed of an engine in RandomNumberGenerator.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
seed_t reseedInstance(EngineId const &id)
Reseeds the specified engine instance in the current module.
state_type state() const
Getters.
Definition: ArtState.h:112
seed_t reseedEvent(EngineId const &id, EventData_t const &data)
Reseeds the specified engine with an event seed (if any)
Definition: SeedMaster.h:572
GlobalSignal< detail::SignalResponseType::FIFO, void(ModuleDescription const &)> sPreModule
seed_t getSeed(std::string moduleLabel)
Returns the seed value for this module label.
Definition: SeedMaster.h:509
GlobalSignal< detail::SignalResponseType::FIFO, void(Event const &)> sPreProcessEvent
static Global_t global
A constant to select a "global" flavour constructor.
Definition: EngineId.h:28
void onNewEvent()
Prepares for a new event.
Definition: SeedMaster.h:726
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
void reseedGlobal()
Reseed all the global engines.
Definition: G4Helper.h:37
void reset_event()
Records the status of ART.
Definition: ArtState.h:83
#define LOG_DEBUG(id)
GlobalSignal< detail::SignalResponseType::LIFO, void(ModuleDescription const &)> sPostModuleEndJob
bool hasEngine(EngineId const &id) const
Returns whether the specified engine is already registered.
EngineInfoIteratorBox engineIDsRange() const
Returns an object to iterate in range-for through configured engine IDs.
Definition: SeedMaster.h:365
GlobalSignal< detail::SignalResponseType::LIFO, void(Event const &)> sPostProcessEvent
void registerSeeder(EngineId const &id, Seeder_t seeder)
Register the specified function to reseed the engine id.
Definition: SeedMaster.h:527
GlobalSignal< detail::SignalResponseType::LIFO, void(ModuleDescription const &)> sPostModuleBeginRun
void preProcessEvent(art::Event const &evt)
void preModuleBeginRun(art::ModuleDescription const &md)
seed_t declareEngine(std::string instance="")
Declares the presence of an engine with a given instance name.
An art service to assist in the distribution of guaranteed unique seeds to all engines within an art ...
void preModuleEndJob(art::ModuleDescription const &md)
void postModuleEndJob(art::ModuleDescription const &)
void set_module(art::ModuleDescription const &desc)
Records the specified module description.
Definition: ArtState.h:86
seed_t registerEngine(SeedMaster_t::Seeder_t seeder, std::string instance="")
Registers an existing engine with NuRandomService.
seed_t prepareEngine(EngineId const &id, SeedMaster_t::Seeder_t seeder)
Registers the engine ID into SeedMaster.
SeedMaster_t seeds
Class managing the seeds.