CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/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 "FWCore/Framework/interface/ESHandle.h"
00013 #include "FWCore/Framework/interface/EventSetup.h"
00014 #include "CondFormats/DataRecord/interface/MixingRcd.h"
00015 #include "CondFormats/RunInfo/interface/MixingModuleConfig.h"
00016 
00017 #include <algorithm>
00018 
00019 namespace edm {
00020   PileUp::PileUp(ParameterSet const& pset, double averageNumber, TH1F * const histo, const bool playback) :
00021     type_(pset.getParameter<std::string>("type")),
00022     averageNumber_(averageNumber),
00023     intAverage_(static_cast<int>(averageNumber)),
00024     histo_(histo),
00025     histoDistribution_(type_ == "histo"),
00026     probFunctionDistribution_(type_ == "probFunction"),
00027     poisson_(type_ == "poisson"),
00028     fixed_(type_ == "fixed"),
00029     none_(type_ == "none"),
00030     input_(VectorInputSourceFactory::get()->makeVectorInputSource(pset, InputSourceDescription()).release()),
00031     poissonDistribution_(0),
00032     poissonDistr_OOT_(0),
00033     playback_(playback),
00034     sequential_(pset.getUntrackedParameter<bool>("sequential", false)),
00035     samelumi_(pset.getUntrackedParameter<bool>("sameLumiBlock", false)),
00036     seed_(0)
00037    {
00038      if (pset.exists("nbPileupEvents"))
00039        seed_=pset.getParameter<edm::ParameterSet>("nbPileupEvents").getUntrackedParameter<int>("seed",0);
00040 
00041     bool DB=type_=="readDB";
00042 
00043     edm::Service<edm::RandomNumberGenerator> rng;
00044     if (!rng.isAvailable()) {
00045       throw cms::Exception("Configuration")
00046         << "PileUp requires the RandomNumberGeneratorService\n"
00047         "which is not present in the configuration file.  You must add the service\n"
00048         "in the configuration file or remove the modules that require it.";
00049     }
00050     
00051     CLHEP::HepRandomEngine& engine = rng->getEngine();
00052     poissonDistribution_ = new CLHEP::RandPoissonQ(engine, averageNumber_);
00053     
00054     // Get seed for the case when using user histogram or probability function
00055     if (histoDistribution_ || probFunctionDistribution_ || DB){ 
00056       if(seed_ !=0) {
00057         gRandom->SetSeed(seed_);
00058         LogInfo("MixingModule") << " Change seed for " << type_ << " mode. The seed is set to " << seed_;
00059       }
00060       else {
00061         gRandom->SetSeed(engine.getSeed());
00062       }
00063     } 
00064      
00065         
00066     if (!(histoDistribution_ || probFunctionDistribution_ || poisson_ || fixed_ || none_) && !DB) {
00067       throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00068         << "'type' parameter (a string) has a value of '" << type_ << "'.\n"
00069         << "Legal values are 'poisson', 'fixed', or 'none'\n";
00070     }
00071 
00072     if (!DB){
00073     manage_OOT_ = pset.getUntrackedParameter<bool>("manage_OOT", false);
00074 
00075     // Check for string describing special processing.  Add these here for individual cases
00076 
00077     PU_Study_ = false;
00078     Study_type_ = "";
00079 
00080     Study_type_ = pset.getUntrackedParameter<std::string>("Special_Pileup_Studies", "");
00081 
00082     if(Study_type_ == "Fixed_ITPU_Vary_OOTPU") {
00083 
00084       PU_Study_ = true;
00085       intFixed_ITPU_ = pset.getUntrackedParameter<int>("intFixed_ITPU", 0);
00086 
00087     }
00088 
00089     if(manage_OOT_) { // figure out what the parameters are
00090 
00091       //      if (playback_) throw cms::Exception("Illegal parameter clash","PileUp::PileUp(ParameterSet const& pset)")
00092       // << " manage_OOT option not allowed with playback ";
00093 
00094       std::string OOT_type = pset.getUntrackedParameter<std::string>("OOT_type");
00095 
00096       if(OOT_type == "Poisson" || OOT_type == "poisson") {
00097         poisson_OOT_ = true;
00098         poissonDistr_OOT_ = new CLHEP::RandPoisson(engine);
00099       }
00100       else if(OOT_type == "Fixed" || OOT_type == "fixed") {
00101         fixed_OOT_ = true;
00102         // read back the fixed number requested out-of-time
00103         intFixed_OOT_ = pset.getUntrackedParameter<int>("intFixed_OOT", -1);
00104         if(intFixed_OOT_ < 0) {
00105           throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)") 
00106             << " Fixed out-of-time pileup requested, but no fixed value given ";
00107         }
00108       }
00109       else {
00110         throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00111           << "'OOT_type' parameter (a string) has a value of '" << OOT_type << "'.\n"
00112           << "Legal values are 'poisson' or 'fixed'\n";
00113       }
00114       edm::LogInfo("MixingModule") <<" Out-of-time pileup will be generated with a " << OOT_type << " distribution. " ;
00115     }
00116     }
00117     
00118   }
00119 
00120   void PileUp::reload(const edm::EventSetup & setup){
00121     //get the required parameters from DB.
00122     edm::ESHandle<MixingModuleConfig> configM;
00123     setup.get<MixingRcd>().get(configM);
00124 
00125     const MixingInputConfig & config=configM->config(inputType_);
00126 
00127     //get the type
00128     type_=config.type();
00129     //set booleans
00130     histoDistribution_=type_ == "histo";
00131     probFunctionDistribution_=type_ == "probFunction";
00132     poisson_=type_ == "poisson";
00133     fixed_=type_ == "fixed";
00134     none_=type_ == "none";
00135     
00136     if (histoDistribution_) edm::LogError("MisConfiguration")<<"type histo cannot be reloaded from DB, yet";
00137     
00138     if (fixed_){
00139       averageNumber_=averageNumber();
00140     }
00141     else if (poisson_)
00142       {
00143         averageNumber_=config.averageNumber();
00144         edm::Service<edm::RandomNumberGenerator> rng; 
00145         CLHEP::HepRandomEngine& engine = rng->getEngine();            
00146         delete poissonDistribution_;
00147         poissonDistribution_ = new CLHEP::RandPoissonQ(engine, averageNumber_);  
00148       }
00149     else if (probFunctionDistribution_)
00150       {
00151         //need to reload the histogram from DB
00152         const std::vector<int> & dataProbFunctionVar = config.probFunctionVariable();
00153         std::vector<double> dataProb = config.probValue();
00154         
00155         int varSize = (int) dataProbFunctionVar.size();
00156         int probSize = (int) dataProb.size();
00157                 
00158         if ((dataProbFunctionVar[0] != 0) || (dataProbFunctionVar[varSize - 1] != (varSize - 1))) 
00159           throw cms::Exception("BadProbFunction") << "Please, check the variables of the probability function! The first variable should be 0 and the difference between two variables should be 1." << std::endl;
00160                 
00161         // Complete the vector containing the probability  function data
00162         // with the values "0"
00163         if (probSize < varSize){
00164           edm::LogWarning("MixingModule") << " The probability function data will be completed with " <<(varSize - probSize)  <<" values 0.";
00165           
00166           for (int i=0; i<(varSize - probSize); i++) dataProb.push_back(0);
00167           
00168           probSize = dataProb.size();
00169           edm::LogInfo("MixingModule") << " The number of the P(x) data set after adding the values 0 is " << probSize;
00170         }
00171         
00172         // Create an histogram with the data from the probability function provided by the user           
00173         int xmin = (int) dataProbFunctionVar[0];
00174         int xmax = (int) dataProbFunctionVar[varSize-1]+1;  // need upper edge to be one beyond last value
00175         int numBins = varSize;
00176         
00177         edm::LogInfo("MixingModule") << "An histogram will be created with " << numBins << " bins in the range ("<< xmin << "," << xmax << ")." << std::endl;
00178 
00179         if (histo_) delete histo_;
00180         histo_ = new TH1F("h","Histo from the user's probability function",numBins,xmin,xmax); 
00181         
00182         LogDebug("MixingModule") << "Filling histogram with the following data:" << std::endl;
00183         
00184         for (int j=0; j < numBins ; j++){
00185           LogDebug("MixingModule") << " x = " << dataProbFunctionVar[j ]<< " P(x) = " << dataProb[j];
00186           histo_->Fill(dataProbFunctionVar[j]+0.5,dataProb[j]); // assuming integer values for the bins, fill bin centers, not edges 
00187         }
00188         
00189         // Check if the histogram is normalized
00190         if ( ((histo_->Integral() - 1) > 1.0e-02) && ((histo_->Integral() - 1) < -1.0e-02)){ 
00191           throw cms::Exception("BadProbFunction") << "The probability function should be normalized!!! " << std::endl;
00192         }
00193         averageNumber_=histo_->GetMean();
00194       }
00195 
00196     int oot=config.outOfTime();
00197     manage_OOT_=false;
00198     if (oot==1)
00199       {
00200         manage_OOT_=true;
00201         poisson_OOT_ = false;
00202         if (poissonDistr_OOT_){delete poissonDistr_OOT_; poissonDistr_OOT_=0; }
00203         fixed_OOT_ = true;
00204         intFixed_OOT_=config.fixedOutOfTime();
00205       }
00206     else if (oot==2)
00207       {
00208         manage_OOT_=true;
00209         poisson_OOT_ = true;
00210         fixed_OOT_ = false;
00211         if (!poissonDistr_OOT_) {
00212           //no need to trash the previous one if already there
00213           edm::Service<edm::RandomNumberGenerator> rng; 
00214           CLHEP::HepRandomEngine& engine = rng->getEngine();                      
00215           poissonDistr_OOT_ = new CLHEP::RandPoisson(engine);
00216         }
00217       }
00218 
00219     
00220   }
00221   PileUp::~PileUp() {
00222     delete poissonDistribution_;
00223     delete poissonDistr_OOT_ ;
00224   }
00225 
00226   void PileUp::CalculatePileup(int MinBunch, int MaxBunch, std::vector<int>& PileupSelection, std::vector<float>& TrueNumInteractions) {
00227 
00228     // if we are managing the distribution of out-of-time pileup separately, select the distribution for bunch
00229     // crossing zero first, save it for later.
00230 
00231     int nzero_crossing = -1;
00232     double Fnzero_crossing = -1;
00233 
00234     if(manage_OOT_) {
00235       if (none_){
00236         nzero_crossing = 0;
00237       }else if (poisson_){
00238         nzero_crossing =  poissonDistribution_->fire() ;
00239       }else if (fixed_){
00240         nzero_crossing =  intAverage_ ;
00241       }else if (histoDistribution_ || probFunctionDistribution_){
00242         double d = histo_->GetRandom();
00243         //n = (int) floor(d + 0.5);  // incorrect for bins with integer edges
00244         Fnzero_crossing =  d;
00245         nzero_crossing = int(d);
00246       }
00247 
00248     }
00249 
00250     for(int bx = MinBunch; bx < MaxBunch+1; ++bx) {
00251 
00252       if(manage_OOT_) {
00253         if(bx==0 && !poisson_OOT_) { 
00254           PileupSelection.push_back(nzero_crossing) ;
00255           TrueNumInteractions.push_back( nzero_crossing );
00256         }
00257         else{
00258           if(poisson_OOT_) {
00259             if(PU_Study_ && (Study_type_ == "Fixed_ITPU_Vary_OOTPU" ) && bx==0 ) {
00260               PileupSelection.push_back(intFixed_ITPU_) ;
00261             }
00262             else{
00263               PileupSelection.push_back(poissonDistr_OOT_->fire(Fnzero_crossing)) ;
00264             }
00265             TrueNumInteractions.push_back( Fnzero_crossing );
00266           }
00267           else {
00268             PileupSelection.push_back(intFixed_OOT_) ;
00269             TrueNumInteractions.push_back( intFixed_OOT_ );
00270           }  
00271         }
00272       }
00273       else {
00274         if (none_){
00275           PileupSelection.push_back(0);
00276           TrueNumInteractions.push_back( 0. );
00277         }else if (poisson_){
00278           PileupSelection.push_back(poissonDistribution_->fire());
00279           TrueNumInteractions.push_back( averageNumber_ );
00280         }else if (fixed_){
00281           PileupSelection.push_back(intAverage_);
00282           TrueNumInteractions.push_back( intAverage_ );
00283         }else if (histoDistribution_ || probFunctionDistribution_){
00284           double d = histo_->GetRandom();
00285           PileupSelection.push_back(int(d));
00286           TrueNumInteractions.push_back( d );
00287         }
00288       }
00289     
00290     }
00291   }
00292 
00293 
00294 } //namespace edm