CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MonitorElement.cc
Go to the documentation of this file.
1 #define __STDC_FORMAT_MACROS 1
3 #include "TClass.h"
4 #include "TMath.h"
5 #include "TList.h"
6 #include "THashList.h"
7 #include <iostream>
8 #include <cassert>
9 #include <cfloat>
10 #include <cinttypes>
11 
13 
14 namespace dqm::impl {
15 
16  static TH1 *checkRootObject(const std::string &name, TObject *tobj, const char *func, int reqdim) {
17  if (!tobj)
18  throw cms::Exception("MonitorElementError") << "Method '" << func
19  << "' cannot be invoked on monitor"
20  " element '"
21  << name << "' because it is not a ROOT object.";
22 
23  auto *h = static_cast<TH1 *>(tobj);
24  int ndim = h->GetDimension();
25  if (reqdim < 0 || reqdim > ndim)
26  throw cms::Exception("MonitorElementError") << "Method '" << func
27  << "' cannot be invoked on monitor"
28  " element '"
29  << name << "' because it requires " << reqdim
30  << " dimensions; this"
31  " object of type '"
32  << typeid(*h).name() << "' has " << ndim << " dimensions";
33 
34  return h;
35  }
36 
38  this->mutable_ = std::make_shared<MutableMonitorElementData>();
39  this->mutable_->data_ = std::move(data);
41  }
42  MonitorElement::MonitorElement(std::shared_ptr<MutableMonitorElementData> data) { switchData(std::move(data)); }
44 
47  auto access = this->access();
48  out.key_ = access.key;
50  if (access.value.object_) {
51  out.value_.object_ = std::unique_ptr<TH1>(static_cast<TH1 *>(access.value.object_->Clone()));
52  }
53  return out;
54  }
55 
56  std::shared_ptr<MutableMonitorElementData> MonitorElement::release() {
57  auto data = this->mutable_;
58  this->mutable_.reset();
59  return data;
60  }
61 
63  assert(other);
64  this->mutable_ = other->mutable_;
66  }
67 
68  void MonitorElement::switchData(std::shared_ptr<MutableMonitorElementData> data) {
69  this->mutable_ = std::move(data);
71  }
72 
73  void MonitorElement::switchObject(std::unique_ptr<TH1> &&newobject) {
74  auto access = this->accessMut();
75  // Assume kind etc. matches.
76  // This should free the old object.
77  access.value.object_ = std::move(newobject);
78  }
79 
81  auto access = this->accessMut();
83  }
84 
86  data_.flags &= ~DQMNet::DQM_PROP_TYPE_MASK;
87  data_.flags |= (int)access.key.kind_;
88 
89  // mark as updated.
91 
92  // lumi flag is approximately equivalent to Scope::LUMI.
94  if (access.key.scope_ == MonitorElementData::Scope::LUMI) {
96  }
97 
98  // these are unsupported and always off.
99  data_.flags &= ~DQMNet::DQM_PROP_HAS_REFERENCE;
100  data_.flags &= ~DQMNet::DQM_PROP_TAGGED;
101  data_.flags &= ~DQMNet::DQM_PROP_RESET;
102  data_.flags &= ~DQMNet::DQM_PROP_ACCUMULATE;
103 
104  // we use ROOT's internal efficiency flag as the truth
105  data_.flags &= ~DQMNet::DQM_PROP_EFFICIENCY_PLOT;
106  if (access.value.object_ && access.value.object_->TestBit(TH1::kIsAverage)) {
108  }
109 
110  data_.tag = 0;
111 
112  // don't touch version (a timestamp).
113 
114  // we could set proper values here, but nobody should use them.
115  data_.run = 0;
116  data_.lumi = 0;
117 
118  // these are relics from the threaded migration and should not be used anywhere.
119  data_.streamId = 0;
120  data_.moduleId = 0;
121 
122  // leaking a pointer here, but that should be fine.
123  data_.dirname = access.key.path_.getDirname();
124 
125  data_.objname = access.key.path_.getObjectname();
126 
127  data_.flags &= ~DQMNet::DQM_PROP_REPORT_ALARM;
128  data_.qreports.clear();
129  for (QReport const &qr : access.value.qreports_) {
130  data_.qreports.push_back(qr.getValue());
131  switch (qr.getStatus()) {
133  break;
136  break;
137  case dqm::qstatus::ERROR:
139  break;
140  default:
142  break;
143  }
144  }
145  }
146 
148 
149  //utility function to check the consistency of the axis labels
150  //taken from TH1::CheckBinLabels which is not public
151  bool MonitorElement::CheckBinLabels(const TAxis *a1, const TAxis *a2) {
152  // check that axis have same labels
153  THashList *l1 = (const_cast<TAxis *>(a1))->GetLabels();
154  THashList *l2 = (const_cast<TAxis *>(a2))->GetLabels();
155 
156  if (!l1 && !l2)
157  return true;
158  if (!l1 || !l2) {
159  return false;
160  }
161  // check now labels sizes are the same
162  if (l1->GetSize() != l2->GetSize()) {
163  return false;
164  }
165  for (int i = 1; i <= a1->GetNbins(); ++i) {
166  TString label1 = a1->GetBinLabel(i);
167  TString label2 = a2->GetBinLabel(i);
168  if (label1 != label2) {
169  return false;
170  }
171  }
172  return true;
173  }
174 
177  auto access = this->accessMut();
178  update();
179  if (kind() == Kind::STRING) {
181  } else {
182  incompatible(__PRETTY_FUNCTION__);
183  }
184  }
185 
187  void MonitorElement::Fill(double x) {
188  auto access = this->accessMut();
189  update();
190  if (kind() == Kind::INT)
191  access.value.scalar_.num = static_cast<int64_t>(x);
192  else if (kind() == Kind::REAL)
193  access.value.scalar_.real = x;
194  else if (kind() == Kind::TH1F)
195  accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, 1);
196  else if (kind() == Kind::TH1S)
197  accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, 1);
198  else if (kind() == Kind::TH1D)
199  accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, 1);
200  else
201  incompatible(__PRETTY_FUNCTION__);
202  }
203 
205  void MonitorElement::doFill(int64_t x) {
206  auto access = this->accessMut();
207  update();
208  if (kind() == Kind::INT)
209  access.value.scalar_.num = static_cast<int64_t>(x);
210  else if (kind() == Kind::REAL)
211  access.value.scalar_.real = static_cast<double>(x);
212  else if (kind() == Kind::TH1F)
213  accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(static_cast<double>(x), 1);
214  else if (kind() == Kind::TH1S)
215  accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(static_cast<double>(x), 1);
216  else if (kind() == Kind::TH1D)
217  accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(static_cast<double>(x), 1);
218  else
219  incompatible(__PRETTY_FUNCTION__);
220  }
221 
223  void MonitorElement::Fill(double x, double yw) {
224  auto access = this->accessMut();
225  update();
226  if (kind() == Kind::TH1F)
227  accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, yw);
228  else if (kind() == Kind::TH1S)
229  accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, yw);
230  else if (kind() == Kind::TH1D)
231  accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, yw);
232  else if (kind() == Kind::TH2F)
233  static_cast<TH2F *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, yw, 1);
234  else if (kind() == Kind::TH2S)
235  static_cast<TH2S *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, yw, 1);
236  else if (kind() == Kind::TH2D)
237  static_cast<TH2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, yw, 1);
238  else if (kind() == Kind::TPROFILE)
239  static_cast<TProfile *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->Fill(x, yw, 1);
240  else
241  incompatible(__PRETTY_FUNCTION__);
242  }
243 
247  void MonitorElement::ShiftFillLast(double y, double ye, int xscale) {
248  // TODO: this should take the lock only once to be actually safe.
249  // But since it is not const, we don't even claim it is thread-safe.
250  update();
251  if (kind() == Kind::TH1F || kind() == Kind::TH1S || kind() == Kind::TH1D) {
252  int nbins = getNbinsX();
253  auto entries = (int)getEntries();
254  // first fill bins from left to right
255  int index = entries + 1;
256  int xlow = 2;
257  int xup = nbins;
258  // if more entries than bins then start shifting
259  if (entries >= nbins) {
260  index = nbins;
261  xlow = entries - nbins + 3;
262  xup = entries + 1;
263  // average first bin
264  double y1 = getBinContent(1);
265  double y2 = getBinContent(2);
266  double y1err = getBinError(1);
267  double y2err = getBinError(2);
268  double N = entries - nbins + 1.;
269  if (ye == 0. || y1err == 0. || y2err == 0.) {
270  // for errors zero calculate unweighted mean and its error
271  double sum = N * y1 + y2;
272  y1 = sum / (N + 1.);
273  // FIXME check if correct
274  double s = (N + 1.) * (N * y1 * y1 + y2 * y2) - sum * sum;
275  if (s >= 0.)
276  y1err = sqrt(s) / (N + 1.);
277  else
278  y1err = 0.;
279  } else {
280  // for errors non-zero calculate weighted mean and its error
281  double denom = (1. / y1err + 1. / y2err);
282  double mean = (y1 / y1err + y2 / y2err) / denom;
283  // FIXME check if correct
284  y1err = sqrt(((y1 - mean) * (y1 - mean) / y1err + (y2 - mean) * (y2 - mean) / y2err) / denom / 2.);
285  y1 = mean; // set y1 to mean for filling below
286  }
287  setBinContent(1, y1);
288  setBinError(1, y1err);
289  // shift remaining bins to the left
290  for (int i = 3; i <= nbins; i++) {
292  setBinError(i - 1, getBinError(i));
293  }
294  }
295  // fill last bin with new values
296  setBinContent(index, y);
297  setBinError(index, ye);
298  // set entries
299  setEntries(entries + 1);
300  // set axis labels and reset drawing option
301  char buffer[10];
302  sprintf(buffer, "%d", xlow * xscale);
303  std::string a(buffer);
304  setBinLabel(2, a);
305  sprintf(buffer, "%d", xup * xscale);
306  std::string b(buffer);
307  setBinLabel(nbins, b);
308  setBinLabel(1, "av.");
309  } else
310  incompatible(__PRETTY_FUNCTION__);
311  }
313  void MonitorElement::Fill(double x, double y, double zw) {
314  auto access = this->accessMut();
315  update();
316  if (kind() == Kind::TH2F)
317  static_cast<TH2F *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw);
318  else if (kind() == Kind::TH2S)
319  static_cast<TH2S *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw);
320  else if (kind() == Kind::TH2D)
321  static_cast<TH2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw);
322  else if (kind() == Kind::TH3F)
323  static_cast<TH3F *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw, 1);
324  else if (kind() == Kind::TPROFILE)
325  static_cast<TProfile *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw);
326  else if (kind() == Kind::TPROFILE2D)
327  static_cast<TProfile2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw, 1);
328  else
329  incompatible(__PRETTY_FUNCTION__);
330  }
331 
333  void MonitorElement::Fill(double x, double y, double z, double w) {
334  auto access = this->accessMut();
335  update();
336  if (kind() == Kind::TH3F)
337  static_cast<TH3F *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, z, w);
338  else if (kind() == Kind::TPROFILE2D)
339  static_cast<TProfile2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, z, w);
340  else
341  incompatible(__PRETTY_FUNCTION__);
342  }
343 
346  auto access = this->accessMut();
347  update();
348  if (kind() == Kind::INT)
349  access.value.scalar_.num = 0;
350  else if (kind() == Kind::REAL)
351  access.value.scalar_.real = 0;
352  else if (kind() == Kind::STRING)
353  access.value.scalar_.str.clear();
354  else
355  return accessRootObject(access, __PRETTY_FUNCTION__, 1)->Reset();
356  }
357 
359  void MonitorElement::packScalarData(std::string &into, const char *prefix) const {
360  auto access = this->access();
361  char buf[64];
362  if (kind() == Kind::INT) {
363  snprintf(buf, sizeof(buf), "%s%" PRId64, prefix, access.value.scalar_.num);
364  into = buf;
365  } else if (kind() == Kind::REAL) {
366  snprintf(buf, sizeof(buf), "%s%.*g", prefix, DBL_DIG + 2, access.value.scalar_.real);
367  into = buf;
368  } else if (kind() == Kind::STRING) {
369  into.reserve(strlen(prefix) + access.value.scalar_.str.size());
370  into += prefix;
371  into += access.value.scalar_.str;
372  } else
373  incompatible(__PRETTY_FUNCTION__);
374  }
375 
378 
383  if (kind() == Kind::INT)
384  packScalarData(result, "i=");
385  else if (kind() == Kind::REAL)
386  packScalarData(result, "f=");
387  else if (kind() == Kind::STRING)
388  packScalarData(result, "s=");
389  else
390  incompatible(__PRETTY_FUNCTION__);
391 
392  return result;
393  }
394 
401  result.reserve(6 + 2 * data_.objname.size() + val.size());
402  result += '<';
403  result += data_.objname;
404  result += '>';
405  result += val;
406  result += '<';
407  result += '/';
408  result += data_.objname;
409  result += '>';
410  return result;
411  }
412 
415  char buf[32];
417  size_t len = sprintf(buf, "t=%" PRIu32, data_.tag);
418 
419  result.reserve(6 + 2 * data_.objname.size() + len);
420  result += '<';
421  result += data_.objname;
422  result += '>';
423  result += buf;
424  result += '<';
425  result += '/';
426  result += data_.objname;
427  result += '>';
428  return result;
429  }
430 
434 
435  result.reserve(6 + 2 * data_.objname.size() + 3);
436  result += '<';
437  result += data_.objname;
438  result += '>';
439  result += "e=1";
440  result += '<';
441  result += '/';
442  result += data_.objname;
443  result += '>';
444  return result;
445  }
446 
448  char buf[64];
450  size_t titlelen = data_.objname.size() + qv.qtname.size() + 1;
451  size_t buflen = sprintf(buf, "qr=st:%d:%.*g:", qv.code, DBL_DIG + 2, qv.qtresult);
452 
453  result.reserve(7 + 2 * titlelen + buflen + qv.algorithm.size() + qv.message.size());
454  result += '<';
455  result += data_.objname;
456  result += '.';
457  result += qv.qtname;
458  result += '>';
459  result += buf;
460  result += qv.algorithm;
461  result += ':';
462  result += qv.message;
463  result += '<';
464  result += '/';
465  result += data_.objname;
466  result += '.';
467  result += qv.qtname;
468  result += '>';
469  return result;
470  }
471 
474  DQMNet::QValue *qv;
475  const_cast<MonitorElement *>(this)->getQReport(false, qtname, qr, qv);
476  return qr;
477  }
478 
479  template <typename FILTER>
480  std::vector<MonitorElementData::QReport *> MonitorElement::filterQReports(FILTER filter) const {
481  auto access = this->access();
482  std::vector<MonitorElementData::QReport *> result;
484  if (filter(qr)) {
485  // const_cast here because this API always violated cons'ness. Should
486  // make the result type const and fix all usages.
487  result.push_back(const_cast<MonitorElementData::QReport *>(&qr));
488  }
489  }
490  return result;
491  }
492 
493  std::vector<MonitorElementData::QReport *> MonitorElement::getQReports() const {
494  return filterQReports([](MonitorElementData::QReport const &qr) { return true; });
495  }
496 
497  std::vector<MonitorElementData::QReport *> MonitorElement::getQWarnings() const {
498  return filterQReports(
499  [](MonitorElementData::QReport const &qr) { return qr.getStatus() == dqm::qstatus::WARNING; });
500  }
501 
502  std::vector<MonitorElementData::QReport *> MonitorElement::getQErrors() const {
503  return filterQReports([](MonitorElementData::QReport const &qr) { return qr.getStatus() == dqm::qstatus::ERROR; });
504  }
505 
506  std::vector<MonitorElementData::QReport *> MonitorElement::getQOthers() const {
507  return filterQReports([](MonitorElementData::QReport const &qr) {
510  });
511  }
512 
513  void MonitorElement::incompatible(const char *func) const {
514  throw cms::Exception("MonitorElementError") << "Method '" << func
515  << "' cannot be invoked on monitor"
516  " element '"
517  << data_.objname << "'";
518  }
519 
520  TH1 const *MonitorElement::accessRootObject(Access const &access, const char *func, int reqdim) const {
521  if (kind() < Kind::TH1F)
522  throw cms::Exception("MonitorElement") << "Method '" << func
523  << "' cannot be invoked on monitor"
524  " element '"
525  << data_.objname << "' because it is not a root object";
526  return access.value.object_.get();
527  }
528  TH1 *MonitorElement::accessRootObject(AccessMut const &access, const char *func, int reqdim) const {
529  if (kind() < Kind::TH1F)
530  throw cms::Exception("MonitorElement") << "Method '" << func
531  << "' cannot be invoked on monitor"
532  " element '"
533  << data_.objname << "' because it is not a root object";
534  return checkRootObject(data_.objname, access.value.object_.get(), func, reqdim);
535  }
536 
537  /*** getter methods (wrapper around ROOT methods) ****/
538  //
540  double MonitorElement::getMean(int axis /* = 1 */) const {
541  auto access = this->access();
542  return accessRootObject(access, __PRETTY_FUNCTION__, axis - 1)->GetMean(axis);
543  }
544 
547  double MonitorElement::getMeanError(int axis /* = 1 */) const {
548  auto access = this->access();
549  return accessRootObject(access, __PRETTY_FUNCTION__, axis - 1)->GetMeanError(axis);
550  }
551 
553  double MonitorElement::getRMS(int axis /* = 1 */) const {
554  auto access = this->access();
555  return accessRootObject(access, __PRETTY_FUNCTION__, axis - 1)->GetRMS(axis);
556  }
557 
559  double MonitorElement::getRMSError(int axis /* = 1 */) const {
560  auto access = this->access();
561  return accessRootObject(access, __PRETTY_FUNCTION__, axis - 1)->GetRMSError(axis);
562  }
563 
566  auto access = this->access();
567  return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetNbinsX();
568  }
569 
572  auto access = this->access();
573  return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetNbinsY();
574  }
575 
578  auto access = this->access();
579  return accessRootObject(access, __PRETTY_FUNCTION__, 3)->GetNbinsZ();
580  }
581 
583  double MonitorElement::getBinContent(int binx) const {
584  auto access = this->access();
585  return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetBinContent(binx);
586  }
587 
589  double MonitorElement::getBinContent(int binx, int biny) const {
590  auto access = this->access();
591  return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetBinContent(binx, biny);
592  }
593 
595  double MonitorElement::getBinContent(int binx, int biny, int binz) const {
596  auto access = this->access();
597  return accessRootObject(access, __PRETTY_FUNCTION__, 3)->GetBinContent(binx, biny, binz);
598  }
599 
601  double MonitorElement::getBinError(int binx) const {
602  auto access = this->access();
603  return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetBinError(binx);
604  }
605 
607  double MonitorElement::getBinError(int binx, int biny) const {
608  auto access = this->access();
609  return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetBinError(binx, biny);
610  }
611 
613  double MonitorElement::getBinError(int binx, int biny, int binz) const {
614  auto access = this->access();
615  return accessRootObject(access, __PRETTY_FUNCTION__, 3)->GetBinError(binx, biny, binz);
616  }
617 
619  double MonitorElement::getEntries() const {
620  auto access = this->access();
621  return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetEntries();
622  }
623 
625  int MonitorElement::getBin(int binx, int biny) const {
626  auto access = this->access();
627  if (kind() == Kind::TPROFILE2D)
628  return static_cast<TProfile2D const *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->GetBin(binx, biny);
629  else {
630  incompatible(__PRETTY_FUNCTION__);
631  return 0;
632  }
633  }
634 
636  double MonitorElement::getBinEntries(int bin) const {
637  auto access = this->access();
638  if (kind() == Kind::TPROFILE)
639  return static_cast<TProfile const *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->GetBinEntries(bin);
640  else if (kind() == Kind::TPROFILE2D)
641  return static_cast<TProfile2D const *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->GetBinEntries(bin);
642  else {
643  incompatible(__PRETTY_FUNCTION__);
644  return 0;
645  }
646  }
647 
649  double MonitorElement::getBinEntries(int binx, int biny) const {
650  auto access = this->access();
651  if (kind() == Kind::TPROFILE2D) {
652  int globBin =
653  static_cast<TProfile2D const *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->GetBin(binx, biny);
654  return static_cast<TProfile2D const *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->GetBinEntries(globBin);
655  } else {
656  incompatible(__PRETTY_FUNCTION__);
657  return 0;
658  }
659  }
660 
662  double MonitorElement::integral() const {
663  auto access = this->access();
664  return accessRootObject(access, __PRETTY_FUNCTION__, 1)->Integral();
665  }
666 
668  std::string MonitorElement::getAxisTitle(int axis /* = 1 */) const {
669  auto access = this->access();
670  return getAxis(access, __PRETTY_FUNCTION__, axis)->GetTitle();
671  }
672 
675  auto access = this->access();
676  return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetTitle();
677  }
678 
679  /*** setter methods (wrapper around ROOT methods) ****/
680  //
682  void MonitorElement::setBinContent(int binx, double content) {
683  auto access = this->accessMut();
684  accessRootObject(access, __PRETTY_FUNCTION__, 1)->SetBinContent(binx, content);
685  }
686 
688  void MonitorElement::setBinContent(int binx, int biny, double content) {
689  auto access = this->accessMut();
690  accessRootObject(access, __PRETTY_FUNCTION__, 2)->SetBinContent(binx, biny, content);
691  }
692 
694  void MonitorElement::setBinContent(int binx, int biny, int binz, double content) {
695  auto access = this->accessMut();
696  accessRootObject(access, __PRETTY_FUNCTION__, 3)->SetBinContent(binx, biny, binz, content);
697  }
698 
700  void MonitorElement::setBinError(int binx, double error) {
701  auto access = this->accessMut();
702  accessRootObject(access, __PRETTY_FUNCTION__, 1)->SetBinError(binx, error);
703  }
704 
706  void MonitorElement::setBinError(int binx, int biny, double error) {
707  auto access = this->accessMut();
708  accessRootObject(access, __PRETTY_FUNCTION__, 2)->SetBinError(binx, biny, error);
709  }
710 
712  void MonitorElement::setBinError(int binx, int biny, int binz, double error) {
713  auto access = this->accessMut();
714  accessRootObject(access, __PRETTY_FUNCTION__, 3)->SetBinError(binx, biny, binz, error);
715  }
716 
718  void MonitorElement::setBinEntries(int bin, double nentries) {
719  auto access = this->accessMut();
720  if (kind() == Kind::TPROFILE)
721  static_cast<TProfile *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->SetBinEntries(bin, nentries);
722  else if (kind() == Kind::TPROFILE2D)
723  static_cast<TProfile2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->SetBinEntries(bin, nentries);
724  else
725  incompatible(__PRETTY_FUNCTION__);
726  }
727 
729  void MonitorElement::setEntries(double nentries) {
730  auto access = this->accessMut();
731  accessRootObject(access, __PRETTY_FUNCTION__, 1)->SetEntries(nentries);
732  }
733 
736  const MonitorElement *num, const MonitorElement *denom, double c1, double c2, const char *options) {
737  if (num->kind() < Kind::TH1F)
738  num->incompatible(__PRETTY_FUNCTION__);
739  if (denom->kind() < Kind::TH1F)
740  denom->incompatible(__PRETTY_FUNCTION__);
741 
742  TH1 const *numH = static_cast<TH1 const *>(num->getRootObject());
743  TH1 const *denomH = static_cast<TH1 const *>(denom->getRootObject());
744  TH1 *thisH = getTH1();
745 
746  //Need to take locks in a consistent order to avoid deadlocks. Use pointer value order of underlying ROOT object..
747  //This is known as the monitor pattern.
748  std::array<const MonitorElement *, 3> order{{this, num, denom}};
749  std::sort(order.begin(), order.end(), [](auto const *lhs, auto const *rhs) {
750  return lhs->mutable_->data_.value_.object_.get() < rhs->mutable_->data_.value_.object_.get();
751  });
752 
753  auto a0 = order[0]->access();
754  auto a1 = order[1]->access();
755  auto a2 = order[2]->access();
756 
757  //Have ROOT do check that the types are compatible
758  thisH->Divide(numH, denomH, c1, c2, options);
759  }
760 
762  void MonitorElement::setBinLabel(int bin, const std::string &label, int axis /* = 1 */) {
763  bool fail = false;
764  {
765  auto access = this->accessMut();
766  update();
767  if (getAxis(access, __PRETTY_FUNCTION__, axis)->GetNbins() >= bin) {
768  getAxis(access, __PRETTY_FUNCTION__, axis)->SetBinLabel(bin, label.c_str());
769  } else {
770  fail = true;
771  }
772  }
773  // do this with the ME lock released to prevent a deadlock
774  if (fail) {
775  // this also takes the lock, make sure to release it before going to edm
776  // (which might take more locks)
777  auto name = getFullname();
778  edm::LogWarning("MonitorElement") << "*** MonitorElement: WARNING:"
779  << "setBinLabel: attempting to set label of non-existent bin number for ME: "
780  << name << " \n";
781  }
782  }
783 
785  void MonitorElement::setAxisRange(double xmin, double xmax, int axis /* = 1 */) {
786  auto access = this->accessMut();
787  getAxis(access, __PRETTY_FUNCTION__, axis)->SetRangeUser(xmin, xmax);
788  }
789 
791  void MonitorElement::setAxisTitle(const std::string &title, int axis /* = 1 */) {
792  auto access = this->accessMut();
793  getAxis(access, __PRETTY_FUNCTION__, axis)->SetTitle(title.c_str());
794  }
795 
797  void MonitorElement::setAxisTimeDisplay(int value, int axis /* = 1 */) {
798  auto access = this->accessMut();
799  getAxis(access, __PRETTY_FUNCTION__, axis)->SetTimeDisplay(value);
800  }
801 
803  void MonitorElement::setAxisTimeFormat(const char *format /* = "" */, int axis /* = 1 */) {
804  auto access = this->accessMut();
805  getAxis(access, __PRETTY_FUNCTION__, axis)->SetTimeFormat(format);
806  }
807 
810  auto access = this->accessMut();
811  accessRootObject(access, __PRETTY_FUNCTION__, 1)->SetTitle(title.c_str());
812  }
813 
814  TAxis *MonitorElement::getAxis(AccessMut const &access, const char *func, int axis) const {
815  TH1 *h = accessRootObject(access, func, axis - 1);
816  TAxis *a = nullptr;
817  if (axis == 1)
818  a = h->GetXaxis();
819  else if (axis == 2)
820  a = h->GetYaxis();
821  else if (axis == 3)
822  a = h->GetZaxis();
823 
824  if (!a)
825  throw cms::Exception("MonitorElementError") << "No such axis " << axis
826  << " in monitor element"
827  " '"
828  << data_.objname << "' of type '" << typeid(*h).name() << "'";
829 
830  return a;
831  }
832 
833  TAxis const *MonitorElement::getAxis(Access const &access, const char *func, int axis) const {
834  TH1 const *h = accessRootObject(access, func, axis - 1);
835  TAxis const *a = nullptr;
836  if (axis == 1)
837  a = h->GetXaxis();
838  else if (axis == 2)
839  a = h->GetYaxis();
840  else if (axis == 3)
841  a = h->GetZaxis();
842 
843  if (!a)
844  throw cms::Exception("MonitorElementError") << "No such axis " << axis
845  << " in monitor element"
846  " '"
847  << data_.objname << "' of type '" << typeid(*h).name() << "'";
848 
849  return a;
850  }
851 
853  auto access = this->accessMut();
854  update();
855  access.value.object_->SetXTitle(title.c_str());
856  }
858  auto access = this->accessMut();
859  update();
860  access.value.object_->SetYTitle(title.c_str());
861  }
862 
864  auto access = this->accessMut();
865  update();
866  if (access.value.object_->GetSumw2() == nullptr) {
867  access.value.object_->Sumw2();
868  }
869  }
870 
872  auto access = this->accessMut();
873  update();
874  access.value.object_->GetXaxis()->SetNoAlphanumeric(false);
875  access.value.object_->GetYaxis()->SetNoAlphanumeric(false);
876  }
877 
878  void MonitorElement::setOption(const char *option) {
879  auto access = this->accessMut();
880  update();
881  access.value.object_->SetOption(option);
882  }
883  double MonitorElement::getAxisMin(int axis) const {
884  auto access = this->access();
885  return getAxis(access, __PRETTY_FUNCTION__, axis)->GetXmin();
886  }
887 
888  double MonitorElement::getAxisMax(int axis) const {
889  auto access = this->access();
890  return getAxis(access, __PRETTY_FUNCTION__, axis)->GetXmax();
891  }
892 
893  void MonitorElement::setCanExtend(unsigned int value) {
894  auto access = this->accessMut();
895  access.value.object_->SetCanExtend(value);
896  }
897 
899  auto access = this->accessMut();
900  if (value == kTRUE)
901  access.value.object_->SetStatOverflows(TH1::kConsider);
902  else
903  access.value.object_->SetStatOverflows(TH1::kIgnore);
904  }
905 
907  auto access = this->accessMut();
908  auto value = access.value.object_->GetStatOverflows();
909  if (value == TH1::kConsider)
910  return true;
911  else
912  return false;
913  }
914 
915  int64_t MonitorElement::getIntValue() const {
916  assert(kind() == Kind::INT);
917  auto access = this->access();
918  return access.value.scalar_.num;
919  }
921  assert(kind() == Kind::REAL);
922  auto access = this->access();
923  return access.value.scalar_.real;
924  }
926  assert(kind() == Kind::STRING);
927  auto access = this->access();
928  return access.value.scalar_.str;
929  }
930 
932  const std::string &qtname,
934  DQMNet::QValue *&qv) {
935  auto access = this->accessMut();
936 
938 
939  assert(access.value.qreports_.size() == data_.qreports.size());
940 
941  qr = nullptr;
942  qv = nullptr;
943 
944  size_t pos = 0, end = access.value.qreports_.size();
945  while (pos < end && data_.qreports[pos].qtname != qtname)
946  ++pos;
947 
948  if (pos == end && !create)
949  return;
950  else if (pos == end) {
953  q.qtresult = 0;
954  q.qtname = qtname;
955  q.message = "NO_MESSAGE_ASSIGNED";
956  q.algorithm = "UNKNOWN_ALGORITHM";
959  }
960 
961  qr = &access.value.qreports_[pos];
962  qv = &(qr->getValue());
963  }
964 
965  // -------------------------------------------------------------------
966  // TODO: all of these are UNSAFE and have to be NON-const.
967  TObject const *MonitorElement::getRootObject() const {
968  auto access = this->access();
969  return access.value.object_.get();
970  }
971 
973  auto access = this->accessMut();
974  return accessRootObject(access, __PRETTY_FUNCTION__, 0);
975  }
976 
978  auto access = this->accessMut();
979  assert(kind() == Kind::TH1F);
980  return static_cast<TH1F *>(accessRootObject(access, __PRETTY_FUNCTION__, 1));
981  }
982 
984  auto access = this->accessMut();
985  assert(kind() == Kind::TH1S);
986  return static_cast<TH1S *>(accessRootObject(access, __PRETTY_FUNCTION__, 1));
987  }
988 
990  auto access = this->accessMut();
991  assert(kind() == Kind::TH1D);
992  return static_cast<TH1D *>(accessRootObject(access, __PRETTY_FUNCTION__, 1));
993  }
994 
996  auto access = this->accessMut();
997  assert(kind() == Kind::TH2F);
998  return static_cast<TH2F *>(accessRootObject(access, __PRETTY_FUNCTION__, 2));
999  }
1000 
1002  auto access = this->accessMut();
1003  assert(kind() == Kind::TH2S);
1004  return static_cast<TH2S *>(accessRootObject(access, __PRETTY_FUNCTION__, 2));
1005  }
1006 
1008  auto access = this->accessMut();
1009  assert(kind() == Kind::TH2D);
1010  return static_cast<TH2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2));
1011  }
1012 
1014  auto access = this->accessMut();
1015  assert(kind() == Kind::TH3F);
1016  return static_cast<TH3F *>(accessRootObject(access, __PRETTY_FUNCTION__, 3));
1017  }
1018 
1020  auto access = this->accessMut();
1021  assert(kind() == Kind::TPROFILE);
1022  return static_cast<TProfile *>(accessRootObject(access, __PRETTY_FUNCTION__, 1));
1023  }
1024 
1026  auto access = this->accessMut();
1028  return static_cast<TProfile2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2));
1029  }
1030 
1031 } // namespace dqm::impl
virtual std::string getTitle() const
get MonitorElement title
static const uint32_t DQM_PROP_REPORT_WARN
Definition: DQMNet.h:50
virtual void setTitle(const std::string &title)
set (ie. change) histogram/profile title
std::shared_ptr< MutableMonitorElementData > mutable_
uint32_t moduleId
Definition: DQMNet.h:95
QReports qreports
Definition: DQMNet.h:98
virtual DQM_DEPRECATED void setCanExtend(unsigned int value)
virtual double integral() const
get integral of bins
virtual void disableAlphanumeric()
const double w
Definition: UKUtility.cc:23
std::shared_ptr< MutableMonitorElementData > release()
TAxis const * getAxis(Access const &access, const char *func, int axis) const
virtual int getNbinsY() const
get # of bins in Y-axis
DQMNet::CoreObject data_
virtual double getAxisMin(int axis=1) const
virtual void setEntries(double nentries)
set # of entries
virtual void setAxisTimeDisplay(int value, int axis=1)
set x-, y-, or z-axis to display time values
MonitorElementData::Key const & key
Definition: DQMNet.h:26
virtual void setOption(const char *option)
virtual void setAxisTimeFormat(const char *format="", int axis=1)
set the format of the time values that are displayed on an axis
uint32_t flags
Definition: DQMNet.h:89
edm::propagate_const< std::unique_ptr< TH1 > > object_
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check the consistency of the axis labels.
virtual double getBinError(int binx) const
get uncertainty on content of bin (1-D) - See TH1::GetBinError for details
virtual int64_t getIntValue() const
virtual int getNbinsZ() const
get # of bins in Z-axis
virtual std::string getAxisTitle(int axis=1) const
get x-, y- or z-axis title (axis=1, 2, 3 respectively)
static const int WARNING
Kind kind() const
Get the type of the monitor element.
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t Func __host__ __device__ V int Func func
static const uint32_t DQM_PROP_EFFICIENCY_PLOT
Definition: DQMNet.h:64
uint32_t tag
Definition: DQMNet.h:90
virtual bool getStatOverflows()
const MonitorElementData::QReport * getQReport(const std::string &qtname) const
get QReport corresponding to &lt;qtname&gt; (null pointer if QReport does not exist)
MonitorElement(MonitorElementData &&data)
assert(be >=bs)
void packQualityData(std::string &into) const
serialise quality report information into a string.
std::vector< MonitorElementData::QReport * > getQOthers() const
from last set of quality tests
void Fill(double x, double y, double z, double w)
can be used with 3D (x, y, z, w) histograms
void incompatible(const char *func) const
uint32_t run
Definition: DQMNet.h:92
void switchData(MonitorElement *other)
int getStatus() const
get test status
tuple result
Definition: mps_fire.py:311
void Fill(long long x)
virtual void Reset()
Remove all data from the ME, keept the empty histogram with all its settings.
DQM_DEPRECATED void ShiftFillLast(double y, double ye=0., int32_t xscale=1)
std::vector< MonitorElementData::QReport * > getQErrors() const
get errors from last set of quality tests
char const * label
MonitorElementData::QReport QReport
std::vector< MonitorElementData::QReport * > getQReports() const
get map of QReports
std::string const & getDirname() const
virtual void setXTitle(std::string const &title)
virtual TProfile2D * getTProfile2D()
virtual int getNbinsX() const
get # of bins in X-axis
virtual void setAxisRange(double xmin, double xmax, int axis=1)
set x-, y- or z-axis range (axis=1, 2, 3 respectively)
virtual double getEntries() const
get # of entries
std::string tagString() const
T sqrt(T t)
Definition: SSEVec.h:19
uint32_t lumi
Definition: DQMNet.h:93
void switchObject(std::unique_ptr< TH1 > &&newobject)
if(conf_.getParameter< bool >("UseStripCablingDB"))
def move
Definition: eostools.py:511
void doFill(int64_t x)
&quot;Fill&quot; ME method for int64_t
MonitorElementData cloneMEData()
static const int DID_NOT_RUN
static const uint32_t DQM_PROP_REPORT_ERROR
Definition: DQMNet.h:49
std::string dirname
Definition: DQMNet.h:96
static const uint32_t DQM_PROP_REPORT_OTHER
Definition: DQMNet.h:51
virtual void setBinLabel(int bin, const std::string &label, int axis=1)
set bin label for x, y or z axis (axis=1, 2, 3 respectively)
virtual double getBinContent(int binx) const
get content of bin (1-D)
virtual TProfile * getTProfile()
std::string objname
Definition: DQMNet.h:97
MonitorElementData::Value & value
void packScalarData(std::string &into, const char *prefix) const
convert scalar data into a string.
std::vector< MonitorElementData::QReport * > filterQReports(FILTER filter) const
MonitorElementData::Value const & value
void update()
Mark the object updated.
virtual double getMean(int axis=1) const
get mean value of histogram along x, y or z axis (axis=1, 2, 3 respectively)
virtual void setYTitle(std::string const &title)
virtual void setBinEntries(int bin, double nentries)
set # of bin entries (to be used for profiles)
virtual int getBin(int binx, int biny) const
get global bin number (for 2-D profiles)
#define N
Definition: blowfish.cc:9
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
static constexpr float a0
virtual double getMeanError(int axis=1) const
MonitorElementData::Key const & key
virtual double getRMS(int axis=1) const
get RMS of histogram along x, y or z axis (axis=1, 2, 3 respectively)
double b
Definition: hdecay.h:118
virtual DQM_DEPRECATED void setStatOverflows(bool value)
static void packQualityData(std::string &into, const QReports &qr)
Definition: DQMNet.cc:158
std::string valueString() const
virtual double getBinEntries(int bin) const
get # of bin entries (for profiles)
std::string const & getObjectname() const
constexpr element_type const * get() const
std::vector< MonitorElementData::QReport * > getQWarnings() const
get warnings from last set of quality tests
std::vector< QReport > qreports_
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
virtual double getFloatValue() const
double a
Definition: hdecay.h:119
const Access access() const
virtual const std::string & getStringValue() const
std::string tagLabelString() const
return label string for the monitor element tag (eg. &lt;name&gt;t=12345&lt;/name&gt;)
virtual double getRMSError(int axis=1) const
get RMS uncertainty of histogram along x, y or z axis(axis=1,2,3 respectively)
std::string getFullname() const
get full name of ME including Pathname
string end
Definition: dataset.py:937
static const int STATUS_OK
auto zw(V v) -> Vec2< typename std::remove_reference< decltype(v[0])>::type >
Definition: ExtVec.h:75
QValue & getValue()
access underlying value
virtual void setBinError(int binx, double error)
set uncertainty on content of bin (1-D)
static TH1 * checkRootObject(const std::string &name, TObject *tobj, const char *func, int reqdim)
static const uint32_t DQM_PROP_NEW
Definition: DQMNet.h:59
Log< level::Warning, false > LogWarning
TH1 const * accessRootObject(Access const &access, const char *func, int reqdim) const
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
uint32_t streamId
Definition: DQMNet.h:94
virtual TObject const * getRootObject() const
std::string effLabelString() const
return label string for the monitor element tag (eg. &lt;name&gt;t=12345&lt;/name&gt;)
static const uint32_t DQM_PROP_LUMI
Definition: DQMNet.h:61
virtual double getAxisMax(int axis=1) const
virtual void divide(const MonitorElement *, const MonitorElement *, double, double, const char *)
Replace entries with results of dividing num by denom.
std::string qualityTagString(const DQMNet::QValue &qv) const
static const int ERROR
virtual void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)