CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/Mixing/Base/src/PileUp.cc

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