CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RandomNumberGeneratorService.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: RandomEngine
4 // Class : RandomNumberGeneratorService
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones, W. David Dagenhart
10 // Created: Tue Mar 7 09:43:46 EST 2006 (originally in FWCore/Services)
11 //
12 
14 
29 
30 #include "CLHEP/Random/engineIDulong.h"
31 #include "CLHEP/Random/JamesRandom.h"
32 #include "CLHEP/Random/RanecuEngine.h"
33 
34 #include <iostream>
35 #include <limits>
36 #include <sstream>
37 #include <unistd.h>
38 
39 namespace edm {
40  namespace service {
41 
42  uint32_t RandomNumberGeneratorService::maxSeedRanecu = 2147483647U;
44  uint32_t RandomNumberGeneratorService::maxSeedTRandom3 = 4294967295U;
45 
47  ActivityRegistry& activityRegistry):
48  saveFileName_(pset.getUntrackedParameter<std::string>("saveFileName")),
49  saveFileNameRecorded_(false),
50  restoreFileName_(pset.getUntrackedParameter<std::string>("restoreFileName")),
51  enableChecking_(pset.getUntrackedParameter<bool>("enableChecking")),
52  firstLumi_(true),
53  childIndex_(0U),
54  eventSeedOffset_(pset.getUntrackedParameter<unsigned>("eventSeedOffset")),
55  failedToFindStatesInLumi_(false) {
56 
57  if(pset.exists("restoreStateTag")) {
58  restoreStateTag_ = pset.getUntrackedParameter<edm::InputTag>("restoreStateTag");
59  } else {
60  restoreStateTag_ = edm::InputTag(pset.getUntrackedParameter<std::string>("restoreStateLabel"), "", "");
61  }
63 
64  if(!restoreFileName_.empty() && !restoreStateTag_.label().empty()) {
66  << "In the configuration for the RandomNumberGeneratorService both\n"
67  << "restoreFileName and restoreStateLabel were set to nonempty values\n"
68  << "which is illegal. It is impossible to restore the random engine\n"
69  << "states two different ways in the same process.\n";
70  }
71 
72  // The saveFileName must correspond to a file name without any path specification.
73  // Throw if that is not true.
74  if(!saveFileName_.empty() && (saveFileName_.find("/") != std::string::npos)) {
76  << "The saveFileName parameter must be a simple file name with no path\n"
77  << "specification. In the configuration, it was given the value \""
78  << saveFileName_ << "\"\n";
79  }
80 
81  // Check if the configuration file is still expressed in the old style.
82  // We do this by looking for a PSet named moduleSeeds. This parameter
83  // is unique to an old style cfg file.
84  if(pset.exists("moduleSeeds")) {
85  oldStyleConfig(pset);
86  } else {
87 
88  uint32_t initialSeed;
89  VUint32 initialSeedSet;
90  std::string engineName;
91 
93  for(VString::const_iterator it = pSets.begin(), itEnd = pSets.end(); it != itEnd; ++it) {
94 
95  ParameterSet const& modulePSet = pset.getParameterSet(*it);
96  engineName = modulePSet.getUntrackedParameter<std::string>("engineName", std::string("HepJamesRandom"));
97 
98  bool initialSeedExists = modulePSet.exists("initialSeed");
99  bool initialSeedSetExists = modulePSet.exists("initialSeedSet");
100 
101  if(initialSeedExists && initialSeedSetExists) {
103  << "For the module with the label \"" << *it << "\",\n"
104  << "both the parameters \"initialSeed\" and \"initialSeedSet\"\n"
105  << "have been set in the configuration. You must set one or\n"
106  << "the other. It is illegal to set both.\n";
107  } else if(!initialSeedExists && !initialSeedSetExists) {
109  << "For the module with the label \"" << *it << "\",\n"
110  << "neither the parameter \"initialSeed\" nor \"initialSeedSet\"\n"
111  << "has been set in the configuration. You must set one or\n"
112  << "the other.\n";
113  } else if(initialSeedExists) {
114  initialSeed = modulePSet.getUntrackedParameter<uint32_t>("initialSeed");
115  initialSeedSet.clear();
116  initialSeedSet.push_back(initialSeed);
117  } else if(initialSeedSetExists) {
118  initialSeedSet = modulePSet.getUntrackedParameter<VUint32>("initialSeedSet");
119  }
120  seedMap_[*it] = initialSeedSet;
121  engineNameMap_[*it] = engineName;
122 
123  // For the CLHEP::RanecuEngine case, require a seed set containing exactly two seeds.
124 
125  if(engineName == std::string("RanecuEngine")) {
126  if(initialSeedSet.size() != 2U) {
128  << "Random engines of type \"RanecuEngine\" require 2 seeds\n"
129  << "be specified with the parameter named \"initialSeedSet\".\n"
130  << "Either \"initialSeedSet\" was not in the configuration\n"
131  << "or its size was not 2 for the module with label \"" << *it << "\".\n" ;
132  }
133  boost::shared_ptr<CLHEP::HepRandomEngine> engine(new CLHEP::RanecuEngine());
134  engineMap_[*it] = engine;
135 
136  if(initialSeedSet[0] > maxSeedRanecu ||
137  initialSeedSet[1] > maxSeedRanecu) { // They need to fit in a 31 bit integer
139  << "The RanecuEngine seeds should be in the range 0 to 2147483647.\n"
140  << "The seeds passed to the RandomNumberGenerationService from the\n"
141  "configuration file were " << initialSeedSet[0] << " and " << initialSeedSet[1]
142  << "\nThis was for the module with label \"" << *it << "\".\n";
143  }
144  long int seedL[2];
145  seedL[0] = static_cast<long int>(initialSeedSet[0]);
146  seedL[1] = static_cast<long int>(initialSeedSet[1]);
147  engine->setSeeds(seedL, 0);
148  }
149  // For the other engines, one seed is required
150  else {
151  if(initialSeedSet.size() != 1U) {
153  << "Random engines of type \"HepJamesRandom\" and \"TRandom3\n"
154  << "require exactly 1 seed be specified in the configuration.\n"
155  << "There were " << initialSeedSet.size() << " seeds set for the\n"
156  << "module with label \"" << *it << "\".\n" ;
157  }
158  long int seedL = static_cast<long int>(initialSeedSet[0]);
159 
160  if(engineName == "HepJamesRandom") {
161  if(initialSeedSet[0] > maxSeedHepJames) {
163  << "The CLHEP::HepJamesRandom engine seed should be in the range 0 to 900000000.\n"
164  << "The seed passed to the RandomNumberGenerationService from the\n"
165  "configuration file was " << initialSeedSet[0] << ". This was for \n"
166  << "the module with label " << *it << ".\n";
167  }
168  boost::shared_ptr<CLHEP::HepRandomEngine> engine(new CLHEP::HepJamesRandom(seedL));
169  engineMap_[*it] = engine;
170  } else if(engineName == "TRandom3") {
171 
172  // There is a dangerous conversion from uint32_t to long
173  // that occurs above. In the next 2 lines we check the
174  // behavior is what we need for the service to work
175  // properly. This conversion is forced on us by the
176  // CLHEP and ROOT interfaces. If the assert ever starts
177  // to fail we will have to come up with a way to deal
178  // with this.
179  uint32_t seedu32 = static_cast<uint32_t>(seedL);
180  assert(initialSeedSet[0] == seedu32);
181 
182  boost::shared_ptr<CLHEP::HepRandomEngine> engine(new TRandomAdaptor(seedL));
183  engineMap_[*it] = engine;
184  } else {
186  << "The random engine name, \"" << engineName
187  << "\", does not correspond to a supported engine.\n"
188  << "This engine was configured for the module with label \"" << *it << "\"";
189  }
190  }
191  }
192  }
193 
195 
198 
201 
204 
207 
210 
213 
216 
219 
221 
222  // the default for the stack is to point to the 'end' of our map which is used to define not set
223  engineStack_.push_back(engineMap_.end());
224  currentEngine_ = engineMap_.end();
225 
226  labelStack_.push_back(std::string());
227  currentLabel_ = std::string();
228  }
229 
231  }
232 
233  CLHEP::HepRandomEngine&
235 
236  if(currentEngine_ == engineMap_.end()) {
237  if(currentLabel_ != std::string()) {
239  << "The module with label \""
240  << currentLabel_
241  << "\" requested a random number engine from the \n"
242  "RandomNumberGeneratorService, but that module was not configured\n"
243  "for random numbers. An engine is created only if a seed(s) is provided\n"
244  "in the configuration file. Please add the following PSet to the\n"
245  "configuration file for the RandomNumberGeneratorService:\n\n"
246  " " << currentLabel_ << " = cms.PSet(\n"
247  " initialSeed = cms.untracked.uint32(your_seed),\n"
248  " engineName = cms.untracked.string('TRandom3')\n"
249  " )\n"
250  "where you replace \"your_seed\" with a number and add a comma if necessary\n"
251  "The \"engineName\" parameter is optional. If absent the default is \"HepJamesRandom\".\n";
252  } else {
254  << "Requested a random number engine from the RandomNumberGeneratorService\n"
255  "when no module was active. This is not supposed to be possible.\n"
256  "Please inform the edm developers about this. It would be helpful to\n"
257  "know the stack. If a source was requesting a random engine this could\n"
258  "happen. Sources are not supposed to be doing that anymore.\n";
259  }
260  }
261  return *(currentEngine_->second);
262  }
263 
264  uint32_t
266 
267  std::map<std::string, VUint32>::const_iterator iter;
268  iter = seedMap_.find(currentLabel_);
269 
270  if(iter == seedMap_.end()) {
271  if(currentLabel_ != std::string()) {
273  << "The module with label \""
274  << currentLabel_
275  << "\" requested a random number seed from the \n"
276  "RandomNumberGeneratorService, but that module was not configured\n"
277  "for random numbers. An engine is created only if a seed(s) is provided\n"
278  "in the configuration file. Please add the following PSet to the\n"
279  "configuration file for the RandomNumberGeneratorService:\n\n"
280  " " << currentLabel_ << " = cms.PSet(\n"
281  " initialSeed = cms.untracked.uint32(your_seed),\n"
282  " engineName = cms.untracked.string('TRandom3')\n"
283  " )\n"
284  "where you replace \"your_seed\" with a number and add a comma if necessary\n"
285  "The \"engineName\" parameter is optional. If absent the default is \"HepJamesRandom\".\n";
286  } else {
288  << "Requested a random number seed from the RandomNumberGeneratorService\n"
289  "when no module was active. This is not supposed to be possible.\n"
290  "Please inform the edm developers about this. It would be helpful to\n"
291  "know the stack. If a source was requesting a random engine this could\n"
292  "happen. Sources are not supposed to be doing that anymore.\n";
293  }
294  }
295  return iter->second[0];
296  }
297 
298  void
301 
302  std::string emptyString;
303  edm::InputTag emptyInputTag("", "", "");
304 
305  desc.addNode( edm::ParameterDescription<edm::InputTag>("restoreStateTag", emptyInputTag, false) xor
306  edm::ParameterDescription<std::string>("restoreStateLabel", emptyString, false) );
307 
308  desc.addUntracked<std::string>("saveFileName", emptyString);
309  desc.addUntracked<std::string>("restoreFileName", emptyString);
310  desc.addUntracked<bool>("enableChecking", false);
311  desc.addUntracked<unsigned>("eventSeedOffset", 0U);
312 
314  // When the migration away from the deprecated interface is complete it would be better
315  // to change the next line to a declaration of a single parameter named initialSeed instead
316  // of being a wildcard. Also the next two lines might also be combined with an "exclusive or"
317  // operator.
318  val.addWildcardUntracked<uint32_t>("*")->setComment("In the new interface, this wildcard will "
319  "match either nothing or one parameter named initialSeed. Either initialSeed will exist or "
320  "initialSeedSet will exist but not both. In the old deprecated interface, this will match "
321  "parameters with the names being the module labels and the values being the seeds");
322  val.addOptionalUntracked<std::vector<uint32_t> >("initialSeedSet")->setComment("New interface only");
323  val.addOptionalUntracked<std::string>("engineName",std::string("HepJamesRandom"))->setComment("New interface only");
324 
326  wnode.setComment("In the new interface, the name of each ParameterSet will be the associated module label. "
327  "In the old deprecated interface there will be one ParameterSet named moduleSeeds");
328  desc.addNode(wnode);
329 
330  // This only exists for backward compatibility reasons
331  // This should be removed if all the configurations are
332  // ever upgraded properly.
333  desc.addOptionalUntracked<uint32_t>("sourceSeed")->
334  setComment("This parameter is deprecated, has no effect and will likely be completely removed someday");
335 
336  descriptions.add("RandomNumberGeneratorService", desc);
337  }
338 
339  void
340  RandomNumberGeneratorService::postForkReacquireResources(unsigned childIndex, unsigned /*kMaxChildren*/) {
341  childIndex_ = childIndex;
342 
343  if(!saveFileName_.empty()) {
344  std::ostringstream suffix;
345  suffix << "_" << childIndex;
346  saveFileName_ += suffix.str();
347  }
348  }
349 
350  // The next three functions contain the complex logic
351  // such that things occur in the proper sequence to be
352  // able to save and restore the states.
353 
354  void
356 
357  if(firstLumi_) {
358  // copy state from engines to lumi cache
360 
361  if(!restoreFileName_.empty()) {
362  // copy state from text file to lumi cache
364  }
365  } else {
367  }
368 
369  // copy state from LuminosityBlock to lumi cache
370  if(!restoreStateTag_.label().empty()) {
372  }
373 
374  if(!firstLumi_ || !restoreFileName_.empty() || !restoreStateTag_.label().empty()) {
375  // copy state from lumi cache to engines
377  }
378  }
379 
380  // During the beginLumi processing the producer will copy the
381  // the lumi cache to a product if the producer was scheduled
382  // in a path in the configuration
383 
384  void
386 
387  if(firstLumi_) {
388  // reset state with new seeds based on child index
390  if(!restoreFileName_.empty()) {
392  // copy state from text file to event cache
394  }
395  }
396  if(!firstLumi_ || !restoreFileName_.empty()) {
397  // copy state from event cache to engines
399  }
400  firstLumi_ = false;
401  }
402 
403  void
405  // copy from Event to event cache
406  if(!restoreStateTag_.label().empty()) {
408  readFromEvent(event);
409 
410  // copy from event cache to engines
412  } else {
413  // copy from engines to event cache
415  }
416  // if requested write text file from both caches
417  if(!saveFileName_.empty()) {
419  if(!saveFileNameRecorded_) {
420  std::string fullName = constructSaveFileName();
421  Service<JobReport> reportSvc;
422  reportSvc->reportRandomStateFile(fullName);
423  saveFileNameRecorded_ = true;
424  }
425  }
426  }
427 
428  // During the event processing the producer will copy the
429  // the event cache to a product if the producer was scheduled
430  // in a path in the configuration
431 
432  void
434  push(description.moduleLabel());
435  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
436  engineStateStack_.push_back(currentEngine_->second->put());
437  }
438  }
439 
440  void
442  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
443  if(engineStateStack_.back() != currentEngine_->second->put()) {
445  << "It is illegal to generate random numbers during module construction because \n"
446  "that makes it very difficult to reproduce the processing of individual\n"
447  "events. Random numbers were generated during module construction for the module with\n"
448  "class name \"" << description.moduleName() << "\"\n"
449  "and module label \"" << description.moduleLabel() << "\"\n";
450  }
451  engineStateStack_.pop_back();
452  }
453  pop();
454  }
455 
456  void
458  push(description.moduleLabel());
459  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
460  engineStateStack_.push_back(currentEngine_->second->put());
461  }
462  }
463 
464  void
466  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
467  if(engineStateStack_.back() != currentEngine_->second->put()) {
469  << "It is illegal to generate random numbers during beginJob because \n"
470  "that makes it very difficult to reproduce the processing of individual\n"
471  "events. Random numbers were generated during beginJob for the module with\n"
472  "class name \"" << description.moduleName() << "\"\n"
473  "and module label \"" << description.moduleLabel() << "\"\n";
474  }
475  engineStateStack_.pop_back();
476  }
477  pop();
478  }
479 
480  void
482  push(description.moduleLabel());
483  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
484  engineStateStack_.push_back(currentEngine_->second->put());
485  }
486  }
487 
488  void
490  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
491  if(engineStateStack_.back() != currentEngine_->second->put()) {
493  << "It is illegal to generate random numbers during beginRun because \n"
494  "that makes it very difficult to reproduce the processing of individual\n"
495  "events. Random numbers were generated during beginRun for the module with\n"
496  "class name \"" << description.moduleName() << "\"\n"
497  "and module label \"" << description.moduleLabel() << "\"\n";
498  }
499  engineStateStack_.pop_back();
500  }
501  pop();
502  }
503 
504  void
506  push(description.moduleLabel());
507  }
508 
509  void
511  pop();
512  }
513 
514  void
516  push(description.moduleLabel());
517  }
518 
519  void
521  pop();
522  }
523 
524  void
526  push(description.moduleLabel());
527  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
528  engineStateStack_.push_back(currentEngine_->second->put());
529  }
530  }
531 
532  void
534  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
535  if(engineStateStack_.back() != currentEngine_->second->put()) {
537  << "It is illegal to generate random numbers during endLumi because \n"
538  "that makes it very difficult to reproduce the processing of individual\n"
539  "events. Random numbers were generated during endLumi for the module with\n"
540  "class name \"" << description.moduleName() << "\"\n"
541  "and module label \"" << description.moduleLabel() << "\"\n";
542  }
543  engineStateStack_.pop_back();
544  }
545  pop();
546  }
547 
548  void
550  push(description.moduleLabel());
551  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
552  engineStateStack_.push_back(currentEngine_->second->put());
553  }
554  }
555 
556  void
558  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
559  if(engineStateStack_.back() != currentEngine_->second->put()) {
561  << "It is illegal to generate random numbers during endRun because \n"
562  "that makes it very difficult to reproduce the processing of individual\n"
563  "events. Random numbers were generated during endRun for the module with\n"
564  "class name \"" << description.moduleName() << "\"\n"
565  "and module label \"" << description.moduleLabel() << "\"\n";
566  }
567  engineStateStack_.pop_back();
568  }
569  pop();
570  }
571 
572  void
574  push(description.moduleLabel());
575  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
576  engineStateStack_.push_back(currentEngine_->second->put());
577  }
578  }
579 
580  void
582  if(enableChecking_ && currentEngine_ != engineMap_.end()) {
583  if(engineStateStack_.back() != currentEngine_->second->put()) {
585  << "It is illegal to generate random numbers during endJob because \n"
586  "that makes it very difficult to reproduce the processing of individual\n"
587  "events. Random numbers were generated during endJob for the module with\n"
588  "class name \"" << description.moduleName() << "\"\n"
589  "and module label \"" << description.moduleLabel() << "\"\n";
590  }
591  engineStateStack_.pop_back();
592  }
593  pop();
594  }
595 
596  std::vector<RandomEngineState> const&
598  return lumiCache_;
599  }
600 
601  std::vector<RandomEngineState> const&
603  return eventCache_;
604  }
605 
606  void
608  std::cout << "\n\nRandomNumberGeneratorService dump\n\n";
609 
610  std::cout << " Contents of seedMap\n";
611  for(std::map<std::string, std::vector<uint32_t> >::const_iterator iter = seedMap_.begin();
612  iter != seedMap_.end();
613  ++iter) {
614  std::cout << " " << iter->first;
615  std::vector<uint32_t> seeds = iter->second;
616  for(std::vector<uint32_t>::const_iterator vIter = seeds.begin();
617  vIter != seeds.end();
618  ++vIter) {
619  std::cout << " " << *vIter;
620  }
621  std::cout << "\n";
622  }
623  std::cout << "\n Contents of engineNameMap\n";
624  for(std::map<std::string, std::string>::const_iterator iter = engineNameMap_.begin();
625  iter != engineNameMap_.end();
626  ++iter) {
627  std::cout << " " << iter->first << " " << iter->second << "\n";
628  }
629  std::cout << "\n Contents of engineMap\n";
630  for(EngineMap::const_iterator iter = engineMap_.begin();
631  iter != engineMap_.end();
632  ++iter) {
633  std::cout << " " << iter->first
634  << " " << iter->second->name() << " ";
635  if(iter->second->name() == std::string("HepJamesRandom")) {
636  std::cout << iter->second->getSeed();
637  } else {
638  std::cout << "Engine does not know original seed";
639  }
640  std::cout << "\n";
641  }
642  std::cout << "\n";
643  std::cout << " currentLabel_ = " << currentLabel_ << "\n";
644  std::cout << " labelStack_ size = " << labelStack_.size() << "\n";
645  int i = 0;
646  for(VString::const_iterator iter = labelStack_.begin();
647  iter != labelStack_.end();
648  ++iter, ++i) {
649  std::cout << " " << i << " " << *iter << "\n";
650  }
651  if(currentEngine_ == engineMap_.end()) {
652  std::cout << " currentEngine points to end\n";
653  } else {
654  std::cout << " currentEngine_ = " << currentEngine_->first
655  << " " << currentEngine_->second->name()
656  << " " << currentEngine_->second->getSeed() << "\n";
657  }
658 
659  std::cout << " engineStack_ size = " << engineStack_.size() << "\n";
660  i = 0;
661  for(std::vector<EngineMap::const_iterator>::const_iterator iter = engineStack_.begin();
662  iter != engineStack_.end();
663  ++iter, ++i) {
664  if(*iter == engineMap_.end()) {
665  std::cout << " " << i << " Points to end of engine map\n";
666  } else {
667  std::cout << " " << i << " " << (*iter)->first
668  << " " << (*iter)->second->name() << " " << (*iter)->second->getSeed() << "\n";
669  }
670  }
671 
672  std::cout << " restoreStateTag_ = " << restoreStateTag_ << "\n";
673  std::cout << " saveFileName_ = " << saveFileName_ << "\n";
674  std::cout << " restoreFileName_ = " << restoreFileName_ << "\n";
675  }
676 
677  void
678  RandomNumberGeneratorService::push(std::string const& iLabel) {
679  currentEngine_ = engineMap_.find(iLabel);
680  engineStack_.push_back(currentEngine_);
681 
682  labelStack_.push_back(iLabel);
683  currentLabel_ = iLabel;
684  }
685 
686  void
688  engineStack_.pop_back();
689  //NOTE: algorithm is such that we always have at least one item in the stacks
690  currentEngine_ = engineStack_.back();
691  labelStack_.pop_back();
692  currentLabel_ = labelStack_.back();
693  }
694 
695  void
697 
700 
701  if(!states.isValid()) {
703  return;
704  }
706  states->getRandomEngineStates(lumiCache_);
707  }
708 
709  void
711 
713 
714  event.getByLabel(restoreStateTag_, states);
715 
716  if(!states.isValid()) {
718  return;
719  } else {
721  << "The RandomNumberGeneratorService is trying to restore\n"
722  << "the state of the random engines by reading a product from\n"
723  << "the Event with input tag \"" << restoreStateTag_ << "\". It\n"
724  << "fails to find one. The label used in the request for the product\n"
725  << "is set in the configuration. It is probably set to the wrong value\n"
726  << "in the configuration file. It must match the module label\n"
727  << "of the RandomEngineStateProducer that created the product in\n"
728  << "a previous process\n";
729  }
730  }
733  << "The RandomNumberGeneratorService is trying to restore\n"
734  << "the state of the random engines by reading a product from\n"
735  << "the Event and LuminosityBlock with input tag \"" << restoreStateTag_ << "\".\n"
736  << "It found the product in the Event but not the one in the LuminosityBlock.\n"
737  << "Either the product in the LuminosityBlock was dropped or\n"
738  << "there is a bug somewhere\n";
739  }
740  states->getRandomEngineStates(eventCache_);
741  }
742 
743  bool
745 
747 
748  event.getByLabel(restoreStateTag_, states);
749  if(!states.isValid()) {
750  return false;
751  }
752  for(std::vector<RandomEngineState>::const_iterator state = states->begin(),
753  iEnd = states->end();
754  state != iEnd; ++state) {
755 
756  std::vector<RandomEngineState>::iterator cachedState =
757  std::lower_bound(eventCache_.begin(), eventCache_.end(), *state);
758 
759 
760  if(cachedState != eventCache_.end() && cachedState->getLabel() == state->getLabel()) {
761  if(cachedState->getSeed().size() != state->getSeed().size() ||
762  cachedState->getState().size() != state->getState().size()) {
764  << "In function RandomNumberGeneratorService::backwardCompatibilityRead.\n"
765  << "When attempting to replay processing with the RandomNumberGeneratorService,\n"
766  << "the engine type for each module must be the same in the replay configuration\n"
767  << "and the original configuration. If this is not the problem, then the data\n"
768  << "is somehow corrupted or there is a bug because the vector in the data containing\n"
769  << "the seeds or engine state is the incorrect size for the type of random engine.\n";
770  }
771  cachedState->setSeed(state->getSeed());
772  cachedState->setState(state->getState());
773  }
774  }
775  return true;
776  }
777 
778  void
779  RandomNumberGeneratorService::snapShot(std::vector<RandomEngineState>& cache) {
780  cache.resize(engineMap_.size());
781  std::vector<RandomEngineState>::iterator state = cache.begin();
782 
783  for(EngineMap::const_iterator iter = engineMap_.begin();
784  iter != engineMap_.end();
785  ++iter, ++state) {
786 
787  state->setLabel(iter->first);
788  state->setSeed(seedMap_[iter->first]);
789 
790  std::vector<unsigned long> stateL = iter->second->put();
791  state->clearStateVector();
792  state->reserveStateVector(stateL.size());
793  for(std::vector<unsigned long>::const_iterator vIter = stateL.begin();
794  vIter != stateL.end();
795  ++vIter) {
796  state->push_back_stateVector(static_cast<uint32_t>(*vIter));
797  }
798  }
799  }
800 
801  void
802  RandomNumberGeneratorService::restoreFromCache(std::vector<RandomEngineState> const& cache) {
803  for(std::vector<RandomEngineState>::const_iterator iter = cache.begin(),
804  iEnd = cache.end();
805  iter != iEnd; ++iter) {
806 
807  std::string const& engineLabel = iter->getLabel();
808 
809  std::vector<uint32_t> const& engineState = iter->getState();
810  std::vector<unsigned long> engineStateL;
811  for(std::vector<uint32_t>::const_iterator iVal = engineState.begin(),
812  theEnd = engineState.end();
813  iVal != theEnd; ++iVal) {
814  engineStateL.push_back(static_cast<unsigned long>(*iVal));
815  }
816 
817  std::vector<uint32_t> const& engineSeeds = iter->getSeed();
818  std::vector<long> engineSeedsL;
819  for(std::vector<uint32_t>::const_iterator iVal = engineSeeds.begin(),
820  theEnd = engineSeeds.end();
821  iVal != theEnd;
822  ++iVal) {
823  long seedL = static_cast<long>(*iVal);
824  engineSeedsL.push_back(seedL);
825 
826  // There is a dangerous conversion from uint32_t to long
827  // that occurs above. In the next 2 lines we check the
828  // behavior is what we need for the service to work
829  // properly. This conversion is forced on us by the
830  // CLHEP and ROOT interfaces. If the assert ever starts
831  // to fail we will have to come up with a way to deal
832  // with this.
833  uint32_t seedu32 = static_cast<uint32_t>(seedL);
834  assert(*iVal == seedu32);
835  }
836 
837  EngineMap::iterator engine = engineMap_.find(engineLabel);
838 
839  if(engine != engineMap_.end()) {
840 
841  seedMap_[engineLabel] = engineSeeds;
842 
843  // We need to handle each type of engine differently because each
844  // has different requirements on the seed or seeds.
845  if(engineStateL[0] == CLHEP::engineIDulong<CLHEP::HepJamesRandom>()) {
846 
847  checkEngineType(engine->second->name(), std::string("HepJamesRandom"), engineLabel);
848 
849  // These two lines actually restore the seed and engine state.
850  engine->second->setSeed(engineSeedsL[0], 0);
851  engine->second->get(engineStateL);
852  } else if(engineStateL[0] == CLHEP::engineIDulong<CLHEP::RanecuEngine>()) {
853 
854  checkEngineType(engine->second->name(), std::string("RanecuEngine"), engineLabel);
855 
856  // This line actually restores the engine state.
857  engine->second->get(engineStateL);
858  } else if(engineStateL[0] == CLHEP::engineIDulong<TRandomAdaptor>()) {
859 
860  checkEngineType(engine->second->name(), std::string("TRandom3"), engineLabel);
861 
862  // This line actually restores the engine state.
863  engine->second->setSeed(engineSeedsL[0], 0);
864  engine->second->get(engineStateL);
865  } else {
866  // This should not be possible because this code should be able to restore
867  // any kind of engine whose state can be saved.
869  << "The RandomNumberGeneratorService is trying to restore the state\n"
870  "of the random engines. The state in the event indicates an engine\n"
871  "of an unknown type. This should not be possible unless you are\n"
872  "running with an old code release on a new file that was created\n"
873  "with a newer release which had new engine types added. In this case\n"
874  "the only solution is to use a newer release. In any other case, notify\n"
875  "the EDM developers because this should not be possible\n";
876  }
877  }
878  }
879  }
880 
881  void
882  RandomNumberGeneratorService::checkEngineType(std::string const& typeFromConfig,
883  std::string const& typeFromEvent,
884  std::string const& engineLabel) {
885  if(typeFromConfig != typeFromEvent) {
887  << "The RandomNumberGeneratorService is trying to restore\n"
888  << "the state of the random engine for the module \""
889  << engineLabel << "\". An\n"
890  << "error was detected because the type of the engine in the\n"
891  << "input file and the configuration file do not match.\n"
892  << "In the configuration file the type is \"" << typeFromConfig
893  << "\".\nIn the input file the type is \"" << typeFromEvent << "\". If\n"
894  << "you are not generating any random numbers in this module, then\n"
895  << "remove the line in the configuration file that gives it\n"
896  << "a seed and the error will go away. Otherwise, you must give\n"
897  << "this module the same engine type in the configuration file or\n"
898  << "stop trying to restore the random engine state.\n";
899  }
900  }
901 
902  void
904  if(!outFile_.is_open()) {
905  outFile_.open(fileName.c_str(), std::ofstream::out | std::ofstream::trunc);
906  }
907  if(!outFile_) {
909  << "Unable to open the file \""
910  << fileName << "\" to save the state of the random engines.\n";
911  }
912  outFile_.seekp(0, std::ios_base::beg);
913  outFile_ << "<RandomEngineStates>\n";
914 
915  outFile_ << "<Event>\n";
917  outFile_ << "</Event>\n" ;
918 
919  outFile_ << "<Lumi>\n";
921  outFile_ << "</Lumi>\n" ;
922 
923  outFile_ << "</RandomEngineStates>\n" ;
924  outFile_.flush();
925  }
926 
927  void
928  RandomNumberGeneratorService::writeStates(std::vector<RandomEngineState> const& v,
929  std::ofstream& outFile) {
930  for(std::vector<RandomEngineState>::const_iterator iter = v.begin(),
931  iEnd = v.end();
932  iter != iEnd; ++iter) {
933 
934  std::vector<uint32_t> const& seedVector = iter->getSeed();
935  std::vector<uint32_t>::size_type seedVectorLength = seedVector.size();
936 
937  std::vector<uint32_t> const& stateVector = iter->getState();
938  std::vector<uint32_t>::size_type stateVectorLength = stateVector.size();
939 
940  outFile << "<ModuleLabel>\n" << iter->getLabel() << "\n</ModuleLabel>\n";
941 
942  outFile << "<SeedLength>\n" << seedVectorLength << "\n</SeedLength>\n" ;
943  outFile << "<InitialSeeds>\n";
944  writeVector(seedVector, outFile);
945  outFile << "</InitialSeeds>\n";
946  outFile << "<FullStateLength>\n" << stateVectorLength << "\n</FullStateLength>\n";
947  outFile << "<FullState>\n";
948  writeVector(stateVector, outFile);
949  outFile << "</FullState>\n";
950  }
951  }
952 
953  void
955  std::ofstream& outFile) {
956  if(v.empty()) return;
957  size_t numItems = v.size();
958  for(size_t i = 0; i < numItems; ++i) {
959  if(i != 0 && i % 10 == 0) outFile << "\n";
960  outFile << std::setw(13) << v[i];
961  }
962  outFile << "\n";
963  }
964 
966  char directory[1500];
967  std::string fullName(getcwd(directory, sizeof(directory)) ? directory : "/PathIsTooBig");
968  fullName += "/" + saveFileName_;
969  return fullName;
970  }
971 
972  void
974  std::string whichStates("<Event>");
975  readStatesFromFile(fileName, eventCache_, whichStates);
976  }
977 
978  void
980  std::string whichStates("<Lumi>");
981  readStatesFromFile(fileName, lumiCache_, whichStates);
982  }
983 
984 
985  void
987  std::vector<RandomEngineState>& cache,
988  std::string const& whichStates) {
989  std::ifstream inFile;
990  inFile.open(fileName.c_str(), std::ifstream::in);
991  if(!inFile) {
993  << "Unable to open the file \""
994  << fileName << "\" to restore the random engine states.\n";
995  }
996 
997  std::string text;
998  inFile >> text;
999  if(!inFile.good() || text != std::string("<RandomEngineStates>")) {
1001  << "Attempting to read file with random number engine states.\n"
1002  << "File \"" << restoreFileName_
1003  << "\" is ill-structured or otherwise corrupted.\n"
1004  << "Cannot read the file header word.\n";
1005  }
1006  bool saveToCache = false;
1007  while(readEngineState(inFile, cache, whichStates, saveToCache)) {}
1008  }
1009 
1011  std::vector<RandomEngineState>& cache,
1012  std::string const& whichStates,
1013  bool& saveToCache) {
1014  std::string leading;
1015  std::string trailing;
1016  std::string moduleLabel;
1017  std::vector<uint32_t>::size_type seedVectorSize;
1018  std::vector<uint32_t> seedVector;
1019  std::vector<uint32_t>::size_type stateVectorSize;
1020  std::vector<uint32_t> stateVector;
1021 
1022  // First we need to look for the special strings
1023  // that mark the end of the file and beginning and
1024  // and end of the data for different sections.
1025 
1026  is >> leading;
1027  if(!is.good()) {
1029  << "File \"" << restoreFileName_
1030  << "\" is ill-structured or otherwise corrupted.\n"
1031  << "Cannot read next field and did not hit the end yet.\n";
1032  }
1033 
1034  // This marks the end of the file. We are done.
1035  if(leading == std::string("</RandomEngineStates>")) return false;
1036 
1037  // This marks the end of a section of the data
1038  if(leading == std::string("</Event>") ||
1039  leading == std::string("</Lumi>")) {
1040  saveToCache = false;
1041  return true;
1042  }
1043 
1044  // This marks the beginning of a section
1045  if(leading == std::string("<Event>") ||
1046  leading == std::string("<Lumi>")) {
1047  saveToCache = (leading == whichStates);
1048  return true;
1049  }
1050 
1051  // Process the next engine state
1052 
1053  is >> moduleLabel >> trailing;
1054  if(!is.good() ||
1055  leading != std::string("<ModuleLabel>") ||
1056  trailing != std::string("</ModuleLabel>")) {
1058  << "File \"" << restoreFileName_
1059  << "\" is ill-structured or otherwise corrupted.\n"
1060  << "Cannot read a module label when restoring random engine states.\n";
1061  }
1062 
1063  is >> leading >> seedVectorSize >> trailing;
1064  if(!is.good() ||
1065  leading != std::string("<SeedLength>") ||
1066  trailing != std::string("</SeedLength>")) {
1068  << "File \"" << restoreFileName_
1069  << "\" is ill-structured or otherwise corrupted.\n"
1070  << "Cannot read seed vector length when restoring random engine states.\n";
1071  }
1072 
1073  is >> leading;
1074  if(!is.good() ||
1075  leading != std::string("<InitialSeeds>")) {
1077  << "File \"" << restoreFileName_
1078  << "\" is ill-structured or otherwise corrupted.\n"
1079  << "Cannot read beginning of InitialSeeds when restoring random engine states.\n";
1080  }
1081 
1082  if(seedVectorSize > maxSeeds) {
1084  << "File \"" << restoreFileName_
1085  << "\" is ill-structured or otherwise corrupted.\n"
1086  << "The number of seeds exceeds 64K.\n";
1087  }
1088 
1089  readVector(is, seedVectorSize, seedVector);
1090 
1091  is >> trailing;
1092  if(!is.good() ||
1093  trailing != std::string("</InitialSeeds>")) {
1095  << "File \"" << restoreFileName_
1096  << "\" is ill-structured or otherwise corrupted.\n"
1097  << "Cannot read end of InitialSeeds when restoring random engine states.\n";
1098  }
1099 
1100  is >> leading >> stateVectorSize >> trailing;
1101  if(!is.good() ||
1102  leading != std::string("<FullStateLength>") ||
1103  trailing != std::string("</FullStateLength>")) {
1105  << "File \"" << restoreFileName_
1106  << "\" is ill-structured or otherwise corrupted.\n"
1107  << "Cannot read state vector length when restoring random engine states.\n";
1108  }
1109 
1110  is >> leading;
1111  if(!is.good() ||
1112  leading != std::string("<FullState>")) {
1114  << "File \"" << restoreFileName_
1115  << "\" is ill-structured or otherwise corrupted.\n"
1116  << "Cannot read beginning of FullState when restoring random engine states.\n";
1117  }
1118 
1119  if(stateVectorSize > maxStates) {
1121  << "File \"" << restoreFileName_
1122  << "\" is ill-structured or otherwise corrupted.\n"
1123  << "The number of states exceeds 64K.\n";
1124  }
1125 
1126  readVector(is, stateVectorSize, stateVector);
1127 
1128  is >> trailing;
1129  if(!is.good() ||
1130  trailing != std::string("</FullState>")) {
1132  << "File \"" << restoreFileName_
1133  << "\" is ill-structured or otherwise corrupted.\n"
1134  << "Cannot read end of FullState when restoring random engine states.\n";
1135  }
1136 
1137  if(saveToCache) {
1138  RandomEngineState randomEngineState;
1139  randomEngineState.setLabel(moduleLabel);
1140  std::vector<RandomEngineState>::iterator state =
1141  std::lower_bound(cache.begin(), cache.end(), randomEngineState);
1142 
1143  if(state != cache.end() && moduleLabel == state->getLabel()) {
1144  if(seedVector.size() != state->getSeed().size() ||
1145  stateVector.size() != state->getState().size()) {
1147  << "File \"" << restoreFileName_
1148  << "\" is ill-structured or otherwise corrupted.\n"
1149  << "Vectors containing engine state are the incorrect size for the type of random engine.\n";
1150  }
1151  state->setSeed(seedVector);
1152  state->setState(stateVector);
1153  }
1154  }
1155  return true;
1156  }
1157 
1158  void
1159  RandomNumberGeneratorService::readVector(std::istream& is, unsigned numItems, std::vector<uint32_t>& v) {
1160  v.clear();
1161  v.reserve(numItems);
1162  uint32_t data;
1163  for(unsigned i = 0; i < numItems; ++i) {
1164  is >> data;
1165  if(!is.good()) {
1167  << "File \"" << restoreFileName_
1168  << "\" is ill-structured or otherwise corrupted.\n"
1169  << "Cannot read vector when restoring random engine states.\n";
1170  }
1171  v.push_back(data);
1172  }
1173  }
1174 
1175  void
1177 
1178  if(childIndex_ == 0U && eventSeedOffset_ == 0U) return;
1179 
1180  for(EngineMap::const_iterator iter = engineMap_.begin();
1181  iter != engineMap_.end();
1182  ++iter) {
1183 
1184  uint32_t offset1 = childIndex_;
1185  uint32_t offset2 = eventSeedOffset_;
1186 
1187  std::string const& moduleLabel = iter->first;
1188  std::string const& engineName = engineNameMap_[moduleLabel];
1189  VUint32& seeds = seedMap_[moduleLabel];
1190 
1191  if(engineName == std::string("RanecuEngine")) {
1192  assert(seeds.size() == 2U);
1193  // Wrap around if the offsets push the seed over the maximum allowed value
1194  uint32_t mod = maxSeedRanecu + 1U;
1195  offset1 = offset1 % mod;
1196  offset2 = offset2 % mod;
1197  seeds[0] = (seeds[0] + offset1) % mod;
1198  seeds[0] = (seeds[0] + offset2) % mod;
1199  long int seedL[2];
1200  seedL[0] = static_cast<long int>(seeds[0]);
1201  seedL[1] = static_cast<long int>(seeds[1]);
1202  iter->second->setSeeds(seedL,0);
1203  } else {
1204  assert(seeds.size() == 1U);
1205 
1206  if(engineName == "HepJamesRandom") {
1207  // Wrap around if the offsets push the seed over the maximum allowed value
1208  uint32_t mod = maxSeedHepJames + 1U;
1209  offset1 = offset1 % mod;
1210  offset2 = offset2 % mod;
1211  seeds[0] = (seeds[0] + offset1) % mod;
1212  seeds[0] = (seeds[0] + offset2) % mod;
1213 
1214  long int seedL = static_cast<long int>(seeds[0]);
1215  iter->second->setSeed(seedL, 0);
1216  } else {
1217  assert(engineName == "TRandom3");
1218  // Wrap around if the offsets push the seed over the maximum allowed value
1219  // We have to be extra careful with this one because it may also go beyond
1220  // the values 32 bits can hold
1221  uint32_t max32 = maxSeedTRandom3;
1222  if((max32 - seeds[0]) >= offset1) {
1223  seeds[0] = seeds[0] + offset1;
1224  } else {
1225  seeds[0] = offset1 - (max32 - seeds[0]) - 1U;
1226  }
1227  if((max32 - seeds[0]) >= offset2) {
1228  seeds[0] = seeds[0] + offset2;
1229  } else {
1230  seeds[0] = offset2 - (max32 - seeds[0]) - 1U;
1231  }
1232  long seedL = static_cast<long>(seeds[0]);
1233 
1234  // There is a dangerous conversion from uint32_t to long
1235  // that occurs above. In the next 2 lines we check the
1236  // behavior is what we need for the service to work
1237  // properly. This conversion is forced on us by the
1238  // CLHEP and ROOT interfaces. If the assert ever starts
1239  // to fail we will have to come up with a way to deal
1240  // with this.
1241  uint32_t seedu32 = static_cast<uint32_t>(seedL);
1242  assert(seeds[0] == seedu32);
1243 
1244  iter->second->setSeed(seedL, 0);
1245  }
1246  }
1247  }
1248  }
1249 
1250  void
1253  for(VString::const_iterator it = pSets.begin(), itEnd = pSets.end(); it != itEnd; ++it) {
1254  if(*it != std::string("moduleSeeds")) {
1256  << "RandomNumberGeneratorService supports two configuration interfaces.\n"
1257  << "One is old and deprecated, but still supported for backward compatibility\n"
1258  << "reasons. It is illegal to mix parameters using both the old and new service\n"
1259  << "interface in the same configuration. It is assumed the old interface is being\n"
1260  << "used if the parameter set named \"moduleSeeds\" exists. In that case it is\n"
1261  << "illegal to have any other nested ParameterSets. This exception was thrown\n"
1262  << "because that happened.\n";
1263  }
1264  }
1265 
1266  ParameterSet const& moduleSeeds = pset.getParameterSet("moduleSeeds");
1267 
1268  std::vector<uint32_t> seeds;
1269 
1270  VString names = moduleSeeds.getParameterNames();
1271  for(VString::const_iterator itName = names.begin(), itNameEnd = names.end();
1272  itName != itNameEnd; ++itName) {
1273 
1274  uint32_t seed = moduleSeeds.getUntrackedParameter<uint32_t>(*itName);
1275 
1276  seeds.clear();
1277  seeds.push_back(seed);
1278  seedMap_[*itName] = seeds;
1279  engineNameMap_[*itName] = std::string("HepJamesRandom");
1280 
1281  if(seed > maxSeedHepJames) {
1283  << "The CLHEP::HepJamesRandom engine seed should be in the range 0 to 900000000.\n"
1284  << "The seed passed to the RandomNumberGenerationService from the\n"
1285  "configuration file was " << seed << ". This was for the module\n"
1286  << "with label \"" << *itName << "\".";
1287  }
1288  long seedL = static_cast<long>(seed);
1289  engineMap_[*itName] = boost::shared_ptr<CLHEP::HepRandomEngine>(new CLHEP::HepJamesRandom(seedL));
1290  }
1291  }
1292  }
1293 }
void watchPostModuleConstruction(PostModuleConstruction::slot_type const &iSlot)
void writeStates(std::vector< RandomEngineState > const &v, std::ofstream &outFile)
void setComment(std::string const &value)
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
void restoreFromCache(std::vector< RandomEngineState > const &cache)
void watchPostModuleBeginLumi(PostModuleBeginLumi::slot_type const &iSlot)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
void postModuleEndJob(ModuleDescription const &description)
void preModuleEndLumi(ModuleDescription const &description)
void watchPreModuleConstruction(PreModuleConstruction::slot_type const &iSlot)
tuple lumi
Definition: fjr2json.py:35
void watchPostModule(PostModule::slot_type const &iSlot)
virtual void print()
For debugging purposes only.
void setLabel(const std::string &value)
std::vector< std::vector< unsigned long > > engineStateStack_
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::string const & moduleName() const
ParameterDescriptionNode * addNode(ParameterDescriptionNode const &node)
void preModuleConstruction(ModuleDescription const &description)
void postModuleEndLumi(ModuleDescription const &description)
void preModule(ModuleDescription const &description)
void postBeginLumi(LuminosityBlock const &lumi, EventSetup const &es)
void postModule(ModuleDescription const &description)
void watchPreModuleEndLumi(PreModuleEndLumi::slot_type const &iSlot)
void preModuleBeginJob(ModuleDescription const &description)
bool getByLabel(std::string const &label, Handle< PROD > &result) const
void readFromLuminosityBlock(LuminosityBlock const &lumi)
void readLumiStatesFromTextFile(std::string const &fileName)
std::map< std::string, std::string > engineNameMap_
std::string const & moduleLabel() const
void checkEngineType(std::string const &typeFromConfig, std::string const &typeFromEvent, std::string const &engineLabel)
uint16_t size_type
ParameterWildcardBase * addWildcardUntracked(U const &pattern)
void watchPreModule(PreModule::slot_type const &iSlot)
dictionary map
Definition: Association.py:196
void preModuleBeginLumi(ModuleDescription const &description)
std::vector< std::string > getParameterNamesForType(bool trackiness=true) const
Definition: ParameterSet.h:195
void postModuleBeginRun(ModuleDescription const &description)
void watchPreModuleEndRun(PreModuleEndRun::slot_type const &iSlot)
virtual CLHEP::HepRandomEngine & getEngine() const
Use this to get the random number engine, this is the only function most users should call...
RandomNumberGeneratorService(ParameterSet const &pset, ActivityRegistry &activityRegistry)
virtual std::vector< RandomEngineState > const & getEventCache() const
void postModuleEndRun(ModuleDescription const &description)
bool readEngineState(std::istream &is, std::vector< RandomEngineState > &cache, std::string const &whichStates, bool &saveToCache)
virtual uint32_t mySeed() const
Exists for backward compatibility.
void watchPostModuleEndRun(PostModuleEndRun::slot_type const &iSlot)
void readEventStatesFromTextFile(std::string const &fileName)
void watchPreModuleEndJob(PreModuleEndJob::slot_type const &iSlot)
virtual void preBeginLumi(LuminosityBlock const &lumi)
tuple text
Definition: runonSM.py:42
void readStatesFromFile(std::string const &fileName, std::vector< RandomEngineState > &cache, std::string const &whichStates)
void snapShot(std::vector< RandomEngineState > &cache)
static void fillDescriptions(ConfigurationDescriptions &descriptions)
list mod
Load physics model.
std::vector< std::string > getParameterNames() const
void watchPostBeginLumi(PostBeginLumi::slot_type const &iSlot)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool isValid() const
Definition: HandleBase.h:76
void watchPreModuleBeginJob(PreModuleBeginJob::slot_type const &iSlot)
void postModuleBeginJob(ModuleDescription const &description)
std::vector< EngineMap::const_iterator > engineStack_
void watchPostModuleBeginRun(PostModuleBeginRun::slot_type const &iSlot)
virtual std::vector< RandomEngineState > const & getLumiCache() const
tuple out
Definition: dbtoconf.py:99
void preModuleEndRun(ModuleDescription const &description)
tuple description
Definition: idDealer.py:66
string fullName
ParameterSet const & getParameterSet(std::string const &) const
void postModuleBeginLumi(ModuleDescription const &description)
void preModuleEndJob(ModuleDescription const &description)
void postForkReacquireResources(unsigned childIndex, unsigned kMaxChildren)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void readVector(std::istream &is, unsigned numItems, std::vector< uint32_t > &v)
void postModuleConstruction(ModuleDescription const &description)
char state
Definition: procUtils.cc:75
std::string const & label() const
Definition: InputTag.h:25
static std::string const emptyString("")
std::string const & process() const
Definition: InputTag.h:29
void watchPostForkReacquireResources(PostForkReacquireResources::slot_type const &iSlot)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
void writeVector(VUint32 const &v, std::ofstream &outFile)
void watchPostModuleBeginJob(PostModuleBeginJob::slot_type const &iSlot)
tuple cout
Definition: gather_cfg.py:121
ParameterDescriptionBase * addOptionalUntracked(U const &iLabel, T const &value)
void watchPreModuleBeginLumi(PreModuleBeginLumi::slot_type const &iSlot)
void preModuleBeginRun(ModuleDescription const &description)
static const HistoName names[]
void watchPostModuleEndJob(PostModuleEndJob::slot_type const &iSlot)
mathSSE::Vec4< T > v
void watchPreModuleBeginRun(PreModuleBeginRun::slot_type const &iSlot)
void watchPostModuleEndLumi(PostModuleEndLumi::slot_type const &iSlot)