CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/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",0))
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       if(seed_ !=0) {
00056         gRandom->SetSeed(seed_);
00057         LogInfo("MixingModule") << " Change seed for " << type_ << " mode. The seed is set to " << seed_;
00058       }
00059       else {
00060         gRandom->SetSeed(engine.getSeed());
00061       }
00062     } 
00063      
00064         
00065     if (!(histoDistribution_ || probFunctionDistribution_ || poisson_ || fixed_ || none_)) {
00066       throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00067         << "'type' parameter (a string) has a value of '" << type_ << "'.\n"
00068         << "Legal values are 'poisson', 'fixed', or 'none'\n";
00069     }
00070 
00071     manage_OOT_ = pset.getUntrackedParameter<bool>("manage_OOT", false);
00072 
00073     if(manage_OOT_) { // figure out what the parameters are
00074 
00075       if (playback_) throw cms::Exception("Illegal parameter clash","PileUp::PileUp(ParameterSet const& pset)")
00076         << " manage_OOT option not allowed with playback ";
00077 
00078       std::string OOT_type = pset.getUntrackedParameter<std::string>("OOT_type");
00079 
00080       if(OOT_type == "Poisson" || OOT_type == "poisson") {
00081         poisson_OOT_ = true;
00082         poissonDistr_OOT_ = new CLHEP::RandPoisson(engine);
00083       }
00084       else if(OOT_type == "Fixed" || OOT_type == "fixed") {
00085         fixed_OOT_ = true;
00086         // read back the fixed number requested out-of-time
00087         intFixed_OOT_ = pset.getUntrackedParameter<int>("intFixed_OOT", -1);
00088         if(intFixed_OOT_ < 0) {
00089           throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)") 
00090             << " Fixed out-of-time pileup requested, but no fixed value given ";
00091         }
00092       }
00093       else {
00094         throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00095           << "'OOT_type' parameter (a string) has a value of '" << OOT_type << "'.\n"
00096           << "Legal values are 'poisson' or 'fixed'\n";
00097       }
00098       edm::LogInfo("MixingModule") <<" Out-of-time pileup will be generated with a " << OOT_type << " distribution. " ;
00099     }
00100     
00101   }
00102 
00103   PileUp::~PileUp() {
00104     delete poissonDistribution_;
00105   }
00106 
00107   void
00108   PileUp::readPileUp(std::vector<EventPrincipalVector> & result,std::vector<std::vector<edm::EventID> > &ids, std::vector< float > &TrueNumInteractions ) {
00109 
00110     // set up vector of event counts for each bunch crossing ahead of time, so that we can
00111     // allow for an arbitrary distribution for out-of-time vs. in-time pileup
00112 
00113     std::vector<int> nint;
00114 
00115     // if we are managing the distribution of out-of-time pileup separately, select the distribution for bunch
00116     // crossing zero first, save it for later.
00117 
00118     int nzero_crossing = -1;
00119     double Fnzero_crossing = -1;
00120 
00121     if(manage_OOT_) {
00122       if (none_){
00123         nzero_crossing = 0;
00124       }else if (poisson_){
00125         nzero_crossing =  poissonDistribution_->fire() ;
00126       }else if (fixed_){
00127         nzero_crossing =  intAverage_ ;
00128       }else if (histoDistribution_ || probFunctionDistribution_){
00129         double d = histo_->GetRandom();
00130         //n = (int) floor(d + 0.5);  // incorrect for bins with integer edges
00131         Fnzero_crossing =  d;
00132       }
00133     }
00134             
00135     for (int i = minBunch_; i <= maxBunch_; ++i) {
00136       
00137       if (playback_){
00138         nint.push_back( ids[i-minBunch_].size() );
00139       //} else if (sequential_) {  // just read many sequentially... why specify?
00140       // For now, the use case for sequential read reads only one event at a time.
00141       // nint.push_back( 1 );
00142         TrueNumInteractions.push_back( ids[i-minBunch_].size() );
00143       } 
00144       else if(manage_OOT_) {
00145         if(i==0 && !poisson_OOT_) { 
00146           nint.push_back(nzero_crossing);
00147           TrueNumInteractions.push_back( nzero_crossing );
00148         }
00149         else{
00150           if(poisson_OOT_) {
00151             nint.push_back( poissonDistr_OOT_->fire(Fnzero_crossing) );
00152             TrueNumInteractions.push_back( Fnzero_crossing );
00153           }
00154           else {
00155             nint.push_back( intFixed_OOT_ );
00156             TrueNumInteractions.push_back( intFixed_OOT_ );
00157           }       
00158         }
00159       } 
00160       else {    
00161         if (none_){
00162           nint.push_back(0);
00163           TrueNumInteractions.push_back( 0. );
00164         }else if (poisson_){
00165           nint.push_back( poissonDistribution_->fire() );
00166           TrueNumInteractions.push_back( averageNumber_ );
00167         }else if (fixed_){
00168           nint.push_back( intAverage_ );
00169           TrueNumInteractions.push_back( intAverage_ );
00170         }else if (histoDistribution_ || probFunctionDistribution_){
00171           double d = histo_->GetRandom();
00172           //n = (int) floor(d + 0.5);  // incorrect for bins with integer edges
00173           nint.push_back( int(d) );
00174           TrueNumInteractions.push_back( d );
00175         }
00176 
00177       }
00178     }
00179 
00180     int n=0;
00181       
00182     for (int i = minBunch_; i <= maxBunch_; ++i) {
00183       EventPrincipalVector eventVector;
00184 
00185       n = nint[i-minBunch_];
00186 
00187       eventVector.reserve(n);
00188       while (n > 0) {
00189         EventPrincipalVector oneResult;
00190         oneResult.reserve(n);
00191         std::vector<edm::EventID> oneResultPlayback;
00192         oneResultPlayback.reserve(n);
00193         if (playback_)   {
00194           input_->readManySpecified(ids[i-minBunch_],oneResult);  // playback
00195         } else if (sequential_) {
00196           unsigned int file;
00197           input_->readManySequential(n, oneResult, file);  // sequential
00198           for (int j=0;j<(int)oneResult.size();j++){
00199             oneResultPlayback.push_back(oneResult[j]->id());
00200           }
00201           ids[i-minBunch_] = oneResultPlayback;
00202         } else  {
00203           unsigned int file;   //FIXME: need unsigned filenr?
00204           input_->readManyRandom(n, oneResult,file);     //no playback
00205           for (int j=0;j<(int)oneResult.size();j++){
00206             oneResultPlayback.push_back(oneResult[j]->id());
00207           }
00208           ids[i-minBunch_] = oneResultPlayback;
00209         }
00210         LogDebug("readPileup") << "READ: " << oneResult.size();
00211         std::copy(oneResult.begin(), oneResult.end(), std::back_inserter(eventVector));
00212         n -= oneResult.size();
00213       }
00214       result.push_back(eventVector);
00215     }
00216   }
00217 
00218 } //namespace edm