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 vector<string> names = ps.getParameterNames();
00033 if (find(names.begin(), names.end(), sourceName)
00034 != names.end())
00035 {
00036
00037
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
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
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
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
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(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
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.;
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
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
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
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
00199 vectorEventIDs_.resize(maxBunch_-minBunch_+1);
00200 }
00201
00202
00203 BMixingModule::~BMixingModule() {;}
00204
00205
00206 void BMixingModule::produce(edm::Event& e, const edm::EventSetup& setup) {
00207
00208
00209
00210 checkSignal(e);
00211
00212
00213 createnewEDProduct();
00214
00215
00216 if (!mixProdStep1_){
00217 addSignals(e,setup);
00218 }
00219
00220
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
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
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 }
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 }