RandomManagerTest_module.cc
Go to the documentation of this file.
1 /**
2  * @file RandomManagerTest_module.cc
3  * @brief Test of the random engine managing interface of NuRandomService
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date February 19th, 2015
6  */
7 
8 
9 // art extensions
10 #define NUTOOLS_RANDOMUTILS_NURANDOMSERVICE_USECLHEP 1 // to have NuSeedService.h define CLHEPengineSeeder
11 #include "nutools/RandomUtils/NuRandomService.h"
12 
14 
15 // C++ includes.
16 #include <string>
17 #include <array>
18 #include <vector>
19 #include <sstream>
20 #include <algorithm> // std::generate()
21 #include <iomanip> // std::setw()
22 
23 // CLHEP libraries
24 #include "CLHEP/Random/RandomEngine.h" // CLHEP::HepRandomEngine
25 #include "CLHEP/Random/Ranlux64Engine.h" // CLHEP::Ranlux64Engine
26 #include "CLHEP/Random/RandFlat.h"
27 
28 // Supporting library include files
30 
31 // Framework includes.
33 #include "cetlib/exempt_ptr.h"
42 
43 namespace testing {
44 
45  /**
46  * @brief Test module for random engine managing interface of NuRandomService
47  *
48  * The test writes on screen the random seeds it gets.
49  *
50  * Configuration parameters:
51  * - *instanceNames* (string list, optional): use one random number
52  * generator for each instance name here specified; if not specified,
53  * an anonymous engine is used
54  * - *externalInstance* (string, optional): if specified, an engine not
55  * managed by RandomNumberGenerator is also used, with this instance name
56  * - *standardInstance* (string, optional): if specified, an engine
57  * is created by RandomNumberGenerator but not registered is NuRandomService
58  * is also used, with this instance name
59  * - *Seed*, *Seed_XXX* (strings, optional): set the seed of instance `XXX`
60  * to a set value ("Seed" sets the seed of the anonymous instance)
61  *
62  */
64  public:
66 
67  explicit RandomManagerTest(fhicl::ParameterSet const& pset);
68 
69  void analyze(const art::Event& event) override;
70 
71  private:
73 
74  std::map<std::string, cet::exempt_ptr<CLHEP::HepRandomEngine>> engines;
75  std::unique_ptr<CLHEP::HepRandomEngine> extEngine{nullptr};
77  }; // class RandomManagerTest
78 
79 
80 
81  //****************************************************************************
82  //--- RandomManagerTest implementation
83  //---
85  art::EDAnalyzer{pset},
86  moduleLabel{pset.get<std::string>("module_label")}
87  {
89 
90  // check if we want an "external" engine
91  std::string externalInstanceName{};
92  if (pset.get_if_present("externalInstance", externalInstanceName)) {
93  mf::LogInfo("RandomManagerTest") << "Creating an unmanaged engine '"
94  << externalInstanceName << "' in module '" << moduleLabel << "'";
95  extEngine = std::make_unique<CLHEP::Ranlux64Engine>();
96 
97  EngineManager->registerEngine(
98  [this](rndm::NuRandomService::EngineId const&, seed_t seed)
99  { this->extEngine->setSeed(seed, 0); },
100  externalInstanceName, pset, "Seed_" + externalInstanceName
101  );
102  } // if we have the external engine
103 
104  // check if we want an unmanaged standard engine
105  std::string standardInstanceName{};
106  if (pset.get_if_present("standardInstance", standardInstanceName)) {
107  mf::LogInfo("RandomManagerTest") << "Creating a standard engine '"
108  << standardInstanceName << "' in module '" << moduleLabel
109  << "' with RandomNumberGenerator";
110  seed_t seed
111  = pset.get<unsigned int>("Seed_" + standardInstanceName, 0);
112  stdEngine = &createEngine(seed, "HepJamesRandom", standardInstanceName);
113  } // if we have the external engine
114 
115  // initialize the standard engines with RandomNumberGenerator
116  auto const instanceNames = pset.get<std::vector<std::string>>("instanceNames", {});
117  for (std::string const& instanceName: instanceNames) {
118  mf::LogInfo("RandomManagerTest") << "Creating a default engine '"
119  << instanceName << "' in module '" << moduleLabel << "'";
120  CLHEP::HepRandomEngine& engine = EngineManager->createEngine
121  (*this, "HepJamesRandom", instanceName, pset, "Seed_" + instanceName);
122  engines.emplace(instanceName, &engine);
123  }
124 
125  // create a default engine, if needed
126  if (instanceNames.empty() && !extEngine && !stdEngine) {
127  mf::LogInfo("RandomManagerTest")
128  << "Creating a nameless default engine in module '"
129  << moduleLabel << "'";
130  CLHEP::HepRandomEngine& engine = EngineManager->createEngine(*this, pset, "Seed");
131  engines.emplace("", &engine);
132  }
133 
134  { // anonymous block
135  mf::LogInfo log("RandomManagerTest");
136  log << "RandomManagerTest[" << moduleLabel << "]: instances:";
137  for (std::string const& instanceName: instanceNames)
138  log << " " << instanceName;
139  } // anonymous block
140 
141  // Add non-art-managed engines to list of engines
142  if (extEngine) {
143  assert(!externalInstanceName.empty());
144  engines.emplace(externalInstanceName, extEngine.get());
145  }
146 
147  if (stdEngine) {
148  assert(!standardInstanceName.empty());
149  engines.emplace(standardInstanceName, stdEngine);
150  }
151 
152  } // RandomManagerTest::RandomManagerTest()
153 
154 
155  //----------------------------------------------------------------------------
157  {
158  mf::LogVerbatim("RandomManagerTest") << "RandomManagerTest[" << moduleLabel << "]::analyze "
159  << event.id();
160 
161  for (auto& [instanceName, engine] : engines) {
162  seed_t actualSeed = testing::NuRandomService::readSeed(*engine);
163  mf::LogVerbatim("RandomManagerTest")
164  << std::setw(12) << (instanceName.empty()? "<default>": instanceName)
166  << " (seed: " << actualSeed << ")";
167  }
168  } // RandomManagerTest::analyze()
169 
170 
171 } // end namespace testing
172 
base_engine_t & createEngine(seed_t seed)
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
art::detail::EngineCreator::seed_t seed_t
LArSoft test utilities.
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:27
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:69
cet::exempt_ptr< CLHEP::HepRandomEngine > stdEngine
std::string CreateCharacter(CLHEP::HepRandomEngine &engine)
Creates a "character statistics" using the specified random engine.
Identifier for a engine, made of module name and optional instance name.
Definition: EngineId.h:22
Functions used in NuRandomService tests.
std::unique_ptr< CLHEP::HepRandomEngine > extEngine
std::reference_wrapper< engine_t > createEngine(Module &module, std::string type, std::string instance="")
Creates an engine with RandomNumberGenerator service.
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
RandomManagerTest(fhicl::ParameterSet const &pset)
void analyze(const art::Event &event) override
seed_t readSeed(CLHEP::HepRandomEngine const &engine)
Returns the seed of the specified engine (CLHEP overload)
Test module for random engine managing interface of NuRandomService.
std::map< std::string, cet::exempt_ptr< CLHEP::HepRandomEngine > > engines
seed_t registerEngine(SeedMaster_t::Seeder_t seeder, std::string instance="")
Registers an existing engine with NuRandomService.
Event finding and building.