CMS 3D CMS Logo

BMixingModule.cc
Go to the documentation of this file.
1 // File: BMixingModule.cc
2 // Description: see BMixingModule.h
3 // Author: Ursula Berthon, LLR Palaiseau, Bill Tanenbaum
4 //
5 //--------------------------------------------
6 
17 
18 #include "TFile.h"
19 #include "TH1F.h"
20 #include <iostream>
21 #include <memory>
22 
23 const unsigned int edm::BMixingModule::maxNbSources_ = 4;
24 
25 namespace {
26  std::shared_ptr<edm::PileUpConfig> maybeConfigPileUp(
27  edm::ParameterSet const& ps, std::string sourceName, const int minb, const int maxb, const bool playback) {
28  std::shared_ptr<edm::PileUpConfig> pileupconfig; // value to be returned
29  // Make sure we have a parameter named 'sourceName'
30  if (ps.exists(sourceName)) {
31  // We have the parameter
32  // and if we have either averageNumber or cfg by luminosity... make the PileUp
33  double averageNumber;
35  std::string histoName = " ";
36  std::unique_ptr<TH1F> h(new TH1F("h", "h", 10, 0, 10));
37  std::vector<int> dataProbFunctionVar;
38  std::vector<double> dataProb;
39 
40  const edm::ParameterSet& psin = ps.getParameter<edm::ParameterSet>(sourceName);
41  std::string type_ = psin.getParameter<std::string>("type");
42  if (ps.exists("readDB") && ps.getParameter<bool>("readDB")) {
43  //in case of DB access, do not try to load anything from the PSet, but wait for beginRun.
44  edm::LogError("BMixingModule") << "Will read from DB: reset to a dummy PileUp object.";
45  std::unique_ptr<TH1F> h;
46  pileupconfig.reset(new edm::PileUpConfig(sourceName, 0.0, h, playback));
47  return pileupconfig;
48  }
49  if (type_ != "none") {
50  if (psin.exists("nbPileupEvents")) {
51  edm::ParameterSet psin_average = psin.getParameter<edm::ParameterSet>("nbPileupEvents");
52  if (psin_average.exists("averageNumber")) {
53  averageNumber = psin_average.getParameter<double>("averageNumber");
54  pileupconfig.reset(new edm::PileUpConfig(sourceName, averageNumber, h, playback));
55  edm::LogInfo("MixingModule") << " Created source " << sourceName << " with averageNumber " << averageNumber;
56  } else if (psin_average.exists("fileName") && psin_average.exists("histoName")) {
57  std::string histoFileName = psin_average.getUntrackedParameter<std::string>("fileName");
58  std::string histoName = psin_average.getUntrackedParameter<std::string>("histoName");
59 
60  std::unique_ptr<TFile> infile(new TFile(histoFileName.c_str()));
61  std::unique_ptr<TH1F> h((TH1F*)infile->Get(histoName.c_str()));
62 
63  // Check if the histogram exists
64  if (!h) {
65  throw cms::Exception("HistogramNotFound") << " Could not find the histogram " << histoName
66  << "in the file " << histoFileName << "." << std::endl;
67  } else {
68  edm::LogInfo("MixingModule")
69  << "Open a root file " << histoFileName << " containing the probability distribution histogram "
70  << histoName << std::endl;
71  edm::LogInfo("MixingModule")
72  << "The PileUp number to be added will be chosen randomly from this histogram" << std::endl;
73  }
74 
75  // Check if the histogram is normalized
76  if (std::abs(h->Integral() - 1) > 1.0e-02)
77  throw cms::Exception("BadHistoDistribution") << "The histogram should be normalized!" << std::endl;
78 
79  // Get the averageNumber from the histo
80  averageNumber = h->GetMean();
81 
82  pileupconfig.reset(new edm::PileUpConfig(sourceName, averageNumber, h, playback));
83  edm::LogInfo("MixingModule") << " Created source " << sourceName << " with averageNumber " << averageNumber;
84 
85  } else if (psin_average.exists("probFunctionVariable") && psin_average.exists("probValue") &&
86  psin_average.exists("histoFileName")) {
87  if (type_ != "probFunction") {
88  edm::LogError("MisConfiguration")
89  << "type is set to: " << type_ << " while parameters implies probFunction; changing.";
90  type_ = "probFunction";
91  }
92 
93  dataProbFunctionVar = psin_average.getParameter<std::vector<int> >("probFunctionVariable");
94  dataProb = psin_average.getParameter<std::vector<double> >("probValue");
95  histoFileName = psin_average.getUntrackedParameter<std::string>("histoFileName");
96 
97  int varSize = (int)dataProbFunctionVar.size();
98  int probSize = (int)dataProb.size();
99 
100  if ((dataProbFunctionVar[0] != 0) || (dataProbFunctionVar[varSize - 1] != (varSize - 1)))
101  throw cms::Exception("BadProbFunction")
102  << "Please, check the variables of the probability function! The first variable should be 0 and the "
103  "difference between two variables should be 1."
104  << std::endl;
105 
106  // Complete the vector containing the probability function data
107  // with the values "0"
108  if (probSize < varSize) {
109  edm::LogInfo("MixingModule")
110  << " The probability function data will be completed with " << (varSize - probSize) << " values 0.";
111 
112  for (int i = 0; i < (varSize - probSize); i++)
113  dataProb.push_back(0);
114 
115  probSize = dataProb.size();
116  edm::LogInfo("MixingModule")
117  << " The number of the P(x) data set after adding the values 0 is " << probSize;
118  }
119 
120  // Create an histogram with the data from the probability function provided by the user
121  int xmin = (int)dataProbFunctionVar[0];
122  int xmax = (int)dataProbFunctionVar[varSize - 1] + 1; // need upper edge to be one beyond last value
123  int numBins = varSize;
124 
125  edm::LogInfo("MixingModule") << "An histogram will be created with " << numBins << " bins in the range ("
126  << xmin << "," << xmax << ")." << std::endl;
127 
128  std::unique_ptr<TH1F> hprob(
129  new TH1F("h", "Histo from the user's probability function", numBins, xmin, xmax));
130 
131  LogDebug("MixingModule") << "Filling histogram with the following data:" << std::endl;
132 
133  for (int j = 0; j < numBins; j++) {
134  LogDebug("MixingModule") << " x = " << dataProbFunctionVar[j] << " P(x) = " << dataProb[j];
135  hprob->Fill(dataProbFunctionVar[j] + 0.5,
136  dataProb[j]); // assuming integer values for the bins, fill bin centers, not edges
137  }
138 
139  // Check if the histogram is normalized
140  if (std::abs(hprob->Integral() - 1) > 1.0e-02) {
141  throw cms::Exception("BadProbFunction")
142  << "The probability function should be normalized!!! " << std::endl;
143  }
144 
145  averageNumber = hprob->GetMean();
146 
147  // Write the created histogram into a root file
148  edm::LogInfo("MixingModule")
149  << " The histogram created from the x, P(x) values will be written into the root file "
150  << histoFileName;
151 
152  TFile* outfile = new TFile(histoFileName.c_str(), "RECREATE");
153  hprob->Write();
154  outfile->Write();
155  outfile->Close();
156  outfile->Delete();
157 
158  pileupconfig.reset(new edm::PileUpConfig(sourceName, averageNumber, hprob, playback));
159  edm::LogInfo("MixingModule") << " Created source " << sourceName << " with averageNumber " << averageNumber;
160  }
161  //special for pileup input
162  else if (sourceName == "input" && psin_average.exists("Lumi") && psin_average.exists("sigmaInel")) {
163  averageNumber = psin_average.getParameter<double>("Lumi") * psin_average.getParameter<double>("sigmaInel") *
164  ps.getParameter<int>("bunchspace") / 1000 * 3564. / 2808.; //FIXME
165  pileupconfig.reset(new edm::PileUpConfig(sourceName, averageNumber, h, playback));
166  edm::LogInfo("MixingModule") << " Created source " << sourceName << " with minBunch,maxBunch " << minb
167  << " " << maxb;
168  edm::LogInfo("MixingModule") << " Luminosity configuration, average number used is " << averageNumber;
169  }
170  }
171  }
172  }
173  return pileupconfig;
174  }
175 } // namespace
176 
177 namespace edm {
178 
179  // Constructor
181  : bunchSpace_(globalConf->bunchSpace_),
182  vertexOffset_(0),
183  minBunch_(globalConf->minBunch_),
184  maxBunch_(globalConf->maxBunch_),
185  mixProdStep1_(pset.getParameter<bool>("mixProdStep1")),
186  mixProdStep2_(pset.getParameter<bool>("mixProdStep2")),
187  readDB_(globalConf->configFromDB_),
188  playback_(globalConf->playback_) {
189  for (size_t makeIdx = 0; makeIdx < maxNbSources_; makeIdx++) {
190  if (globalConf->inputConfigs_[makeIdx]) {
191  const edm::ParameterSet& psin =
192  pset.getParameter<edm::ParameterSet>(globalConf->inputConfigs_[makeIdx]->sourcename_);
193  inputSources_.push_back(
194  std::make_shared<PileUp>(psin, globalConf->inputConfigs_[makeIdx], consumesCollector(), readDB_));
195  inputSources_.back()->input(makeIdx);
196  } else {
197  inputSources_.push_back(nullptr);
198  }
199  }
200  }
201 
202  // Virtual destructor needed.
204 
206  for (size_t endIdx = 0; endIdx < maxNbSources_; ++endIdx) {
207  if (inputSources_[endIdx])
208  inputSources_[endIdx]->beginJob(iES);
209  }
210  }
211 
212  namespace MixingCache {
213  Config::Config(edm::ParameterSet const& pset, unsigned int maxNbSources)
214  : bunchSpace_(pset.getParameter<int>("bunchspace")),
215  minBunch_((pset.getParameter<int>("minBunch") * 25) / bunchSpace_),
216  maxBunch_((pset.getParameter<int>("maxBunch") * 25) / bunchSpace_),
217  playback_(pset.getUntrackedParameter<bool>("playback", false)) {
218  if (playback_) {
219  //this could be explicitly checked
220  LogInfo("MixingModule") << " ATTENTION:Mixing will be done in playback mode! \n"
221  << " ATTENTION:Mixing Configuration must be the same as for the original mixing!";
222  }
223 
224  // Just for debugging print out.
225  sourceNames_.push_back("input");
226  sourceNames_.push_back("cosmics");
227  sourceNames_.push_back("beamhalo_plus");
228  sourceNames_.push_back("beamhalo_minus");
229 
230  for (size_t makeIdx = 0; makeIdx < maxNbSources; makeIdx++) {
231  inputConfigs_.push_back(maybeConfigPileUp(pset, sourceNames_[makeIdx], minBunch_, maxBunch_, playback_));
232  }
233 
234  if (pset.exists("readDB"))
235  configFromDB_ = pset.getParameter<bool>("readDB");
236  }
237  } // namespace MixingCache
238 
239  std::unique_ptr<MixingCache::Config> BMixingModule::initializeGlobalCache(edm::ParameterSet const& pset) {
240  return std::make_unique<MixingCache::Config>(pset, maxNbSources_);
241  }
242 
243  // update method call at begin run/lumi to reload the mixing configuration
245  update(setup);
246  for (size_t endIdx = 0; endIdx < maxNbSources_; ++endIdx) {
247  if (inputSources_[endIdx])
248  inputSources_[endIdx]->beginLuminosityBlock(lumi, setup);
249  }
250  }
251 
253  for (size_t endIdx = 0; endIdx < maxNbSources_; ++endIdx) {
254  if (inputSources_[endIdx])
255  inputSources_[endIdx]->beginRun(run, setup);
256  }
257  }
258 
260  for (size_t endIdx = 0; endIdx < maxNbSources_; ++endIdx) {
261  if (inputSources_[endIdx])
262  inputSources_[endIdx]->endLuminosityBlock(lumi, setup);
263  }
264  }
265 
267  for (size_t endIdx = 0; endIdx < maxNbSources_; ++endIdx) {
268  if (inputSources_[endIdx])
269  inputSources_[endIdx]->endRun(run, setup);
270  }
271  }
272 
275  for (size_t makeIdx = 0; makeIdx < maxNbSources_; makeIdx++) {
276  if (inputSources_[makeIdx])
277  inputSources_[makeIdx]->reload(setup);
278  }
279  reload(setup);
280  }
281  }
282 
283  // Functions that get called by framework every event
285  // Check if the signal is present in the root file
286  // for all the objects we want to mix
287  checkSignal(e);
288 
289  // Create EDProduct
291 
293 
294  // Add signals
295  if (!mixProdStep1_) {
296  addSignals(e, setup);
297  }
298 
299  doPileUp(e, setup);
300 
301  // Includes putting digi products into the edm::Event.
303 
304  // Put output into event (here only playback info)
305  put(e, setup);
306  }
307 
309  for (size_t dropIdx = 0; dropIdx < maxNbSources_; ++dropIdx) {
310  if (inputSources_[dropIdx])
311  inputSources_[dropIdx]->setupPileUpEvent(setup);
312  }
313  }
314 
315  void BMixingModule::dropUnwantedBranches(std::vector<std::string> const& wantedBranches) {
316  for (size_t dropIdx = 0; dropIdx < maxNbSources_; ++dropIdx) {
317  if (inputSources_[dropIdx])
318  inputSources_[dropIdx]->dropUnwantedBranches(wantedBranches);
319  }
320  }
321 
323  for (size_t endIdx = 0; endIdx < maxNbSources_; ++endIdx) {
324  if (inputSources_[endIdx])
325  inputSources_[endIdx]->beginStream(streamID);
326  }
327  }
328 
330  ExceptionCollector exceptionCollector(
331  "Multiple exceptions were thrown while executing endStream and endJob for mixing modules. "
332  "An exception message follows for each.\n");
333 
334  for (size_t endIdx = 0; endIdx < maxNbSources_; ++endIdx) {
335  if (inputSources_[endIdx])
336  inputSources_[endIdx]->endStream(exceptionCollector);
337  }
338  if (exceptionCollector.hasThrown()) {
339  exceptionCollector.rethrow();
340  }
341  }
342 
344  edm::LogWarning("MixingModule") << "BMixingModule::createnewEDProduct must be overwritten!";
345  }
346 
348  edm::LogWarning("MixingModule") << "BMixingModule::checkSignal must be overwritten!";
349  }
350 
352  edm::LogWarning("MixingModule") << "BMixingModule::setBcrOffset must be overwritten!";
353  }
354 
355  void BMixingModule::setSourceOffset(const unsigned int s) {
356  edm::LogWarning("MixingModule") << "BMixingModule::setSourceOffset must be overwritten!";
357  }
358 
360  edm::LogWarning("MixingModule") << "BMixingModule::doPileUp must be overwritten!";
361  }
362 
363 } // namespace edm
edm::ESWatcher< MixingRcd > parameterWatcher_
void beginRun(const edm::Run &r, const edm::EventSetup &setup) override
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
static std::unique_ptr< MixingCache::Config > initializeGlobalCache(edm::ParameterSet const &)
virtual void addSignals(const edm::Event &e, const edm::EventSetup &c)
Definition: BMixingModule.h:80
void produce(edm::Event &e1, const edm::EventSetup &c) override
virtual void finalizeEvent(edm::Event &event, const edm::EventSetup &setup)
Definition: BMixingModule.h:57
std::vector< std::string > sourceNames_
Definition: BMixingModule.h:36
bool exists(std::string const &parameterName) const
checks if a parameter exists
virtual void checkSignal(const edm::Event &e)
void endStream() override
Log< level::Error, false > LogError
virtual void put(edm::Event &e, const edm::EventSetup &c)
Definition: BMixingModule.h:85
void endRun(const edm::Run &r, const edm::EventSetup &setup) override
virtual void setBcrOffset()
T getUntrackedParameter(std::string const &, T const &) const
virtual void createnewEDProduct()
virtual void setSourceOffset(const unsigned int s)
virtual void doPileUp(edm::Event &e, const edm::EventSetup &c)
void registerLateConsumes(eventsetup::ESRecordsToProductResolverIndices const &) override
virtual void initializeEvent(const edm::Event &event, const edm::EventSetup &setup)
Definition: BMixingModule.h:54
Config(edm::ParameterSet const &pset, unsigned int maxNbSources)
void beginStream(edm::StreamID) override
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static const unsigned int maxNbSources_
virtual void reload(const edm::EventSetup &setup)
Definition: BMixingModule.h:69
Log< level::Info, false > LogInfo
~BMixingModule() override
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
bool const mixProdStep1_
Definition: BMixingModule.h:99
HLT enums.
std::vector< std::shared_ptr< PileUp > > inputSources_
void dropUnwantedBranches(std::vector< std::string > const &wantedBranches)
Log< level::Warning, false > LogWarning
void beginLuminosityBlock(const edm::LuminosityBlock &l, const edm::EventSetup &setup) override
void update(edm::EventSetup const &)
std::vector< std::shared_ptr< PileUpConfig > > inputConfigs_
Definition: BMixingModule.h:37
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
void setupPileUpEvent(const edm::EventSetup &setup)
void endLuminosityBlock(const edm::LuminosityBlock &l, const edm::EventSetup &setup) override
Definition: Run.h:45
#define LogDebug(id)
BMixingModule(const edm::ParameterSet &ps, MixingCache::Config const *globalConf)