LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
PerEventPolicy.h
Go to the documentation of this file.
1 
12 #ifndef NURANDOM_RANDOMUTILS_PROVIDERS_PEREVENTPOLICY_H
13 #define NURANDOM_RANDOMUTILS_PROVIDERS_PEREVENTPOLICY_H 1
14 
15 // C/C++ standard libraries
16 #include <string>
17 #include <memory> // std::unique_ptr<>
18 #include <type_traits> // std::make_signed<>
19 
20 // From art and its tool chain
22 #include "fhiclcpp/ParameterSet.h"
24 
25 // Some helper classes
26 #include "nurandom/RandomUtils/Providers/PolicyFactory.h" // makeRandomSeedPolicy
30 
31 
32 namespace rndm {
33 
34  namespace details {
35 
77  template <typename SEED>
78  class PerEventPolicy: public RandomSeedPolicyBase<SEED> {
79  public:
82  using seed_t = typename base_t::seed_t;
83 
86 
87  typedef enum {
92  } SeedAlgo_t;
93 
96  PerEventPolicy(fhicl::ParameterSet const& pset): base_t("perEvent")
97  { this_t::configure(pset); }
98 
100  virtual bool yieldsUniqueSeeds() const override { return false; }
101 
102 
118  virtual void configure(fhicl::ParameterSet const& pset) override;
119 
121  virtual void print(std::ostream& out) const override;
122 
123 
125  static constexpr const char* DefaultVersion = "v1";
126 
127 
129  template <typename Hashable>
130  static seed_t SeedFromHash(Hashable const& info)
131  { return makeValid(std::hash<Hashable>()(info)); }
132 
134  static std::string UniqueEventIDString(EventData_t const& info);
135 
137  static std::string UniqueEventString(EventData_t const& info);
138 
139 
140  private:
141 
143  using SeedOffset_t = typename std::make_signed<seed_t>::type;
144 
145  SeedAlgo_t algo;
146 
148 
151 
153  virtual seed_t createSeed(SeedMasterHelper::EngineId const& id) override;
154 
167  virtual seed_t createEventSeed
168  (SeedMasterHelper::EngineId const& id, EventData_t const& info)
169  override;
170 
172  template <typename T>
174 
177  (SeedMasterHelper::EngineId const& id, EventData_t const& info);
178 
179 
181  static const std::vector<std::string> algoNames;
183 
184  static std::vector<std::string> InitAlgoNames();
186  }; // class PerEventPolicy<>
187 
188 
189 
190  //--------------------------------------------------------------------------
191  //--- PerEventPolicy template implementation
192  //---
193  template <typename SEED>
194  std::vector<std::string> PerEventPolicy<SEED>::InitAlgoNames() {
195 
196  std::vector<std::string> names((size_t) NAlgos);
197 
198  names[saEventTimestamp_v1] = "EventTimestamp_v1";
199 
200  return names;
201  } // PerEventPolicy<SEED>::InitAlgoNames()
202 
203 
204  template <typename SEED>
205  const std::vector<std::string> PerEventPolicy<SEED>::algoNames
207 
208 
209  //--------------------------------------------------------------------------
210  template <typename SEED>
212  (EventData_t const& info)
213  {
214  return "Run: " + std::to_string(info.runNumber)
215  + " Subrun: " + std::to_string(info.subRunNumber)
216  + " Event: " + std::to_string(info.eventNumber)
217  ;
218  } // PerEventPolicy<SEED>::UniqueEventIDString()
219 
220 
221  template <typename SEED>
223  (EventData_t const& info)
224  {
225  return UniqueEventIDString(info)
226  + " Timestamp: " + std::to_string(info.time);
227  } // PerEventPolicy<SEED>::UniqueEventString()
228 
229 
230  template <typename SEED>
232  (SeedMasterHelper::EngineId const& id, EventData_t const& info)
233  -> seed_t
234  {
235  if (!info.isTimeValid) {
237  << "Input event has an invalid timestamp,"
238  " random seed per-event policy EventTimestamp_v1 can't be used.\n";
239  }
240  std::string s = UniqueEventString(info)
241  + " Process: " + info.processName
242  + " Module: " + id.moduleLabel;
243  if (!id.instanceName.empty())
244  s.append(" Instance: ").append(id.instanceName);
245  seed_t seed = SeedFromHash(s);
246  MF_LOG_DEBUG("PerEventPolicy") << "Seed from: '" << s << "': " << seed;
247  return seed;
248  } // PerEventPolicy<SEED>::EventTimestamp_v1()
249 
250 
251  //--------------------------------------------------------------------------
252  template <typename SEED>
254  // set the per-event algorithm
255  algo = saUndefined;
256  std::string algorithm_name
257  = pset.get<std::string>("algorithm", "default");
258 
259  if (algorithm_name == "default") algo = saDefault;
260  else {
261  for (size_t iAlgo = 0; iAlgo < (size_t) NAlgos; ++iAlgo) {
262  if (algorithm_name != algoNames[iAlgo]) continue;
263  algo = (SeedAlgo_t) iAlgo;
264  break;
265  } // for
266  }
267  if (algo == saUndefined) {
269  << "No valid event random seed algorithm specified!\n";
270  }
271 
272  // read an optional overall offset
273  offset = pset.get<SeedOffset_t>("offset", 0);
274 
275  // EventTimestamp_v1 does not require specific configuration
276 
277 
278  // set the pre-event algorithm
279  auto const& initSeedConfig
280  = pset.get<fhicl::ParameterSet>("initSeedPolicy", {});
281  if (!initSeedConfig.is_empty()) {
282  try {
283  initSeedPolicy = makeRandomSeedPolicy<seed_t>(initSeedConfig);
284  }
285  catch(cet::exception const& e) {
286  throw cet::exception{ "PerEventPolicy", "", e }
287  << "Error creating the pre-event policy of `perEvent` random policy"
288  " from configuration:\n"
289  << initSeedConfig.to_indented_string(2);
290  }
291  } // if pre-event policy
292 
293  } // PerEventPolicy<SEED>::configure()
294 
295 
296  //--------------------------------------------------------------------------
298  template <typename SEED>
299  void PerEventPolicy<SEED>::print(std::ostream& out) const {
300  base_t::print(out);
301  out
302  << "\n algorithm version: " << algoNames[algo];
303  if (offset != 0)
304  out << "\n constant offset: " << offset;
305  if (initSeedPolicy) {
306  out << "\n special policy for random seeds before the event: '"
308  << "'\n" << std::string(60, '-');
309  initSeedPolicy->print(out);
310  out << "\n" << std::string(60, '-');
311  }
312  } // PerEventPolicy<SEED>::print()
313 
314 
315  //--------------------------------------------------------------------------
316  template <typename SEED>
320 
321 
322  //--------------------------------------------------------------------------
323  template <typename SEED>
325  (SeedMasterHelper::EngineId const& id, EventData_t const& info)
326  {
328  switch (algo) {
329  case saEventTimestamp_v1:
330  seed = EventTimestamp_v1(id, info);
331  break;
332  case saUndefined:
334  << "Per-event random number seeder not configured!\n";
335  default:
337  << "Unsupported per-event random number seeder (#"
338  << ((int) algo) << ")\n";
339  } // switch
340  return seed + offset;
341  } // PerEventPolicy<SEED>::createEventSeed()
342 
343 
344  } // namespace details
345 
346 } // namespace rndm
347 
348 
349 #endif // NURANDOM_RANDOMUTILS_PROVIDERS_PEREVENTPOLICY_H
virtual void print(std::ostream &out) const override
Prints the details of the configuration of the random generator.
virtual seed_t createEventSeed(SeedMasterHelper::EngineId const &id, EventData_t const &info) override
Returns a seed proper for the specified event information.
static std::string UniqueEventIDString(EventData_t const &info)
Converts run, subrun and event numbers into a string.
SEED seed_t
type of the random seed
Definition: BasePolicies.h:45
static seed_t EventTimestamp_v1(SeedMasterHelper::EngineId const &id, EventData_t const &info)
Implementation of the EventTimestamp_v1 algorithm.
SeedOffset_t offset
offset added to all the seeds
std::string const & policyName(Policy policy)
Returns the name of the specified policy.
Definition: PolicyNames.cxx:56
Simple data structure with data needed to extract a seed from a event.
total number of seed algorithms
typename std::make_signed< seed_t >::type SeedOffset_t
type for seed offset
virtual void print(std::ostream &out) const
Prints information on the configuration of this policy.
Definition: BasePolicies.h:76
std::string processName
name of the running process
virtual void configure(fhicl::ParameterSet const &pset) override
Configure this policy.
static seed_t SeedFromHash(Hashable const &info)
Converts some information into a valid seed by means of hash values.
virtual seed_t getSeed(SeedMasterHelper::EngineId const &id)
Returns the next random number.
Definition: BasePolicies.h:64
typename base_t::seed_t seed_t
static std::vector< std::string > InitAlgoNames()
Algorithm name (manual) handling.
Interface for a policy implementation.
Definition: BasePolicies.h:43
long seed
Definition: chem4.cc:67
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
T get(std::string const &key) const
Definition: ParameterSet.h:314
static const std::vector< std::string > algoNames
Algorithm name (manual) handling.
Identifier for a engine, made of module name and optional instance name.
Definition: EngineId.h:22
SeedAlgo_t algo
the algorithm to extract the seed
Defines an interface for random seed assignment policies.
static seed_t makeValid(T value)
Renders a seed valid.
double value
Definition: spectrum.C:18
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
Helper to instantiate a random number policy class.
Implementation of the "perEvent" policy.
Class storing a seed in the valid range.
#define MF_LOG_DEBUG(id)
static constexpr seed_t InvalidSeed
An invalid seed.
Definition: BasePolicies.h:51
PolicyStruct_t< seed_t > initSeedPolicy
Policy used for initialization before the event (none by default).
PerEventPolicy(fhicl::ParameterSet const &pset)
static constexpr const char * DefaultVersion
Default algorithm version.
A data object holding enough data to define a event seed.
Float_t e
Definition: plot.C:35
virtual seed_t createSeed(SeedMasterHelper::EngineId const &id) override
Per-job seed: pre-event seeds are returned (or invalid if none).
static std::string UniqueEventString(EventData_t const &info)
Converts event ID and timestamp information into a string.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
virtual bool yieldsUniqueSeeds() const override
Returns whether the returned seed should be unique: for us it "no".
An identifier for random engines.