test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HistogramManager.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: SiPixelPhase1Common
4 // Class : HistogramManager
5 //
7 
8 #include <sstream>
9 #include <boost/algorithm/string.hpp>
10 
11 // Geometry stuff
15 
16 // Logger
18 
20  GeometryInterface& geo)
21  : iConfig(iconfig),
22  geometryInterface(geo),
23  enabled(iconfig.getParameter<bool>("enabled")),
24  perLumiHarvesting(iconfig.getParameter<bool>("perLumiHarvesting")),
25  bookUndefined(iconfig.getParameter<bool>("bookUndefined")),
26  top_folder_name(iconfig.getParameter<std::string>("topFolderName")),
27  name(iconfig.getParameter<std::string>("name")),
28  title(iconfig.getParameter<std::string>("title")),
29  xlabel(iconfig.getParameter<std::string>("xlabel")),
30  ylabel(iconfig.getParameter<std::string>("ylabel")),
31  dimensions(iconfig.getParameter<int>("dimensions")),
32  range_x_nbins(iconfig.getParameter<int>("range_nbins")),
33  range_x_min(iconfig.getParameter<double>("range_min")),
34  range_x_max(iconfig.getParameter<double>("range_max")),
35  range_y_nbins(iconfig.getParameter<int>("range_y_nbins")),
36  range_y_min(iconfig.getParameter<double>("range_y_min")),
37  range_y_max(iconfig.getParameter<double>("range_y_max")) {
38  auto spec_configs = iconfig.getParameter<edm::VParameterSet>("specs");
39  for (auto spec : spec_configs) {
40  // this would fit better in SummationSpecification(...), but it has to
41  // happen here.
42  auto conf = spec.getParameter<edm::ParameterSet>("conf");
43  if (!conf.getParameter<bool>("enabled")) continue;
45  }
46 }
47 
49  specs.push_back(spec);
50  tables.push_back(Table());
51  counters.push_back(Table());
53  fastpath.push_back(nullptr);
54 }
55 
56 // This is the hottest function in the HistogramManager. Make sure it does not
57 // allocate memory or other expensive things.
58 // Currently the GeometryInterface::extract (some virtual calls) and the map
59 // lookups should be the most expensive things, but they should only happen if
60 // the module changed from the last call; an optimization that fails when row/
61 // col are used.
62 // fillInternal (called from here) does more lookups on the geometry, if EXTEND
63 // is used; we do not attempt the optimization there since in most cases row/
64 // col are involved.
65 void HistogramManager::fill(double x, double y, DetId sourceModule,
66  const edm::Event* sourceEvent, int col, int row) {
67  if (!enabled) return;
68  bool cached = true;
69  // We could be smarter on row/col and only check if they appear in the spec
70  // but that just asks for bugs.
71  if (col != this->iq.col || row != this->iq.row ||
72  sourceModule != this->iq.sourceModule ||
73  sourceEvent != this->iq.sourceEvent ||
74  sourceModule == 0xFFFFFFFF ||
75  sourceModule == DetId(0) // Hack for eventrate-like things, since the
76  // sourceEvent ptr might not change.
77  ) {
78  cached = false;
79  iq = GeometryInterface::InterestingQuantities{sourceEvent, sourceModule,
80  int16_t(col), int16_t(row)};
81  }
82  for (unsigned int i = 0; i < specs.size(); i++) {
83  auto& s = specs[i];
84  auto& t = s.steps[0].type == SummationStep::COUNT ? counters[i] : tables[i];
85  if (!cached) {
86  significantvalues[i].clear();
87  geometryInterface.extractColumns(s.steps[0].columns, iq,
89  fastpath[i] = nullptr;
90  }
91 
92  if (!fastpath[i]) {
93  auto histo = t.find(significantvalues[i]);
94  if (histo == t.end()) {
95  if (!bookUndefined) continue;
96  edm::LogError("HistogramManager") << "Missing Histogram!\n"
97  << "path " << makePath(significantvalues[i]) << "\n"
98  << "name " << tables[i].begin()->second.th1->GetName() << "\n";
99  assert(!"Histogram not booked! Probably inconsistent geometry description.");
100  }
101 
102  fastpath[i] = &(histo->second);
103  }
104  if (s.steps[0].type == SummationStep::COUNT) {
105  fastpath[i]->count++;
106  fastpath[i]->iq_sample = iq;
107  } else {
108  fillInternal(x, y, this->dimensions, iq, s.steps.begin()+1, s.steps.end(), *(fastpath[i]));
109  }
110  }
111 }
112 void HistogramManager::fill(double x, DetId sourceModule,
113  const edm::Event* sourceEvent, int col, int row) {
114  assert(this->dimensions == 1);
115  fill(x, 0.0, sourceModule, sourceEvent, col, row);
116 }
117 void HistogramManager::fill(DetId sourceModule, const edm::Event* sourceEvent,
118  int col, int row) {
119  assert(this->dimensions == 0);
120  fill(0.0, 0.0, sourceModule, sourceEvent, col, row);
121 }
122 
123 void HistogramManager::fillInternal(double x, double y, int n_parameters,
125  std::vector<SummationStep>::iterator first,
126  std::vector<SummationStep>::iterator last,
128 
129  double fx = 0, fy = 0, fz = 0;
130  int tot_parameters = n_parameters;
131  for (auto it = first; it != last; ++it) {
132  if (it->stage != SummationStep::STAGE1) break;
133  // The specification builder precomputes where x and y go, this loop will
134  // always do 3 iterations to set x, y, z. The builder does not know how
135  // many parameters we have, so we have to check that and count the total.
136  switch (it->type) {
138  if (it->arg[0] == '1' && n_parameters >= 1) fx = x;
139  if (it->arg[0] == '2' && n_parameters >= 2) fx = y;
140  break;
142  if (it->arg[0] == '1' && n_parameters >= 1) fy = x;
143  if (it->arg[0] == '2' && n_parameters >= 2) fy = y;
144  break;
146  if (it->arg[0] == '1' && n_parameters >= 1) fz = x;
147  if (it->arg[0] == '2' && n_parameters >= 2) fz = y;
148  break;
150  fx = geometryInterface.extract(it->columns[0], iq).second;
151  tot_parameters++;
152  break;
154  fy = geometryInterface.extract(it->columns[0], iq).second;
155  tot_parameters++;
156  break;
158  break; // profile does not make a difference here, only in booking
159  default:
160  assert(!"illegal step in STAGE1!");
161  }
162  }
163 
164  switch(tot_parameters) {
165  case 1:
166  dest.me->Fill(fx);
167  break;
168  case 2:
169  dest.me->Fill(fx, fy);
170  break;
171  case 3:
172  dest.me->Fill(fx, fy, fz);
173  break;
174  default:
175  edm::LogError("HistogramManager") << "got " << tot_parameters << " dimensions\n"
176  << "name " << dest.th1->GetName() << "\n";
177  assert(!"More than 3 dimensions should never occur.");
178  }
179 }
180 
181 
182 // This is only used for ndigis-like counting. It could be more optimized, but
183 // is probably fine for a per-event thing.
185  if (!enabled) return;
186  for (unsigned int i = 0; i < specs.size(); i++) {
187  auto& s = specs[i];
188  auto& t = tables[i];
189  auto& c = counters[i];
190  if (s.steps[0].type != SummationStep::COUNT) continue; // no counting, done
191  assert((s.steps.size() >= 2 && s.steps[1].type == SummationStep::GROUPBY)
192  || !"Incomplete spec (but this cannot be caught in Python)");
193  for (auto& e : c) {
194  // the iq on the counter can only be a _sample_, since many modules
195  // could be grouped on one counter. Even worse, the sourceEvent ptr
196  // could be dangling if the counter was not touched in this event, so
197  // we replace it. row/col are most likely useless as well.
198  auto iq = e.second.iq_sample;
199  iq.sourceEvent = sourceEvent;
200 
201  significantvalues[i].clear();
202  geometryInterface.extractColumns(s.steps[1].columns, iq,
204  auto histo = t.find(significantvalues[i]);
205  if (histo == t.end()) {
206  if (!bookUndefined) continue;
207  edm::LogError("HistogramManager") << "Histogram Missing!\n"
208  << "path " << makePath(significantvalues[i]) << "\n"
209  << "name " << t.begin()->second.th1->GetName() << "\n"
210  << "ctr " << makePath(e.first) << " detid " << iq.sourceModule << "\n";
211  assert(!"Histogram not booked! (per-event) Probably inconsistent geometry description.");
212  }
213  fillInternal(e.second.count, 0, 1, iq, s.steps.begin()+2, s.steps.end(), histo->second);
214  e.second.count = 0;
215  }
216  }
217 }
218 
220  GeometryInterface::Values const& significantvalues) {
221  // non-number output names (_pO etc.) are hardwired here.
222  // PERF: memoize the names in a map, probably ignoring row/col
223  // TODO: more pretty names for DetIds using PixelBarrelName etc.
224  std::ostringstream dir("");
225  for (auto e : significantvalues.values) {
227  std::string value = "_" + std::to_string(e.second);
228  if (e.second == 0) value = ""; // hide Barrel_0 etc.
229  if (name == "") continue; // nameless dummy column is dropped
230  if (name == "PXDisk" && e.second > 0) // +/- sign for disk num
231  value = "_+" + std::to_string(e.second);
232  // pretty (legacy?) names for Shells and HalfCylinders
233  std::map<int, std::string> shellname{
234  {11, "_mI"}, {12, "_mO"}, {21, "_pI"}, {22, "_pO"}};
235  if (name == "HalfCylinder" || name == "Shell") value = shellname[e.second];
236  if (e.second == GeometryInterface::UNDEFINED) value = "_UNDEFINED";
237 
238  dir << name << value << "/";
239  }
240  return top_folder_name + "/" + dir.str();
241 }
242 
245  std::string name = this->name;
246  for (SummationStep step : s.steps) {
247  if (step.stage == SummationStep::FIRST || step.stage == SummationStep::STAGE1) {
248  switch (step.type) {
250  name = "num_" + name;
251  break;
255  geometryInterface.extract(step.columns[0], iq).first;
256  std::string colname = geometryInterface.pretty(col0);
257  name = name + "_per_" + colname;
258  break;
259  }
260  default:
261  // Maybe PROFILE is worth showing.
262  break; // not visible in name
263  }
264  }
265  }
266  return name;
267 }
268 
269 
271  edm::EventSetup const& iSetup) {
272  if (!geometryInterface.loaded()) {
273  geometryInterface.load(iSetup);
274  }
275  if (!enabled) return;
276 
277  struct MEInfo {
278  int dimensions = 1;
279  double range_x_min = 1e12;
280  double range_x_max = -1e12;
281  double range_y_min = 1e12;
282  double range_y_max = -1e12;
283  double range_z_min = 1e12; // z range carried around but unused
284  double range_z_max = -1e12;
285  int range_x_nbins = 0;
286  int range_y_nbins = 0;
287  int range_z_nbins = 0;
288  std::string name, title, xlabel, ylabel, zlabel;
289  bool do_profile = false;
290  };
291  std::map<GeometryInterface::Values, MEInfo> toBeBooked;
292 
293  for (unsigned int i = 0; i < specs.size(); i++) {
294  auto& s = specs[i];
295  auto& t = tables[i];
296  auto& c = counters[i];
297  toBeBooked.clear();
298  bool bookCounters = false;
299 
300  auto firststep = s.steps.begin();
301  int n_parameters = this->dimensions;
302  if (firststep->type != SummationStep::GROUPBY) {
303  ++firststep;
304  n_parameters = 1;
305  bookCounters = true;
306  }
308 
309  for (auto iq : geometryInterface.allModules()) {
310 
311  if (bookCounters) {
312  // add an entry for the counting step if present
313  geometryInterface.extractColumns(s.steps[0].columns, iq,
314  significantvalues);
315  c[significantvalues].iq_sample = iq;
316  }
317 
318  geometryInterface.extractColumns(firststep->columns, iq,
319  significantvalues);
320  if (!bookUndefined) {
321  // skip if any column is UNDEFINED
322  bool ok = true;
323  for (auto e : significantvalues.values)
324  if (e.second == GeometryInterface::UNDEFINED) ok = false;
325  if (!ok) continue;
326  }
327 
328  auto histo = toBeBooked.find(significantvalues);
329  if (histo == toBeBooked.end()) {
330  // create new histo
331  MEInfo& mei = toBeBooked[significantvalues];
332  mei.name = makeName(s, iq);
333  mei.title = this->title;
334  if (bookCounters)
335  mei.title = "Number of " + mei.title + " per Event and "
336  + geometryInterface.pretty(geometryInterface.extract(*(s.steps[0].columns.end()-1), iq).first);
337  std::string xlabel = bookCounters ? "#" + this->xlabel : this->xlabel;
338 
339  // refer to fillInternal() for the actual execution
340  // compute labels, title, type, user-set ranges here
341  int tot_parameters = n_parameters;
342 #define SET_AXIS(to, from) \
343  mei.to##label = from##label; \
344  mei.range_##to##_min = this->range_##from##_min; \
345  mei.range_##to##_max = this->range_##from##_max; \
346  mei.range_##to##_nbins = this->range_##from##_nbins
347  for (auto it = firststep+1; it != s.steps.end(); ++it) {
348  if (it->stage != SummationStep::STAGE1) break;
349  switch (it->type) {
351  if (it->arg[0] == '1' && n_parameters >= 1) { SET_AXIS(x, x); }
352  if (it->arg[0] == '2' && n_parameters >= 2) { SET_AXIS(x, y); }
353  break;
355  if (it->arg[0] == '1' && n_parameters >= 1) { SET_AXIS(y, x); }
356  if (it->arg[0] == '2' && n_parameters >= 2) { SET_AXIS(y, y); }
357  break;
359  if (it->arg[0] == '1' && n_parameters >= 1) { SET_AXIS(z, x); }
360  if (it->arg[0] == '2' && n_parameters >= 2) { SET_AXIS(z, y); }
361  break;
363  assert(mei.range_x_nbins == 0);
364  auto col = geometryInterface.extract(it->columns[0], iq).first;
365  mei.xlabel = geometryInterface.pretty(col);
366  mei.title = mei.title + " by " + mei.xlabel;
368  mei.range_x_min = geometryInterface.minValue(col[0]);
370  mei.range_x_max = geometryInterface.maxValue(col[0]);
371  tot_parameters++; }
372  break;
374  auto col = geometryInterface.extract(it->columns[0], iq).first;
375  mei.ylabel = geometryInterface.pretty(col);
376  mei.title = mei.title + " by " + mei.ylabel;
378  mei.range_y_min = geometryInterface.minValue(col[0]);
380  mei.range_y_max = geometryInterface.maxValue(col[0]);
381  tot_parameters++; }
382  break;
384  mei.do_profile = true;
385  break;
386  default:
387  assert(!"illegal step in STAGE1! (booking)");
388  }
389  }
390  mei.dimensions = tot_parameters;
391  if (mei.do_profile) mei.title = "Profile of " + mei.title;
392  if (mei.zlabel.size() > 0) mei.title = mei.title + " (Z: " + mei.zlabel + ")";
393  }
394  // only update range
395  MEInfo& mei = toBeBooked[significantvalues];
396  double val;
397 
398  for (auto it = firststep+1; it != s.steps.end(); ++it) {
399  if (it->stage != SummationStep::STAGE1) break;
400  switch (it->type) {
402  val = geometryInterface.extract(it->columns[0], iq).second;
403  if (val == GeometryInterface::UNDEFINED) break;
404  mei.range_x_min = std::min(mei.range_x_min, val);
405  mei.range_x_max = std::max(mei.range_x_max, val);
406  break;
408  val = geometryInterface.extract(it->columns[0], iq).second;
409  if (val == GeometryInterface::UNDEFINED) break;
410  mei.range_y_min = std::min(mei.range_y_min, val);
411  mei.range_y_max = std::max(mei.range_y_max, val);
412  break;
413  default: // ignore the rest, code above will catch bugs
414  break;
415  }
416  }
417  }
418 
419  // Now do the actual booking.
420  for (auto& e : toBeBooked) {
421  AbstractHistogram& h = t[e.first];
422  iBooker.setCurrentFolder(makePath(e.first));
423  MEInfo& mei = e.second;
424 
425  // we assume integer range on EXTEND-axis, n bins was neveer set so 0.
426  // due to how we counted above, we need to include lower and upper bound
427  if (mei.range_x_nbins == 0) {
428  mei.range_x_min -= 0.5;
429  mei.range_x_max += 0.5;
430  mei.range_x_nbins = int(mei.range_x_max - mei.range_x_min);
431  }
432  if (mei.range_y_nbins == 0) {
433  mei.range_y_min -= 0.5;
434  mei.range_y_max += 0.5;
435  mei.range_y_nbins = int(mei.range_y_max - mei.range_y_min);
436  }
437 
438  if (mei.dimensions == 1) {
439  h.me = iBooker.book1D(mei.name, (mei.title + ";" + mei.xlabel).c_str(),
440  mei.range_x_nbins, mei.range_x_min, mei.range_x_max);
441  } else if (mei.dimensions == 2 && !mei.do_profile) {
442  h.me = iBooker.book2D(mei.name, (mei.title + ";" + mei.xlabel + ";" + mei.ylabel).c_str(),
443  mei.range_x_nbins, mei.range_x_min, mei.range_x_max,
444  mei.range_y_nbins, mei.range_y_min, mei.range_y_max);
445  } else if (mei.dimensions == 2 && mei.do_profile) {
446  h.me = iBooker.bookProfile(mei.name, (mei.title + ";" + mei.xlabel + ";" + mei.ylabel).c_str(),
447  mei.range_x_nbins, mei.range_x_min, mei.range_x_max, 0.0, 0.0);
448  } else if (mei.dimensions == 3 && mei.do_profile) {
449  h.me = iBooker.bookProfile2D(mei.name, (mei.title + ";" + mei.xlabel + ";" + mei.ylabel).c_str(),
450  mei.range_x_nbins, mei.range_x_min, mei.range_x_max,
451  mei.range_y_nbins, mei.range_y_min, mei.range_y_max,
452  0.0, 0.0); // Z range is ignored if min==max
453  } else {
454  edm::LogError("HistogramManager") << "Illegal Histogram!\n"
455  << "name " << mei.name << "\n"
456  << "dim " << mei.dimensions << " profile " << mei.do_profile << "\n";
457  assert(!"Illegal Histogram kind.");
458  }
459  h.th1 = h.me->getTH1();
460  }
461  }
462 }
463 
464 
465 
467  DQMStore::IGetter& iGetter,
468  edm::LuminosityBlock const& lumiBlock,
469  edm::EventSetup const& iSetup) {
470  if (!enabled) return;
471  // this should also give us the GeometryInterface for offline, though it is a
472  // bit dirty and might explode.
473  if (!geometryInterface.loaded()) {
474  geometryInterface.load(iSetup);
475  }
476  if (perLumiHarvesting) {
477  this->lumisection = &lumiBlock; // "custom" steps can use this
478  executeHarvesting(iBooker, iGetter);
479  this->lumisection = nullptr;
480  }
481 }
482 
484  DQMStore::IGetter& iGetter) {
485  t.clear();
487  auto firststep = s.steps.begin();
488  if (firststep->type != SummationStep::GROUPBY) ++firststep;
489 
490  for (auto iq : geometryInterface.allModules()) {
491 
492  geometryInterface.extractColumns(firststep->columns, iq,
493  significantvalues);
494 
495  auto histo = t.find(significantvalues);
496  if (histo == t.end()) {
497  std::string name = makeName(s, iq);
498  std::string path = makePath(significantvalues) + name;
499  MonitorElement* me = iGetter.get(path);
500  if (!me) {
501  if (bookUndefined)
502  edm::LogError("HistogramManager") << "ME " << path << " not found\n";
503  // else this will happen quite often
504  } else {
506  histo.me = me;
507  histo.th1 = histo.me->getTH1();
508  histo.iq_sample = iq;
509  }
510  }
511  }
512 }
513 
515  // Simple regrouping, sum histos if they end up in the same place.
516  Table out;
518  for (auto& e : t) {
519  TH1* th1 = e.second.th1;
520  geometryInterface.extractColumns(step.columns, e.second.iq_sample,
521  significantvalues);
522  AbstractHistogram& new_histo = out[significantvalues];
523  if (!new_histo.me) {
524  iBooker.setCurrentFolder(makePath(significantvalues));
525  if (dynamic_cast<TH1F*>(th1)) new_histo.me = iBooker.book1D(th1->GetName(), (TH1F*) th1);
526  else if (dynamic_cast<TH2F*>(th1)) new_histo.me = iBooker.book2D(th1->GetName(), (TH2F*) th1);
527  else if (dynamic_cast<TProfile*>(th1)) new_histo.me = iBooker.bookProfile(th1->GetName(), (TProfile*) th1);
528  else if (dynamic_cast<TProfile2D*>(th1)) new_histo.me = iBooker.bookProfile2D(th1->GetName(), (TProfile2D*) th1);
529  else assert(!"No idea how to book this.");
530  new_histo.th1 = new_histo.me->getTH1();
531  new_histo.iq_sample = e.second.iq_sample;
532  } else {
533  new_histo.th1->Add(th1);
534  }
535  }
536  t.swap(out);
537 }
538 
540  // For the moment only X.
541  // first pass determines the range.
542  std::map<GeometryInterface::Values, int> nbins;
543  // separators collects meta info for the render plugin about the boundaries.
544  // for each EXTEND, this is added to the axis label. In total this is not
545  // fully correct since we have to assume the the substructure of each sub-
546  // histogram is the same, which is e.g. not true for layers. It still works
547  // since layers only contain leaves (ladders).
548  std::map<GeometryInterface::Values, std::string> separators;
549 
551 
552  for (auto& e : t) {
553  geometryInterface.extractColumns(step.columns, e.second.iq_sample,
554  significantvalues);
555  int& n = nbins[significantvalues];
556  assert(e.second.th1 || !"invalid histogram");
557  // if we reduce, every histogram only needs one bin
558  int bins = reduce_type != "" ? 1 : e.second.th1->GetXaxis()->GetNbins();
559  if (bins > 1) separators[significantvalues] += std::to_string(n) + ",";
560  n += bins;
561  }
562  for (auto& e : separators) e.second = "(" + e.second + ")/";
563 
564  Table out;
565  for (auto& e : t) {
566  geometryInterface.extractColumns(step.columns, e.second.iq_sample,
567  significantvalues);
568  TH1* th1 = e.second.th1;
569  assert(th1);
570 
571  AbstractHistogram& new_histo = out[significantvalues];
572  if (!new_histo.me) {
573  // TODO: this might be incorrect, but it is only for the title.
574  // we put the name of the actual, last column of a input histo there.
575  std::string colname = geometryInterface.pretty((e.first.values.end()-1)->first);
576  if (colname == "") { // dummy column. There is nothing to do here.
577  new_histo = e.second;
578  continue;
579  }
580 
581  auto separator = separators[significantvalues];
582 
583  auto eps = std::string(""); // for conciseness below
584  auto red = reduce_type;
585  boost::algorithm::to_lower(red);
586  auto name = std::string(red != "" ? red + "_" : eps) + th1->GetName();
587  auto title = eps + th1->GetTitle() + " per " + colname + ";" +
588  colname + separator +
589  (red != "" ? th1->GetYaxis()->GetTitle() : th1->GetXaxis()->GetTitle()) + ";" +
590  (red != "" ? red + " of " + th1->GetXaxis()->GetTitle() : th1->GetYaxis()->GetTitle());
591  iBooker.setCurrentFolder(makePath(significantvalues));
592 
593  if (th1->GetDimension() == 1) {
594  new_histo.me = iBooker.book1D(name, title,
595  nbins[significantvalues], 0.5, nbins[significantvalues] + 0.5);
596  } else {
597  assert(!"2D extend not implemented in harvesting.");
598  }
599  new_histo.th1 = new_histo.me->getTH1();
600  new_histo.iq_sample = e.second.iq_sample;
601  new_histo.count = 1; // used as a fill pointer. Assumes histograms are
602  // ordered correctly (map should provide that)
603  }
604 
605  // now add data.
606  if (new_histo.th1->GetDimension() == 1) {
607  if (reduce_type == "") { // no reduction, concatenate
608  for (int i = 1; i <= th1->GetXaxis()->GetNbins(); i++) {
609  new_histo.th1->SetBinContent(new_histo.count, th1->GetBinContent(i));
610  new_histo.th1->SetBinError(new_histo.count, th1->GetBinError(i));
611  new_histo.count += 1;
612  }
613  } else if (reduce_type == "MEAN") {
614  new_histo.th1->SetBinContent(new_histo.count, th1->GetMean());
615  new_histo.th1->SetBinError(new_histo.count, th1->GetMeanError());
616  new_histo.count += 1;
617  } else {
618  assert(!"Reduction type not supported");
619  }
620  } else {
621  assert(!"2D extend not implemented in harvesting.");
622  }
623  }
624  t.swap(out);
625 }
626 
628  DQMStore::IGetter& iGetter) {
629  if (!enabled) return;
630  // Debug output
631  for (auto& s : specs) {
632  edm::LogInfo log("HistogramManager");
633  log << "Specs for " << name << " ";
634  s.dump(log, geometryInterface);
635  }
636 
637  for (unsigned int i = 0; i < specs.size(); i++) {
638  auto& s = specs[i];
639  auto& t = tables[i];
640  loadFromDQMStore(s, t, iGetter);
641 
642  std::string reduce_type = "";
643 
644  // now execute step2.
645  for (SummationStep step : s.steps) {
646  if (step.stage == SummationStep::STAGE2) {
647  switch (step.type) {
648  case SummationStep::SAVE:
649  // no explicit implementation atm.
650  break;
652  executeGroupBy(step, t, iBooker);
653  break;
655  // reduction is done in the following EXTEND
656  reduce_type = step.arg;
657  break;
659  executeExtend(step, t, reduce_type, iBooker);
660  reduce_type = "";
661  break;
663  assert(!"EXTEND_Y currently not supported in harvesting.");
664  break;
666  if (customHandler) customHandler(step, t, iBooker, iGetter);
667  break;
668  default:
669  assert(!"Operation not supported in harvesting.");
670  }
671  }
672  }
673  }
674 }
void executeHarvesting(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter)
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
MonitorElement * me
GeometryInterface::InterestingQuantities iq_sample
void addSpec(SummationSpecification spec)
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
MonitorElement * bookProfile(Args &&...args)
Definition: DQMStore.h:157
std::vector< GeometryInterface::Column > columns
void executePerLumiHarvesting(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, edm::LuminosityBlock const &lumiBlock, edm::EventSetup const &iSetup)
MonitorElement * get(const std::string &path)
Definition: DQMStore.cc:305
std::vector< ParameterSet > VParameterSet
Definition: ParameterSet.h:33
void executeExtend(SummationStep &step, Table &t, std::string const &reduction, DQMStore::IBooker &iBooker)
std::string pretty(Column col)
assert(m_qm.get())
std::vector< SummationSpecification > specs
std::vector< SummationStep > steps
std::string top_folder_name
void fill(DetId sourceModule, const edm::Event *sourceEvent=0, int col=0, int row=0)
void Fill(long long x)
std::vector< std::pair< Column, Value > > values
void fillInternal(double x, double y, int n_parameters, GeometryInterface::InterestingQuantities const &iq, std::vector< SummationStep >::iterator first, std::vector< SummationStep >::iterator last, AbstractHistogram &dest)
T x() const
Cartesian x coordinate.
std::string xlabel
void loadFromDQMStore(SummationSpecification &s, Table &t, DQMStore::IGetter &iGetter)
void load(edm::EventSetup const &iSetup)
void extractColumns(std::vector< Column > const &names, InterestingQuantities const &iq, Values &out)
MonitorElement * bookProfile2D(Args &&...args)
Definition: DQMStore.h:163
void executeGroupBy(SummationStep &step, Table &t, DQMStore::IBooker &iBooker)
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:115
std::string makeName(SummationSpecification const &s, GeometryInterface::InterestingQuantities const &iq)
string xlabel
Definition: compare.py:25
TH1 * getTH1(void) const
T min(T a, T b)
Definition: MathUtil.h:58
static const Value UNDEFINED
std::array< ID, 2 > Column
std::string ylabel
Definition: DetId.h:18
std::vector< AbstractHistogram * > fastpath
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:277
std::vector< GeometryInterface::Values > significantvalues
MonitorElement * book2D(Args &&...args)
Definition: DQMStore.h:133
std::map< GeometryInterface::Values, AbstractHistogram > Table
std::function< void(SummationStep &step, Table &t, DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter)> customHandler
HistogramManager(const edm::ParameterSet &iConfig, GeometryInterface &geo)
std::vector< Table > tables
edm::LuminosityBlock const * lumisection
std::pair< Column, Value > extract(Column const &col, InterestingQuantities const &iq)
std::vector< Table > counters
std::vector< InterestingQuantities > const & allModules()
step
dbl *** dir
Definition: mlp_gen.cc:35
void executePerEventHarvesting(edm::Event const *ev)
void book(DQMStore::IBooker &iBooker, edm::EventSetup const &iSetup)
int col
Definition: cuy.py:1008
GeometryInterface::InterestingQuantities iq
std::string makePath(GeometryInterface::Values const &)
#define SET_AXIS(to, from)
GeometryInterface & geometryInterface