00001 #include "Mixing/Base/interface/PileUp.h"
00002 #include "FWCore/Framework/interface/EventPrincipal.h"
00003 #include "FWCore/Framework/interface/InputSourceDescription.h"
00004 #include "FWCore/Sources/interface/VectorInputSourceFactory.h"
00005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "FWCore/Utilities/interface/Exception.h"
00008
00009 #include "FWCore/ServiceRegistry/interface/Service.h"
00010 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00011
00012 #include "CLHEP/Random/RandPoissonQ.h"
00013
00014 #include <algorithm>
00015
00016 namespace edm {
00017 PileUp::PileUp(ParameterSet const& pset, int const minb, int const maxb, double averageNumber, const bool playback) :
00018 type_(pset.getParameter<std::string>("type")),
00019 minBunch_(minb),
00020 maxBunch_(maxb),
00021 averageNumber_(averageNumber),
00022 intAverage_(static_cast<int>(averageNumber)),
00023 poisson_(type_ == "poisson"),
00024 fixed_(type_ == "fixed"),
00025 none_(type_ == "none"),
00026 input_(VectorInputSourceFactory::get()->makeVectorInputSource(pset, InputSourceDescription()).release()),
00027 poissonDistribution_(0),
00028 playback_(playback)
00029 {
00030
00031 edm::Service<edm::RandomNumberGenerator> rng;
00032 if (!rng.isAvailable()) {
00033 throw cms::Exception("Configuration")
00034 << "PileUp requires the RandomNumberGeneratorService\n"
00035 "which is not present in the configuration file. You must add the service\n"
00036 "in the configuration file or remove the modules that require it.";
00037 }
00038
00039 CLHEP::HepRandomEngine& engine = rng->getEngine();
00040
00041 poissonDistribution_ = new CLHEP::RandPoissonQ(engine, averageNumber_);
00042
00043 if (!(poisson_ || fixed_ || none_)) {
00044 throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00045 << "'type' parameter (a string) has a value of '" << type_ << "'.\n"
00046 << "Legal values are 'poisson', 'fixed', or 'none'\n";
00047 }
00048 }
00049
00050 PileUp::~PileUp() {
00051 delete poissonDistribution_;
00052 }
00053
00054 void
00055 PileUp::readPileUp(std::vector<EventPrincipalVector> & result,std::vector<edm::EventID> &ids, std::vector<int> &fileNrs,std::vector<unsigned int> & nrEvents) {
00056 for (int i = minBunch_; i <= maxBunch_; ++i) {
00057 EventPrincipalVector eventVector;
00058 int n;
00059
00060 if (!playback_){
00061 n = (none_ ? 0 : (poisson_ ? poissonDistribution_->fire() : intAverage_));
00062 nrEvents[i-minBunch_]=n;
00063 }else {
00064 n=nrEvents[i-minBunch_];
00065 }
00066 eventVector.reserve(n);
00067 while (n > 0) {
00068 EventPrincipalVector oneResult;
00069 oneResult.reserve(n);
00070 if (!playback_) {
00071 unsigned int file;
00072 input_->readManyRandom(n, oneResult,file);
00073 ids[i-minBunch_]=oneResult[0]->id();
00074 fileNrs[i-minBunch_]=file;
00075 } else {
00076 input_->readMany(n, oneResult,ids[i-minBunch_],fileNrs[i-minBunch_]);
00077 }
00078 LogDebug("readPileup") << "READ: " << oneResult.size();
00079 std::copy(oneResult.begin(), oneResult.end(), std::back_inserter(eventVector));
00080 n -= oneResult.size();
00081 }
00082 result.push_back(eventVector);
00083 }
00084 }
00085 }