CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/SimDataFormats/RandomEngine/src/RandomEngineStates.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "SimDataFormats/RandomEngine/interface/RandomEngineStates.h"
00003 #include "SimDataFormats/RandomEngine/interface/RandomEngineState.h"
00004 #include "FWCore/Utilities/interface/EDMException.h"
00005 
00006 #include <algorithm>
00007 
00008 namespace edm {
00009 
00010   RandomEngineStates::RandomEngineStates() {
00011   }
00012 
00013   RandomEngineStates::~RandomEngineStates() {
00014   }
00015 
00016   void
00017   RandomEngineStates::getRandomEngineStates(std::vector<RandomEngineState> & states) const {
00018 
00019     // First check for data corruption so that the following code
00020     // does not encounter out of range errors.
00021     bool corrupt = false;
00022 
00023     if (moduleLabels_.size() != seedLengths_.size()) corrupt = true;
00024     if (moduleLabels_.size() != stateLengths_.size()) corrupt = true;
00025 
00026     unsigned int sum = 0U;
00027     for (std::vector<unsigned>::const_iterator i = seedLengths_.begin(),
00028                                             iEnd = seedLengths_.end();
00029          i != iEnd; ++i) {
00030       sum += *i;
00031     }
00032     if (sum != seedVectors_.size()) corrupt = true;
00033 
00034     sum = 0U;
00035     for (std::vector<unsigned>::const_iterator i = stateLengths_.begin(),
00036                                             iEnd = stateLengths_.end();
00037          i != iEnd; ++i) {
00038       sum += *i;
00039     }
00040     if (sum != stateVectors_.size()) corrupt = true;
00041 
00042     if (corrupt) {
00043       throw edm::Exception(errors::EventCorruption)
00044         << "RandomEngineStates data is corrupted.\n";
00045     }
00046 
00047     // Done with error checks.  Now do the work.
00048 
00049     std::vector<unsigned>::const_iterator seedLength = seedLengths_.begin();
00050     std::vector<unsigned>::const_iterator seedBegin = seedVectors_.begin();
00051     std::vector<unsigned>::const_iterator seedEnd = seedVectors_.begin();
00052 
00053     std::vector<unsigned>::const_iterator stateLength = stateLengths_.begin();
00054     std::vector<unsigned>::const_iterator stateBegin = stateVectors_.begin();
00055     std::vector<unsigned>::const_iterator stateEnd = stateVectors_.begin();
00056 
00057     for (std::vector<std::string>::const_iterator label = moduleLabels_.begin(),
00058                                                labelEnd = moduleLabels_.end();
00059          label != labelEnd;
00060          ++label, ++seedLength, ++stateLength) {
00061 
00062       seedBegin = seedEnd;
00063       seedEnd += *seedLength;
00064 
00065       stateBegin = stateEnd;
00066       stateEnd += *stateLength;
00067 
00068       RandomEngineState randomEngineState;
00069       randomEngineState.setLabel(*label);
00070       std::vector<RandomEngineState>::iterator state = 
00071         std::lower_bound(states.begin(), states.end(), randomEngineState);
00072 
00073       if (state != states.end() && *label == state->getLabel()) {
00074         if (*seedLength != state->getSeed().size() ||
00075             *stateLength != state->getState().size()) {
00076           throw edm::Exception(edm::errors::Configuration)
00077             << "When attempting to replay processing with the RandomNumberGeneratorService,\n"
00078             << "the engine type for each module must be the same in the replay configuration\n"
00079             << "and the original configuration.  If this is not the problem, then the data\n"
00080             << "is somehow corrupted or there is a bug because the vector in the data containing\n"
00081             << "the seeds or engine state is the incorrect size for the type of random engine.\n";
00082         }
00083 
00084         state->clearSeedVector();
00085         state->reserveSeedVector(*seedLength);
00086         for (std::vector<unsigned int>::const_iterator i = seedBegin;
00087              i != seedEnd; ++i) {
00088           state->push_back_seedVector(*i);
00089         }
00090 
00091         state->clearStateVector();
00092         state->reserveStateVector(*stateLength);
00093         for (std::vector<unsigned int>::const_iterator i = stateBegin;
00094              i != stateEnd; ++i) {
00095           state->push_back_stateVector(*i);
00096         }
00097       }
00098     }
00099   }
00100 
00101 
00102   void
00103   RandomEngineStates::setRandomEngineStates(std::vector<RandomEngineState> const& states) {
00104 
00105     moduleLabels_.resize(states.size());
00106     seedLengths_.resize(states.size());
00107     seedVectors_.clear();
00108     stateLengths_.resize(states.size());
00109     stateVectors_.clear();
00110 
00111     std::vector<std::string>::iterator label = moduleLabels_.begin();
00112     std::vector<unsigned>::iterator seedLength = seedLengths_.begin();
00113     std::vector<unsigned>::iterator stateLength = stateLengths_.begin();
00114 
00115 
00116     for (std::vector<RandomEngineState>::const_iterator state = states.begin(),
00117                                                          iEnd = states.end();
00118          state != iEnd; ++state, ++label, ++seedLength, ++stateLength) {
00119 
00120       *label = state->getLabel();
00121 
00122       std::vector<uint32_t> const& seedVector = state->getSeed();
00123       *seedLength = seedVector.size();
00124 
00125       for (std::vector<uint32_t>::const_iterator j = seedVector.begin(),
00126                                               jEnd = seedVector.end();
00127            j != jEnd; ++j) {
00128         seedVectors_.push_back(*j);
00129       }
00130 
00131       std::vector<uint32_t> const& stateVector = state->getState();
00132       *stateLength = stateVector.size();
00133 
00134       for (std::vector<uint32_t>::const_iterator j = stateVector.begin(),
00135                                               jEnd = stateVector.end();
00136            j != jEnd; ++j) {
00137         stateVectors_.push_back(*j);
00138       }
00139     }
00140   }
00141 
00142   bool
00143   RandomEngineStates::isProductEqual(RandomEngineStates const& randomEngineStates) const {
00144     if (moduleLabels_ == randomEngineStates.moduleLabels_ &&
00145         seedLengths_ == randomEngineStates.seedLengths_ &&
00146         seedVectors_ == randomEngineStates.seedVectors_ &&
00147         stateLengths_ == randomEngineStates.stateLengths_ &&
00148         stateVectors_ == randomEngineStates.stateVectors_) {
00149       return true;
00150     }
00151     return false;
00152   }
00153 }