CMS 3D CMS Logo

MonitorElement.cc

Go to the documentation of this file.
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   // Rerun quality tests where the ME or the quality algorithm was modified.
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   // Update QReport statistics.
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 /*** getter methods (wrapper around ROOT methods) ****/
00419 // 
00421 float
00422 MonitorElement::getMean(int axis /* = 1 */) const
00423 { return accessRootObject(__PRETTY_FUNCTION__, axis-1)
00424     ->GetMean(axis); }
00425 
00428 float
00429 MonitorElement::getMeanError(int axis /* = 1 */) const
00430 { return accessRootObject(__PRETTY_FUNCTION__, axis-1)
00431     ->GetMeanError(axis); }
00432 
00434 float
00435 MonitorElement::getRMS(int axis /* = 1 */) const
00436 { return accessRootObject(__PRETTY_FUNCTION__, axis-1)
00437     ->GetRMS(axis); }
00438 
00440 float
00441 MonitorElement::getRMSError(int axis /* = 1 */) 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 /* = 1 */) 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 /*** setter methods (wrapper around ROOT methods) ****/
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 /* = 1 */)
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 /* = 1 */)
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 /* = 1 */)
00661 {
00662   update();
00663   getAxis(__PRETTY_FUNCTION__, axis)
00664     ->SetTitle(title.c_str());
00665 }
00666 
00668 void
00669 MonitorElement::setAxisTimeDisplay(int value, int axis /* = 1 */)
00670 {
00671   update();
00672   getAxis(__PRETTY_FUNCTION__, axis)
00673     ->SetTimeDisplay(value);
00674 }
00675 
00677 void
00678 MonitorElement::setAxisTimeFormat(const char *format /* = "" */, int axis /* = 1 */)
00679 {
00680   update();
00681   getAxis(__PRETTY_FUNCTION__, axis)
00682     ->SetTimeFormat(format);
00683 }
00684 
00686 void
00687 MonitorElement::setAxisTimeOffset(double toffset, const char *option /* ="local" */, int axis /* = 1 */)
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 // ------------ Operations for MEs that are normally never reset ---------
00724 
00727 void
00728 MonitorElement::softReset(void)
00729 {
00730   update();
00731 
00732   // Create the reference object the first time this is called.
00733   // On subsequent calls accumulate the current value to the
00734   // reference, and then reset the current value.  This way the
00735   // future contents will have the reference "subtracted".
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 // implementation: Giuseppe.Della-Ricca@ts.infn.it
00923 // Can be called with sum = h1 or sum = h2
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 // implementation: Giuseppe.Della-Ricca@ts.infn.it
00969 // Can be called with sum = h1 or sum = h2
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   // will copy functions only if local-copy and original-object are equal
01019   // (ie. no soft-resetting or accumulating is enabled)
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     // not interested in statistics
01030     if (obj->IsA()->GetName() == "TPaveStats")
01031       continue;
01032 
01033     if(TF1 *fn = dynamic_cast<TF1 *>(obj))
01034       tof->Add(new TF1(*fn));
01035     //else if (dynamic_cast<TPaveStats *>(obj))
01036     //  ; // FIXME? tof->Add(new TPaveStats(*stats));
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       // subtract "reference"
01064       orig->Add(from, refvalue_, 1, -1);
01065     else if (kind_ == DQM_KIND_TPROFILE)
01066       // subtract "reference"
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       // subtract "reference"
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 // --- Operations on MEs that are normally reset at end of monitoring cycle ---
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 }

Generated on Tue Jun 9 17:34:15 2009 for CMSSW by  doxygen 1.5.4