LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
NuRandomService.h
Go to the documentation of this file.
1 
10 #ifndef NURANDOM_RANDOMUTILS_NuRandomService_H
11 #define NURANDOM_RANDOMUTILS_NuRandomService_H 1
12 
13 #ifndef NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP
14 # define NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP 1
16 #endif // NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP
17 
18 // ROOT libraries
19 #ifndef NURANDOM_RANDOMUTILS_NuRandomService_USEROOT
20 # define NURANDOM_RANDOMUTILS_NuRandomService_USEROOT 0
22 #endif // NURANDOM_RANDOMUTILS_NuRandomService_USEROOT
23 
24 
25 // C/C++ standard libraries
26 #include <functional>
27 #include <string>
28 #include <utility> // std::forward()
29 #include <initializer_list>
30 
31 // Some helper classes.
34 
35 // CLHEP libraries
36 #if (NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP)
37 # include "CLHEP/Random/RandomEngine.h"
38 #endif // NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP
39 
40 // ROOT libraries
41 #if (NURANDOM_RANDOMUTILS_NuRandomService_USEROOT)
42 # include "TRandom.h"
43 #endif // NURANDOM_RANDOMUTILS_NuRandomService_USEROOT
44 
45 // From art and its tool chain.
47 #include "fhiclcpp/ParameterSet.h"
52 
53 // Forward declarations
54 namespace art {
55  class ActivityRegistry;
56  class ModuleDescription;
57  class ModuleContext;
58  class Run;
59  class SubRun;
60 }
61 
62 namespace rndm {
63 
66 
69 
401  public:
403  using engine_t = CLHEP::HepRandomEngine;
404 
406 
408 
410  static constexpr seed_t InvalidSeed = SeedMaster_t::InvalidSeed;
411 
413 
414  // Accept compiler written d'tor. Not copyable or assignable.
415  // This class is not copyable or assignable: these methods are not implemented.
416  NuRandomService(NuRandomService const&) = delete;
417  NuRandomService const& operator=(NuRandomService const&) = delete;
418  NuRandomService(NuRandomService&&) = delete;
419  NuRandomService const& operator=(NuRandomService&&) = delete;
420  ~NuRandomService() = default;
421 
423  static constexpr bool isSeedValid(seed_t seed)
424  { return seed != InvalidSeed; }
425 
426 
450  seed_t getSeed
451  (std::string const& moduleLabel, std::string const& instanceName);
452 
465  seed_t getSeed(std::string instanceName = "");
466 
467 
491  seed_t getGlobalSeed(std::string instanceName);
492 
493 
495  seed_t getCurrentSeed(std::string instanceName) const
496  { return seeds.getCurrentSeed(qualify_engine_label(instanceName)); }
497 
500  { return seeds.getCurrentSeed(qualify_engine_label()); }
501 
503  seed_t getGlobalCurrentSeed(std::string instanceName) const
504  { return seeds.getCurrentSeed(qualify_global_engine(instanceName)); }
505 
506 
507  // --- BEGIN --- Create and register an engine -----------------------------
508 #if (NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP)
509 
531 
559  std::reference_wrapper<NuRandomService::engine_t> registerAndSeedEngine(
560  engine_t& engine,
561  std::string type = "", std::string instance = "",
562  std::optional<seed_t> const seed = std::nullopt
563  );
564 
580  [[nodiscard]] std::reference_wrapper<engine_t> registerAndSeedEngine(
581  engine_t& engine, std::string type, std::string instance,
582  SeedAtom const& seedParam
583  );
584 
600  [[nodiscard]] std::reference_wrapper<engine_t> registerAndSeedEngine
601  (engine_t& engine, std::string type, SeedAtom const& seedParam)
602  { return registerAndSeedEngine(engine, type, "", seedParam); }
603 
619  [[nodiscard]] std::reference_wrapper<engine_t> registerAndSeedEngine
620  (engine_t& engine, SeedAtom const& seedParam)
621  { return registerAndSeedEngine(engine, "", "", seedParam); }
622 
640  [[nodiscard]] std::reference_wrapper<engine_t> registerAndSeedEngine(
641  engine_t& engine, std::string type, std::string instance,
642  fhicl::ParameterSet const& pset, std::string pname
643  )
644  { return registerAndSeedEngine(engine, type, instance, pset, { pname }); }
645 
663  [[nodiscard]] std::reference_wrapper<engine_t> registerAndSeedEngine(
664  engine_t& engine, std::string type, std::string instance,
665  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
666  );
667 
668 
682  [[nodiscard]] std::reference_wrapper<engine_t> registerAndSeedEngine(
683  engine_t& engine, std::string type,
684  fhicl::ParameterSet const& pset, std::string pname
685  )
686  { return registerAndSeedEngine(engine, type, "", pset, pname); }
687 
705  [[nodiscard]] std::reference_wrapper<engine_t> registerAndSeedEngine(
706  engine_t& engine, std::string type,
707  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
708  )
709  { return registerAndSeedEngine(engine, type, "", pset, pnames); }
710 
725  [[nodiscard]] std::reference_wrapper<engine_t> registerAndSeedEngine(
726  engine_t& engine,
727  fhicl::ParameterSet const& pset, std::string pname
728  )
729  { return registerAndSeedEngine(engine, pset, { pname }); }
730 
747  [[nodiscard]] std::reference_wrapper<engine_t> registerAndSeedEngine(
748  engine_t& engine,
749  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
750  )
751  { return registerAndSeedEngine(engine, "", "", pset, pnames); }
752 
753 #endif // NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP
754  // --- END --- Create and register an engine -------------------------------
756 
757 
758 
759  // --- BEGIN --- Register an existing engine -------------------------------
766 
813  seed_t registerEngine(
814  SeedMaster_t::Seeder_t seeder, std::string const instance = "",
815  std::optional<seed_t> const seed = std::nullopt
816  );
817 
818 
833  seed_t registerEngine(
834  SeedMaster_t::Seeder_t seeder, std::string const instance,
835  SeedAtom const& seedParam
836  );
837 
852  seed_t registerEngine
853  (SeedMaster_t::Seeder_t seeder, SeedAtom const& seedParam)
854  { return registerEngine(seeder, "", seedParam); }
855 
872  SeedMaster_t::Seeder_t seeder, std::string instance,
873  fhicl::ParameterSet const& pset, std::string pname
874  )
875  { return registerEngine(seeder, instance, pset, { pname }); }
876 
893  seed_t registerEngine(
894  SeedMaster_t::Seeder_t seeder, std::string instance,
895  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
896  );
897 
914  SeedMaster_t::Seeder_t seeder,
915  fhicl::ParameterSet const& pset, std::string pname
916  )
917  { return registerEngine(seeder, "", pset, pname); }
918 
935  SeedMaster_t::Seeder_t seeder,
936  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
937  )
938  { return registerEngine(seeder, "", pset, pnames); }
939 
940 #if (NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP)
941 
953  seed_t registerEngine
954  (CLHEP::HepRandomEngine& engine, std::string instance = "")
955  { return registerEngine(CLHEPengineSeeder(engine), instance); }
956 
971  CLHEP::HepRandomEngine& engine, std::string instance,
972  SeedAtom const& seedParam
973  )
974  { return registerEngine(CLHEPengineSeeder(engine), instance, seedParam); }
975 
991  CLHEP::HepRandomEngine& engine, std::string instance,
992  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
993  )
994  {
995  return registerEngine
996  (CLHEPengineSeeder(engine), instance, pset, pnames);
997  }
998 #endif // NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP
999 
1001  // --- END --- Register an existing engine ---------------------------------
1002 
1003 
1006 
1020  seed_t declareEngine(std::string instance = "");
1021 
1042  seed_t declareEngine
1043  (std::string instance, fhicl::ParameterSet const& pset, std::string pname)
1044  { return declareEngine(instance, pset, { pname }); }
1045 
1059  seed_t declareEngine(
1060  std::string instance,
1061  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
1062  );
1063 
1075  seed_t declareEngine(fhicl::ParameterSet const& pset, std::string pname)
1076  { return declareEngine("", pset, pname); }
1077 
1092  fhicl::ParameterSet const& pset, std::initializer_list<std::string> pnames
1093  )
1094  { return declareEngine("", pset, pnames); }
1096 
1098 
1114  seed_t defineEngine
1115  (SeedMaster_t::Seeder_t seeder, std::string instance = {});
1116 
1117 #if (NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP)
1118 
1129  seed_t defineEngine
1130  (CLHEP::HepRandomEngine& engine, std::string instance = {})
1131  { return defineEngine(CLHEPengineSeeder(engine), instance); }
1132 #endif // NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP
1133 
1135 
1137  template<class Stream>
1138  void print(Stream&& out) const
1139  { seeds.print(std::forward<Stream>(out)); }
1140 
1142  void print() const { print(mf::LogInfo("NuRandomService")); }
1143 
1144 #if (NURANDOM_RANDOMUTILS_NuRandomService_USEROOT)
1145  class TRandomSeeder {
1147  public:
1148  TRandomSeeder(TRandom* engine): pRandom(engine) {}
1149  void operator() (EngineId const&, seed_t seed)
1150  { if (pRandom) pRandom->SetSeed(seed); }
1151  protected:
1152  TRandom* pRandom = nullptr;
1153  }; // class TRandomSeeder
1154 #endif // NURANDOM_RANDOMUTILS_NuRandomService_USEROOT
1155 
1156 #if (NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP)
1157  class CLHEPengineSeeder {
1159  public:
1160  CLHEPengineSeeder(CLHEP::HepRandomEngine& e): engine(e) {}
1161  CLHEPengineSeeder(CLHEP::HepRandomEngine* e): engine(*e) {}
1162  void operator() (EngineId const&, seed_t seed)
1163  {
1164  engine.setSeed(seed, 0);
1165  MF_LOG_DEBUG("CLHEPengineSeeder")
1166  << "CLHEP engine: '" << engine.name() << "'[" << ((void*) &engine)
1167  << "].setSeed(" << seed << ", 0)";
1168  }
1169  protected:
1170  CLHEP::HepRandomEngine& engine;
1171  }; // class CLHEPengineSeeder
1172 #endif // NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP
1173 
1174  private:
1175 
1178 
1189 
1191  int verbosity = 0;
1192  bool bPrintEndOfJobSummary = false;
1193 
1195  seed_t registerEngineID(
1196  EngineId const& id,
1198  );
1199 
1201  seed_t defineEngineID(EngineId const& id, SeedMaster_t::Seeder_t seeder);
1202 
1203 
1205  bool hasEngine(EngineId const& id) const { return seeds.hasEngine(id); }
1206 
1207  // Main logic for computing and validating a seed.
1208  seed_t getSeed(EngineId const&);
1209 
1210  // Main logic for computing and validating a seed.
1211  seed_t getEventSeed(EngineId const&);
1212 
1218  seed_t reseedInstance(EngineId const& id);
1219 
1221  void reseedModule(std::string currentModule);
1223  void reseedModule();
1225 
1227  void reseedGlobal();
1228 
1230  seed_t prepareEngine(EngineId const& id, SeedMaster_t::Seeder_t seeder);
1231 
1232  // Helper functions for all policies
1233  void ensureValidState(bool bGlobal = false) const;
1234 
1236  EngineId qualify_engine_label
1238  (std::string moduleLabel, std::string instanceName) const;
1239  EngineId qualify_engine_label(std::string instanceName = "") const;
1240  EngineId qualify_global_engine(std::string instanceName = "") const
1241  { return EngineId(instanceName, EngineId::global); }
1243 
1245  static std::optional<seed_t> readSeedParameter
1248  (fhicl::ParameterSet const& pset, std::string pname)
1249  { return readSeedParameter(pset, { pname }); }
1250  static std::optional<seed_t> readSeedParameter(
1251  fhicl::ParameterSet const& pset,
1252  std::initializer_list<std::string> pnames
1253  );
1254  static std::optional<seed_t> readSeedParameter(SeedAtom const& param);
1256 
1258  seed_t querySeed(EngineId const& id);
1259 
1260 
1263  std::pair<seed_t, bool> extractSeed
1264  (EngineId const& id, std::optional<seed_t> seed);
1265 
1267  void freezeSeed(EngineId const& id, seed_t frozen_seed);
1268 
1270  void registerEngineIdAndSeeder
1271  (EngineId const& id, SeedMaster_t::Seeder_t seeder);
1272 
1274  seed_t seedEngine(EngineId const& id) { return seeds.reseed(id); }
1275 
1276  // Call backs that will be called by art.
1277  void preModuleConstruction (art::ModuleDescription const& md);
1278  void postModuleConstruction(art::ModuleDescription const&);
1279  void preModuleBeginRun (art::ModuleContext const& mc);
1280  void postModuleBeginRun (art::ModuleContext const&);
1281  void preProcessEvent (art::Event const& evt, art::ScheduleContext);
1282  void preModule (art::ModuleContext const& mc);
1283  void postModule (art::ModuleContext const&);
1284  void postProcessEvent (art::Event const&, art::ScheduleContext);
1285  void preModuleEndJob (art::ModuleDescription const& md);
1286  void postModuleEndJob (art::ModuleDescription const&);
1287  void postEndJob ();
1288 
1289 
1290  }; // class NuRandomService
1291 
1292 
1293 #if (NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP)
1294  //----------------------------------------------------------------------------
1295  // FIXME: See if the engine preparation can be done similarly to how
1296  // it is described in the "Create and register an engine"
1297  // documentation above.
1298 
1299  //----------------------------------------------------------------------------
1300  inline std::reference_wrapper<NuRandomService::engine_t>
1301  NuRandomService::registerAndSeedEngine(engine_t& engine,
1302  std::string type,
1303  std::string instance,
1304  std::optional<seed_t> const seed)
1305  {
1306  EngineId const id = qualify_engine_label(instance);
1307  registerEngineIdAndSeeder(id, CLHEPengineSeeder{engine});
1308  auto const [seedValue, frozen] = extractSeed(id, seed);
1309  engine.setSeed(seedValue, 0);
1310  mf::LogInfo("NuRandomService")
1311  << "Seeding " << type << " engine \"" << id.artName()
1312  << "\" with seed " << seedValue << ".";
1313  if (frozen) freezeSeed(id, seedValue);
1314  return engine;
1315  } // NuRandomService::registerAndSeedEngine(seed_t)
1316 
1317 
1318  inline std::reference_wrapper<NuRandomService::engine_t>
1319  NuRandomService::registerAndSeedEngine(engine_t& engine,
1320  std::string type,
1321  std::string instance,
1322  SeedAtom const& seedParam)
1323  {
1324  return registerAndSeedEngine(engine, type, instance, readSeedParameter(seedParam));
1325  } // NuRandomService::registerAndSeedEngine(ParameterSet)
1326 
1327 
1328  inline std::reference_wrapper<NuRandomService::engine_t>
1329  NuRandomService::registerAndSeedEngine(engine_t& engine,
1330  std::string type,
1331  std::string instance,
1332  fhicl::ParameterSet const& pset,
1333  std::initializer_list<std::string> pnames)
1334  {
1335  return
1336  registerAndSeedEngine(engine, type, instance, readSeedParameter(pset, pnames));
1337  }
1338 
1339 
1340 #endif // NURANDOM_RANDOMUTILS_NuRandomService_USECLHEP
1341 
1342 } // namespace rndm
1343 
1345 
1346 #endif // NURANDOM_RANDOMUTILS_NuRandomService_H
CLHEP::HepRandomEngine engine_t
A class to assist in the distribution of guaranteed unique seeds.
void print(Stream &&out) const
Prints known (EngineId,seed) pairs.
Seeder_t functor setting the seed of a CLHEP::HepRandomEngine engine (untested!)
seed_t registerEngine(CLHEP::HepRandomEngine &engine, std::string instance, fhicl::ParameterSet const &pset, std::initializer_list< std::string > pnames)
Registers an existing CLHEP engine with art::NuRandomService.
seed_t getCurrentSeed() const
Returns the last computed seed for the default engine of current module.
Class holding the current state of art processing.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::reference_wrapper< engine_t > registerAndSeedEngine(engine_t &engine, fhicl::ParameterSet const &pset, std::initializer_list< std::string > pnames)
Creates an engine with art::RandomNumberGenerator service.
seed_t getCurrentSeed(std::string instanceName) const
Returns the last computed seed for specified engine of current module.
const std::string instance
seed_t seedEngine(EngineId const &id)
Calls the seeder with the specified seed and engine ID.
seed_t registerEngine(SeedMaster_t::Seeder_t seeder, fhicl::ParameterSet const &pset, std::initializer_list< std::string > pnames)
Registers an existing engine with art::NuRandomService.
seed_t registerEngine(SeedMaster_t::Seeder_t seeder, fhicl::ParameterSet const &pset, std::string pname)
Registers an existing engine with art::NuRandomService.
art::detail::EngineCreator::seed_t seed_t
Type of seed used in art and by us.
bool hasEngine(EngineId const &id) const
Returns whether the specified engine is already registered.
Definition: SeedMaster.h:264
EngineId qualify_global_engine(std::string instanceName="") const
Returns a fully qualified EngineId.
seed_t registerEngine(CLHEP::HepRandomEngine &engine, std::string instance, SeedAtom const &seedParam)
Registers an existing CLHEP engine with art::NuRandomService.
long seed
Definition: chem4.cc:67
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:206
Describe the current state of art processing, as understood by the NuRandomService.
Definition: ArtState.h:32
#define DECLARE_ART_SERVICE(svc, scope)
CLHEPengineSeeder(CLHEP::HepRandomEngine *e)
NuRandomServiceHelper::ArtState state
Identifier for a engine, made of module name and optional instance name.
Definition: EngineId.h:22
static constexpr bool isSeedValid(seed_t seed)
Returns whether the specified seed is valid.
seed_t declareEngine(fhicl::ParameterSet const &pset, std::string pname)
Declares the presence of an engine with a default instance name.
CLHEPengineSeeder(CLHEP::HepRandomEngine &e)
seed_t getGlobalCurrentSeed(std::string instanceName) const
Returns the last computed seed for the specified global engine.
std::vector< TrajPoint > seeds
Definition: DataStructs.cxx:14
std::reference_wrapper< engine_t > registerAndSeedEngine(engine_t &engine, fhicl::ParameterSet const &pset, std::string pname)
Creates an engine with art::RandomNumberGenerator service.
#define MF_LOG_DEBUG(id)
seed_t registerEngine(SeedMaster_t::Seeder_t seeder, std::string instance, fhicl::ParameterSet const &pset, std::string pname)
Registers an existing engine with art::NuRandomService.
Definition: MVAAlg.h:12
bool hasEngine(EngineId const &id) const
Returns whether the specified engine is already registered.
seed_t reseed(EngineId const &id)
Reseeds the specified engine with a global seed (if any)
Definition: SeedMaster.h:506
TCEvent evt
Definition: DataStructs.cxx:8
Float_t e
Definition: plot.C:35
seed_t declareEngine(fhicl::ParameterSet const &pset, std::initializer_list< std::string > pnames)
Declares the presence of an engine with a default instance name.
std::reference_wrapper< engine_t > registerAndSeedEngine(engine_t &engine, std::string type, fhicl::ParameterSet const &pset, std::initializer_list< std::string > pnames)
Creates an engine with art::RandomNumberGenerator service.
std::reference_wrapper< engine_t > registerAndSeedEngine(engine_t &engine, std::string type, std::string instance, fhicl::ParameterSet const &pset, std::string pname)
Creates an engine with art::RandomNumberGenerator service.
An art service to assist in the distribution of guaranteed unique seeds to all engines within an art ...
SeedMaster_t seeds
Class managing the seeds.
std::reference_wrapper< engine_t > registerAndSeedEngine(engine_t &engine, std::string type, fhicl::ParameterSet const &pset, std::string pname)
Creates an engine with art::RandomNumberGenerator service.
art::detail::EngineCreator::seed_t seed_t