00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "IOMC/RandomEngine/src/RandomNumberGeneratorService.h"
00015
00016 #include <iostream>
00017 #include <fstream>
00018 #include <limits>
00019 #include <unistd.h>
00020
00021 #include "FWCore/Framework/interface/Event.h"
00022 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00023 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00024 #include "SimDataFormats/RandomEngine/interface/RandomEngineState.h"
00025 #include "CLHEP/Random/JamesRandom.h"
00026 #include "CLHEP/Random/RanecuEngine.h"
00027 #include "CLHEP/Random/engineIDulong.h"
00028 #include "FWCore/Utilities/interface/EDMException.h"
00029
00030 #include "FWCore/ServiceRegistry/interface/Service.h"
00031 #include "FWCore/MessageLogger/interface/JobReport.h"
00032 #include "IOMC/RandomEngine/src/TRandomAdaptor.h"
00033
00034 using namespace edm::service;
00035
00036 typedef std::vector<std::string> VString;
00037 typedef std::vector<uint32_t> Vuint32;
00038 typedef edm::ParameterSet PSet;
00039
00040 static const std::string sourceLabel("@source");
00041
00042
00043 RandomNumberGeneratorService::RandomNumberGeneratorService(const ParameterSet& iPSet,
00044 ActivityRegistry& iRegistry):
00045
00046
00047
00048
00049 restoreStateLabel_(iPSet.getUntrackedParameter<std::string>("restoreStateLabel", std::string())),
00050 saveFileName_(std::string()),
00051 saveFileNameRecorded_(false),
00052 restoreFileName_(std::string()),
00053 oldStyle_(false)
00054 {
00055
00056 std::string labels;
00057 std::vector<uint32_t> seeds;
00058 PSet empty_PSet;
00059 VString empty_VString;
00060 Vuint32 empty_Vuint32;
00061
00062
00063
00064
00065 saveFileName_ = iPSet.getUntrackedParameter<std::string>("saveFileName", std::string());
00066 restoreFileName_ = iPSet.getUntrackedParameter<std::string>("restoreFileName",std::string());
00067
00068
00069
00070 if(!saveFileName_.empty() && (saveFileName_.find("/") != std::string::npos)) {
00071 std::ostringstream sstr;
00072 sstr << "Configuration: The saveFileName parameter " << saveFileName_ << "\n"
00073 << "must be a simple file name with no path specification.\n" ;
00074 edm::Exception except(edm::errors::Configuration, sstr.str());
00075 throw except;
00076 }
00077
00078
00079
00080
00081
00082 VString pSets = iPSet.getParameterNamesForType<edm::ParameterSet>();
00083 for(VString::const_iterator it = pSets.begin(), itEnd = pSets.end(); it != itEnd; ++it) {
00084 if(*it == std::string("moduleSeeds")) oldStyle_ = true;
00085 }
00086
00087
00088
00089
00090 if(iPSet.getUntrackedParameter<uint32_t>("sourceSeed",0) != 0) oldStyle_ = true;
00091
00092 if(oldStyle_) {
00093 oldStyleConfig(iPSet);
00094 } else {
00095
00096
00097
00098
00099
00100
00101
00102 bool source;
00103 std::string engineName;
00104 uint32_t initialSeed;
00105 std::vector<uint32_t> initialSeedSet;
00106
00107 std::string sourceEngine = iPSet.getUntrackedParameter<std::string>("sourceEngine",std::string(""));
00108 if(!sourceEngine.empty()) {
00109 throw edm::Exception(edm::errors::Configuration)
00110 << "sourceEngine is obsolete for new-style configuration files."
00111 << "\nPlease switch to the newer cfg format for the RandomNumberGeneratorService." ;
00112 }
00113
00114 uint32_t sourceSeed = iPSet.getUntrackedParameter<uint32_t>("sourceSeed",0);
00115 if(sourceSeed != 0) {
00116 throw edm::Exception(edm::errors::Configuration)
00117 << "sourceSeed is obsolete for new-style configuration files."
00118 << "\nPlease switch to the newer cfg format for the RandomNumberGeneratorService." ;
00119 }
00120
00121 std::vector<uint32_t> sourceSeedVector = iPSet.getUntrackedParameter<std::vector<uint32_t> >("sourceSeedVector",empty_Vuint32);
00122 if(!sourceSeedVector.empty()) {
00123 throw edm::Exception(edm::errors::Configuration)
00124 << "sourceSeedVector is obsolete for new-style configuration files."
00125 << "\nPlease switch to the newer cfg format for the RandomNumberGeneratorService." ;
00126 }
00127
00128 VString pSets = iPSet.getParameterNamesForType<edm::ParameterSet>();
00129 for(VString::const_iterator it = pSets.begin(), itEnd = pSets.end(); it != itEnd; ++it) {
00130 source = false;
00131 if(*it == std::string("moduleEngines")) {
00132 throw edm::Exception(edm::errors::Configuration)
00133 << "moduleEngines is obsolete for new-style configuration files."
00134 << "\nPlease switch to the newer cfg format for the RandomNumberGeneratorService." ;
00135 }
00136
00137 if(*it == std::string("moduleSeedVectors")) {
00138 throw edm::Exception(edm::errors::Configuration)
00139 << "moduleSeedVectors is obsolete for new-style configuration files."
00140 << "\nPlease switch to the newer cfg format for the RandomNumberGeneratorService." ;
00141 }
00142
00143
00144 if(*it == std::string("theSource")) source = true;
00145
00146 PSet secondary = iPSet.getParameter<edm::ParameterSet>(*it);
00147 engineName = secondary.getUntrackedParameter<std::string>("engineName",std::string("HepJamesRandom"));
00148 if(!isEngineNameValid(engineName)) {
00149 throw edm::Exception(edm::errors::Configuration)
00150 << "The specified Random Engine name, " << engineName
00151 << " does not correspond to a supported engine." ;
00152 }
00153
00154
00155
00156 if(engineName == std::string("RanecuEngine")) {
00157 if(secondary.exists("initialSeedSet")) {
00158 initialSeedSet = secondary.getUntrackedParameter<std::vector<uint32_t> >("initialSeedSet",empty_Vuint32);
00159 uint32_t nSeeds = initialSeedSet.size();
00160 uint32_t mSeeds = expectedSeedCount(engineName);
00161 if(nSeeds != mSeeds) {
00162 throw edm::Exception(edm::errors::Configuration)
00163 << "RanecuEngine requires 2 seeds and "
00164 << nSeeds << " seeds were\n"
00165 << "specified in the configuration file for "
00166 << "the module with label " << *it << "." ;
00167 }
00168 if(source) {
00169 seedMap_[sourceLabel] = initialSeedSet;
00170 } else {
00171 seedMap_[*it] = initialSeedSet;
00172 }
00173 CLHEP::HepRandomEngine* engine = new RanecuEngine();
00174 if(source) {
00175 engineMap_[sourceLabel] = engine;
00176 } else {
00177 engineMap_[*it] = engine;
00178 }
00179 if (initialSeedSet[0] > std::numeric_limits<uint32_t>::max() ||
00180 initialSeedSet[1] > std::numeric_limits<uint32_t>::max()) {
00181 throw edm::Exception(edm::errors::Configuration)
00182 << "The RanecuEngine seeds should be in the range 0 to " << std::numeric_limits<uint32_t>::max() << " .\n"
00183 << "The seeds passed to the RandomNumberGenerationService from the\n"
00184 "configuration file were " << initialSeedSet[0] << " and " << initialSeedSet[1]
00185 << " (or one was negative\nor larger "
00186 "than a 32 bit unsigned integer).\nThis was for "
00187 << "the module with label " << *it << ".";
00188 }
00189 long int seedL[2];
00190 seedL[0] = static_cast<long int>(initialSeedSet[0]);
00191 seedL[1] = static_cast<long int>(initialSeedSet[1]);
00192 engine->setSeeds(seedL,0);
00193 } else {
00194 throw edm::Exception(edm::errors::Configuration)
00195 << "No initialSeedSet was supplied for engine " << engineName
00196 << ". Aborting." ;
00197 }
00198
00199
00200
00201
00202
00203
00204 } else {
00205 initialSeed = 0;
00206 if(secondary.exists("initialSeed")) {
00207 initialSeed = secondary.getUntrackedParameter<uint32_t>("initialSeed",0);
00208 }
00209 if(secondary.exists("initialSeedSet")) {
00210 initialSeedSet = secondary.getUntrackedParameter<std::vector<uint32_t> >("initialSeedSet",empty_Vuint32);
00211 initialSeed = initialSeedSet[0];
00212 }
00213 if(initialSeed == 0) {
00214 throw edm::Exception(edm::errors::Configuration)
00215 << "No initialSeed was supplied for engine " << engineName
00216 << ". Aborting." ;
00217 }
00218 seeds.clear();
00219 seeds.push_back(initialSeed);
00220 if(source) {
00221 seedMap_[sourceLabel] = seeds;
00222 } else {
00223 seedMap_[*it] = seeds;
00224 }
00225 if(engineName == "HepJamesRandom") {
00226 if (initialSeed > 900000000) {
00227 throw edm::Exception(edm::errors::Configuration)
00228 << "The HepJamesRandom engine seed should be in the range 0 to 900000000.\n"
00229 << "The seed passed to the RandomNumberGenerationService from the\n"
00230 "configuration file was " << initialSeed
00231 << " or negative or larger\n"
00232 "than a 32 bit unsigned integer. This was for "
00233 << "the module with label " << *it << ".";
00234 }
00235 long int seedL = static_cast<long int>(initialSeed);
00236 CLHEP::HepRandomEngine* engine = new HepJamesRandom(seedL);
00237 if(source) {
00238 engineMap_[sourceLabel] = engine;
00239 } else {
00240 engineMap_[*it] = engine;
00241 }
00242 } else if(engineName == "TRandom3") {
00243 CLHEP::HepRandomEngine* engine = new TRandomAdaptor(initialSeed);
00244 if(source) {
00245 engineMap_[sourceLabel] = engine;
00246 } else {
00247 engineMap_[*it] = engine;
00248 }
00249 }
00250 }
00251 }
00252 }
00253
00254 iRegistry.watchPostBeginJob(this,&RandomNumberGeneratorService::postBeginJob);
00255 iRegistry.watchPostEndJob(this,&RandomNumberGeneratorService::postEndJob);
00256
00257 iRegistry.watchPreModuleConstruction(this,&RandomNumberGeneratorService::preModuleConstruction);
00258 iRegistry.watchPostModuleConstruction(this,&RandomNumberGeneratorService::postModuleConstruction);
00259
00260 iRegistry.watchPreSourceConstruction(this,&RandomNumberGeneratorService::preSourceConstruction);
00261 iRegistry.watchPostSourceConstruction(this,&RandomNumberGeneratorService::postSourceConstruction);
00262
00263 iRegistry.watchPreProcessEvent(this,&RandomNumberGeneratorService::preEventProcessing);
00264 iRegistry.watchPostProcessEvent(this,&RandomNumberGeneratorService::postEventProcessing);
00265
00266 iRegistry.watchPreModule(this,&RandomNumberGeneratorService::preModule);
00267 iRegistry.watchPostModule(this,&RandomNumberGeneratorService::postModule);
00268
00269 iRegistry.watchPreModuleBeginJob(this,&RandomNumberGeneratorService::preModuleBeginJob);
00270 iRegistry.watchPostModuleBeginJob(this,&RandomNumberGeneratorService::postModuleBeginJob);
00271
00272 iRegistry.watchPreModuleEndJob(this,&RandomNumberGeneratorService::preModuleEndJob);
00273 iRegistry.watchPostModuleEndJob(this,&RandomNumberGeneratorService::postModuleEndJob);
00274
00275
00276 engineStack_.push_back(engineMap_.end());
00277 currentEngine_ = engineMap_.end();
00278
00279 labelStack_.push_back(std::string());
00280 currentLabel_ = std::string();
00281 }
00282
00283 RandomNumberGeneratorService::~RandomNumberGeneratorService()
00284 {
00285
00286 for (EngineMap::iterator iter = engineMap_.begin();
00287 iter != engineMap_.end();
00288 ++iter) {
00289 delete iter->second;
00290 }
00291 }
00292
00293 CLHEP::HepRandomEngine&
00294 RandomNumberGeneratorService::getEngine() const {
00295
00296 if (currentEngine_ == engineMap_.end()) {
00297 if (currentLabel_ != std::string() ) {
00298 if ( currentLabel_ != sourceLabel) {
00299 if(oldStyle_) {
00300 throw edm::Exception(edm::errors::Configuration)
00301 << "The module with label \""
00302 << currentLabel_
00303 << "\" requested a random number engine from the \n"
00304 "RandomNumberGeneratorService, but that module was not configured\n"
00305 "for random numbers. An engine is created only if a seed(s) is provided\n"
00306 "in the configuration file. Please add the following line to the\n"
00307 "configuration file in the moduleSeeds PSet of the RandomNumberGeneratorService:\n"
00308 " untracked uint32 " << currentLabel_ << " = <your random number seed>\n\n"
00309 "Adding the line above will not work if you have modified the default and\n"
00310 "selected a different type of random engine that requires two or more seeds.\n"
00311 "In that case, you will need to add the following line to the moduleSeedVectors\n"
00312 "PSet instead:\n"
00313 " untracked vuint32 " << currentLabel_
00314 << " = { <your first random number seed>, <your second random number seed> ... }\n\n";
00315 } else {
00316 throw edm::Exception(edm::errors::Configuration)
00317 << "The module with label \""
00318 << currentLabel_
00319 << "\" requested a random number engine from the \n"
00320 "RandomNumberGeneratorService, but that module was not configured\n"
00321 "for random numbers. An engine is created only if a seed(s) is provided\n"
00322 "in the configuration file. Please add the following PSet to the\n"
00323 "configuration file for the RandomNumberGeneratorService:\n"
00324 " PSet " << currentLabel_ << " = {\n"
00325 " untracked string engineName = <name of chosen engine>\n"
00326 " untracked uint32 initialSeed = <value of chosen seed>\n"
00327 " }\n"
00328 "Adding the line above will not work if you have modified the default and\n"
00329 "selected a different type of random engine that requires two or more seeds.\n"
00330 "In that case, you will need to replace the line with initialSeed with\n"
00331 " untracked vuint32 initialSeedSet = { <your first random number seed>,"
00332 "<your second random number seed> ... }\n\n";
00333 }
00334 } else {
00335 if(oldStyle_) {
00336 throw edm::Exception(edm::errors::Configuration)
00337 << "The source requested a random number engine from the \n"
00338 "RandomNumberGeneratorService, but the source was not configured\n"
00339 "for random numbers. An engine is created only if a seed(s) is provided\n"
00340 "in the configuration file. Please add the following line to the\n"
00341 "configuration file in the RandomNumberGeneratorService block:\n"
00342 " untracked uint32 sourceSeed = <your random number seed>\n\n"
00343 "Adding the line above will not work if you have modified the default and\n"
00344 "selected a different type of random engine that requires two or more seeds.\n"
00345 "In that case, you will need to add the following line instead:\n"
00346 " untracked vuint32 sourceSeedVector = { <your first random number seed>, <your second random number seed> ... }\n\n";
00347 } else {
00348 throw edm::Exception(edm::errors::Configuration)
00349 << "The source requested a random number engine from the \n"
00350 "RandomNumberGeneratorService, but the source was not configured\n"
00351 "for random numbers. An engine is created only if a seed(s) is provided\n"
00352 "in the configuration file. Please add the following PSet to the\n"
00353 "configuration file in the RandomNumberGeneratorService block:\n"
00354 " PSet theSource = {\n"
00355 " untracked string engineName = <name of chosen engine>\n"
00356 " untracked uint32 initialSeed = <value of chosen seed>\n"
00357 " }\n"
00358 "Adding the line above will not work if you have modified the default and\n"
00359 "selected a different type of random engine that requires two or more seeds.\n"
00360 "In that case, you will need to add the following line instead:\n"
00361 " untracked vuint32 sourceSeedVector = { <your first random number seed>, <your second random number seed> ... }\n\n";
00362 }
00363 }
00364 }
00365 else {
00366 throw edm::Exception(edm::errors::Unknown)
00367 << "Requested a random number engine from the RandomNumberGeneratorService\n"
00368 "when no module was active. This is not supposed to be possible.\n"
00369 "Please rerun the job using a debugger to get a traceback to show\n"
00370 "what routines were called and then send information to the edm developers.";
00371 }
00372 }
00373 return *(currentEngine_->second);
00374 }
00375
00376 uint32_t
00377 RandomNumberGeneratorService::mySeed() const {
00378
00379 std::map<std::string, std::vector<uint32_t> >::const_iterator iter;
00380 iter = seedMap_.find(currentLabel_);
00381
00382 if (iter == seedMap_.end()) {
00383 if (currentLabel_ != std::string() ) {
00384 if ( currentLabel_ != sourceLabel) {
00385 if(oldStyle_) {
00386 throw edm::Exception(edm::errors::Configuration)
00387 << "The module with label \""
00388 << currentLabel_
00389 << "\" requested a random number engine from the \n"
00390 "RandomNumberGeneratorService, but that module was not configured\n"
00391 "for random numbers. An engine is created only if a seed(s) is provided\n"
00392 "in the configuration file. Please add the following line to the\n"
00393 "configuration file in the moduleSeeds PSet of the RandomNumberGeneratorService:\n"
00394 " untracked uint32 " << currentLabel_ << " = <your random number seed>\n\n"
00395 "Adding the line above will not work if you have modified the default and\n"
00396 "selected a different type of random engine that requires two or more seeds.\n"
00397 "In that case, you will need to add the following line to the moduleSeedVectors\n"
00398 "PSet instead:\n"
00399 " untracked vuint32 " << currentLabel_
00400 << " = { <your first random number seed>, <your second random number seed> ... }\n\n";
00401 } else {
00402 throw edm::Exception(edm::errors::Configuration)
00403 << "The module with label \""
00404 << currentLabel_
00405 << "\" requested a random number engine from the \n"
00406 "RandomNumberGeneratorService, but that module was not configured\n"
00407 "for random numbers. An engine is created only if a seed(s) is provided\n"
00408 "in the configuration file. Please add the following PSet to the\n"
00409 "configuration file for the RandomNumberGeneratorService:\n"
00410 " PSet " << currentLabel_ << " = {\n"
00411 " untracked string engineName = <name of chosen engine>\n"
00412 " untracked uint32 initialSeed = <value of chosen seed>\n"
00413 " }\n"
00414 "Adding the line above will not work if you have modified the default and\n"
00415 "selected a different type of random engine that requires two or more seeds.\n"
00416 "In that case, you will need to replace the line with initialSeed with\n"
00417 " untracked vuint32 initialSeedSet = { <your first random number seed>,"
00418 "<your second random number seed> ... }\n\n";
00419 }
00420 } else {
00421 if(oldStyle_) {
00422 throw edm::Exception(edm::errors::Configuration)
00423 << "The source requested a random number engine from the \n"
00424 "RandomNumberGeneratorService, but the source was not configured\n"
00425 "for random numbers. An engine is created only if a seed(s) is provided\n"
00426 "in the configuration file. Please add the following line to the\n"
00427 "configuration file in the RandomNumberGeneratorService block:\n"
00428 " untracked uint32 sourceSeed = <your random number seed>\n\n"
00429 "Adding the line above will not work if you have modified the default and\n"
00430 "selected a different type of random engine that requires two or more seeds.\n"
00431 "In that case, you will need to add the following line instead:\n"
00432 " untracked vuint32 sourceSeedVector = { <your first random number seed>, <your second random number seed> ... }\n\n";
00433 } else {
00434 throw edm::Exception(edm::errors::Configuration)
00435 << "The source requested a random number engine from the \n"
00436 "RandomNumberGeneratorService, but the source was not configured\n"
00437 "for random numbers. An engine is created only if a seed(s) is provided\n"
00438 "in the configuration file. Please add the following PSet to the\n"
00439 "configuration file in the RandomNumberGeneratorService block:\n"
00440 " PSet theSource = {\n"
00441 " untracked string engineName = <name of chosen engine>\n"
00442 " untracked uint32 initialSeed = <value of chosen seed>\n"
00443 " }\n"
00444 "Adding the line above will not work if you have modified the default and\n"
00445 "selected a different type of random engine that requires two or more seeds.\n"
00446 "In that case, you will need to add the following line instead:\n"
00447 " untracked vuint32 sourceSeedVector = { <your first random number seed>, <your second random number seed> ... }\n\n";
00448 }
00449 }
00450 } else {
00451 throw edm::Exception(edm::errors::Unknown)
00452 << "Requested a random number engine from the RandomNumberGeneratorService\n"
00453 "when no module was active. This is not supposed to be possible.\n"
00454 "Please rerun the job using a debugger to get a traceback to show\n"
00455 "what routines were called and then send information to the edm developers.";
00456 }
00457 }
00458 return iter->second[0];
00459 }
00460
00461 void
00462 RandomNumberGeneratorService::preModuleConstruction(const ModuleDescription& iDesc)
00463 {
00464 push(iDesc.moduleLabel_);
00465 }
00466
00467 void
00468 RandomNumberGeneratorService::postModuleConstruction(const ModuleDescription&)
00469 {
00470 pop();
00471 }
00472
00473 void
00474 RandomNumberGeneratorService::preSourceConstruction(const ModuleDescription& iDesc)
00475 {
00476 push(sourceLabel);
00477 }
00478
00479 void
00480 RandomNumberGeneratorService::postSourceConstruction(const ModuleDescription&)
00481 {
00482 pop();
00483 }
00484
00485 void
00486 RandomNumberGeneratorService::postBeginJob()
00487 {
00488
00489 push(sourceLabel);
00490
00491
00492 if(!restoreFileName_.empty()) restoreEngineState(restoreFileName_);
00493
00494
00495 if(!saveFileName_.empty()) {
00496 saveEngineState(saveFileName_);
00497 if(!saveFileNameRecorded_) {
00498 std::string fullName = constructSaveFileName();
00499 Service<JobReport> reportSvc;
00500 reportSvc->reportRandomStateFile(fullName);
00501 saveFileNameRecorded_ = true;
00502 }
00503 }
00504 }
00505
00506 void
00507 RandomNumberGeneratorService::postEndJob()
00508 {
00509 if (labelStack_.size() != 1) {
00510 pop();
00511 }
00512 }
00513
00514 void
00515 RandomNumberGeneratorService::preEventProcessing(const edm::EventID&, const edm::Timestamp&)
00516 {
00517
00518 pop();
00519 }
00520
00521 void
00522 RandomNumberGeneratorService::postEventProcessing(const Event&, const EventSetup&)
00523 {
00524
00525 if(!saveFileName_.empty()) {
00526 saveEngineState(saveFileName_);
00527 if(!saveFileNameRecorded_) {
00528 std::string fullName = constructSaveFileName();
00529 Service<JobReport> reportSvc;
00530 reportSvc->reportRandomStateFile(fullName);
00531 saveFileNameRecorded_ = true;
00532 }
00533 }
00534
00535 push(sourceLabel);
00536 }
00537
00538 void
00539 RandomNumberGeneratorService::preModule(const ModuleDescription& iDesc)
00540 {
00541 push(iDesc.moduleLabel_);
00542 }
00543
00544 void
00545 RandomNumberGeneratorService::postModule(const ModuleDescription&)
00546 {
00547 pop();
00548 }
00549
00550 void
00551 RandomNumberGeneratorService::preModuleBeginJob(const ModuleDescription& iDesc)
00552 {
00553 push(iDesc.moduleLabel_);
00554 }
00555
00556 void
00557 RandomNumberGeneratorService::postModuleBeginJob(const ModuleDescription&)
00558 {
00559 pop();
00560 }
00561
00562 void
00563 RandomNumberGeneratorService::preModuleEndJob(const ModuleDescription& iDesc)
00564 {
00565 push(iDesc.moduleLabel_);
00566 }
00567
00568 void
00569 RandomNumberGeneratorService::postModuleEndJob(const ModuleDescription&)
00570 {
00571 pop();
00572 }
00573
00574 const std::vector<std::string>&
00575 RandomNumberGeneratorService::getCachedLabels() const {
00576
00577 return cachedLabels_;
00578 }
00579
00580 const std::vector<std::vector<uint32_t> >&
00581 RandomNumberGeneratorService::getCachedStates() const {
00582
00583 return cachedStates_;
00584 }
00585
00586 const std::vector<std::vector<uint32_t> >&
00587 RandomNumberGeneratorService::getCachedSeeds() const {
00588
00589 return cachedSeeds_;
00590 }
00591
00592 void
00593 RandomNumberGeneratorService::restoreState(const edm::Event& iEvent) {
00594
00595 if ( restoreStateLabel_ == std::string()) return;
00596
00597 Handle<std::vector<RandomEngineState> > states;
00598
00599 iEvent.getByLabel(restoreStateLabel_, states);
00600 if(!states.isValid()) {
00601 throw edm::Exception(edm::errors::ProductNotFound)
00602 << "The RandomNumberGeneratorService is trying to restore\n"
00603 << "the state of the random engines by reading an object from\n"
00604 << "the event with label \"" << restoreStateLabel_ << "\". It\n"
00605 << "fails to find one. This is probably set to the wrong value\n"
00606 << "in the configuration file. It must match the module label\n"
00607 << "of the RandomEngineStateProducer that created the object in\n"
00608 << "a previous process\n";
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 EngineMap::iterator sourceEngine = engineMap_.find(sourceLabel);
00625 if (sourceEngine != engineMap_.end()) {
00626 throw edm::Exception(edm::errors::UnimplementedFeature)
00627 << "The RandomNumberGeneratorService was instructed to restore\n"
00628 << "the state of the random engines and the source is\n"
00629 << "configured to generate random numbers.\n"
00630 << "Currently the RandomNumberGeneratorService is not\n"
00631 << "capable of restoring the random engine state of the\n"
00632 << "source. This feature has not been implemented yet.\n"
00633 << "You need to remove the line in the configuration file\n"
00634 << "that gives the source a seed or stop trying to restore\n"
00635 << "the state of the random numbers (remove the line that sets\n"
00636 << "the \"restoreStateLabel\" in the configuration file).\n";
00637 }
00638
00639
00640
00641
00642
00643 for (std::vector<RandomEngineState>::const_iterator iter = states->begin();
00644 iter != states->end();
00645 ++iter) {
00646 std::string engineLabel = iter->getLabel();
00647 std::vector<uint32_t> engineState = iter->getState();
00648 std::vector<unsigned long> engineStateL;
00649 for (std::vector<uint32_t>::const_iterator iVal = engineState.begin();
00650 iVal != engineState.end();
00651 ++iVal) {
00652 engineStateL.push_back(static_cast<unsigned long>(*iVal));
00653 }
00654
00655 std::vector<uint32_t> engineSeeds = iter->getSeed();
00656 std::vector<long> engineSeedsL;
00657 for (std::vector<uint32_t>::const_iterator iVal = engineSeeds.begin();
00658 iVal != engineSeeds.end();
00659 ++iVal) {
00660 engineSeedsL.push_back(static_cast<long>(*iVal));
00661 }
00662
00663 EngineMap::iterator engine = engineMap_.find(engineLabel);
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 if (engine != engineMap_.end()) {
00677
00678 seedMap_[engineLabel] = engineSeeds;
00679
00680
00681
00682 if (engineStateL[0] == CLHEP::engineIDulong<CLHEP::HepJamesRandom>()) {
00683
00684 checkEngineType(engine->second->name(), std::string("HepJamesRandom"), engineLabel);
00685
00686
00687 engine->second->setSeed(engineSeedsL[0], 0);
00688 engine->second->get(engineStateL);
00689 }
00690 else if (engineStateL[0] == CLHEP::engineIDulong<CLHEP::RanecuEngine>()) {
00691
00692 checkEngineType(engine->second->name(), std::string("RanecuEngine"), engineLabel);
00693
00694
00695 engine->second->get(engineStateL);
00696 }
00697
00698 else if (engineStateL[0] == CLHEP::engineIDulong<TRandomAdaptor>()) {
00699
00700 checkEngineType(engine->second->name(), std::string("TRandom3"), engineLabel);
00701
00702
00703 engine->second->setSeed(engineSeedsL[0], 0);
00704 engine->second->get(engineStateL);
00705 }
00706
00707
00708 else {
00709 throw edm::Exception(edm::errors::Unknown)
00710 << "The RandomNumberGeneratorService is trying to restore the state\n"
00711 "of the random engines. The state in the event indicates an engine\n"
00712 "of an unknown type. This should not be possible unless you are\n"
00713 "running with an old code release on a new file that was created\n"
00714 "with a newer release which had new engine types added. In this case\n"
00715 "the only solution is to use a newer release. In any other case, notify\n"
00716 "the EDM developers because this should not be possible\n";
00717 }
00718 }
00719 }
00720 snapShot();
00721 }
00722
00723 void
00724 RandomNumberGeneratorService::snapShot()
00725 {
00726 cachedLabels_.clear();
00727 cachedStates_.clear();
00728 cachedSeeds_.clear();
00729
00730
00731
00732
00733 for (EngineMap::const_iterator iter = engineMap_.begin();
00734 iter != engineMap_.end();
00735 ++iter) {
00736
00737 cachedLabels_.push_back(iter->first);
00738
00739 std::vector<unsigned long> stateL = iter->second->put();
00740 std::vector<uint32_t> state32;
00741 for (std::vector<unsigned long>::const_iterator vIter = stateL.begin();
00742 vIter != stateL.end();
00743 ++vIter) {
00744 state32.push_back(static_cast<uint32_t>(*vIter));
00745 }
00746 cachedStates_.push_back(state32);
00747
00748 cachedSeeds_.push_back(seedMap_[iter->first]);
00749 }
00750 }
00751
00752 void
00753 RandomNumberGeneratorService::print() {
00754 std::cout << "\n\nRandomNumberGeneratorService dump\n\n";
00755
00756 std::cout << " Contents of seedMap\n";
00757 for (std::map<std::string, std::vector<uint32_t> >::const_iterator iter = seedMap_.begin();
00758 iter != seedMap_.end();
00759 ++iter) {
00760 std::cout << " " << iter->first;
00761 std::vector<uint32_t> seeds = iter->second;
00762 for (std::vector<uint32_t>::const_iterator vIter = seeds.begin();
00763 vIter != seeds.end();
00764 ++vIter) {
00765 std::cout << " " << *vIter;
00766 }
00767 std::cout << "\n";
00768 }
00769 std::cout << "\n Contents of engineMap\n";
00770 for (EngineMap::const_iterator iter = engineMap_.begin();
00771 iter != engineMap_.end();
00772 ++iter) {
00773 std::cout << " " << iter->first
00774 << " " << iter->second->name()
00775 << " " << iter->second->getSeed()
00776 << "\n";
00777 }
00778 std::cout << "\n";
00779 std::cout << " currentLabel_ = " << currentLabel_ << "\n";
00780 std::cout << " labelStack_ size = " << labelStack_.size() << "\n";
00781 int i = 0;
00782 for (std::vector<std::string>::const_iterator iter = labelStack_.begin();
00783 iter != labelStack_.end();
00784 ++iter, ++i) {
00785 std::cout << " " << i << " " << *iter << "\n";
00786 }
00787 if (currentEngine_ == engineMap_.end()) {
00788 std::cout << " currentEngine points to end\n";
00789 }
00790 else {
00791 std::cout << " currentEngine_ = " << currentEngine_->first
00792 << " " << currentEngine_->second->name()
00793 << " " << currentEngine_->second->getSeed() << "\n";
00794 }
00795
00796 std::cout << " engineStack_ size = " << engineStack_.size() << "\n";
00797 i = 0;
00798 for (std::vector<EngineMap::const_iterator>::const_iterator iter = engineStack_.begin();
00799 iter != engineStack_.end();
00800 ++iter, ++i) {
00801 if (*iter == engineMap_.end()) {
00802 std::cout << " " << i << " Points to end of engine map\n";
00803 }
00804 else {
00805 std::cout << " " << i << " " << (*iter)->first
00806 << " " << (*iter)->second->name() << " " << (*iter)->second->getSeed() << "\n";
00807 }
00808 }
00809
00810 std::cout << " restoreStateLabel_ = " << restoreStateLabel_ << "\n";
00811
00812 int size = getCachedLabels().size();
00813 std::cout << " cachedLabels size = " << size << "\n";
00814 for (int i = 0; i < size; ++i) {
00815 std::cout << " " << i << " " << getCachedLabels()[i] << "\n";
00816 }
00817
00818 size = getCachedStates().size();
00819 std::cout << " cachedStates size = " << size << "\n";
00820 for (int i = 0; i < size; ++i) {
00821 std::vector<uint32_t> state = getCachedStates()[i];
00822 std::cout << " " << i << " : ";
00823 int j = 0;
00824 for (std::vector<uint32_t>::const_iterator iter = state.begin();
00825 iter != state.end();
00826 ++iter, ++j) {
00827 if (j > 0 && (j % 10) == 0) {
00828 std::cout << "\n ";
00829 }
00830 std::cout << " " << *iter;
00831 }
00832 std::cout << "\n";
00833 }
00834
00835 size = getCachedSeeds().size();
00836 std::cout << " cachedSeeds size = " << size << "\n";
00837 for (int i = 0; i < size; ++i) {
00838 std::vector<uint32_t> seeds = getCachedSeeds()[i];
00839 std::cout << " " << i << " : ";
00840 for (std::vector<uint32_t>::const_iterator iter = seeds.begin();
00841 iter != seeds.end();
00842 ++iter) {
00843 std::cout << " " << *iter;
00844 }
00845 std::cout << "\n";
00846 }
00847 }
00848
00849 void
00850 RandomNumberGeneratorService::push(const std::string& iLabel)
00851 {
00852 currentEngine_ = engineMap_.find(iLabel);
00853 engineStack_.push_back(currentEngine_);
00854
00855 labelStack_.push_back(iLabel);
00856 currentLabel_ = iLabel;
00857 }
00858
00859 void
00860 RandomNumberGeneratorService::pop()
00861 {
00862 engineStack_.pop_back();
00863
00864 currentEngine_ = engineStack_.back();
00865 labelStack_.pop_back();
00866 currentLabel_ = labelStack_.back();
00867 }
00868
00869 void
00870 RandomNumberGeneratorService::checkEngineType(const std::string& typeFromConfig,
00871 const std::string& typeFromEvent,
00872 const std::string& engineLabel)
00873 {
00874 if (typeFromConfig != typeFromEvent) {
00875
00876 if (engineLabel == sourceLabel) {
00877 throw edm::Exception(edm::errors::Configuration)
00878 << "The RandomNumberGeneratorService is trying to restore\n"
00879 << "the state of the random engine for the source. An\n"
00880 << "error was detected because the type of the engine in the\n"
00881 << "input file and the configuration file do not match.\n"
00882 << "In the configuration file the type is \"" << typeFromConfig
00883 << "\".\nIn the input file the type is \"" << typeFromEvent << "\". If\n"
00884 << "you are not generating any random numbers in the source, then\n"
00885 << "remove the line in the configuration file that gives the source\n"
00886 << "a seed and the error will go away. Otherwise, you must give\n"
00887 << "the source the same engine type in the configuration file or\n"
00888 << "stop trying to restore the random engine state.\n";
00889 }
00890 else {
00891 throw edm::Exception(edm::errors::Configuration)
00892 << "The RandomNumberGeneratorService is trying to restore\n"
00893 << "the state of the random engine for the module \""
00894 << engineLabel << "\". An\n"
00895 << "error was detected because the type of the engine in the\n"
00896 << "input file and the configuration file do not match.\n"
00897 << "In the configuration file the type is \"" << typeFromConfig
00898 << "\".\nIn the input file the type is \"" << typeFromEvent << "\". If\n"
00899 << "you are not generating any random numbers in this module, then\n"
00900 << "remove the line in the configuration file that gives it\n"
00901 << "a seed and the error will go away. Otherwise, you must give\n"
00902 << "this module the same engine type in the configuration file or\n"
00903 << "stop trying to restore the random engine state.\n";
00904 }
00905 }
00906 }
00907
00908 void
00909 RandomNumberGeneratorService::dumpVector(const std::vector<uint32_t> &v)
00910 {
00911 if(v.empty()) return;
00912 size_t numItems = v.size();
00913 for( int i=0; i<(int)numItems; ++i) {
00914 if( i != 0 && i%10 == 0 ) std::cerr << std::endl;
00915 std::cerr << std::setw(13) << v[i] ;
00916 }
00917 if(numItems%10 != 0) std::cerr << std::endl;
00918 }
00919
00920 void
00921 RandomNumberGeneratorService::stashVector(const std::vector<unsigned long> &v,
00922 std::ostream &outFile)
00923 {
00924 if(v.empty()) return;
00925 size_t numItems = v.size();
00926 for( int i=0; i<(int)numItems; ++i) {
00927 if( i != 0 && i%10 == 0 ) outFile << "\n" ;
00928 outFile << std::setw(13) << v[i] ;
00929 }
00930 if(numItems%10 != 0) outFile << "\n" ;
00931 }
00932
00933 std::vector<unsigned long>
00934 RandomNumberGeneratorService::restoreVector(std::istream &is, const int32_t numItems)
00935 {
00936 unsigned long value;
00937 std::vector<unsigned long> v;
00938 std::ostringstream sstr;
00939 int i = 0;
00940 is >> std::ws;
00941 while(i<numItems) {
00942 if(!(is >> value)) {
00943 sstr << "Configuration: Unable to read the random engine state vector from file, "
00944 << restoreFileName_ << ".\n"
00945 << "The file has probably been corrupted.\n" ;
00946 edm::Exception except(edm::errors::Configuration, sstr.str());
00947 throw except;
00948 } else {
00949 v.push_back(value);
00950 ++i;
00951 }
00952 }
00953 return v;
00954 }
00955
00956
00957 void RandomNumberGeneratorService::restoreEngineState(const std::string& fileName)
00958 {
00959
00960
00961
00962 std::ifstream inFile;
00963 std::ostringstream sstr;
00964 inFile.open(fileName.c_str(), std::ifstream::in);
00965 if(!inFile) {
00966 sstr << "Configuration: Unable to open the file, "
00967 << fileName << ", to restore the engine status.\n" ;
00968 edm::Exception except(edm::errors::Configuration, sstr.str());
00969 throw except;
00970 }
00971
00972 std::string text;
00973 inFile >> text;
00974 if(text != std::string("<RandomEngineStates>")) {
00975 sstr << "Configuration: File, " << restoreFileName_
00976 << " is ill-structured or otherwise corrupted.\n"
00977 << "Cannot read the file header word.\n" ;
00978 edm::Exception except(edm::errors::Configuration, sstr.str());
00979 throw except;
00980 }
00981 while(processStanza(inFile)) { }
00982 }
00983
00984 bool RandomNumberGeneratorService::processStanza(std::istream &is)
00985 {
00986 std::string leading, trailing;
00987 std::string moduleLabel;
00988 std::string engineName;
00989 long initialSeed;
00990 int stateVectorLength;
00991 std::vector<unsigned long> stateVector;
00992 std::ostringstream sstr;
00993
00994 is >> leading;
00995 if(leading == std::string("</RandomEngineStates>")) return false;
00996 is >> moduleLabel >> trailing;
00997 if(leading != std::string("<ModuleLabel>") || trailing != std::string("</ModuleLabel>")) {
00998 sstr << "Configuration: File, " << restoreFileName_
00999 << ", is ill-structured or otherwise corrupted.\n"
01000 << "Cannot read a module label.\n" ;
01001 edm::Exception except(edm::errors::Configuration, sstr.str());
01002 throw except;
01003 }
01004
01005 is >> leading >> engineName >> trailing;
01006 if(leading != std::string("<EngineName>") || trailing != std::string("</EngineName>")) {
01007 sstr << "Configuration: File, " << restoreFileName_
01008 << ", is ill-structured or otherwise corrupted.\n"
01009 << "Cannot read an engine name.\n" ;
01010 edm::Exception except(edm::errors::Configuration, sstr.str());
01011 throw except;
01012 }
01013
01014 is >> leading >> initialSeed >> trailing;
01015 if(leading != std::string("<InitialSeed>") || trailing != std::string("</InitialSeed>")) {
01016 sstr << "Configuration: File, " << restoreFileName_
01017 << ", is ill-structured or otherwise corrupted.\n"
01018 << "Cannot read initial seed(s).\n" ;
01019 edm::Exception except(edm::errors::Configuration, sstr.str());
01020 throw except;
01021 }
01022
01023 is >> leading >> stateVectorLength >> trailing;
01024 if(leading != std::string("<FullStateLength>") || trailing != std::string("</FullStateLength>")) {
01025 sstr << "Configuration: File, " << restoreFileName_
01026 << ", is ill-structured or otherwise corrupted.\n"
01027 << "Cannot read the state vector length.\n" ;
01028 edm::Exception except(edm::errors::Configuration, sstr.str());
01029 throw except;
01030 }
01031
01032 is >> leading;
01033 if(leading != std::string("<FullState>")) {
01034 sstr << "Configuration: File, " << restoreFileName_
01035 << ", is ill-structured or otherwise corrupted.\n"
01036 << "Cannot read state vector header.\n" ;
01037 edm::Exception except(edm::errors::Configuration, sstr.str());
01038 throw except;
01039 }
01040 stateVector = restoreVector(is, stateVectorLength);
01041 is >> trailing;
01042 if(trailing != std::string("</FullState>")) {
01043 sstr << "Configuration: File, " << restoreFileName_
01044 << ", is ill-structured or otherwise corrupted.\n"
01045 << "Cannot read state vector trailer.\n" ;
01046 edm::Exception except(edm::errors::Configuration, sstr.str());
01047 throw except;
01048 }
01049
01050
01051
01052
01053 CLHEP::HepRandomEngine* engine;
01054 EngineMap::iterator iter = engineMap_.find(moduleLabel);
01055 if(iter == engineMap_.end()) {
01056 if(moduleLabel == sourceLabel) {
01057
01058
01059
01060
01061
01062 sstr << "Configuration: sourceLabel @source is currently disallowed"
01063 << "\nbut appears in save file, " << saveFileName_ << "\n" ;
01064 edm::Exception except(edm::errors::Configuration, sstr.str());
01065 throw except;
01066 } else {
01067 sstr << "Configuration: The module label, " << moduleLabel
01068 << ", found in the state save file does not match any label "
01069 << "in the configuration file. There is a mismatch between "
01070 << "the configuration file and the state save file, "
01071 << saveFileName_ << "\n" ;
01072 edm::Exception except(edm::errors::Configuration, sstr.str());
01073 throw except;
01074 }
01075 } else {
01076 engine = iter->second;
01077 if(engine->name() != engineName) {
01078 sstr << "Configuration: The engine name in the configuration file (" << engine->name()
01079 << ")\ndoes not match the name (" << engineName << ") in the state save file,\n"
01080 << saveFileName_ << ", for the module labelled " << moduleLabel << "\n" ;
01081 edm::Exception except(edm::errors::Configuration, sstr.str());
01082 throw except;
01083 }
01084 engine->setSeed(initialSeed,0);
01085 bool success = engine->get(stateVector);
01086 if(!success) {
01087 sstr << "Configuration: Setting the state of " << engine->name() << " failed.\n"
01088 << "Aborting.\n" ;
01089 edm::Exception except(edm::errors::Configuration, sstr.str());
01090 throw except;
01091 }
01092 }
01093 return true;
01094 }
01095
01096 void RandomNumberGeneratorService::saveEngineState(const std::string& fileName)
01097 {
01098 std::ofstream outFile;
01099 outFile.open(fileName.c_str(), std::ofstream::out | std::ofstream::trunc);
01100 if(!outFile) {
01101 std::ostringstream sstr;
01102 sstr << "Configuration: Unable to open the file, "
01103 << fileName << ", to save the engine status.\n" ;
01104 edm::Exception except(edm::errors::Configuration, sstr.str());
01105 throw except;
01106 }
01107 outFile << "<RandomEngineStates>\n" ;
01108 for(EngineMap::const_iterator iter = engineMap_.begin(), iterEnd = engineMap_.end();
01109 iter != iterEnd;
01110 ++iter) {
01111 std::string moduleLabel = iter->first;
01112
01113
01114
01115
01116
01117 if(moduleLabel != sourceLabel) {
01118 std::string engineName = iter->second->name();
01119 long initialSeed = iter->second->getSeed();
01120 std::vector<unsigned long> stateVector = iter->second->put();
01121 int stateVectorLength = stateVector.size();
01122
01123 outFile << "<ModuleLabel>\n" << moduleLabel << "\n</ModuleLabel>\n" ;
01124 outFile << "<EngineName>\n" << engineName << "\n</EngineName>\n" ;
01125 outFile << "<InitialSeed>\n" << initialSeed << "\n</InitialSeed>\n" ;
01126 outFile << "<FullStateLength>\n" << stateVectorLength << "\n</FullStateLength>\n" ;
01127 outFile << "<FullState>\n" ;
01128 stashVector(stateVector, outFile);
01129 outFile << "</FullState>\n" ;
01130 }
01131 }
01132 outFile << "</RandomEngineStates>\n" ;
01133 }
01134
01135 bool RandomNumberGeneratorService::isEngineNameValid(std::string const &name)
01136 {
01137 bool valid = false;
01138 if(name == std::string("HepJamesRandom")) valid = true;
01139 if(name == std::string("RanecuEngine")) valid = true;
01140 if(name == std::string("TRandom3")) valid = true;
01141 return valid;
01142 }
01143
01144 int32_t RandomNumberGeneratorService::expectedSeedCount(std::string const &name)
01145 {
01146 int32_t count = 0;
01147 if(name == std::string("HepJamesRandom")) count = 1;
01148 if(name == std::string("RanecuEngine")) count = 2;
01149 if(name == std::string("TRandom3")) count = 1;
01150 return count;
01151 }
01152 std::string RandomNumberGeneratorService::constructSaveFileName()
01153 {
01154 std::string fullName;
01155 fullName.reserve(1000);
01156 fullName = getcwd(&fullName[0],1000);
01157 fullName += "/" + saveFileName_;
01158 fullName.reserve();
01159 return fullName;
01160 }
01161
01162 void
01163 RandomNumberGeneratorService::oldStyleConfig(const ParameterSet& iPSet)
01164 {
01165 std::string labels;
01166 std::vector<uint32_t> seeds;
01167 PSet empty_PSet;
01168 VString empty_VString;
01169 Vuint32 empty_Vuint32;
01170
01171 std::string engineName;
01172
01173 VString pSets = iPSet.getParameterNamesForType<edm::ParameterSet>();
01174 for(VString::const_iterator it = pSets.begin(), itEnd = pSets.end(); it != itEnd; ++it) {
01175 if(*it == std::string("theSource")) {
01176 throw edm::Exception(edm::errors::Configuration)
01177 << "PSet theSource is not recognized for old-style configuration files."
01178 << "\nYou must be consistent in your use of new- or old-style cfg format"
01179 << "\nfor the RandomNumberGeneratorService." ;
01180 }
01181 }
01182
01183
01184
01185
01186
01187
01188 if(iPSet.exists("sourceSeedVector")) {
01189 seeds = iPSet.getUntrackedParameter<std::vector<uint32_t> >("sourceSeedVector");
01190
01191 } else if(iPSet.exists("sourceSeed")) {
01192 uint32_t seed = iPSet.getUntrackedParameter<uint32_t>("sourceSeed");
01193 seeds.push_back(seed);
01194 }
01195
01196
01197 if (seeds.size() > 0) {
01198 seedMap_[sourceLabel] = seeds;
01199 }
01200
01201 if(iPSet.exists("moduleSeedVectors")) {
01202 const edm::ParameterSet& moduleSeedVectors = iPSet.getParameter<edm::ParameterSet>("moduleSeedVectors");
01203
01204 std::vector<std::string> names = moduleSeedVectors.getParameterNames();
01205 for(std::vector<std::string>::const_iterator itName = names.begin(), itNameEnd = names.end(); itName != itNameEnd; ++itName) {
01206
01207 if(seedMap_.find(*itName) == seedMap_.end()) {
01208 if(moduleSeedVectors.exists(*itName)) {
01209 seeds = moduleSeedVectors.getUntrackedParameter<std::vector<uint32_t> >(*itName);
01210 if (seeds.size() > 0) {
01211 seedMap_[*itName] = seeds;
01212 }
01213 }
01214 }
01215 }
01216
01217
01218 }
01219
01220
01221 if(iPSet.exists("moduleSeeds")) {
01222 const edm::ParameterSet& moduleSeeds = iPSet.getParameter<edm::ParameterSet>("moduleSeeds");
01223
01224 std::vector<std::string> names = moduleSeeds.getParameterNames();
01225 for(std::vector<std::string>::const_iterator itName = names.begin(), itNameEnd = names.end();
01226 itName != itNameEnd; ++itName) {
01227
01228
01229 if (seedMap_.find(*itName) == seedMap_.end()) {
01230
01231 if(moduleSeeds.exists(*itName)) {
01232 uint32_t seed = moduleSeeds.getUntrackedParameter<uint32_t>(*itName);
01233 seeds.clear();
01234 seeds.push_back(seed);
01235 seedMap_[*itName] = seeds;
01236 }
01237
01238
01239 }
01240 }
01241 }
01242
01243
01244
01245
01246
01247
01248
01249 for (std::map<std::string, std::vector<uint32_t> >::iterator seedIter = seedMap_.begin();
01250 seedIter != seedMap_.end();
01251 ++seedIter) {
01252
01253
01254 std::string engineName = "HepJamesRandom";
01255
01256
01257
01258 if(engineMap_.find(seedIter->first) == engineMap_.end()) {
01259
01260 if (seedIter->first == sourceLabel) {
01261 if(iPSet.exists("sourceEngine")) {
01262 engineName = iPSet.getUntrackedParameter<std::string>("sourceEngine");
01263 }
01264 } else if(iPSet.exists("moduleEngines")) {
01265 const edm::ParameterSet& moduleEngines = iPSet.getParameter<edm::ParameterSet>("moduleEngines");
01266 if(moduleEngines.exists(seedIter->first)) {
01267 engineName = moduleEngines.getUntrackedParameter<std::string>(seedIter->first);
01268 }
01269 }
01270
01271
01272 std::string outputString = "the module with label \"";
01273 outputString += seedIter->first;
01274 outputString += "\"";
01275 if (seedIter->first == sourceLabel) outputString = "the source";
01276
01277 if (engineName == "HepJamesRandom") {
01278
01279 if (seedIter->second.size() != 1) {
01280 throw edm::Exception(edm::errors::Configuration)
01281 << "HepJamesRandom engine requires 1 seed and "
01282 << seedIter->second.size()
01283 << " seeds were\n"
01284 << "specified in the configuration file for "
01285 << outputString << ".";
01286 }
01287
01288 if (seedIter->second[0] > 900000000) {
01289 throw edm::Exception(edm::errors::Configuration)
01290 << "The HepJamesRandom engine seed should be in the range 0 to 900000000.\n"
01291 << "The seed passed to the RandomNumberGenerationService from the\n"
01292 "configuration file was " << seedIter->second[0]
01293 << " or negative or larger\n"
01294 "than a 32 bit unsigned integer. This was for "
01295 << outputString << ".";
01296 }
01297 long seedL = static_cast<long>(seedIter->second[0]);
01298 CLHEP::HepRandomEngine* engine = new CLHEP::HepJamesRandom(seedL);
01299 engineMap_[seedIter->first] = engine;
01300 } else if (engineName == "RanecuEngine") {
01301
01302 if (seedIter->second.size() != 2) {
01303 throw edm::Exception(edm::errors::Configuration)
01304 << "RanecuEngine requires 2 seeds and "
01305 << seedIter->second.size()
01306 << " seeds were\n"
01307 << "specified in the configuration file for "
01308 << outputString << ".";
01309 }
01310
01311 if (seedIter->second[0] > std::numeric_limits<uint32_t>::max() ||
01312 seedIter->second[1] > std::numeric_limits<uint32_t>::max()) {
01313 throw edm::Exception(edm::errors::Configuration)
01314 << "The RanecuEngine seeds should be in the range 0 to " << std::numeric_limits<uint32_t>::max() << ".\n"
01315 << "The seeds passed to the RandomNumberGenerationService from the\n"
01316 "configuration file were " << seedIter->second[0] << " and " << seedIter->second[1]
01317 << " (or one was negative\nor larger "
01318 "than a 32 bit unsigned integer).\nThis was for "
01319 << outputString << ".";
01320 }
01321 long seedL[2];
01322 seedL[0] = static_cast<long>(seedIter->second[0]);
01323 seedL[1] = static_cast<long>(seedIter->second[1]);
01324 CLHEP::HepRandomEngine* engine = new CLHEP::RanecuEngine();
01325 engine->setSeeds(seedL, 0);
01326 engineMap_[seedIter->first] = engine;
01327
01328 } else if (engineName == "TRandom3") {
01329
01330 if (seedIter->second.size() != 1) {
01331 throw edm::Exception(edm::errors::Configuration)
01332 << "TRandom3 engine requires 1 seed and "
01333 << seedIter->second.size()
01334 << " seeds were\n"
01335 << "specified in the configuration file for "
01336 << outputString << ".";
01337 }
01338 long seedL = static_cast<long>(seedIter->second[0]);
01339 CLHEP::HepRandomEngine* engine = new TRandomAdaptor(seedL);
01340 engineMap_[seedIter->first] = engine;
01341 } else {
01342 throw edm::Exception(edm::errors::Configuration)
01343 << "The configuration file requested the RandomNumberGeneratorService\n"
01344 "create an unknown random engine type named \""
01345 << engineName
01346 << "\"\nfor " << outputString
01347 << "\nCurrently the only valid types are HepJamesRandom, RanecuEngine and TRandom3";
01348 }
01349 }
01350 }
01351 }