CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_2_9_HLT1_bphpatch4/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     vector<string> names = ps.getParameterNames();
00033     if (find(names.begin(), names.end(), sourceName)
00034         != names.end())
00035       {
00036         // We have the parameter
00037         // and if we have either averageNumber or cfg by luminosity... make the PileUp
00038         double averageNumber;
00039         std::string histoFileName=" ";
00040         std::string histoName =" ";
00041         TH1F * h = new TH1F("h","h",10,0,10);
00042         vector<int> dataProbFunctionVar;
00043         vector<double> dataProb;
00044         
00045         edm::ParameterSet psin=ps.getParameter<edm::ParameterSet>(sourceName);
00046         if (psin.getParameter<std::string>("type")!="none") {
00047           vector<string> namesIn = psin.getParameterNames();
00048           if (find(namesIn.begin(), namesIn.end(), std::string("nbPileupEvents"))
00049               != namesIn.end()) {
00050             edm::ParameterSet psin_average=psin.getParameter<edm::ParameterSet>("nbPileupEvents");
00051             vector<string> namesAverage = psin_average.getParameterNames();
00052             if (find(namesAverage.begin(), namesAverage.end(), std::string("averageNumber"))
00053                 != namesAverage.end()) 
00054               {
00055                 averageNumber=psin_average.getParameter<double>("averageNumber");
00056                 pileup.reset(new edm::PileUp(ps.getParameter<edm::ParameterSet>(sourceName),minb,maxb,averageNumber,h,playback));
00057                 edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with minBunch,maxBunch "<<minb<<" "<<maxb<<" and averageNumber "<<averageNumber;
00058               }
00059             else if (find(namesAverage.begin(), namesAverage.end(), std::string("fileName"))
00060                 != namesAverage.end() && find(namesAverage.begin(), namesAverage.end(), std::string("histoName"))
00061                 != namesAverage.end()){
00062                 
00063                
00064                 std::string histoFileName = psin_average.getUntrackedParameter<std::string>("fileName");
00065                 std::string histoName = psin_average.getUntrackedParameter<std::string>("histoName");
00066                                                 
00067                 TFile *infile = new TFile(histoFileName.c_str());
00068                 TH1F *h = (TH1F*)infile->Get(histoName.c_str());
00069                 
00070                 // Check if the histogram exists           
00071                 if (!h) {
00072                   throw cms::Exception("HistogramNotFound") << " Could not find the histogram " << histoName 
00073                                                             << "in the file " << histoFileName << "." << std::endl;
00074                 }else{
00075                   edm::LogInfo("MixingModule") << "Open a root file " << histoFileName << " containing the probability distribution histogram " << histoName << std::endl;
00076                   edm::LogInfo("MixingModule") << "The PileUp number to be added will be chosen randomly from this histogram" << std::endl;
00077                 }
00078                 
00079                 // Check if the histogram is normalized
00080                 if (((h->Integral() - 1) > 1.0e-02) && ((h->Integral() - 1) < -1.0e-02)) throw cms::Exception("BadHistoDistribution") << "The histogram should be normalized!" << std::endl;
00081                                                 
00082                 // Get the averageNumber from the histo 
00083                 averageNumber = h->GetMean();
00084                 
00085                 pileup.reset(new edm::PileUp(ps.getParameter<edm::ParameterSet>(sourceName),minb,maxb,averageNumber,h,playback));
00086                 edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with minBunch,maxBunch "<<minb<<" "<<maxb<<" and averageNumber "<<averageNumber;
00087               
00088               }
00089             else if (find(namesAverage.begin(), namesAverage.end(), std::string("probFunctionVariable"))
00090                 != namesAverage.end() && find(namesAverage.begin(), namesAverage.end(), std::string("probValue"))
00091                 != namesAverage.end() && find(namesAverage.begin(), namesAverage.end(), std::string("histoFileName"))
00092                 != namesAverage.end()){
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(ps.getParameter<edm::ParameterSet>(sourceName),minb,maxb,averageNumber,hprob,playback));
00148                 edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with minBunch,maxBunch "<<minb<<" "<<maxb<<" and averageNumber "<<averageNumber;
00149                 
00150               } 
00151             //special for pileup input
00152             else if (sourceName=="input" && find(namesAverage.begin(), namesAverage.end(), std::string("Lumi")) 
00153                      != namesAverage.end() && find(namesAverage.begin(), namesAverage.end(), std::string("sigmaInel"))
00154                      != namesAverage.end()) {
00155                      
00156               averageNumber=psin_average.getParameter<double>("Lumi")*psin_average.getParameter<double>("sigmaInel")*ps.getParameter<int>("bunchspace")/1000*3564./2808.;  //FIXME
00157               pileup.reset(new
00158               edm::PileUp(ps.getParameter<edm::ParameterSet>(sourceName),minb,maxb,averageNumber,h,playback));
00159               edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with minBunch,maxBunch "<<minb<<" "<<maxb;
00160               edm::LogInfo("MixingModule")<<" Luminosity configuration, average number used is "<<averageNumber;
00161             }
00162           }
00163         }
00164       }
00165     return pileup;
00166   }
00167 }
00168 
00169 namespace edm {
00170 
00171   // Constructor 
00172   BMixingModule::BMixingModule(const edm::ParameterSet& pset) :
00173     bunchSpace_(pset.getParameter<int>("bunchspace")),
00174     minBunch_((pset.getParameter<int>("minBunch")*25)/pset.getParameter<int>("bunchspace")),
00175     maxBunch_((pset.getParameter<int>("maxBunch")*25)/pset.getParameter<int>("bunchspace")),
00176     mixProdStep1_(pset.getParameter<bool>("mixProdStep1")),
00177     mixProdStep2_(pset.getParameter<bool>("mixProdStep2"))      
00178   {  
00179     // FIXME: temporary to keep bwds compatibility for cfg files
00180     vector<string> names = pset.getParameterNames();
00181     if (find(names.begin(), names.end(),"playback")
00182         != names.end()) {
00183       playback_=pset.getUntrackedParameter<bool>("playback");
00184     } else
00185       playback_=false;
00186 
00187     //We use std::cout in order to make sure the message appears in all possible configurations of the Message Logger
00188     if (playback_) {
00189       LogInfo("MixingModule") <<" ATTENTION:Mixing will be done in playback mode! \n"
00190                               <<" ATTENTION:Mixing Configuration must be the same as for the original mixing!";
00191     }
00192     
00193     input_=     maybeMakePileUp(pset,"input",minBunch_,maxBunch_,playback_);
00194     cosmics_=   maybeMakePileUp(pset,"cosmics",minBunch_,maxBunch_,playback_);
00195     beamHalo_p_=maybeMakePileUp(pset,"beamhalo_plus",minBunch_,maxBunch_,playback_);
00196     beamHalo_m_=maybeMakePileUp(pset,"beamhalo_minus",minBunch_,maxBunch_,playback_);
00197 
00198     //prepare playback info structures
00199     vectorEventIDs_.resize(maxBunch_-minBunch_+1);
00200   }
00201 
00202   // Virtual destructor needed.
00203   BMixingModule::~BMixingModule() {;}
00204 
00205   // Functions that get called by framework every event
00206   void BMixingModule::produce(edm::Event& e, const edm::EventSetup& setup) { 
00207 
00208     // Check if the signal is present in the root file 
00209     // for all the objects we want to mix
00210     checkSignal(e);
00211     
00212     // Create EDProduct
00213     createnewEDProduct();
00214 
00215     // Add signals
00216     if (!mixProdStep1_){ 
00217       addSignals(e,setup);
00218     }
00219 
00220     // Read the PileUp 
00221     for (unsigned int is=0;is< maxNbSources_;++is) {
00222       doit_[is]=false;
00223       pileup_[is].clear();
00224       TrueNumInteractions_[is].clear();
00225     }
00226     
00227     if (input_)  {
00228       if (playback_) {
00229         getEventStartInfo(e,0);
00230         input_->readPileUp(pileup_[0], vectorEventIDs_, TrueNumInteractions_[0]);
00231       } else {
00232         input_->readPileUp(pileup_[0], vectorEventIDs_, TrueNumInteractions_[0]); 
00233         setEventStartInfo(0);
00234       }
00235       if (input_->doPileup()) {  
00236         LogDebug("MixingModule") <<"\n\n==============================>Adding pileup to signal event "<<e.id(); 
00237         doit_[0]=true;
00238       } 
00239     }
00240     if (cosmics_) {
00241       if (playback_) {
00242         getEventStartInfo(e,1);
00243         cosmics_->readPileUp(pileup_[1], vectorEventIDs_, TrueNumInteractions_[1]); 
00244       } else {
00245         cosmics_->readPileUp(pileup_[1], vectorEventIDs_, TrueNumInteractions_[1]); 
00246         setEventStartInfo(1);
00247       }
00248       if (cosmics_->doPileup()) {  
00249         LogDebug("MixingModule") <<"\n\n==============================>Adding cosmics to signal event "<<e.id(); 
00250         doit_[1]=true;
00251       } 
00252     }
00253 
00254     if (beamHalo_p_) {
00255       if (playback_) {
00256         getEventStartInfo(e,2);
00257         beamHalo_p_->readPileUp(pileup_[2], vectorEventIDs_, TrueNumInteractions_[2]);
00258       } else {
00259         beamHalo_p_->readPileUp(pileup_[2], vectorEventIDs_, TrueNumInteractions_[2]);
00260         setEventStartInfo(2);
00261       }
00262       if (beamHalo_p_->doPileup()) {  
00263         LogDebug("MixingModule") <<"\n\n==============================>Adding beam halo+ to signal event "<<e.id();
00264         doit_[2]=true;
00265       } 
00266     }
00267 
00268     if (beamHalo_m_) {
00269       if (playback_) {
00270         getEventStartInfo(e,3);
00271         beamHalo_m_->readPileUp(pileup_[3], vectorEventIDs_, TrueNumInteractions_[3]);
00272       } else {
00273         beamHalo_m_->readPileUp(pileup_[3], vectorEventIDs_, TrueNumInteractions_[3]);
00274         setEventStartInfo(3);
00275       }
00276       if (beamHalo_m_->doPileup()) {  
00277         LogDebug("MixingModule") <<"\n\n==============================>Adding beam halo- to signal event "<<e.id();
00278         doit_[3]=true;
00279       }
00280     }
00281 
00282     doPileUp(e,setup);
00283 
00284     // Put output into event (here only playback info)
00285     put(e,setup);
00286   }
00287 
00288   void BMixingModule::merge(const int bcr, const EventPrincipalVector& vec, unsigned int worker, const edm::EventSetup& setup) {
00289     //
00290     // main loop: loop over events and merge 
00291     //    
00292     eventId_=0;
00293     LogDebug("MixingModule") <<"For bunchcrossing "<<bcr<<", "<<vec.size()<<" events will be merged";
00294     vertexoffset=0;
00295     int i=0;
00296     for (EventPrincipalVector::const_iterator it = vec.begin(); it != vec.end(); ++it) {
00297       LogDebug("MixingModule") <<" merging Event:  id " << (*it)->id();
00298       
00299       addPileups(bcr, &(**it), ++eventId_,worker,setup);
00300       i = i + 1;
00301     }// end main loop
00302   }
00303 
00304   void BMixingModule::dropUnwantedBranches(std::vector<std::string> const& wantedBranches) {
00305       if (input_) input_->dropUnwantedBranches(wantedBranches);
00306       if (cosmics_) cosmics_->dropUnwantedBranches(wantedBranches);
00307       if (beamHalo_p_) beamHalo_p_->dropUnwantedBranches(wantedBranches);
00308       if (beamHalo_m_) beamHalo_m_->dropUnwantedBranches(wantedBranches);
00309   }
00310 
00311   void BMixingModule::endJob() {
00312       if (input_) input_->endJob();
00313       if (cosmics_) cosmics_->endJob();
00314       if (beamHalo_p_) beamHalo_p_->endJob();
00315       if (beamHalo_m_) beamHalo_m_->endJob();
00316   }
00317 
00318 } //edm