CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/Mixing/Base/src/PileUp.cc

Go to the documentation of this file.
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 #include "CLHEP/Random/RandFlat.h"
00014 
00015 #include "TRandom.h"
00016 #include "TFile.h"
00017 #include "TH1F.h"
00018 
00019 #include <algorithm>
00020 
00021 namespace edm {
00022   PileUp::PileUp(ParameterSet const& pset, int const minb, int const maxb, double averageNumber, TH1F * const histo, const bool playback) :
00023     type_(pset.getParameter<std::string>("type")),
00024     minBunch_(minb),
00025     maxBunch_(maxb),
00026     averageNumber_(averageNumber),
00027     intAverage_(static_cast<int>(averageNumber)),
00028     histo_(histo),
00029     histoDistribution_(type_ == "histo"),
00030     probFunctionDistribution_(type_ == "probFunction"),
00031     poisson_(type_ == "poisson"),
00032     fixed_(type_ == "fixed"),
00033     none_(type_ == "none"),
00034     input_(VectorInputSourceFactory::get()->makeVectorInputSource(pset, InputSourceDescription()).release()),
00035     poissonDistribution_(0),
00036     playback_(playback),
00037     sequential_(pset.getUntrackedParameter<bool>("sequential", false)),
00038     seed_(pset.getParameter<edm::ParameterSet>("nbPileupEvents").getUntrackedParameter<int>("seed",1234))
00039    {
00040 
00041     
00042     edm::Service<edm::RandomNumberGenerator> rng;
00043     if (!rng.isAvailable()) {
00044       throw cms::Exception("Configuration")
00045         << "PileUp requires the RandomNumberGeneratorService\n"
00046         "which is not present in the configuration file.  You must add the service\n"
00047         "in the configuration file or remove the modules that require it.";
00048     }
00049     
00050     CLHEP::HepRandomEngine& engine = rng->getEngine();
00051     poissonDistribution_ = new CLHEP::RandPoissonQ(engine, averageNumber_);
00052     
00053     // Get seed for the case when using user histogram or probability function
00054     if (histoDistribution_ || probFunctionDistribution_){ 
00055       gRandom->SetSeed(seed_);
00056       LogInfo("MixingModule") << " Change seed for " << type_ << " mode. The seed is set to " << seed_;
00057     } 
00058      
00059         
00060     if (!(histoDistribution_ || probFunctionDistribution_ || poisson_ || fixed_ || none_)) {
00061       throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00062         << "'type' parameter (a string) has a value of '" << type_ << "'.\n"
00063         << "Legal values are 'poisson', 'fixed', or 'none'\n";
00064     }
00065 
00066     manage_OOT_ = pset.getUntrackedParameter<bool>("manage_OOT", false);
00067 
00068     if(manage_OOT_) { // figure out what the parameters are
00069 
00070       if (playback_) throw cms::Exception("Illegal parameter clash","PileUp::PileUp(ParameterSet const& pset)")
00071         << " manage_OOT option not allowed with playback ";
00072 
00073       std::string OOT_type = pset.getUntrackedParameter<std::string>("OOT_type");
00074 
00075       if(OOT_type == "Poisson" || OOT_type == "poisson") {
00076         poisson_OOT_ = true;
00077         poissonDistr_OOT_ = new CLHEP::RandPoisson(engine);
00078       }
00079       else if(OOT_type == "Fixed" || OOT_type == "fixed") {
00080         fixed_OOT_ = true;
00081         // read back the fixed number requested out-of-time
00082         intFixed_OOT_ = pset.getUntrackedParameter<int>("intFixed_OOT", -1);
00083         if(intFixed_OOT_ < 0) {
00084           throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)") 
00085             << " Fixed out-of-time pileup requested, but no fixed value given ";
00086         }
00087       }
00088       else {
00089         throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00090           << "'OOT_type' parameter (a string) has a value of '" << OOT_type << "'.\n"
00091           << "Legal values are 'poisson' or 'fixed'\n";
00092       }
00093       edm::LogInfo("MixingModule") <<" Out-of-time pileup will be generated with a " << OOT_type << " distribution. " ;
00094     }
00095     
00096   }
00097 
00098   PileUp::~PileUp() {
00099     delete poissonDistribution_;
00100   }
00101 
00102   void
00103   PileUp::readPileUp(std::vector<EventPrincipalVector> & result,std::vector<std::vector<edm::EventID> > &ids) {
00104 
00105     // set up vector of event counts for each bunch crossing ahead of time, so that we can
00106     // allow for an arbitrary distribution for out-of-time vs. in-time pileup
00107 
00108     std::vector<int> nint;
00109 
00110     // if we are managing the distribution of out-of-time pileup separately, select the distribution for bunch
00111     // crossing zero first, save it for later.
00112 
00113     int nzero_crossing = -1;
00114 
00115     if(manage_OOT_) {
00116       if (none_){
00117         nzero_crossing = 0;
00118       }else if (poisson_){
00119         nzero_crossing =  poissonDistribution_->fire() ;
00120       }else if (fixed_){
00121         nzero_crossing =  intAverage_ ;
00122       }else if (histoDistribution_ || probFunctionDistribution_){
00123         double d = histo_->GetRandom();
00124         //n = (int) floor(d + 0.5);  // incorrect for bins with integer edges
00125         nzero_crossing =  int(d);
00126       }
00127     }
00128             
00129     for (int i = minBunch_; i <= maxBunch_; ++i) {
00130       
00131       if (playback_){
00132         nint.push_back( ids[i-minBunch_].size() );
00133       //} else if (sequential_) {  // just read many sequentially... why specify?
00134       // For now, the use case for sequential read reads only one event at a time.
00135       // nint.push_back( 1 );
00136       } 
00137       else if(manage_OOT_) {
00138         if(i==0 && !poisson_OOT_) nint.push_back(nzero_crossing);
00139         else{
00140           if(poisson_OOT_) {
00141             nint.push_back( poissonDistr_OOT_->fire(float(nzero_crossing)) );
00142           }
00143           else {
00144             nint.push_back( intFixed_OOT_ );
00145           }       
00146         }
00147       } 
00148       else {    
00149         if (none_){
00150           nint.push_back(0);
00151         }else if (poisson_){
00152           nint.push_back( poissonDistribution_->fire() );
00153         }else if (fixed_){
00154           nint.push_back( intAverage_ );
00155         }else if (histoDistribution_ || probFunctionDistribution_){
00156           double d = histo_->GetRandom();
00157           //n = (int) floor(d + 0.5);  // incorrect for bins with integer edges
00158           nint.push_back( int(d) );
00159         }
00160 
00161       }
00162     }
00163 
00164     int n=0;
00165       
00166     for (int i = minBunch_; i <= maxBunch_; ++i) {
00167       EventPrincipalVector eventVector;
00168 
00169       n = nint[i-minBunch_];
00170 
00171       eventVector.reserve(n);
00172       while (n > 0) {
00173         EventPrincipalVector oneResult;
00174         oneResult.reserve(n);
00175         std::vector<edm::EventID> oneResultPlayback;
00176         oneResultPlayback.reserve(n);
00177         if (playback_)   {
00178           input_->readManySpecified(ids[i-minBunch_],oneResult);  // playback
00179         } else if (sequential_) {
00180           unsigned int file;
00181           input_->readManySequential(n, oneResult, file);  // sequential
00182           for (int j=0;j<(int)oneResult.size();j++){
00183             oneResultPlayback.push_back(oneResult[j]->id());
00184           }
00185           ids[i-minBunch_] = oneResultPlayback;
00186         } else  {
00187           unsigned int file;   //FIXME: need unsigned filenr?
00188           input_->readManyRandom(n, oneResult,file);     //no playback
00189           for (int j=0;j<(int)oneResult.size();j++){
00190             oneResultPlayback.push_back(oneResult[j]->id());
00191           }
00192           ids[i-minBunch_] = oneResultPlayback;
00193         }
00194         LogDebug("readPileup") << "READ: " << oneResult.size();
00195         std::copy(oneResult.begin(), oneResult.end(), std::back_inserter(eventVector));
00196         n -= oneResult.size();
00197       }
00198       result.push_back(eventVector);
00199     }
00200   }
00201 
00202 } //namespace edm