00001
00002
00003
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;
00031
00032 if (ps.exists(sourceName))
00033 {
00034
00035
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
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
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
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
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
00105
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
00116 int xmin = (int) dataProbFunctionVar[0];
00117 int xmax = (int) dataProbFunctionVar[varSize-1]+1;
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]);
00129 }
00130
00131
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
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
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.;
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
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
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
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
00201 BMixingModule::~BMixingModule() {;}
00202
00203
00204 void BMixingModule::beginLuminosityBlock(edm::LuminosityBlock&, edm::EventSetup const&setup){
00205 update(setup);
00206 }
00207
00208 void BMixingModule::beginRun(edm::Run & r, const edm::EventSetup & setup){
00209 update(setup);
00210 }
00211
00212 void BMixingModule::update(const edm::EventSetup & setup){
00213 if (readDB_ && parameterWatcher_.check(setup)){
00214 for (size_t makeIdx = 0; makeIdx < maxNbSources_; makeIdx++ ) {
00215 if (inputSources_[makeIdx]) inputSources_[makeIdx]->reload(setup);
00216 }
00217 reload(setup);
00218 }
00219 }
00220
00221
00222 void BMixingModule::produce(edm::Event& e, const edm::EventSetup& setup) {
00223
00224
00225
00226 checkSignal(e);
00227
00228
00229 createnewEDProduct();
00230
00231 initializeEvent(e, setup);
00232
00233
00234 if (!mixProdStep1_){
00235 addSignals(e,setup);
00236 }
00237
00238 doPileUp(e,setup);
00239
00240
00241 finalizeEvent(e, setup);
00242
00243
00244 put(e,setup);
00245 }
00246
00247 void BMixingModule::dropUnwantedBranches(std::vector<std::string> const& wantedBranches) {
00248 for (size_t dropIdx=0; dropIdx<maxNbSources_; dropIdx++ ) {
00249 if( inputSources_[dropIdx] ) inputSources_[dropIdx]->dropUnwantedBranches(wantedBranches);
00250 }
00251 }
00252
00253 void BMixingModule::endJob() {
00254 for (size_t endIdx=0; endIdx<maxNbSources_; endIdx++ ) {
00255 if( inputSources_[endIdx] ) inputSources_[endIdx]->endJob();
00256 }
00257 }
00258
00259 }