File indexing completed on 2025-03-10 23:53:32
0001 #define __STDC_FORMAT_MACROS 1
0002 #include "DQMServices/Core/interface/MonitorElement.h"
0003 #include "TClass.h"
0004 #include "TMath.h"
0005 #include "TList.h"
0006 #include "THashList.h"
0007 #include <iostream>
0008 #include <cassert>
0009 #include <cfloat>
0010 #include <cinttypes>
0011
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013
0014 namespace dqm::impl {
0015
0016 static TH1 *checkRootObject(const std::string &name, TObject *tobj, const char *func, int reqdim) {
0017 if (!tobj)
0018 throw cms::Exception("MonitorElementError") << "Method '" << func
0019 << "' cannot be invoked on monitor"
0020 " element '"
0021 << name << "' because it is not a ROOT object.";
0022
0023 auto *h = static_cast<TH1 *>(tobj);
0024 int ndim = h->GetDimension();
0025 if (reqdim < 0 || reqdim > ndim)
0026 throw cms::Exception("MonitorElementError") << "Method '" << func
0027 << "' cannot be invoked on monitor"
0028 " element '"
0029 << name << "' because it requires " << reqdim
0030 << " dimensions; this"
0031 " object of type '"
0032 << typeid(*h).name() << "' has " << ndim << " dimensions";
0033
0034 return h;
0035 }
0036
0037 MonitorElement::MonitorElement(MonitorElementData &&data) {
0038 this->mutable_ = std::make_shared<MutableMonitorElementData>();
0039 this->mutable_->data_ = std::move(data);
0040 syncCoreObject();
0041 }
0042 MonitorElement::MonitorElement(std::shared_ptr<MutableMonitorElementData> data) { switchData(std::move(data)); }
0043 MonitorElement::MonitorElement(MonitorElement *me) { switchData(me); }
0044
0045 MonitorElementData MonitorElement::cloneMEData() {
0046 MonitorElementData out;
0047 auto access = this->access();
0048 out.key_ = access.key;
0049 out.value_.scalar_ = access.value.scalar_;
0050 if (access.value.object_) {
0051 out.value_.object_ = std::unique_ptr<TH1>(static_cast<TH1 *>(access.value.object_->Clone()));
0052 }
0053 return out;
0054 }
0055
0056 std::shared_ptr<MutableMonitorElementData> MonitorElement::release() {
0057 auto data = this->mutable_;
0058 this->mutable_.reset();
0059 return data;
0060 }
0061
0062 void MonitorElement::switchData(MonitorElement *other) {
0063 assert(other);
0064 this->mutable_ = other->mutable_;
0065 syncCoreObject();
0066 }
0067
0068 void MonitorElement::switchData(std::shared_ptr<MutableMonitorElementData> data) {
0069 this->mutable_ = std::move(data);
0070 syncCoreObject();
0071 }
0072
0073 void MonitorElement::switchObject(std::unique_ptr<TH1> &&newobject) {
0074 auto access = this->accessMut();
0075
0076
0077 access.value.object_ = std::move(newobject);
0078 }
0079
0080 void MonitorElement::syncCoreObject() {
0081 auto access = this->accessMut();
0082 syncCoreObject(access);
0083 }
0084
0085 void MonitorElement::syncCoreObject(AccessMut &access) {
0086 data_.flags &= ~DQMNet::DQM_PROP_TYPE_MASK;
0087 data_.flags |= (int)access.key.kind_;
0088
0089
0090 data_.flags |= DQMNet::DQM_PROP_NEW;
0091
0092
0093 data_.flags &= ~DQMNet::DQM_PROP_LUMI;
0094 if (access.key.scope_ == MonitorElementData::Scope::LUMI) {
0095 data_.flags |= DQMNet::DQM_PROP_LUMI;
0096 }
0097
0098
0099 data_.flags &= ~DQMNet::DQM_PROP_HAS_REFERENCE;
0100 data_.flags &= ~DQMNet::DQM_PROP_TAGGED;
0101 data_.flags &= ~DQMNet::DQM_PROP_RESET;
0102 data_.flags &= ~DQMNet::DQM_PROP_ACCUMULATE;
0103
0104
0105 data_.flags &= ~DQMNet::DQM_PROP_EFFICIENCY_PLOT;
0106 if (access.value.object_ && access.value.object_->TestBit(TH1::kIsAverage)) {
0107 data_.flags |= DQMNet::DQM_PROP_EFFICIENCY_PLOT;
0108 }
0109
0110 data_.tag = 0;
0111
0112
0113
0114
0115 data_.run = 0;
0116 data_.lumi = 0;
0117
0118
0119 data_.streamId = 0;
0120 data_.moduleId = 0;
0121
0122
0123 data_.dirname = access.key.path_.getDirname();
0124
0125 data_.objname = access.key.path_.getObjectname();
0126
0127 data_.flags &= ~DQMNet::DQM_PROP_REPORT_ALARM;
0128 data_.qreports.clear();
0129 for (QReport const &qr : access.value.qreports_) {
0130 data_.qreports.push_back(qr.getValue());
0131 switch (qr.getStatus()) {
0132 case dqm::qstatus::STATUS_OK:
0133 break;
0134 case dqm::qstatus::WARNING:
0135 data_.flags |= DQMNet::DQM_PROP_REPORT_WARN;
0136 break;
0137 case dqm::qstatus::ERROR:
0138 data_.flags |= DQMNet::DQM_PROP_REPORT_ERROR;
0139 break;
0140 default:
0141 data_.flags |= DQMNet::DQM_PROP_REPORT_OTHER;
0142 break;
0143 }
0144 }
0145 }
0146
0147 MonitorElement::~MonitorElement() {}
0148
0149
0150
0151 bool MonitorElement::CheckBinLabels(const TAxis *a1, const TAxis *a2) {
0152
0153 THashList *l1 = (const_cast<TAxis *>(a1))->GetLabels();
0154 THashList *l2 = (const_cast<TAxis *>(a2))->GetLabels();
0155
0156 if (!l1 && !l2)
0157 return true;
0158 if (!l1 || !l2) {
0159 return false;
0160 }
0161
0162 if (l1->GetSize() != l2->GetSize()) {
0163 return false;
0164 }
0165 for (int i = 1; i <= a1->GetNbins(); ++i) {
0166 TString label1 = a1->GetBinLabel(i);
0167 TString label2 = a2->GetBinLabel(i);
0168 if (label1 != label2) {
0169 return false;
0170 }
0171 }
0172 return true;
0173 }
0174
0175
0176 void MonitorElement::Fill(std::string &value) {
0177 auto access = this->accessMut();
0178 update();
0179 if (kind() == Kind::STRING) {
0180 access.value.scalar_.str = value;
0181 } else {
0182 incompatible(__PRETTY_FUNCTION__);
0183 }
0184 }
0185
0186
0187 void MonitorElement::Fill(double x) {
0188 auto access = this->accessMut();
0189 update();
0190 if (kind() == Kind::INT)
0191 access.value.scalar_.num = static_cast<int64_t>(x);
0192 else if (kind() == Kind::REAL)
0193 access.value.scalar_.real = x;
0194 else if (kind() == Kind::TH1F)
0195 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, 1);
0196 else if (kind() == Kind::TH1S)
0197 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, 1);
0198 else if (kind() == Kind::TH1I)
0199 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, 1);
0200 else if (kind() == Kind::TH1D)
0201 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, 1);
0202 else
0203 incompatible(__PRETTY_FUNCTION__);
0204 }
0205
0206
0207 void MonitorElement::doFill(int64_t x) {
0208 auto access = this->accessMut();
0209 update();
0210 if (kind() == Kind::INT)
0211 access.value.scalar_.num = static_cast<int64_t>(x);
0212 else if (kind() == Kind::REAL)
0213 access.value.scalar_.real = static_cast<double>(x);
0214 else if (kind() == Kind::TH1F)
0215 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(static_cast<double>(x), 1);
0216 else if (kind() == Kind::TH1S)
0217 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(static_cast<double>(x), 1);
0218 else if (kind() == Kind::TH1I)
0219 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(static_cast<double>(x), 1);
0220 else if (kind() == Kind::TH1D)
0221 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(static_cast<double>(x), 1);
0222 else
0223 incompatible(__PRETTY_FUNCTION__);
0224 }
0225
0226
0227 void MonitorElement::Fill(double x, double yw) {
0228 auto access = this->accessMut();
0229 update();
0230 if (kind() == Kind::TH1F)
0231 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, yw);
0232 else if (kind() == Kind::TH1S)
0233 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, yw);
0234 else if (kind() == Kind::TH1D)
0235 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, yw);
0236 else if (kind() == Kind::TH1I)
0237 accessRootObject(access, __PRETTY_FUNCTION__, 1)->Fill(x, yw);
0238 else if (kind() == Kind::TH2F)
0239 static_cast<TH2F *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, yw, 1);
0240 else if (kind() == Kind::TH2S)
0241 static_cast<TH2S *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, yw, 1);
0242 else if (kind() == Kind::TH2D)
0243 static_cast<TH2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, yw, 1);
0244 else if (kind() == Kind::TH2I)
0245 static_cast<TH2I *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, yw, 1);
0246 else if (kind() == Kind::TH2Poly)
0247 static_cast<TH2Poly *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, yw, 1);
0248 else if (kind() == Kind::TPROFILE)
0249 static_cast<TProfile *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->Fill(x, yw, 1);
0250 else
0251 incompatible(__PRETTY_FUNCTION__);
0252 }
0253
0254
0255
0256
0257 void MonitorElement::ShiftFillLast(double y, double ye, int xscale) {
0258
0259
0260 update();
0261 if (kind() == Kind::TH1F || kind() == Kind::TH1S || kind() == Kind::TH1D || kind() == Kind::TH1I) {
0262 int nbins = getNbinsX();
0263 auto entries = (int)getEntries();
0264
0265 int index = entries + 1;
0266 int xlow = 2;
0267 int xup = nbins;
0268
0269 if (entries >= nbins) {
0270 index = nbins;
0271 xlow = entries - nbins + 3;
0272 xup = entries + 1;
0273
0274 double y1 = getBinContent(1);
0275 double y2 = getBinContent(2);
0276 double y1err = getBinError(1);
0277 double y2err = getBinError(2);
0278 double N = entries - nbins + 1.;
0279 if (ye == 0. || y1err == 0. || y2err == 0.) {
0280
0281 double sum = N * y1 + y2;
0282 y1 = sum / (N + 1.);
0283
0284 double s = (N + 1.) * (N * y1 * y1 + y2 * y2) - sum * sum;
0285 if (s >= 0.)
0286 y1err = sqrt(s) / (N + 1.);
0287 else
0288 y1err = 0.;
0289 } else {
0290
0291 double denom = (1. / y1err + 1. / y2err);
0292 double mean = (y1 / y1err + y2 / y2err) / denom;
0293
0294 y1err = sqrt(((y1 - mean) * (y1 - mean) / y1err + (y2 - mean) * (y2 - mean) / y2err) / denom / 2.);
0295 y1 = mean;
0296 }
0297 setBinContent(1, y1);
0298 setBinError(1, y1err);
0299
0300 for (int i = 3; i <= nbins; i++) {
0301 setBinContent(i - 1, getBinContent(i));
0302 setBinError(i - 1, getBinError(i));
0303 }
0304 }
0305
0306 setBinContent(index, y);
0307 setBinError(index, ye);
0308
0309 setEntries(entries + 1);
0310
0311 char buffer[10];
0312 sprintf(buffer, "%d", xlow * xscale);
0313 std::string a(buffer);
0314 setBinLabel(2, a);
0315 sprintf(buffer, "%d", xup * xscale);
0316 std::string b(buffer);
0317 setBinLabel(nbins, b);
0318 setBinLabel(1, "av.");
0319 } else
0320 incompatible(__PRETTY_FUNCTION__);
0321 }
0322
0323 void MonitorElement::Fill(double x, double y, double zw) {
0324 auto access = this->accessMut();
0325 update();
0326 if (kind() == Kind::TH2F)
0327 static_cast<TH2F *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw);
0328 else if (kind() == Kind::TH2S)
0329 static_cast<TH2S *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw);
0330 else if (kind() == Kind::TH2D)
0331 static_cast<TH2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw);
0332 else if (kind() == Kind::TH2I)
0333 static_cast<TH2I *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw);
0334 else if (kind() == Kind::TH2Poly)
0335 static_cast<TH2Poly *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw);
0336 else if (kind() == Kind::TH3F)
0337 static_cast<TH3F *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw, 1);
0338 else if (kind() == Kind::TPROFILE)
0339 static_cast<TProfile *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw);
0340 else if (kind() == Kind::TPROFILE2D)
0341 static_cast<TProfile2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, zw, 1);
0342 else
0343 incompatible(__PRETTY_FUNCTION__);
0344 }
0345
0346
0347 void MonitorElement::Fill(double x, double y, double z, double w) {
0348 auto access = this->accessMut();
0349 update();
0350 if (kind() == Kind::TH3F)
0351 static_cast<TH3F *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, z, w);
0352 else if (kind() == Kind::TPROFILE2D)
0353 static_cast<TProfile2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->Fill(x, y, z, w);
0354 else
0355 incompatible(__PRETTY_FUNCTION__);
0356 }
0357
0358
0359 void MonitorElement::Reset() {
0360 auto access = this->accessMut();
0361 update();
0362 if (kind() == Kind::INT)
0363 access.value.scalar_.num = 0;
0364 else if (kind() == Kind::REAL)
0365 access.value.scalar_.real = 0;
0366 else if (kind() == Kind::STRING)
0367 access.value.scalar_.str.clear();
0368 else if (kind() == Kind::TH1F)
0369 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->Reset();
0370 else if (kind() == Kind::TH1S)
0371 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->Reset();
0372 else if (kind() == Kind::TH1D)
0373 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->Reset();
0374 else if (kind() == Kind::TH1I)
0375 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->Reset();
0376 else if (kind() == Kind::TPROFILE)
0377 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->Reset();
0378 else if (kind() == Kind::TH2F)
0379 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->Reset();
0380 else if (kind() == Kind::TH2S)
0381 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->Reset();
0382 else if (kind() == Kind::TH2D)
0383 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->Reset();
0384 else if (kind() == Kind::TH2I)
0385 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->Reset();
0386 else if (kind() == Kind::TH2Poly)
0387 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->Reset();
0388 else if (kind() == Kind::TPROFILE2D)
0389 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->Reset();
0390 else if (kind() == Kind::TH3F)
0391 return accessRootObject(access, __PRETTY_FUNCTION__, 3)->Reset();
0392 else
0393 incompatible(__PRETTY_FUNCTION__);
0394 }
0395
0396
0397 void MonitorElement::packScalarData(std::string &into, const char *prefix) const {
0398 auto access = this->access();
0399 char buf[64];
0400 if (kind() == Kind::INT) {
0401 snprintf(buf, sizeof(buf), "%s%" PRId64, prefix, access.value.scalar_.num);
0402 into = buf;
0403 } else if (kind() == Kind::REAL) {
0404 snprintf(buf, sizeof(buf), "%s%.*g", prefix, DBL_DIG + 2, access.value.scalar_.real);
0405 into = buf;
0406 } else if (kind() == Kind::STRING) {
0407 into.reserve(strlen(prefix) + access.value.scalar_.str.size());
0408 into += prefix;
0409 into += access.value.scalar_.str;
0410 } else
0411 incompatible(__PRETTY_FUNCTION__);
0412 }
0413
0414
0415 void MonitorElement::packQualityData(std::string &into) const { DQMNet::packQualityData(into, data_.qreports); }
0416
0417
0418
0419 std::string MonitorElement::valueString() const {
0420 std::string result;
0421 if (kind() == Kind::INT)
0422 packScalarData(result, "i=");
0423 else if (kind() == Kind::REAL)
0424 packScalarData(result, "f=");
0425 else if (kind() == Kind::STRING)
0426 packScalarData(result, "s=");
0427 else
0428 incompatible(__PRETTY_FUNCTION__);
0429
0430 return result;
0431 }
0432
0433
0434
0435
0436 std::string MonitorElement::tagString() const {
0437 std::string result;
0438 std::string val(valueString());
0439 result.reserve(6 + 2 * data_.objname.size() + val.size());
0440 result += '<';
0441 result += data_.objname;
0442 result += '>';
0443 result += val;
0444 result += '<';
0445 result += '/';
0446 result += data_.objname;
0447 result += '>';
0448 return result;
0449 }
0450
0451
0452 std::string MonitorElement::tagLabelString() const {
0453 char buf[32];
0454 std::string result;
0455 size_t len = sprintf(buf, "t=%" PRIu32, data_.tag);
0456
0457 result.reserve(6 + 2 * data_.objname.size() + len);
0458 result += '<';
0459 result += data_.objname;
0460 result += '>';
0461 result += buf;
0462 result += '<';
0463 result += '/';
0464 result += data_.objname;
0465 result += '>';
0466 return result;
0467 }
0468
0469
0470 std::string MonitorElement::effLabelString() const {
0471 std::string result;
0472
0473 result.reserve(6 + 2 * data_.objname.size() + 3);
0474 result += '<';
0475 result += data_.objname;
0476 result += '>';
0477 result += "e=1";
0478 result += '<';
0479 result += '/';
0480 result += data_.objname;
0481 result += '>';
0482 return result;
0483 }
0484
0485 std::string MonitorElement::qualityTagString(const DQMNet::QValue &qv) const {
0486 char buf[64];
0487 std::string result;
0488 size_t titlelen = data_.objname.size() + qv.qtname.size() + 1;
0489 size_t buflen = sprintf(buf, "qr=st:%d:%.*g:", qv.code, DBL_DIG + 2, qv.qtresult);
0490
0491 result.reserve(7 + 2 * titlelen + buflen + qv.algorithm.size() + qv.message.size());
0492 result += '<';
0493 result += data_.objname;
0494 result += '.';
0495 result += qv.qtname;
0496 result += '>';
0497 result += buf;
0498 result += qv.algorithm;
0499 result += ':';
0500 result += qv.message;
0501 result += '<';
0502 result += '/';
0503 result += data_.objname;
0504 result += '.';
0505 result += qv.qtname;
0506 result += '>';
0507 return result;
0508 }
0509
0510 const MonitorElementData::QReport *MonitorElement::getQReport(const std::string &qtname) const {
0511 MonitorElementData::MonitorElementData::QReport *qr;
0512 DQMNet::QValue *qv;
0513 const_cast<MonitorElement *>(this)->getQReport(false, qtname, qr, qv);
0514 return qr;
0515 }
0516
0517 template <typename FILTER>
0518 std::vector<MonitorElementData::QReport *> MonitorElement::filterQReports(FILTER filter) const {
0519 auto access = this->access();
0520 std::vector<MonitorElementData::QReport *> result;
0521 for (MonitorElementData::QReport const &qr : access.value.qreports_) {
0522 if (filter(qr)) {
0523
0524
0525 result.push_back(const_cast<MonitorElementData::QReport *>(&qr));
0526 }
0527 }
0528 return result;
0529 }
0530
0531 std::vector<MonitorElementData::QReport *> MonitorElement::getQReports() const {
0532 return filterQReports([](MonitorElementData::QReport const &qr) { return true; });
0533 }
0534
0535 std::vector<MonitorElementData::QReport *> MonitorElement::getQWarnings() const {
0536 return filterQReports(
0537 [](MonitorElementData::QReport const &qr) { return qr.getStatus() == dqm::qstatus::WARNING; });
0538 }
0539
0540 std::vector<MonitorElementData::QReport *> MonitorElement::getQErrors() const {
0541 return filterQReports([](MonitorElementData::QReport const &qr) { return qr.getStatus() == dqm::qstatus::ERROR; });
0542 }
0543
0544 std::vector<MonitorElementData::QReport *> MonitorElement::getQOthers() const {
0545 return filterQReports([](MonitorElementData::QReport const &qr) {
0546 return qr.getStatus() != dqm::qstatus::STATUS_OK && qr.getStatus() != dqm::qstatus::WARNING &&
0547 qr.getStatus() != dqm::qstatus::ERROR;
0548 });
0549 }
0550
0551 void MonitorElement::incompatible(const char *func) const {
0552 throw cms::Exception("MonitorElementError") << "Method '" << func
0553 << "' cannot be invoked on monitor"
0554 " element '"
0555 << data_.objname << "'";
0556 }
0557
0558 TH1 const *MonitorElement::accessRootObject(Access const &access, const char *func, int reqdim) const {
0559 if (kind() < Kind::TH1F)
0560 throw cms::Exception("MonitorElement") << "Method '" << func
0561 << "' cannot be invoked on monitor"
0562 " element '"
0563 << data_.objname << "' because it is not a root object";
0564 return access.value.object_.get();
0565 }
0566 TH1 *MonitorElement::accessRootObject(AccessMut const &access, const char *func, int reqdim) const {
0567 if (kind() < Kind::TH1F)
0568 throw cms::Exception("MonitorElement") << "Method '" << func
0569 << "' cannot be invoked on monitor"
0570 " element '"
0571 << data_.objname << "' because it is not a root object";
0572 return checkRootObject(data_.objname, access.value.object_.get(), func, reqdim);
0573 }
0574
0575
0576
0577
0578 double MonitorElement::getMean(int axis ) const {
0579 auto access = this->access();
0580 return accessRootObject(access, __PRETTY_FUNCTION__, axis - 1)->GetMean(axis);
0581 }
0582
0583
0584
0585 double MonitorElement::getMeanError(int axis ) const {
0586 auto access = this->access();
0587 return accessRootObject(access, __PRETTY_FUNCTION__, axis - 1)->GetMeanError(axis);
0588 }
0589
0590
0591 double MonitorElement::getRMS(int axis ) const {
0592 auto access = this->access();
0593 return accessRootObject(access, __PRETTY_FUNCTION__, axis - 1)->GetRMS(axis);
0594 }
0595
0596
0597 double MonitorElement::getRMSError(int axis ) const {
0598 auto access = this->access();
0599 return accessRootObject(access, __PRETTY_FUNCTION__, axis - 1)->GetRMSError(axis);
0600 }
0601
0602
0603 int MonitorElement::getNbinsX() const {
0604 auto access = this->access();
0605 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetNbinsX();
0606 }
0607
0608
0609 int MonitorElement::getNbinsY() const {
0610 auto access = this->access();
0611 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetNbinsY();
0612 }
0613
0614
0615 int MonitorElement::getNbinsZ() const {
0616 auto access = this->access();
0617 return accessRootObject(access, __PRETTY_FUNCTION__, 3)->GetNbinsZ();
0618 }
0619
0620
0621 double MonitorElement::getBinContent(int binx) const {
0622 auto access = this->access();
0623 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetBinContent(binx);
0624 }
0625
0626
0627 double MonitorElement::getBinContent(int binx, int biny) const {
0628 auto access = this->access();
0629 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetBinContent(binx, biny);
0630 }
0631
0632
0633 double MonitorElement::getBinContent(int binx, int biny, int binz) const {
0634 auto access = this->access();
0635 return accessRootObject(access, __PRETTY_FUNCTION__, 3)->GetBinContent(binx, biny, binz);
0636 }
0637
0638
0639 double MonitorElement::getBinError(int binx) const {
0640 auto access = this->access();
0641 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetBinError(binx);
0642 }
0643
0644
0645 double MonitorElement::getBinError(int binx, int biny) const {
0646 auto access = this->access();
0647 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetBinError(binx, biny);
0648 }
0649
0650
0651 double MonitorElement::getBinError(int binx, int biny, int binz) const {
0652 auto access = this->access();
0653 return accessRootObject(access, __PRETTY_FUNCTION__, 3)->GetBinError(binx, biny, binz);
0654 }
0655
0656
0657 double MonitorElement::getEntries() const {
0658 auto access = this->access();
0659 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetEntries();
0660 }
0661
0662
0663 int MonitorElement::getBin(int binx, int biny) const {
0664 auto access = this->access();
0665 if (kind() == Kind::TPROFILE2D)
0666 return static_cast<TProfile2D const *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->GetBin(binx, biny);
0667 else {
0668 incompatible(__PRETTY_FUNCTION__);
0669 return 0;
0670 }
0671 }
0672
0673
0674 int MonitorElement::getNcells() const {
0675 auto access = this->access();
0676 if (kind() == Kind::TH1F)
0677 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetNcells();
0678 else if (kind() == Kind::TH1S)
0679 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetNcells();
0680 else if (kind() == Kind::TH1D)
0681 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetNcells();
0682 else if (kind() == Kind::TH1I)
0683 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetNcells();
0684 else if (kind() == Kind::TPROFILE)
0685 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetNcells();
0686 else if (kind() == Kind::TH2F)
0687 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetNcells();
0688 else if (kind() == Kind::TH2S)
0689 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetNcells();
0690 else if (kind() == Kind::TH2D)
0691 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetNcells();
0692 else if (kind() == Kind::TH2I)
0693 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetNcells();
0694 else if (kind() == Kind::TH2Poly)
0695 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetNcells();
0696 else if (kind() == Kind::TPROFILE2D)
0697 return accessRootObject(access, __PRETTY_FUNCTION__, 2)->GetNcells();
0698 else if (kind() == Kind::TH3F)
0699 return accessRootObject(access, __PRETTY_FUNCTION__, 3)->GetNcells();
0700 else {
0701 incompatible(__PRETTY_FUNCTION__);
0702 return 0;
0703 }
0704 }
0705
0706
0707 double MonitorElement::getBinEntries(int bin) const {
0708 auto access = this->access();
0709 if (kind() == Kind::TPROFILE)
0710 return static_cast<TProfile const *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->GetBinEntries(bin);
0711 else if (kind() == Kind::TPROFILE2D)
0712 return static_cast<TProfile2D const *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->GetBinEntries(bin);
0713 else {
0714 incompatible(__PRETTY_FUNCTION__);
0715 return 0;
0716 }
0717 }
0718
0719
0720 double MonitorElement::getBinEntries(int binx, int biny) const {
0721 auto access = this->access();
0722 if (kind() == Kind::TPROFILE2D) {
0723 int globBin =
0724 static_cast<TProfile2D const *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->GetBin(binx, biny);
0725 return static_cast<TProfile2D const *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->GetBinEntries(globBin);
0726 } else {
0727 incompatible(__PRETTY_FUNCTION__);
0728 return 0;
0729 }
0730 }
0731
0732
0733 double MonitorElement::integral() const {
0734 auto access = this->access();
0735 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->Integral();
0736 }
0737
0738
0739 std::string MonitorElement::getAxisTitle(int axis ) const {
0740 auto access = this->access();
0741 return getAxis(access, __PRETTY_FUNCTION__, axis)->GetTitle();
0742 }
0743
0744
0745 std::string MonitorElement::getTitle() const {
0746 auto access = this->access();
0747 return accessRootObject(access, __PRETTY_FUNCTION__, 1)->GetTitle();
0748 }
0749
0750
0751
0752
0753 void MonitorElement::addBin(TGraph *graph) {
0754 auto access = this->accessMut();
0755 if (kind() == Kind::TH2Poly) {
0756 static_cast<TH2Poly *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->AddBin(graph);
0757 } else {
0758 incompatible(__PRETTY_FUNCTION__);
0759 }
0760 }
0761
0762
0763 void MonitorElement::addBin(int n, const double *x, const double *y) {
0764 auto access = this->accessMut();
0765 if (kind() == Kind::TH2Poly) {
0766 static_cast<TH2Poly *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->AddBin(n, x, y);
0767 } else {
0768 incompatible(__PRETTY_FUNCTION__);
0769 }
0770 }
0771
0772
0773 void MonitorElement::addBin(double x1, double y1, double x2, double y2) {
0774 auto access = this->accessMut();
0775 if (kind() == Kind::TH2Poly) {
0776 static_cast<TH2Poly *>(accessRootObject(access, __PRETTY_FUNCTION__, 2))->AddBin(x1, y1, x2, y2);
0777 } else {
0778 incompatible(__PRETTY_FUNCTION__);
0779 }
0780 }
0781
0782
0783 void MonitorElement::setBinContent(int binx, double content) {
0784 auto access = this->accessMut();
0785 accessRootObject(access, __PRETTY_FUNCTION__, 1)->SetBinContent(binx, content);
0786 }
0787
0788
0789 void MonitorElement::setBinContent(int binx, int biny, double content) {
0790 auto access = this->accessMut();
0791 accessRootObject(access, __PRETTY_FUNCTION__, 2)->SetBinContent(binx, biny, content);
0792 }
0793
0794
0795 void MonitorElement::setBinContent(int binx, int biny, int binz, double content) {
0796 auto access = this->accessMut();
0797 accessRootObject(access, __PRETTY_FUNCTION__, 3)->SetBinContent(binx, biny, binz, content);
0798 }
0799
0800
0801 void MonitorElement::setBinError(int binx, double error) {
0802 auto access = this->accessMut();
0803 accessRootObject(access, __PRETTY_FUNCTION__, 1)->SetBinError(binx, error);
0804 }
0805
0806
0807 void MonitorElement::setBinError(int binx, int biny, double error) {
0808 auto access = this->accessMut();
0809 accessRootObject(access, __PRETTY_FUNCTION__, 2)->SetBinError(binx, biny, error);
0810 }
0811
0812
0813 void MonitorElement::setBinError(int binx, int biny, int binz, double error) {
0814 auto access = this->accessMut();
0815 accessRootObject(access, __PRETTY_FUNCTION__, 3)->SetBinError(binx, biny, binz, error);
0816 }
0817
0818
0819 void MonitorElement::setBinEntries(int bin, double nentries) {
0820 auto access = this->accessMut();
0821 if (kind() == Kind::TPROFILE)
0822 static_cast<TProfile *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->SetBinEntries(bin, nentries);
0823 else if (kind() == Kind::TPROFILE2D)
0824 static_cast<TProfile2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 1))->SetBinEntries(bin, nentries);
0825 else
0826 incompatible(__PRETTY_FUNCTION__);
0827 }
0828
0829
0830 void MonitorElement::setEntries(double nentries) {
0831 auto access = this->accessMut();
0832 accessRootObject(access, __PRETTY_FUNCTION__, 1)->SetEntries(nentries);
0833 }
0834
0835
0836 void MonitorElement::divide(
0837 const MonitorElement *num, const MonitorElement *denom, double c1, double c2, const char *options) {
0838 if (num->kind() < Kind::TH1F)
0839 num->incompatible(__PRETTY_FUNCTION__);
0840 if (denom->kind() < Kind::TH1F)
0841 denom->incompatible(__PRETTY_FUNCTION__);
0842
0843 TH1 const *numH = static_cast<TH1 const *>(num->getRootObject());
0844 TH1 const *denomH = static_cast<TH1 const *>(denom->getRootObject());
0845 TH1 *thisH = getTH1();
0846
0847
0848
0849 std::array<const MonitorElement *, 3> order{{this, num, denom}};
0850 std::sort(order.begin(), order.end(), [](auto const *lhs, auto const *rhs) {
0851 return lhs->mutable_->data_.value_.object_.get() < rhs->mutable_->data_.value_.object_.get();
0852 });
0853
0854 auto a0 = order[0]->access();
0855 auto a1 = order[1]->access();
0856 auto a2 = order[2]->access();
0857
0858
0859 thisH->Divide(numH, denomH, c1, c2, options);
0860 }
0861
0862
0863 void MonitorElement::setBinLabel(int bin, const std::string &label, int axis ) {
0864 bool fail = false;
0865 {
0866 auto access = this->accessMut();
0867 update();
0868 if (getAxis(access, __PRETTY_FUNCTION__, axis)->GetNbins() >= bin) {
0869 getAxis(access, __PRETTY_FUNCTION__, axis)->SetBinLabel(bin, label.c_str());
0870 } else {
0871 fail = true;
0872 }
0873 }
0874
0875 if (fail) {
0876
0877
0878 auto name = getFullname();
0879 edm::LogWarning("MonitorElement") << "*** MonitorElement: WARNING:"
0880 << "setBinLabel: attempting to set label of non-existent bin number for ME: "
0881 << name << " \n";
0882 }
0883 }
0884
0885
0886 void MonitorElement::setAxisRange(double xmin, double xmax, int axis ) {
0887 auto access = this->accessMut();
0888 getAxis(access, __PRETTY_FUNCTION__, axis)->SetRangeUser(xmin, xmax);
0889 }
0890
0891
0892 void MonitorElement::setAxisTitle(const std::string &title, int axis ) {
0893 auto access = this->accessMut();
0894 getAxis(access, __PRETTY_FUNCTION__, axis)->SetTitle(title.c_str());
0895 }
0896
0897
0898 void MonitorElement::setAxisTimeDisplay(int value, int axis ) {
0899 auto access = this->accessMut();
0900 getAxis(access, __PRETTY_FUNCTION__, axis)->SetTimeDisplay(value);
0901 }
0902
0903
0904 void MonitorElement::setAxisTimeFormat(const char *format , int axis ) {
0905 auto access = this->accessMut();
0906 getAxis(access, __PRETTY_FUNCTION__, axis)->SetTimeFormat(format);
0907 }
0908
0909
0910 void MonitorElement::setTitle(const std::string &title) {
0911 auto access = this->accessMut();
0912 accessRootObject(access, __PRETTY_FUNCTION__, 1)->SetTitle(title.c_str());
0913 }
0914
0915 TAxis *MonitorElement::getAxis(AccessMut const &access, const char *func, int axis) const {
0916 TH1 *h = accessRootObject(access, func, axis - 1);
0917 TAxis *a = nullptr;
0918 if (axis == 1)
0919 a = h->GetXaxis();
0920 else if (axis == 2)
0921 a = h->GetYaxis();
0922 else if (axis == 3)
0923 a = h->GetZaxis();
0924
0925 if (!a)
0926 throw cms::Exception("MonitorElementError") << "No such axis " << axis
0927 << " in monitor element"
0928 " '"
0929 << data_.objname << "' of type '" << typeid(*h).name() << "'";
0930
0931 return a;
0932 }
0933
0934 TAxis const *MonitorElement::getAxis(Access const &access, const char *func, int axis) const {
0935 TH1 const *h = accessRootObject(access, func, axis - 1);
0936 TAxis const *a = nullptr;
0937 if (axis == 1)
0938 a = h->GetXaxis();
0939 else if (axis == 2)
0940 a = h->GetYaxis();
0941 else if (axis == 3)
0942 a = h->GetZaxis();
0943
0944 if (!a)
0945 throw cms::Exception("MonitorElementError") << "No such axis " << axis
0946 << " in monitor element"
0947 " '"
0948 << data_.objname << "' of type '" << typeid(*h).name() << "'";
0949
0950 return a;
0951 }
0952
0953 void MonitorElement::setXTitle(std::string const &title) {
0954 auto access = this->accessMut();
0955 update();
0956 access.value.object_->SetXTitle(title.c_str());
0957 }
0958 void MonitorElement::setYTitle(std::string const &title) {
0959 auto access = this->accessMut();
0960 update();
0961 access.value.object_->SetYTitle(title.c_str());
0962 }
0963
0964 void MonitorElement::enableSumw2() {
0965 auto access = this->accessMut();
0966 update();
0967 if (access.value.object_->GetSumw2() == nullptr) {
0968 access.value.object_->Sumw2();
0969 }
0970 }
0971
0972 void MonitorElement::disableAlphanumeric() {
0973 auto access = this->accessMut();
0974 update();
0975 access.value.object_->GetXaxis()->SetNoAlphanumeric(false);
0976 access.value.object_->GetYaxis()->SetNoAlphanumeric(false);
0977 }
0978
0979 void MonitorElement::setOption(const char *option) {
0980 auto access = this->accessMut();
0981 update();
0982 access.value.object_->SetOption(option);
0983 }
0984 double MonitorElement::getAxisMin(int axis) const {
0985 auto access = this->access();
0986 return getAxis(access, __PRETTY_FUNCTION__, axis)->GetXmin();
0987 }
0988
0989 double MonitorElement::getAxisMax(int axis) const {
0990 auto access = this->access();
0991 return getAxis(access, __PRETTY_FUNCTION__, axis)->GetXmax();
0992 }
0993
0994 void MonitorElement::setCanExtend(unsigned int value) {
0995 auto access = this->accessMut();
0996 access.value.object_->SetCanExtend(value);
0997 }
0998
0999 void MonitorElement::setStatOverflows(bool value) {
1000 auto access = this->accessMut();
1001 if (value == kTRUE)
1002 access.value.object_->SetStatOverflows(TH1::kConsider);
1003 else
1004 access.value.object_->SetStatOverflows(TH1::kIgnore);
1005 }
1006
1007 bool MonitorElement::getStatOverflows() {
1008 auto access = this->accessMut();
1009 auto value = access.value.object_->GetStatOverflows();
1010 if (value == TH1::kConsider)
1011 return true;
1012 else
1013 return false;
1014 }
1015
1016 int64_t MonitorElement::getIntValue() const {
1017 assert(kind() == Kind::INT);
1018 auto access = this->access();
1019 return access.value.scalar_.num;
1020 }
1021 double MonitorElement::getFloatValue() const {
1022 assert(kind() == Kind::REAL);
1023 auto access = this->access();
1024 return access.value.scalar_.real;
1025 }
1026 const std::string &MonitorElement::getStringValue() const {
1027 assert(kind() == Kind::STRING);
1028 auto access = this->access();
1029 return access.value.scalar_.str;
1030 }
1031
1032 void MonitorElement::getQReport(bool create,
1033 const std::string &qtname,
1034 MonitorElementData::QReport *&qr,
1035 DQMNet::QValue *&qv) {
1036 auto access = this->accessMut();
1037
1038 syncCoreObject(access);
1039
1040 assert(access.value.qreports_.size() == data_.qreports.size());
1041
1042 qr = nullptr;
1043 qv = nullptr;
1044
1045 size_t pos = 0, end = access.value.qreports_.size();
1046 while (pos < end && data_.qreports[pos].qtname != qtname)
1047 ++pos;
1048
1049 if (pos == end && !create)
1050 return;
1051 else if (pos == end) {
1052 DQMNet::QValue q;
1053 q.code = dqm::qstatus::DID_NOT_RUN;
1054 q.qtresult = 0;
1055 q.qtname = qtname;
1056 q.message = "NO_MESSAGE_ASSIGNED";
1057 q.algorithm = "UNKNOWN_ALGORITHM";
1058 access.value.qreports_.push_back(MonitorElementData::QReport(q));
1059 syncCoreObject(access);
1060 }
1061
1062 qr = &access.value.qreports_[pos];
1063 qv = &(qr->getValue());
1064 }
1065
1066
1067
1068 TObject const *MonitorElement::getRootObject() const {
1069 auto access = this->access();
1070 return access.value.object_.get();
1071 }
1072
1073 TH1 *MonitorElement::getTH1() {
1074 auto access = this->accessMut();
1075 return accessRootObject(access, __PRETTY_FUNCTION__, 0);
1076 }
1077
1078 TH1F *MonitorElement::getTH1F() {
1079 auto access = this->accessMut();
1080 assert(kind() == Kind::TH1F);
1081 return static_cast<TH1F *>(accessRootObject(access, __PRETTY_FUNCTION__, 1));
1082 }
1083
1084 TH1S *MonitorElement::getTH1S() {
1085 auto access = this->accessMut();
1086 assert(kind() == Kind::TH1S);
1087 return static_cast<TH1S *>(accessRootObject(access, __PRETTY_FUNCTION__, 1));
1088 }
1089
1090 TH1I *MonitorElement::getTH1I() {
1091 auto access = this->accessMut();
1092 assert(kind() == Kind::TH1I);
1093 return static_cast<TH1I *>(accessRootObject(access, __PRETTY_FUNCTION__, 1));
1094 }
1095
1096 TH1D *MonitorElement::getTH1D() {
1097 auto access = this->accessMut();
1098 assert(kind() == Kind::TH1D);
1099 return static_cast<TH1D *>(accessRootObject(access, __PRETTY_FUNCTION__, 1));
1100 }
1101
1102 TH2F *MonitorElement::getTH2F() {
1103 auto access = this->accessMut();
1104 assert(kind() == Kind::TH2F);
1105 return static_cast<TH2F *>(accessRootObject(access, __PRETTY_FUNCTION__, 2));
1106 }
1107
1108 TH2S *MonitorElement::getTH2S() {
1109 auto access = this->accessMut();
1110 assert(kind() == Kind::TH2S);
1111 return static_cast<TH2S *>(accessRootObject(access, __PRETTY_FUNCTION__, 2));
1112 }
1113
1114 TH2I *MonitorElement::getTH2I() {
1115 auto access = this->accessMut();
1116 assert(kind() == Kind::TH2I);
1117 return static_cast<TH2I *>(accessRootObject(access, __PRETTY_FUNCTION__, 2));
1118 }
1119
1120 TH2D *MonitorElement::getTH2D() {
1121 auto access = this->accessMut();
1122 assert(kind() == Kind::TH2D);
1123 return static_cast<TH2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2));
1124 }
1125
1126 TH2Poly *MonitorElement::getTH2Poly() {
1127 auto access = this->accessMut();
1128 assert(kind() == Kind::TH2Poly);
1129 return static_cast<TH2Poly *>(accessRootObject(access, __PRETTY_FUNCTION__, 2));
1130 }
1131
1132 TH3F *MonitorElement::getTH3F() {
1133 auto access = this->accessMut();
1134 assert(kind() == Kind::TH3F);
1135 return static_cast<TH3F *>(accessRootObject(access, __PRETTY_FUNCTION__, 3));
1136 }
1137
1138 TProfile *MonitorElement::getTProfile() {
1139 auto access = this->accessMut();
1140 assert(kind() == Kind::TPROFILE);
1141 return static_cast<TProfile *>(accessRootObject(access, __PRETTY_FUNCTION__, 1));
1142 }
1143
1144 TProfile2D *MonitorElement::getTProfile2D() {
1145 auto access = this->accessMut();
1146 assert(kind() == Kind::TPROFILE2D);
1147 return static_cast<TProfile2D *>(accessRootObject(access, __PRETTY_FUNCTION__, 2));
1148 }
1149
1150 }