00001 #define DQM_ROOT_METHODS 1
00002 #include "DQMServices/Core/interface/MonitorElement.h"
00003 #include "DQMServices/Core/interface/QTest.h"
00004 #include "TClass.h"
00005 #include "TMath.h"
00006 #include "TList.h"
00007 #include <iostream>
00008 #include <cassert>
00009
00010 static TH1 *
00011 checkRootObject(const std::string &name, TObject *tobj, const char *func, int reqdim)
00012 {
00013 if (! tobj)
00014 throw cms::Exception("MonitorElement")
00015 << "Method '" << func << "' cannot be invoked on monitor element '"
00016 << name << "' because it is not a ROOT object.";
00017
00018 TH1 *h = dynamic_cast<TH1 *>(tobj);
00019 if (! h)
00020 throw cms::Exception("MonitorElement")
00021 << "Method '" << func << "' cannot be invoked on monitor element '"
00022 << name << "' because it is not a ROOT histogram; it is of type '"
00023 << typeid(*tobj).name() << "'";
00024
00025 int ndim = h->GetDimension();
00026 if (reqdim < 0 || reqdim > ndim)
00027 throw cms::Exception("MonitorElement")
00028 << "Method '" << func << "' cannot be invoked on monitor element '"
00029 << name << "' because it requires " << reqdim
00030 << " dimensions; this object of type '" << typeid(*h).name()
00031 << "' has " << ndim << " dimensions";
00032
00033 return h;
00034 }
00035
00036 MonitorElement *
00037 MonitorElement::initialise(Kind kind, const std::string &path)
00038 {
00039 const char *slash = strrchr(path.c_str(), '/');
00040 data_.name = path;
00041 kind_ = kind;
00042 if (slash)
00043 {
00044 name_ = slash+1;
00045 path_ = std::string(path.c_str(), slash);
00046 }
00047 else
00048 {
00049 name_ = path;
00050 path_.clear();
00051 }
00052
00053 switch (kind)
00054 {
00055 case DQM_KIND_INT:
00056 case DQM_KIND_REAL:
00057 case DQM_KIND_STRING:
00058 data_.object = new TObjString;
00059 static_cast<TObjString *>(data_.object)
00060 ->SetString(tagString().c_str());
00061 data_.flags |= DQMNet::DQM_FLAG_SCALAR;
00062 break;
00063
00064 case DQM_KIND_TH1F:
00065 case DQM_KIND_TH1S:
00066 case DQM_KIND_TH2F:
00067 case DQM_KIND_TH2S:
00068 case DQM_KIND_TH3F:
00069 case DQM_KIND_TPROFILE:
00070 case DQM_KIND_TPROFILE2D:
00071 break;
00072
00073 default:
00074 throw cms::Exception("MonitorElement")
00075 << "cannot initialise monitor element '" << path
00076 << "' to invalid type " << kind;
00077 }
00078
00079 return this;
00080 }
00081
00082 MonitorElement *
00083 MonitorElement::initialise(Kind kind, const std::string &path, TH1 *rootobj)
00084 {
00085 initialise(kind, path);
00086 switch (kind)
00087 {
00088 case DQM_KIND_TH1F:
00089 assert(dynamic_cast<TH1F *>(rootobj));
00090 curvalue_.tobj = data_.object = rootobj;
00091 break;
00092
00093 case DQM_KIND_TH1S:
00094 assert(dynamic_cast<TH1S *>(rootobj));
00095 curvalue_.tobj = data_.object = rootobj;
00096 break;
00097
00098 case DQM_KIND_TH2F:
00099 assert(dynamic_cast<TH2F *>(rootobj));
00100 curvalue_.tobj = data_.object = rootobj;
00101 break;
00102
00103 case DQM_KIND_TH2S:
00104 assert(dynamic_cast<TH2S *>(rootobj));
00105 curvalue_.tobj = data_.object = rootobj;
00106 break;
00107
00108 case DQM_KIND_TH3F:
00109 assert(dynamic_cast<TH3F *>(rootobj));
00110 curvalue_.tobj = data_.object = rootobj;
00111 break;
00112
00113 case DQM_KIND_TPROFILE:
00114 assert(dynamic_cast<TProfile *>(rootobj));
00115 curvalue_.tobj = data_.object = rootobj;
00116 break;
00117
00118 case DQM_KIND_TPROFILE2D:
00119 assert(dynamic_cast<TProfile2D *>(rootobj));
00120 curvalue_.tobj = data_.object = rootobj;
00121 break;
00122
00123 default:
00124 throw cms::Exception("MonitorElement")
00125 << "cannot initialise monitor element '" << path
00126 << "' as a root object with type " << kind;
00127 }
00128
00129 return this;
00130 }
00131
00132 MonitorElement *
00133 MonitorElement::initialise(Kind kind, const std::string &path, const std::string &value)
00134 {
00135 initialise(kind, path);
00136 if (kind == DQM_KIND_STRING)
00137 {
00138 curvalue_.str = value;
00139 static_cast<TObjString *>(data_.object)
00140 ->SetString(tagString().c_str());
00141 }
00142 else
00143 throw cms::Exception("MonitorElement")
00144 << "cannot initialise monitor element '" << path
00145 << "' as a string with type " << kind;
00146
00147 return this;
00148 }
00149
00150 MonitorElement::MonitorElement(void)
00151 : kind_ (DQM_KIND_INVALID),
00152 nqerror_ (0),
00153 nqwarning_ (0),
00154 nqother_ (0),
00155 refvalue_ (0)
00156 {
00157 data_.version = 0;
00158 data_.object = 0;
00159 data_.reference = 0;
00160 data_.flags = DQMNet::DQM_FLAG_NEW;
00161
00162 curvalue_.num = 0;
00163 curvalue_.real = 0;
00164 curvalue_.tobj = 0;
00165 }
00166
00167 MonitorElement::~MonitorElement(void)
00168 {
00169 delete data_.object;
00170 delete refvalue_;
00171 }
00172
00175 void
00176 MonitorElement::Fill(float x)
00177 {
00178 update();
00179 if (kind_ == DQM_KIND_INT)
00180 {
00181 curvalue_.num = int(x);
00182 static_cast<TObjString *>(data_.object)
00183 ->SetString(tagString().c_str());
00184 }
00185 else if (kind_ == DQM_KIND_REAL)
00186 {
00187 curvalue_.real = x;
00188 static_cast<TObjString *>(data_.object)
00189 ->SetString(tagString().c_str());
00190 }
00191 else if (kind_ == DQM_KIND_TH1F)
00192 accessRootObject(__PRETTY_FUNCTION__, 1)
00193 ->Fill(x, 1);
00194 else if (kind_ == DQM_KIND_TH1S)
00195 accessRootObject(__PRETTY_FUNCTION__, 1)
00196 ->Fill(x, 1);
00197 else
00198 incompatible(__PRETTY_FUNCTION__);
00199 }
00200
00202 void
00203 MonitorElement::Fill(float x, float yw)
00204 {
00205 update();
00206 if (kind_ == DQM_KIND_TH1F)
00207 accessRootObject(__PRETTY_FUNCTION__, 1)
00208 ->Fill(x, yw);
00209 else if (kind_ == DQM_KIND_TH1S)
00210 accessRootObject(__PRETTY_FUNCTION__, 1)
00211 ->Fill(x, yw);
00212 else if (kind_ == DQM_KIND_TH2F)
00213 static_cast<TH2F *>(accessRootObject(__PRETTY_FUNCTION__, 2))
00214 ->Fill(x, yw, 1);
00215 else if (kind_ == DQM_KIND_TH2S)
00216 static_cast<TH2S *>(accessRootObject(__PRETTY_FUNCTION__, 2))
00217 ->Fill(x, yw, 1);
00218 else if (kind_ == DQM_KIND_TPROFILE)
00219 static_cast<TProfile *>(accessRootObject(__PRETTY_FUNCTION__, 1))
00220 ->Fill(x, yw, 1);
00221 else
00222 incompatible(__PRETTY_FUNCTION__);
00223 }
00224
00226 void
00227 MonitorElement::Fill(float x, float y, float zw)
00228 {
00229 update();
00230 if (kind_ == DQM_KIND_TH2F)
00231 static_cast<TH2F *>(accessRootObject(__PRETTY_FUNCTION__, 2))
00232 ->Fill(x, y, zw);
00233 else if (kind_ == DQM_KIND_TH2S)
00234 static_cast<TH2S *>(accessRootObject(__PRETTY_FUNCTION__, 2))
00235 ->Fill(x, y, zw);
00236 else if (kind_ == DQM_KIND_TH3F)
00237 static_cast<TH3F *>(accessRootObject(__PRETTY_FUNCTION__, 2))
00238 ->Fill(x, y, zw, 1);
00239 else if (kind_ == DQM_KIND_TPROFILE)
00240 static_cast<TProfile *>(accessRootObject(__PRETTY_FUNCTION__, 2))
00241 ->Fill(x, y, zw);
00242 else if (kind_ == DQM_KIND_TPROFILE2D)
00243 static_cast<TProfile2D *>(accessRootObject(__PRETTY_FUNCTION__, 2))
00244 ->Fill(x, y, zw, 1);
00245 else
00246 incompatible(__PRETTY_FUNCTION__);
00247 }
00248
00250 void
00251 MonitorElement::Fill(float x, float y, float z, float w)
00252 {
00253 update();
00254 if (kind_ == DQM_KIND_TH3F)
00255 static_cast<TH3F *>(accessRootObject(__PRETTY_FUNCTION__, 2))
00256 ->Fill(x, y, z, w);
00257 else if (kind_ == DQM_KIND_TPROFILE2D)
00258 static_cast<TProfile2D *>(accessRootObject(__PRETTY_FUNCTION__, 2))
00259 ->Fill(x, y, z, w);
00260 else
00261 incompatible(__PRETTY_FUNCTION__);
00262 }
00263
00265 void
00266 MonitorElement::Reset(void)
00267 {
00268 update();
00269 if (kind_ == DQM_KIND_INT)
00270 curvalue_.num = 0;
00271 else if (kind_ == DQM_KIND_REAL)
00272 curvalue_.real = 0;
00273 else if (kind_ == DQM_KIND_STRING)
00274 curvalue_.str.clear();
00275 else
00276 return accessRootObject(__PRETTY_FUNCTION__, 1)
00277 ->Reset();
00278 }
00279
00282 std::string
00283 MonitorElement::valueString(void) const
00284 {
00285 std::ostringstream buf;
00286 if (kind_ == DQM_KIND_INT)
00287 buf << "i=" << curvalue_.num;
00288 else if (kind_ == DQM_KIND_REAL)
00289 buf << "f=" << std::setprecision(16) << curvalue_.real;
00290 else if (kind_ == DQM_KIND_STRING)
00291 buf << "s=" << curvalue_.str;
00292 else
00293 incompatible(__PRETTY_FUNCTION__);
00294 return buf.str();
00295 }
00296
00300 std::string
00301 MonitorElement::tagString(void) const
00302 { return "<" + getName() + ">" + valueString() + "</" + getName() + ">"; }
00303
00304 std::string
00305 MonitorElement::qualityTagString(const DQMNet::QValue &qv) const
00306 {
00307 std::string title;
00308 title.reserve(name_.size() + qv.qtname.size() + 2);
00309 title += name_;
00310 title += '.';
00311 title += qv.qtname;
00312
00313 std::ostringstream retval;
00314 retval << "<" << title << ">"
00315 << "qr=st." << qv.code << "." << qv.message
00316 << "</" << title << ">";
00317 return retval.str();
00318 }
00319
00320 const QReport *
00321 MonitorElement::getQReport(const std::string &qtname) const
00322 {
00323 QReport *qr;
00324 DQMNet::QValue *qv;
00325 const_cast<MonitorElement *>(this)->getQReport(false, qtname, qr, qv);
00326 return qr;
00327 }
00328
00329 std::vector<QReport *>
00330 MonitorElement::getQReports(void) const
00331 {
00332 std::vector<QReport *> result;
00333 result.reserve(qreports_.size());
00334 for (size_t i = 0, e = qreports_.size(); i != e; ++i)
00335 result.push_back(const_cast<QReport *>(&qreports_[i]));
00336 return result;
00337 }
00338
00339 std::vector<QReport *>
00340 MonitorElement::getQWarnings(void) const
00341 {
00342 std::vector<QReport *> result;
00343 result.reserve(qreports_.size());
00344 for (size_t i = 0, e = qreports_.size(); i != e; ++i)
00345 if (data_.qreports[i].code == dqm::qstatus::WARNING)
00346 result.push_back(const_cast<QReport *>(&qreports_[i]));
00347 return result;
00348 }
00349
00350 std::vector<QReport *>
00351 MonitorElement::getQErrors(void) const
00352 {
00353 std::vector<QReport *> result;
00354 result.reserve(qreports_.size());
00355 for (size_t i = 0, e = qreports_.size(); i != e; ++i)
00356 if (data_.qreports[i].code == dqm::qstatus::ERROR)
00357 result.push_back(const_cast<QReport *>(&qreports_[i]));
00358 return result;
00359 }
00360
00361 std::vector<QReport *>
00362 MonitorElement::getQOthers(void) const
00363 {
00364 std::vector<QReport *> result;
00365 result.reserve(qreports_.size());
00366 for (size_t i = 0, e = qreports_.size(); i != e; ++i)
00367 if (data_.qreports[i].code != dqm::qstatus::STATUS_OK
00368 && data_.qreports[i].code != dqm::qstatus::WARNING
00369 && data_.qreports[i].code != dqm::qstatus::ERROR)
00370 result.push_back(const_cast<QReport *>(&qreports_[i]));
00371 return result;
00372 }
00373
00375 void
00376 MonitorElement::runQTests(void)
00377 {
00378 assert(qreports_.size() == data_.qreports.size());
00379
00380
00381 bool dirty = wasUpdated();
00382 for (size_t i = 0, e = data_.qreports.size(); i < e; ++i)
00383 {
00384 DQMNet::QValue &qv = data_.qreports[i];
00385 QReport &qr = qreports_[i];
00386 QCriterion *qc = qr.qcriterion_;
00387 qr.qvalue_ = &qv;
00388
00389 if (qc && (dirty || qc->wasModified()))
00390 {
00391 assert(qc->getName() == qv.qtname);
00392 std::string oldMessage = qv.message;
00393 int oldStatus = qv.code;
00394
00395 qc->runTest(this, qr, qv);
00396
00397 if (oldStatus != qv.code || oldMessage != qv.message)
00398 update();
00399 }
00400 }
00401
00402
00403 updateQReportStats();
00404 }
00405
00406 void
00407 MonitorElement::incompatible(const char *func) const
00408 {
00409 throw cms::Exception("MonitorElement")
00410 << "Method '" << func << "' cannot be invoked on monitor element '"
00411 << data_.name << "'";
00412 }
00413
00414 TH1 *
00415 MonitorElement::accessRootObject(const char *func, int reqdim) const
00416 { return checkRootObject(data_.name, curvalue_.tobj, func, reqdim); }
00417
00418
00419
00421 float
00422 MonitorElement::getMean(int axis ) const
00423 { return accessRootObject(__PRETTY_FUNCTION__, axis-1)
00424 ->GetMean(axis); }
00425
00428 float
00429 MonitorElement::getMeanError(int axis ) const
00430 { return accessRootObject(__PRETTY_FUNCTION__, axis-1)
00431 ->GetMeanError(axis); }
00432
00434 float
00435 MonitorElement::getRMS(int axis ) const
00436 { return accessRootObject(__PRETTY_FUNCTION__, axis-1)
00437 ->GetRMS(axis); }
00438
00440 float
00441 MonitorElement::getRMSError(int axis ) const
00442 { return accessRootObject(__PRETTY_FUNCTION__, axis-1)
00443 ->GetRMSError(axis); }
00444
00446 int
00447 MonitorElement::getNbinsX(void) const
00448 { return accessRootObject(__PRETTY_FUNCTION__, 1)
00449 ->GetNbinsX(); }
00450
00452 int
00453 MonitorElement::getNbinsY(void) const
00454 { return accessRootObject(__PRETTY_FUNCTION__, 2)
00455 ->GetNbinsY(); }
00456
00458 int
00459 MonitorElement::getNbinsZ(void) const
00460 { return accessRootObject(__PRETTY_FUNCTION__, 3)
00461 ->GetNbinsZ(); }
00462
00464 float
00465 MonitorElement::getBinContent(int binx) const
00466 { return accessRootObject(__PRETTY_FUNCTION__, 1)
00467 ->GetBinContent(binx); }
00468
00470 float
00471 MonitorElement::getBinContent(int binx, int biny) const
00472 { return accessRootObject(__PRETTY_FUNCTION__, 2)
00473 ->GetBinContent(binx, biny); }
00474
00476 float
00477 MonitorElement::getBinContent(int binx, int biny, int binz) const
00478 { return accessRootObject(__PRETTY_FUNCTION__, 3)
00479 ->GetBinContent(binx, biny, binz); }
00480
00482 float
00483 MonitorElement::getBinError(int binx) const
00484 { return accessRootObject(__PRETTY_FUNCTION__, 1)
00485 ->GetBinError(binx); }
00486
00488 float
00489 MonitorElement::getBinError(int binx, int biny) const
00490 { return accessRootObject(__PRETTY_FUNCTION__, 2)
00491 ->GetBinError(binx, biny); }
00492
00494 float
00495 MonitorElement::getBinError(int binx, int biny, int binz) const
00496 { return accessRootObject(__PRETTY_FUNCTION__, 3)
00497 ->GetBinError(binx, biny, binz); }
00498
00500 float
00501 MonitorElement::getEntries(void) const
00502 { return accessRootObject(__PRETTY_FUNCTION__, 1)
00503 ->GetEntries(); }
00504
00506 float
00507 MonitorElement::getBinEntries(int bin) const
00508 {
00509 if (kind_ == DQM_KIND_TPROFILE)
00510 return static_cast<TProfile *>(accessRootObject(__PRETTY_FUNCTION__, 1))
00511 ->GetBinEntries(bin);
00512 else if (kind_ == DQM_KIND_TPROFILE2D)
00513 return static_cast<TProfile2D *>(accessRootObject(__PRETTY_FUNCTION__, 1))
00514 ->GetBinEntries(bin);
00515 else
00516 {
00517 incompatible(__PRETTY_FUNCTION__);
00518 return 0;
00519 }
00520 }
00521
00523 float
00524 MonitorElement::getYmin(void) const
00525 {
00526 if (kind_ == DQM_KIND_TPROFILE)
00527 return static_cast<TProfile *>(accessRootObject(__PRETTY_FUNCTION__, 1))
00528 ->GetYmin();
00529 else
00530 {
00531 incompatible(__PRETTY_FUNCTION__);
00532 return 0;
00533 }
00534 }
00535
00537 float
00538 MonitorElement::getYmax(void) const
00539 {
00540 if (kind_ == DQM_KIND_TPROFILE)
00541 return static_cast<TProfile *>(accessRootObject(__PRETTY_FUNCTION__, 1))
00542 ->GetYmax();
00543 else
00544 {
00545 incompatible(__PRETTY_FUNCTION__);
00546 return 0;
00547 }
00548 }
00549
00551 std::string
00552 MonitorElement::getAxisTitle(int axis ) const
00553 { return getAxis(__PRETTY_FUNCTION__, axis)
00554 ->GetTitle(); }
00555
00557 std::string
00558 MonitorElement::getTitle(void) const
00559 { return accessRootObject(__PRETTY_FUNCTION__, 1)
00560 ->GetTitle(); }
00561
00562
00563
00565 void
00566 MonitorElement::setBinContent(int binx, float content)
00567 {
00568 update();
00569 accessRootObject(__PRETTY_FUNCTION__, 1)
00570 ->SetBinContent(binx, content);
00571 }
00572
00574 void
00575 MonitorElement::setBinContent(int binx, int biny, float content)
00576 {
00577 update();
00578 accessRootObject(__PRETTY_FUNCTION__, 2)
00579 ->SetBinContent(binx, biny, content); }
00580
00582 void
00583 MonitorElement::setBinContent(int binx, int biny, int binz, float content)
00584 {
00585 update();
00586 accessRootObject(__PRETTY_FUNCTION__, 3)
00587 ->SetBinContent(binx, biny, binz, content); }
00588
00590 void
00591 MonitorElement::setBinError(int binx, float error)
00592 {
00593 update();
00594 accessRootObject(__PRETTY_FUNCTION__, 1)
00595 ->SetBinError(binx, error);
00596 }
00597
00599 void
00600 MonitorElement::setBinError(int binx, int biny, float error)
00601 {
00602 update();
00603 accessRootObject(__PRETTY_FUNCTION__, 2)
00604 ->SetBinError(binx, biny, error);
00605 }
00606
00608 void
00609 MonitorElement::setBinError(int binx, int biny, int binz, float error)
00610 {
00611 update();
00612 accessRootObject(__PRETTY_FUNCTION__, 3)
00613 ->SetBinError(binx, biny, binz, error);
00614 }
00615
00617 void
00618 MonitorElement::setBinEntries(int bin, float nentries)
00619 {
00620 update();
00621 if (kind_ == DQM_KIND_TPROFILE)
00622 static_cast<TProfile *>(accessRootObject(__PRETTY_FUNCTION__, 1))
00623 ->SetBinEntries(bin, nentries);
00624 else if (kind_ == DQM_KIND_TPROFILE2D)
00625 static_cast<TProfile2D *>(accessRootObject(__PRETTY_FUNCTION__, 1))
00626 ->SetBinEntries(bin, nentries);
00627 else
00628 incompatible(__PRETTY_FUNCTION__);
00629 }
00630
00632 void
00633 MonitorElement::setEntries(float nentries)
00634 {
00635 update();
00636 accessRootObject(__PRETTY_FUNCTION__, 1)
00637 ->SetEntries(nentries);
00638 }
00639
00641 void
00642 MonitorElement::setBinLabel(int bin, const std::string &label, int axis )
00643 {
00644 update();
00645 getAxis(__PRETTY_FUNCTION__, axis)
00646 ->SetBinLabel(bin, label.c_str());
00647 }
00648
00650 void
00651 MonitorElement::setAxisRange(float xmin, float xmax, int axis )
00652 {
00653 update();
00654 getAxis(__PRETTY_FUNCTION__, axis)
00655 ->SetRangeUser(xmin, xmax);
00656 }
00657
00659 void
00660 MonitorElement::setAxisTitle(const std::string &title, int axis )
00661 {
00662 update();
00663 getAxis(__PRETTY_FUNCTION__, axis)
00664 ->SetTitle(title.c_str());
00665 }
00666
00668 void
00669 MonitorElement::setAxisTimeDisplay(int value, int axis )
00670 {
00671 update();
00672 getAxis(__PRETTY_FUNCTION__, axis)
00673 ->SetTimeDisplay(value);
00674 }
00675
00677 void
00678 MonitorElement::setAxisTimeFormat(const char *format , int axis )
00679 {
00680 update();
00681 getAxis(__PRETTY_FUNCTION__, axis)
00682 ->SetTimeFormat(format);
00683 }
00684
00686 void
00687 MonitorElement::setAxisTimeOffset(double toffset, const char *option , int axis )
00688 {
00689 update();
00690 getAxis(__PRETTY_FUNCTION__, axis)
00691 ->SetTimeOffset(toffset, option);
00692 }
00693
00695 void
00696 MonitorElement::setTitle(const std::string &title)
00697 {
00698 update();
00699 accessRootObject(__PRETTY_FUNCTION__, 1)
00700 ->SetTitle(title.c_str());
00701 }
00702
00703 TAxis *
00704 MonitorElement::getAxis(const char *func, int axis) const
00705 {
00706 TH1 *h = accessRootObject(func, axis-1);
00707 TAxis *a = 0;
00708 if (axis == 1)
00709 a = h->GetXaxis();
00710 else if (axis == 2)
00711 a = h->GetYaxis();
00712 else if (axis == 3)
00713 a = h->GetZaxis();
00714
00715 if (! a)
00716 throw cms::Exception("MonitorElement")
00717 << "No such axis " << axis << " in monitor element '"
00718 << data_.name << "' of type '" << typeid(*h).name() << "'";
00719
00720 return a;
00721 }
00722
00723
00724
00727 void
00728 MonitorElement::softReset(void)
00729 {
00730 update();
00731
00732
00733
00734
00735
00736 if (kind_ == DQM_KIND_TH1F)
00737 {
00738 TH1F *orig = static_cast<TH1F *>(curvalue_.tobj);
00739 TH1F *r = static_cast<TH1F *>(refvalue_);
00740 if (! r)
00741 {
00742 refvalue_ = r = new TH1F((std::string(orig->GetName()) + "_ref").c_str(),
00743 orig->GetTitle(),
00744 orig->GetNbinsX(),
00745 orig->GetXaxis()->GetXmin(),
00746 orig->GetXaxis()->GetXmax());
00747 r->SetDirectory(0);
00748 r->Reset();
00749 }
00750
00751 r->Add(orig);
00752 orig->Reset();
00753 }
00754 else if (kind_ == DQM_KIND_TH1S)
00755 {
00756 TH1S *orig = static_cast<TH1S *>(curvalue_.tobj);
00757 TH1S *r = static_cast<TH1S *>(refvalue_);
00758 if (! r)
00759 {
00760 refvalue_ = r = new TH1S((std::string(orig->GetName()) + "_ref").c_str(),
00761 orig->GetTitle(),
00762 orig->GetNbinsX(),
00763 orig->GetXaxis()->GetXmin(),
00764 orig->GetXaxis()->GetXmax());
00765 r->SetDirectory(0);
00766 r->Reset();
00767 }
00768
00769 r->Add(orig);
00770 orig->Reset();
00771 }
00772 else if (kind_ == DQM_KIND_TH2F)
00773 {
00774 TH2F *orig = static_cast<TH2F *>(curvalue_.tobj);
00775 TH2F *r = static_cast<TH2F *>(refvalue_);
00776 if (! r)
00777 {
00778 refvalue_ = r = new TH2F((std::string(orig->GetName()) + "_ref").c_str(),
00779 orig->GetTitle(),
00780 orig->GetNbinsX(),
00781 orig->GetXaxis()->GetXmin(),
00782 orig->GetXaxis()->GetXmax(),
00783 orig->GetNbinsY(),
00784 orig->GetYaxis()->GetXmin(),
00785 orig->GetYaxis()->GetXmax());
00786 r->SetDirectory(0);
00787 r->Reset();
00788 }
00789
00790 r->Add(orig);
00791 orig->Reset();
00792 }
00793 else if (kind_ == DQM_KIND_TH2S)
00794 {
00795 TH2S *orig = static_cast<TH2S *>(curvalue_.tobj);
00796 TH2S *r = static_cast<TH2S *>(refvalue_);
00797 if (! r)
00798 {
00799 refvalue_ = r = new TH2S((std::string(orig->GetName()) + "_ref").c_str(),
00800 orig->GetTitle(),
00801 orig->GetNbinsX(),
00802 orig->GetXaxis()->GetXmin(),
00803 orig->GetXaxis()->GetXmax(),
00804 orig->GetNbinsY(),
00805 orig->GetYaxis()->GetXmin(),
00806 orig->GetYaxis()->GetXmax());
00807 r->SetDirectory(0);
00808 r->Reset();
00809 }
00810
00811 r->Add(orig);
00812 orig->Reset();
00813 }
00814 else if (kind_ == DQM_KIND_TH3F)
00815 {
00816 TH3F *orig = static_cast<TH3F *>(curvalue_.tobj);
00817 TH3F *r = static_cast<TH3F *>(refvalue_);
00818 if (! r)
00819 {
00820 refvalue_ = r = new TH3F((std::string(orig->GetName()) + "_ref").c_str(),
00821 orig->GetTitle(),
00822 orig->GetNbinsX(),
00823 orig->GetXaxis()->GetXmin(),
00824 orig->GetXaxis()->GetXmax(),
00825 orig->GetNbinsY(),
00826 orig->GetYaxis()->GetXmin(),
00827 orig->GetYaxis()->GetXmax(),
00828 orig->GetNbinsZ(),
00829 orig->GetZaxis()->GetXmin(),
00830 orig->GetZaxis()->GetXmax());
00831 r->SetDirectory(0);
00832 r->Reset();
00833 }
00834
00835 r->Add(orig);
00836 orig->Reset();
00837 }
00838 else if (kind_ == DQM_KIND_TPROFILE)
00839 {
00840 TProfile *orig = static_cast<TProfile *>(curvalue_.tobj);
00841 TProfile *r = static_cast<TProfile *>(refvalue_);
00842 if (! r)
00843 {
00844 refvalue_ = r = new TProfile((std::string(orig->GetName()) + "_ref").c_str(),
00845 orig->GetTitle(),
00846 orig->GetNbinsX(),
00847 orig->GetXaxis()->GetXmin(),
00848 orig->GetXaxis()->GetXmax(),
00849 orig->GetYaxis()->GetXmin(),
00850 orig->GetYaxis()->GetXmax(),
00851 orig->GetErrorOption());
00852 r->SetDirectory(0);
00853 r->Reset();
00854 }
00855
00856 addProfiles(r, orig, r, 1, 1);
00857 orig->Reset();
00858 }
00859 else if (kind_ == DQM_KIND_TPROFILE2D)
00860 {
00861 TProfile2D *orig = static_cast<TProfile2D *>(curvalue_.tobj);
00862 TProfile2D *r = static_cast<TProfile2D *>(refvalue_);
00863 if (! r)
00864 {
00865 refvalue_ = r = new TProfile2D((std::string(orig->GetName()) + "_ref").c_str(),
00866 orig->GetTitle(),
00867 orig->GetNbinsX(),
00868 orig->GetXaxis()->GetXmin(),
00869 orig->GetXaxis()->GetXmax(),
00870 orig->GetNbinsY(),
00871 orig->GetYaxis()->GetXmin(),
00872 orig->GetYaxis()->GetXmax(),
00873 orig->GetZaxis()->GetXmin(),
00874 orig->GetZaxis()->GetXmax(),
00875 orig->GetErrorOption());
00876 r->SetDirectory(0);
00877 r->Reset();
00878 }
00879
00880 addProfiles(r, orig, r, 1, 1);
00881 orig->Reset();
00882 }
00883 else
00884 incompatible(__PRETTY_FUNCTION__);
00885 }
00886
00888 void
00889 MonitorElement::disableSoftReset(void)
00890 {
00891 if (refvalue_)
00892 {
00893 if (kind_ == DQM_KIND_TH1F
00894 || kind_ == DQM_KIND_TH1S
00895 || kind_ == DQM_KIND_TH2F
00896 || kind_ == DQM_KIND_TH2S
00897 || kind_ == DQM_KIND_TH3F)
00898 {
00899 TH1 *orig = static_cast<TH1 *>(curvalue_.tobj);
00900 orig->Add(refvalue_);
00901 }
00902 else if (kind_ == DQM_KIND_TPROFILE)
00903 {
00904 TProfile *orig = static_cast<TProfile *>(curvalue_.tobj);
00905 TProfile *r = static_cast<TProfile *>(refvalue_);
00906 addProfiles(orig, r, orig, 1, 1);
00907 }
00908 else if (kind_ == DQM_KIND_TPROFILE2D)
00909 {
00910 TProfile2D *orig = static_cast<TProfile2D *>(curvalue_.tobj);
00911 TProfile2D *r = static_cast<TProfile2D *>(refvalue_);
00912 addProfiles(orig, r, orig, 1, 1);
00913 }
00914 else
00915 incompatible(__PRETTY_FUNCTION__);
00916
00917 delete refvalue_;
00918 refvalue_ = 0;
00919 }
00920 }
00921
00922
00923
00924 void
00925 MonitorElement::addProfiles(TProfile *h1, TProfile *h2, TProfile *sum, float c1, float c2)
00926 {
00927 assert(h1);
00928 assert(h2);
00929 assert(sum);
00930
00931 static const Int_t NUM_STAT = 6;
00932 Double_t stats1[NUM_STAT];
00933 Double_t stats2[NUM_STAT];
00934 Double_t stats3[NUM_STAT];
00935
00936 for (Int_t i = 0; i < NUM_STAT; ++i)
00937 stats1[i] = stats2[i] = stats3[i] = 0;
00938
00939 h1->GetStats(stats1);
00940 h2->GetStats(stats2);
00941
00942 for (Int_t i = 0; i < NUM_STAT; ++i)
00943 stats3[i] = c1*stats1[i] + c2*stats2[i];
00944
00945 stats3[1] = c1*TMath::Abs(c1)*stats1[1]
00946 + c2*TMath::Abs(c2)*stats2[1];
00947
00948 Double_t entries = c1*h1->GetEntries() + c2* h2->GetEntries();
00949 TArrayD* h1sumw2 = h1->GetSumw2();
00950 TArrayD* h2sumw2 = h2->GetSumw2();
00951 for (Int_t bin = 0, nbin = sum->GetNbinsX()+1; bin <= nbin; ++bin)
00952 {
00953 Double_t entries = c1*h1->GetBinEntries(bin)
00954 + c2*h2->GetBinEntries(bin);
00955 Double_t content = c1*h1->GetBinEntries(bin)*h1->GetBinContent(bin)
00956 + c2*h2->GetBinEntries(bin)*h2->GetBinContent(bin);
00957 Double_t error = TMath::Sqrt(c1*TMath::Abs(c1)*h1sumw2->fArray[bin]
00958 + c2*TMath::Abs(c2)*h2sumw2->fArray[bin]);
00959 sum->SetBinContent(bin, content);
00960 sum->SetBinError(bin, error);
00961 sum->SetBinEntries(bin, entries);
00962 }
00963
00964 sum->SetEntries(entries);
00965 sum->PutStats(stats3);
00966 }
00967
00968
00969
00970 void
00971 MonitorElement::addProfiles(TProfile2D *h1, TProfile2D *h2, TProfile2D *sum, float c1, float c2)
00972 {
00973 assert(h1);
00974 assert(h2);
00975 assert(sum);
00976
00977 static const Int_t NUM_STAT = 9;
00978 Double_t stats1[NUM_STAT];
00979 Double_t stats2[NUM_STAT];
00980 Double_t stats3[NUM_STAT];
00981 for (Int_t i = 0; i < NUM_STAT; ++i)
00982 stats1[i] = stats2[i] = stats3[i] = 0;
00983
00984 h1->GetStats(stats1);
00985 h2->GetStats(stats2);
00986
00987 for (Int_t i = 0; i < NUM_STAT; i++)
00988 stats3[i] = c1*stats1[i] + c2*stats2[i];
00989
00990 stats3[1] = c1*TMath::Abs(c1)*stats1[1]
00991 + c2*TMath::Abs(c2)*stats2[1];
00992
00993 Double_t entries = c1*h1->GetEntries() + c2*h2->GetEntries();
00994 TArrayD *h1sumw2 = h1->GetSumw2();
00995 TArrayD *h2sumw2 = h2->GetSumw2();
00996 for (Int_t xbin = 0, nxbin = sum->GetNbinsX()+1; xbin <= nxbin; ++xbin)
00997 for (Int_t ybin = 0, nybin = sum->GetNbinsY()+1; ybin <= nybin; ++ybin)
00998 {
00999 Int_t bin = sum->GetBin(xbin, ybin);
01000 Double_t entries = c1*h1->GetBinEntries(bin)
01001 + c2*h2->GetBinEntries(bin);
01002 Double_t content = c1*h1->GetBinEntries(bin)*h1->GetBinContent(bin)
01003 + c2*h2->GetBinEntries(bin)*h2->GetBinContent(bin);
01004 Double_t error = TMath::Sqrt(c1*TMath::Abs(c1)*h1sumw2->fArray[bin]
01005 + c2*TMath::Abs(c2)*h2sumw2->fArray[bin]);
01006
01007 sum->SetBinContent(bin, content);
01008 sum->SetBinError(bin, error);
01009 sum->SetBinEntries(bin, entries);
01010 }
01011 sum->SetEntries(entries);
01012 sum->PutStats(stats3);
01013 }
01014
01015 void
01016 MonitorElement::copyFunctions(TH1 *from, TH1 *to)
01017 {
01018
01019
01020 if (isSoftResetEnabled() || isAccumulateEnabled())
01021 return;
01022
01023 update();
01024 TList *fromf = from->GetListOfFunctions();
01025 TList *tof = to->GetListOfFunctions();
01026 for (int i = 0, nfuncs = fromf ? fromf->GetSize() : 0; i < nfuncs; ++i)
01027 {
01028 TObject *obj = fromf->At(i);
01029
01030 if (obj->IsA()->GetName() == "TPaveStats")
01031 continue;
01032
01033 if(TF1 *fn = dynamic_cast<TF1 *>(obj))
01034 tof->Add(new TF1(*fn));
01035
01036
01037 else
01038 throw cms::Exception("MonitorElement")
01039 << "Cannot extract function '" << obj->GetName()
01040 << "' of type '" << obj->IsA()->GetName()
01041 << "' from monitor element '" << data_.name
01042 << "' for a copy";
01043 }
01044 }
01045
01046 void
01047 MonitorElement::copyFrom(TH1 *from)
01048 {
01049 TH1 *orig = accessRootObject(__PRETTY_FUNCTION__, 1);
01050 if (orig->GetTitle() != from->GetTitle())
01051 orig->SetTitle(from->GetTitle());
01052
01053 if (!isAccumulateEnabled())
01054 orig->Reset();
01055
01056 if (isSoftResetEnabled())
01057 {
01058 if (kind_ == DQM_KIND_TH1F
01059 || kind_ == DQM_KIND_TH1S
01060 || kind_ == DQM_KIND_TH2F
01061 || kind_ == DQM_KIND_TH2S
01062 || kind_ == DQM_KIND_TH3F)
01063
01064 orig->Add(from, refvalue_, 1, -1);
01065 else if (kind_ == DQM_KIND_TPROFILE)
01066
01067 addProfiles(static_cast<TProfile *>(from),
01068 static_cast<TProfile *>(refvalue_),
01069 static_cast<TProfile *>(orig),
01070 1, -1);
01071 else if (kind_ == DQM_KIND_TPROFILE2D)
01072
01073 addProfiles(static_cast<TProfile2D *>(from),
01074 static_cast<TProfile2D *>(refvalue_),
01075 static_cast<TProfile2D *>(orig),
01076 1, -1);
01077 else
01078 incompatible(__PRETTY_FUNCTION__);
01079 }
01080 else
01081 orig->Add(from);
01082
01083 copyFunctions(from, orig);
01084 }
01085
01086
01087 void
01088 MonitorElement::getQReport(bool create, const std::string &qtname, QReport *&qr, DQMNet::QValue *&qv)
01089 {
01090 assert(qreports_.size() == data_.qreports.size());
01091
01092 qr = 0;
01093 qv = 0;
01094
01095 size_t pos = 0, end = qreports_.size();
01096 while (pos < end && data_.qreports[pos].qtname != qtname)
01097 ++pos;
01098
01099 if (pos == end && ! create)
01100 return;
01101 else if (pos == end)
01102 {
01103 data_.qreports.push_back(DQMNet::QValue());
01104 qreports_.push_back(QReport(0, 0));
01105
01106 DQMNet::QValue &q = data_.qreports.back();
01107 q.code = dqm::qstatus::DID_NOT_RUN;
01108 q.qtname = qtname;
01109 q.message = "NO_MESSAGE_ASSIGNED";
01110 q.algorithm = "UNKNOWN_ALGORITHM";
01111 }
01112
01113 qr = &qreports_[pos];
01114 qv = &data_.qreports[pos];
01115 }
01116
01118 void
01119 MonitorElement::addQReport(const DQMNet::QValue &desc, QCriterion *qc)
01120 {
01121 QReport *qr;
01122 DQMNet::QValue *qv;
01123 getQReport(true, desc.qtname, qr, qv);
01124 qr->qcriterion_ = qc;
01125 *qv = desc;
01126 update();
01127 }
01128
01129 void
01130 MonitorElement::addQReport(QCriterion *qc)
01131 {
01132 QReport *qr;
01133 DQMNet::QValue *qv;
01134 getQReport(true, qc->getName(), qr, qv);
01135 qv->code = dqm::qstatus::DID_NOT_RUN;
01136 qv->message = "NO_MESSAGE_ASSIGNED";
01137 qr->qcriterion_ = qc;
01138 update();
01139 }
01140
01142 void
01143 MonitorElement::updateQReportStats(void)
01144 {
01145 nqerror_ = nqwarning_ = nqother_ = 0;
01146 for (size_t i = 0, e = data_.qreports.size(); i < e; ++i)
01147 switch (data_.qreports[i].code)
01148 {
01149 case dqm::qstatus::STATUS_OK: break;
01150 case dqm::qstatus::WARNING: ++nqwarning_; break;
01151 case dqm::qstatus::ERROR: ++nqerror_; break;
01152 default: ++nqother_; break;
01153 }
01154
01155 data_.flags &= ~(DQMNet::DQM_FLAG_REPORT_ERROR
01156 | DQMNet::DQM_FLAG_REPORT_WARNING
01157 | DQMNet::DQM_FLAG_REPORT_OTHER);
01158 if (nqerror_)
01159 data_.flags |= DQMNet::DQM_FLAG_REPORT_ERROR;
01160 if (nqwarning_)
01161 data_.flags |= DQMNet::DQM_FLAG_REPORT_WARNING;
01162 if (nqother_)
01163 data_.flags |= DQMNet::DQM_FLAG_REPORT_OTHER;
01164 }
01165
01166
01167 TObject *
01168 MonitorElement::getRootObject(void) const
01169 {
01170 const_cast<MonitorElement *>(this)->update();
01171 return data_.object;
01172 }
01173
01174 TH1 *
01175 MonitorElement::getTH1(void) const
01176 {
01177 const_cast<MonitorElement *>(this)->update();
01178 return accessRootObject(__PRETTY_FUNCTION__, 0);
01179 }
01180
01181 TH1F *
01182 MonitorElement::getTH1F(void) const
01183 {
01184 assert(kind_ == DQM_KIND_TH1F);
01185 const_cast<MonitorElement *>(this)->update();
01186 return dynamic_cast<TH1F *>(accessRootObject(__PRETTY_FUNCTION__, 1));
01187 }
01188
01189 TH1S *
01190 MonitorElement::getTH1S(void) const
01191 {
01192 assert(kind_ == DQM_KIND_TH1S);
01193 const_cast<MonitorElement *>(this)->update();
01194 return dynamic_cast<TH1S *>(accessRootObject(__PRETTY_FUNCTION__, 1));
01195 }
01196
01197 TH2F *
01198 MonitorElement::getTH2F(void) const
01199 {
01200 assert(kind_ == DQM_KIND_TH2F);
01201 const_cast<MonitorElement *>(this)->update();
01202 return dynamic_cast<TH2F *>(accessRootObject(__PRETTY_FUNCTION__, 2));
01203 }
01204
01205 TH2S *
01206 MonitorElement::getTH2S(void) const
01207 {
01208 assert(kind_ == DQM_KIND_TH2S);
01209 const_cast<MonitorElement *>(this)->update();
01210 return dynamic_cast<TH2S *>(accessRootObject(__PRETTY_FUNCTION__, 2));
01211 }
01212
01213 TH3F *
01214 MonitorElement::getTH3F(void) const
01215 {
01216 assert(kind_ == DQM_KIND_TH3F);
01217 const_cast<MonitorElement *>(this)->update();
01218 return dynamic_cast<TH3F *>(accessRootObject(__PRETTY_FUNCTION__, 3));
01219 }
01220
01221 TProfile *
01222 MonitorElement::getTProfile(void) const
01223 {
01224 assert(kind_ == DQM_KIND_TPROFILE);
01225 const_cast<MonitorElement *>(this)->update();
01226 return dynamic_cast<TProfile *>(accessRootObject(__PRETTY_FUNCTION__, 1));
01227 }
01228
01229 TProfile2D *
01230 MonitorElement::getTProfile2D(void) const
01231 {
01232 assert(kind_ == DQM_KIND_TPROFILE2D);
01233 const_cast<MonitorElement *>(this)->update();
01234 return dynamic_cast<TProfile2D *>(accessRootObject(__PRETTY_FUNCTION__, 2));
01235 }
01236
01237
01238 TObject *
01239 MonitorElement::getRefRootObject(void) const
01240 {
01241 const_cast<MonitorElement *>(this)->update();
01242 return data_.reference;
01243 }
01244
01245 TH1 *
01246 MonitorElement::getRefTH1(void) const
01247 {
01248 const_cast<MonitorElement *>(this)->update();
01249 return checkRootObject(data_.name, data_.reference, __PRETTY_FUNCTION__, 0);
01250 }
01251
01252 TH1F *
01253 MonitorElement::getRefTH1F(void) const
01254 {
01255 assert(kind_ == DQM_KIND_TH1F);
01256 const_cast<MonitorElement *>(this)->update();
01257 return dynamic_cast<TH1F *>
01258 (checkRootObject(data_.name, data_.reference, __PRETTY_FUNCTION__, 1));
01259 }
01260
01261 TH1S *
01262 MonitorElement::getRefTH1S(void) const
01263 {
01264 assert(kind_ == DQM_KIND_TH1S);
01265 const_cast<MonitorElement *>(this)->update();
01266 return dynamic_cast<TH1S *>
01267 (checkRootObject(data_.name, data_.reference, __PRETTY_FUNCTION__, 1));
01268 }
01269
01270 TH2F *
01271 MonitorElement::getRefTH2F(void) const
01272 {
01273 assert(kind_ == DQM_KIND_TH2F);
01274 const_cast<MonitorElement *>(this)->update();
01275 return dynamic_cast<TH2F *>
01276 (checkRootObject(data_.name, data_.reference, __PRETTY_FUNCTION__, 2));
01277 }
01278
01279 TH2S *
01280 MonitorElement::getRefTH2S(void) const
01281 {
01282 assert(kind_ == DQM_KIND_TH2S);
01283 const_cast<MonitorElement *>(this)->update();
01284 return dynamic_cast<TH2S *>
01285 (checkRootObject(data_.name, data_.reference, __PRETTY_FUNCTION__, 2));
01286 }
01287
01288 TH3F *
01289 MonitorElement::getRefTH3F(void) const
01290 {
01291 assert(kind_ == DQM_KIND_TH3F);
01292 const_cast<MonitorElement *>(this)->update();
01293 return dynamic_cast<TH3F *>
01294 (checkRootObject(data_.name, data_.reference, __PRETTY_FUNCTION__, 3));
01295 }
01296
01297 TProfile *
01298 MonitorElement::getRefTProfile(void) const
01299 {
01300 assert(kind_ == DQM_KIND_TPROFILE);
01301 const_cast<MonitorElement *>(this)->update();
01302 return dynamic_cast<TProfile *>
01303 (checkRootObject(data_.name, data_.reference, __PRETTY_FUNCTION__, 1));
01304 }
01305
01306 TProfile2D *
01307 MonitorElement::getRefTProfile2D(void) const
01308 {
01309 assert(kind_ == DQM_KIND_TPROFILE2D);
01310 const_cast<MonitorElement *>(this)->update();
01311 return dynamic_cast<TProfile2D *>
01312 (checkRootObject(data_.name, data_.reference, __PRETTY_FUNCTION__, 2));
01313 }