CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/Mixing/Base/src/BMixingModule.cc

Go to the documentation of this file.
00001 // File: BMixingModule.cc
00002 // Description:  see BMixingModule.h
00003 // Author:  Ursula Berthon, LLR Palaiseau, Bill Tanenbaum
00004 //
00005 //--------------------------------------------
00006 
00007 #include "Mixing/Base/interface/BMixingModule.h"
00008 #include "FWCore/Utilities/interface/GetPassID.h"
00009 #include "FWCore/Version/interface/GetReleaseVersion.h"
00010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00011 #include "FWCore/Framework/interface/Event.h"
00012 #include "FWCore/Framework/interface/EventSetup.h"
00013 #include "FWCore/Framework/interface/EventPrincipal.h"
00014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00015 #include "DataFormats/Common/interface/Handle.h"
00016 
00017 #include "TFile.h"
00018 #include "TH1F.h"
00019 
00020 using namespace std;
00021 
00022 int edm::BMixingModule::vertexoffset = 0;
00023 const unsigned int edm::BMixingModule::maxNbSources_ =4;
00024 
00025 namespace
00026 {
00027   boost::shared_ptr<edm::PileUp>
00028   maybeMakePileUp(edm::ParameterSet const& ps,std::string sourceName, const int minb, const int maxb, const bool playback)
00029   { 
00030     boost::shared_ptr<edm::PileUp> pileup; // value to be returned
00031     // Make sure we have a parameter named 'sourceName'
00032     if (ps.exists(sourceName))
00033       {
00034         // We have the parameter
00035         // and if we have either averageNumber or cfg by luminosity... make the PileUp
00036         double averageNumber;
00037         std::string histoFileName=" ";
00038         std::string histoName =" ";
00039         TH1F * h = new TH1F("h","h",10,0,10);
00040         vector<int> dataProbFunctionVar;
00041         vector<double> dataProb;
00042 
00043         
00044         const edm::ParameterSet & psin=ps.getParameter<edm::ParameterSet>(sourceName);
00045         std::string type_=psin.getParameter<std::string>("type");
00046         if (ps.exists("readDB") && ps.getParameter<bool>("readDB")){
00047           //in case of DB access, do not try to load anything from the PSet, but wait for beginRun.
00048           edm::LogError("BMixingModule")<<"Will read from DB: reset to a dummy PileUp object.";
00049           pileup.reset(new edm::PileUp(psin,0,0,playback));
00050           return pileup;
00051         }
00052         if (type_!="none"){
00053           if (psin.exists("nbPileupEvents")) {
00054             edm::ParameterSet psin_average=psin.getParameter<edm::ParameterSet>("nbPileupEvents");
00055             if (psin_average.exists("averageNumber"))
00056               {
00057                 averageNumber=psin_average.getParameter<double>("averageNumber");
00058                 pileup.reset(new edm::PileUp(psin,averageNumber,h,playback));
00059                 edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with averageNumber "<<averageNumber;
00060               }
00061             else if (psin_average.exists("fileName") && psin_average.exists("histoName")) {
00062                 std::string histoFileName = psin_average.getUntrackedParameter<std::string>("fileName");
00063                 std::string histoName = psin_average.getUntrackedParameter<std::string>("histoName");
00064                                                 
00065                 TFile *infile = new TFile(histoFileName.c_str());
00066                 TH1F *h = (TH1F*)infile->Get(histoName.c_str());
00067                 
00068                 // Check if the histogram exists           
00069                 if (!h) {
00070                   throw cms::Exception("HistogramNotFound") << " Could not find the histogram " << histoName 
00071                                                             << "in the file " << histoFileName << "." << std::endl;
00072                 }else{
00073                   edm::LogInfo("MixingModule") << "Open a root file " << histoFileName << " containing the probability distribution histogram " << histoName << std::endl;
00074                   edm::LogInfo("MixingModule") << "The PileUp number to be added will be chosen randomly from this histogram" << std::endl;
00075                 }
00076                 
00077                 // Check if the histogram is normalized
00078                 if (((h->Integral() - 1) > 1.0e-02) && ((h->Integral() - 1) < -1.0e-02)) throw cms::Exception("BadHistoDistribution") << "The histogram should be normalized!" << std::endl;
00079                                                 
00080                 // Get the averageNumber from the histo 
00081                 averageNumber = h->GetMean();
00082                 
00083                 pileup.reset(new edm::PileUp(psin,averageNumber,h,playback));
00084                 edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with averageNumber "<<averageNumber;
00085               
00086               }
00087             else if (psin_average.exists("probFunctionVariable") && psin_average.exists("probValue") && psin_average.exists("histoFileName"))
00088               {
00089                 if (type_!="probFunction") {
00090                   edm::LogError("MisConfiguration")<<"type is set to: "<<type_<<" while parameters implies probFunction; changing.";
00091                   type_="probFunction";
00092                 }
00093 
00094                 dataProbFunctionVar = psin_average.getParameter<vector<int> >("probFunctionVariable");
00095                 dataProb = psin_average.getParameter<vector<double> >("probValue");
00096                 histoFileName = psin_average.getUntrackedParameter<std::string>("histoFileName"); 
00097                                                         
00098                 int varSize = (int) dataProbFunctionVar.size();
00099                 int probSize = (int) dataProb.size();
00100                 
00101                 if ((dataProbFunctionVar[0] != 0) || (dataProbFunctionVar[varSize - 1] != (varSize - 1))) 
00102                   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." << endl;
00103                 
00104                 // Complete the vector containing the probability  function data
00105                 // with the values "0"
00106                 if (probSize < varSize){
00107                   edm::LogInfo("MixingModule") << " The probability function data will be completed with " <<(varSize - probSize)  <<" values 0."; 
00108                   
00109                   for (int i=0; i<(varSize - probSize); i++) dataProb.push_back(0);
00110                   
00111                   probSize = dataProb.size();
00112                   edm::LogInfo("MixingModule") << " The number of the P(x) data set after adding the values 0 is " << probSize;
00113                 }
00114                                         
00115                 // Create an histogram with the data from the probability function provided by the user           
00116                 int xmin = (int) dataProbFunctionVar[0];
00117                 int xmax = (int) dataProbFunctionVar[varSize-1]+1;  // need upper edge to be one beyond last value
00118                 int numBins = varSize;
00119                 
00120                 edm::LogInfo("MixingModule") << "An histogram will be created with " << numBins << " bins in the range ("<< xmin << "," << xmax << ")." << std::endl;
00121                                 
00122                 TH1F *hprob = new TH1F("h","Histo from the user's probability function",numBins,xmin,xmax); 
00123                 
00124                 LogDebug("MixingModule") << "Filling histogram with the following data:" << std::endl;
00125                 
00126                 for (int j=0; j < numBins ; j++){
00127                   LogDebug("MixingModule") << " x = " << dataProbFunctionVar[j ]<< " P(x) = " << dataProb[j];
00128                   hprob->Fill(dataProbFunctionVar[j]+0.5,dataProb[j]); // assuming integer values for the bins, fill bin centers, not edges 
00129                 }
00130                                 
00131                 // Check if the histogram is normalized
00132                 if ( ((hprob->Integral() - 1) > 1.0e-02) && ((hprob->Integral() - 1) < -1.0e-02)){ 
00133                   throw cms::Exception("BadProbFunction") << "The probability function should be normalized!!! " << endl;
00134                 }
00135                 
00136                 averageNumber = hprob->GetMean();
00137                                 
00138                 // Write the created histogram into a root file
00139                 edm::LogInfo("MixingModule") << " The histogram created from the x, P(x) values will be written into the root file " << histoFileName; 
00140                 
00141                 TFile * outfile = new TFile(histoFileName.c_str(),"RECREATE");
00142                 hprob->Write();
00143                 outfile->Write();
00144                 outfile->Close();
00145                 outfile->Delete();              
00146                 
00147                 pileup.reset(new edm::PileUp(psin,averageNumber,hprob,playback));
00148                 edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with averageNumber "<<averageNumber;
00149                 
00150               } 
00151             //special for pileup input
00152             else if (sourceName=="input" && psin_average.exists("Lumi") && psin_average.exists("sigmaInel")) {
00153               averageNumber=psin_average.getParameter<double>("Lumi")*psin_average.getParameter<double>("sigmaInel")*ps.getParameter<int>("bunchspace")/1000*3564./2808.;  //FIXME
00154               pileup.reset(new
00155               edm::PileUp(psin,averageNumber,h,playback));
00156               edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with minBunch,maxBunch "<<minb<<" "<<maxb;
00157               edm::LogInfo("MixingModule")<<" Luminosity configuration, average number used is "<<averageNumber;
00158             }
00159           }
00160         }
00161       }
00162     return pileup;
00163   }
00164 }
00165 
00166 namespace edm {
00167 
00168   // Constructor 
00169   BMixingModule::BMixingModule(const edm::ParameterSet& pset) :
00170     bunchSpace_(pset.getParameter<int>("bunchspace")),
00171     minBunch_((pset.getParameter<int>("minBunch")*25)/pset.getParameter<int>("bunchspace")),
00172     maxBunch_((pset.getParameter<int>("maxBunch")*25)/pset.getParameter<int>("bunchspace")),
00173     mixProdStep1_(pset.getParameter<bool>("mixProdStep1")),
00174     mixProdStep2_(pset.getParameter<bool>("mixProdStep2")),
00175     readDB_(false)
00176   { 
00177     if (pset.exists("readDB"))      readDB_=pset.getParameter<bool>("readDB");
00178 
00179     playback_=pset.getUntrackedParameter<bool>("playback",false);
00180 
00181     if (playback_) {
00182       //this could be explicitely checked
00183       LogInfo("MixingModule") <<" ATTENTION:Mixing will be done in playback mode! \n"
00184                               <<" ATTENTION:Mixing Configuration must be the same as for the original mixing!";
00185     }
00186 
00187     // Just for debugging print out.
00188     sourceNames_.push_back("input");
00189     sourceNames_.push_back("cosmics");
00190     sourceNames_.push_back("beamhalo_plus");
00191     sourceNames_.push_back("beamhalo_minus");
00192 
00193     for (size_t makeIdx = 0; makeIdx < maxNbSources_; makeIdx++ ) {
00194       inputSources_.push_back(maybeMakePileUp(pset,sourceNames_[makeIdx],
00195                                               minBunch_,maxBunch_,playback_));
00196       if (inputSources_.back()) inputSources_.back()->input(makeIdx);
00197     }
00198   }
00199 
00200   // Virtual destructor needed.
00201   BMixingModule::~BMixingModule() {;}
00202 
00203   // method call at begin run/lumi to reload the mixing configuration
00204   void BMixingModule::beginLuminosityBlock(edm::LuminosityBlock&, edm::EventSetup const&setup){
00205     update(setup);
00206   }
00207   void BMixingModule::beginRun(edm::Run & r, const edm::EventSetup & setup){
00208     update(setup);
00209   }
00210 
00211   void BMixingModule::update(const edm::EventSetup & setup){
00212     if (readDB_ && parameterWatcher_.check(setup)){
00213       for (size_t makeIdx = 0; makeIdx < maxNbSources_; makeIdx++ ) {
00214         if (inputSources_[makeIdx]) inputSources_[makeIdx]->reload(setup);
00215       }
00216       reload(setup);
00217     }
00218   }
00219 
00220   // Functions that get called by framework every event
00221   void BMixingModule::produce(edm::Event& e, const edm::EventSetup& setup) { 
00222 
00223     // Check if the signal is present in the root file 
00224     // for all the objects we want to mix
00225     checkSignal(e);
00226     
00227     // Create EDProduct
00228     createnewEDProduct();
00229 
00230     // Add signals
00231     if (!mixProdStep1_){ 
00232       addSignals(e,setup);
00233     }
00234 
00235     doPileUp(e,setup);
00236 
00237     // Put output into event (here only playback info)
00238     put(e,setup);
00239   }
00240 
00241   void BMixingModule::dropUnwantedBranches(std::vector<std::string> const& wantedBranches) {
00242     for (size_t dropIdx=0; dropIdx<maxNbSources_; dropIdx++ ) {
00243       if( inputSources_[dropIdx] ) inputSources_[dropIdx]->dropUnwantedBranches(wantedBranches);
00244     }
00245   }
00246 
00247   void BMixingModule::endJob() {
00248     for (size_t endIdx=0; endIdx<maxNbSources_; endIdx++ ) {
00249       if( inputSources_[endIdx] ) inputSources_[endIdx]->endJob();
00250     }
00251   }
00252 
00253 } //edm