00001 #include "DQMServices/Core/interface/Standalone.h"
00002 #include "DQMServices/Core/interface/DQMStore.h"
00003 #include "DQMServices/Core/interface/QReport.h"
00004 #include "DQMServices/Core/interface/QTest.h"
00005 #include "DQMServices/Core/src/DQMError.h"
00006 #include "classlib/utils/RegexpMatch.h"
00007 #include "classlib/utils/Regexp.h"
00008 #include "classlib/utils/StringOps.h"
00009 #include "TFile.h"
00010 #include "TROOT.h"
00011 #include "TKey.h"
00012 #include "TClass.h"
00013 #include "TSystem.h"
00014 #include <iterator>
00015 #include <cerrno>
00016
00043
00044
00045 static std::string s_monitorDirName = "DQMData";
00046 static std::string s_referenceDirName = "Reference";
00047 static std::string s_collateDirName = "Collate";
00048 static std::string s_safe = "/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+=_()# ";
00049 static DQMStore *s_instance = 0;
00050
00051 static const lat::Regexp s_rxmeval ("^<(.*)>(i|f|s|t|qr)=(.*)</\\1>$");
00052 static const lat::Regexp s_rxmeqr1 ("^st:(\\d+):([-+e.\\d]+):([^:]*):(.*)$");
00053 static const lat::Regexp s_rxmeqr2 ("^st\\.(\\d+)\\.(.*)$");
00054
00058 static bool
00059 isSubdirectory(const std::string &ofdir, const std::string &path)
00060 {
00061 return (ofdir.empty()
00062 || (path.size() >= ofdir.size()
00063 && path.compare(0, ofdir.size(), ofdir) == 0
00064 && (path.size() == ofdir.size()
00065 || path[ofdir.size()] == '/')));
00066 }
00067
00068 static void
00069 cleanTrailingSlashes(const std::string &path, std::string &clean, const std::string *&cleaned)
00070 {
00071 clean.clear();
00072 cleaned = &path;
00073
00074 size_t len = path.size();
00075 for ( ; len > 0 && path[len-1] == '/'; --len)
00076 ;
00077
00078 if (len != path.size())
00079 {
00080 clean = path.substr(0, len);
00081 cleaned = &clean;
00082 }
00083 }
00084
00085 static void
00086 splitPath(std::string &dir, std::string &name, const std::string &path)
00087 {
00088 size_t slash = path.rfind('/');
00089 if (slash != std::string::npos)
00090 {
00091 dir.append(path, 0, slash);
00092 name.append(path, slash+1, std::string::npos);
00093 }
00094 else
00095 name = path;
00096 }
00097
00098 static void
00099 mergePath(std::string &path, const std::string &dir, const std::string &name)
00100 {
00101 path.reserve(dir.size() + name.size() + 2);
00102 path += dir;
00103 if (! path.empty())
00104 path += '/';
00105 path += name;
00106 }
00107
00108 template <class T>
00109 QCriterion *
00110 makeQCriterion(const std::string &qtname)
00111 { return new T(qtname); }
00112
00113 template <class T>
00114 void
00115 initQCriterion(std::map<std::string, QCriterion *(*)(const std::string &)> &m)
00116 { m[T::getAlgoName()] = &makeQCriterion<T>; }
00117
00119 DQMStore *
00120 DQMStore::instance(void)
00121 {
00122 if (! s_instance)
00123 {
00124 try
00125 {
00126 DQMStore *bei = new DQMStore(edm::ParameterSet());
00127 assert (s_instance == bei);
00128 }
00129 catch(DQMError &e)
00130 {
00131 std::cout << e.what() << std::endl;
00132 exit(255);
00133 }
00134 }
00135
00136 return s_instance;
00137 }
00138
00139 DQMStore::DQMStore(const edm::ParameterSet &pset)
00140 : verbose_ (1),
00141 verboseQT_ (1),
00142 reset_ (false),
00143 collateHistograms_ (false),
00144 readSelectedDirectory_ (""),
00145 pwd_ ("")
00146 {
00147 assert(! s_instance);
00148 s_instance = this;
00149 makeDirectory("");
00150 reset();
00151
00152
00153 verbose_ = pset.getUntrackedParameter<int>("verbose", 0);
00154 if (verbose_ > 0)
00155 std::cout << "DQMStore: verbosity set to " << verbose_ << std::endl;
00156
00157 verboseQT_ = pset.getUntrackedParameter<int>("verboseQT", 0);
00158 if (verbose_ > 0)
00159 std::cout << "DQMStore: QTest verbosity set to " << verboseQT_ << std::endl;
00160
00161 collateHistograms_ = pset.getUntrackedParameter<bool>("collateHistograms", false);
00162 if (collateHistograms_)
00163 std::cout << "DQMStore: histogram collation is enabled\n";
00164
00165 std::string ref = pset.getUntrackedParameter<std::string>("referenceFileName", "");
00166 if (! ref.empty())
00167 {
00168 std::cout << "DQMStore: using reference file '" << ref << "'\n";
00169 readFile(ref, true, "", s_referenceDirName, StripRunDirs, false);
00170 }
00171
00172 initQCriterion<Comp2RefChi2>(qalgos_);
00173 initQCriterion<Comp2RefKolmogorov>(qalgos_);
00174 initQCriterion<ContentsXRange>(qalgos_);
00175 initQCriterion<ContentsYRange>(qalgos_);
00176 initQCriterion<MeanWithinExpected>(qalgos_);
00177 initQCriterion<Comp2RefEqualH>(qalgos_);
00178 initQCriterion<DeadChannel>(qalgos_);
00179 initQCriterion<NoisyChannel>(qalgos_);
00180 initQCriterion<ContentsWithinExpected>(qalgos_);
00181 initQCriterion<CompareToMedian>(qalgos_);
00182 }
00183
00184 DQMStore::~DQMStore(void)
00185 {
00186 for (QCMap::iterator i = qtests_.begin(), e = qtests_.end(); i != e; ++i)
00187 delete i->second;
00188
00189 for (QTestSpecs::iterator i = qtestspecs_.begin(), e = qtestspecs_.end(); i != e; ++i)
00190 delete i->first;
00191
00192 if (s_instance == this)
00193 s_instance = 0;
00194 }
00195
00200 void
00201 DQMStore::setVerbose(unsigned level)
00202 { return; }
00203
00208 const std::string &
00209 DQMStore::pwd(void) const
00210 { return pwd_; }
00211
00213 void
00214 DQMStore::cd(void)
00215 { setCurrentFolder(""); }
00216
00218 void
00219 DQMStore::cd(const std::string &subdir)
00220 {
00221 std::string clean;
00222 const std::string *cleaned = 0;
00223 cleanTrailingSlashes(subdir, clean, cleaned);
00224
00225 if (! dirExists(*cleaned))
00226 raiseDQMError("DQMStore", "Cannot 'cd' into non-existent directory '%s'",
00227 cleaned->c_str());
00228
00229 setCurrentFolder(*cleaned);
00230 }
00231
00236 void
00237 DQMStore::setCurrentFolder(const std::string &fullpath)
00238 {
00239 std::string clean;
00240 const std::string *cleaned = 0;
00241 cleanTrailingSlashes(fullpath, clean, cleaned);
00242 makeDirectory(*cleaned);
00243 pwd_ = *cleaned;
00244 }
00245
00247 void
00248 DQMStore::goUp(void)
00249 {
00250 size_t pos = pwd_.rfind('/');
00251 if (pos == std::string::npos)
00252 setCurrentFolder("");
00253 else
00254 setCurrentFolder(pwd_.substr(0, pos));
00255 }
00256
00257
00259 void
00260 DQMStore::makeDirectory(const std::string &path)
00261 {
00262 std::string prev;
00263 std::string subdir;
00264 std::string name;
00265 prev.reserve(path.size());
00266 subdir.reserve(path.size());
00267 name.reserve(path.size());
00268 size_t prevname = 0;
00269 size_t slash = 0;
00270
00271 while (true)
00272 {
00273
00274 subdir.clear();
00275 subdir.append(path, 0, slash);
00276 name.clear();
00277 name.append(subdir, prevname, std::string::npos);
00278 if (! prev.empty() && findObject(prev, name))
00279 raiseDQMError("DQMStore", "Attempt to create subdirectory '%s'"
00280 " which already exists as a monitor element",
00281 subdir.c_str());
00282
00283 if (! dirs_.count(subdir))
00284 dirs_.insert(subdir);
00285
00286
00287 if (slash+1 >= path.size())
00288 break;
00289
00290
00291
00292 prevname = slash ? slash+1 : slash;
00293 prev = subdir;
00294 if ((slash = path.find('/', ++slash)) == std::string::npos)
00295 slash = path.size();
00296 }
00297 }
00298
00300 bool
00301 DQMStore::dirExists(const std::string &path) const
00302 { return dirs_.count(path) > 0; }
00303
00307 template <class HISTO, class COLLATE>
00308 MonitorElement *
00309 DQMStore::book(const std::string &dir, const std::string &name,
00310 const char *context, int kind,
00311 HISTO *h, COLLATE collate)
00312 {
00313 assert(name.find('/') == std::string::npos);
00314 std::string path;
00315 mergePath(path, dir, name);
00316
00317
00318 h->SetDirectory(0);
00319
00320
00321 if (MonitorElement *me = findObject(dir, name))
00322 {
00323 if (collateHistograms_)
00324 {
00325 collate(me, h);
00326 delete h;
00327 return me;
00328 }
00329 else
00330 {
00331 if (verbose_ > 1)
00332 std::cout << "DQMStore: "
00333 << context << ": monitor element '"
00334 << path << "' already exists, collating" << std::endl;
00335 me->Reset();
00336 collate(me, h);
00337 delete h;
00338 return me;
00339 }
00340 }
00341 else
00342 {
00343
00344 assert(dirs_.count(dir));
00345 MonitorElement proto(&*dirs_.find(dir), name);
00346 MonitorElement *me
00347 = const_cast<MonitorElement &>(*data_.insert(proto).first)
00348 .initialise((MonitorElement::Kind)kind, h);
00349
00350
00351 QTestSpecs::iterator qi = qtestspecs_.begin();
00352 QTestSpecs::iterator qe = qtestspecs_.end();
00353 for ( ; qi != qe; ++qi)
00354 if (qi->first->match(path))
00355 me->addQReport(qi->second);
00356
00357
00358 std::string refdir;
00359 refdir.reserve(s_referenceDirName.size() + dir.size() + 2);
00360 refdir += s_referenceDirName;
00361 refdir += '/';
00362 refdir += dir;
00363
00364 if (MonitorElement *refme = findObject(refdir, name))
00365 {
00366 me->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
00367 me->reference_ = refme->object_;
00368 }
00369
00370
00371 return me;
00372 }
00373 }
00374
00375 MonitorElement *
00376 DQMStore::book(const std::string &dir,
00377 const std::string &name,
00378 const char *context)
00379 {
00380 assert(name.find('/') == std::string::npos);
00381
00382
00383 if (MonitorElement *me = findObject(dir, name))
00384 {
00385 if (verbose_ > 1)
00386 {
00387 std::string path;
00388 mergePath(path, dir, name);
00389
00390 std::cout << "DQMStore: "
00391 << context << ": monitor element '"
00392 << path << "' already exists, resetting" << std::endl;
00393 }
00394 me->Reset();
00395 return me;
00396 }
00397 else
00398 {
00399
00400 assert(dirs_.count(dir));
00401 MonitorElement me(&*dirs_.find(dir), name);
00402 return &const_cast<MonitorElement &>(*data_.insert(me).first);
00403 }
00404 }
00405
00406
00408 MonitorElement *
00409 DQMStore::bookInt(const std::string &dir, const std::string &name)
00410 {
00411 if (collateHistograms_)
00412 {
00413 if (MonitorElement *me = findObject(dir, name))
00414 {
00415 me->Fill(0);
00416 return me;
00417 }
00418 }
00419
00420 return book(dir, name, "bookInt")
00421 ->initialise(MonitorElement::DQM_KIND_INT);
00422 }
00423
00425 MonitorElement *
00426 DQMStore::bookInt(const char *name)
00427 { return bookInt(pwd_, name); }
00428
00430 MonitorElement *
00431 DQMStore::bookInt(const std::string &name)
00432 {
00433 return bookInt(pwd_, name);
00434 }
00435
00436
00438 MonitorElement *
00439 DQMStore::bookFloat(const std::string &dir, const std::string &name)
00440 {
00441 if (collateHistograms_)
00442 {
00443 if (MonitorElement *me = findObject(dir, name))
00444 {
00445 me->Fill(0.);
00446 return me;
00447 }
00448 }
00449
00450 return book(dir, name, "bookFloat")
00451 ->initialise(MonitorElement::DQM_KIND_REAL);
00452 }
00453
00455 MonitorElement *
00456 DQMStore::bookFloat(const char *name)
00457 { return bookFloat(pwd_, name); }
00458
00460 MonitorElement *
00461 DQMStore::bookFloat(const std::string &name)
00462 {
00463 return bookFloat(pwd_, name);
00464 }
00465
00466
00468 MonitorElement *
00469 DQMStore::bookString(const std::string &dir,
00470 const std::string &name,
00471 const std::string &value)
00472 {
00473 if (collateHistograms_)
00474 {
00475 if (MonitorElement *me = findObject(dir, name))
00476 return me;
00477 }
00478
00479 return book(dir, name, "bookString")
00480 ->initialise(MonitorElement::DQM_KIND_STRING, value);
00481 }
00482
00484 MonitorElement *
00485 DQMStore::bookString(const char *name, const char *value)
00486 { return bookString(pwd_, name, value); }
00487
00489 MonitorElement *
00490 DQMStore::bookString(const std::string &name, const std::string &value)
00491 {
00492 return bookString(pwd_, name, value);
00493 }
00494
00495
00497 MonitorElement *
00498 DQMStore::book1D(const std::string &dir, const std::string &name, TH1F *h)
00499 {
00500 return book(dir, name, "book1D", MonitorElement::DQM_KIND_TH1F, h, collate1D);
00501 }
00502
00504 MonitorElement *
00505 DQMStore::book1S(const std::string &dir, const std::string &name, TH1S *h)
00506 {
00507 return book(dir, name, "book1S", MonitorElement::DQM_KIND_TH1S, h, collate1S);
00508 }
00509
00511 MonitorElement *
00512 DQMStore::book1DD(const std::string &dir, const std::string &name, TH1D *h)
00513 {
00514 return book(dir, name, "book1DD", MonitorElement::DQM_KIND_TH1D, h, collate1DD);
00515 }
00516
00518 MonitorElement *
00519 DQMStore::book1D(const char *name, const char *title,
00520 int nchX, double lowX, double highX)
00521 {
00522 return book1D(pwd_, name, new TH1F(name, title, nchX, lowX, highX));
00523 }
00524
00526 MonitorElement *
00527 DQMStore::book1D(const std::string &name, const std::string &title,
00528 int nchX, double lowX, double highX)
00529 {
00530 return book1D(pwd_, name, new TH1F(name.c_str(), title.c_str(), nchX, lowX, highX));
00531 }
00532
00534 MonitorElement *
00535 DQMStore::book1S(const char *name, const char *title,
00536 int nchX, double lowX, double highX)
00537 {
00538 return book1S(pwd_, name, new TH1S(name, title, nchX, lowX, highX));
00539 }
00540
00542 MonitorElement *
00543 DQMStore::book1S(const std::string &name, const std::string &title,
00544 int nchX, double lowX, double highX)
00545 {
00546 return book1S(pwd_, name, new TH1S(name.c_str(), title.c_str(), nchX, lowX, highX));
00547 }
00548
00550 MonitorElement *
00551 DQMStore::book1DD(const char *name, const char *title,
00552 int nchX, double lowX, double highX)
00553 {
00554 return book1DD(pwd_, name, new TH1D(name, title, nchX, lowX, highX));
00555 }
00556
00558 MonitorElement *
00559 DQMStore::book1DD(const std::string &name, const std::string &title,
00560 int nchX, double lowX, double highX)
00561 {
00562 return book1DD(pwd_, name, new TH1D(name.c_str(), title.c_str(), nchX, lowX, highX));
00563 }
00564
00566 MonitorElement *
00567 DQMStore::book1D(const char *name, const char *title,
00568 int nchX, float *xbinsize)
00569 {
00570 return book1D(pwd_, name, new TH1F(name, title, nchX, xbinsize));
00571 }
00572
00574 MonitorElement *
00575 DQMStore::book1D(const std::string &name, const std::string &title,
00576 int nchX, float *xbinsize)
00577 {
00578 return book1D(pwd_, name, new TH1F(name.c_str(), title.c_str(), nchX, xbinsize));
00579 }
00580
00582 MonitorElement *
00583 DQMStore::book1D(const char *name, TH1F *source)
00584 {
00585 return book1D(pwd_, name, static_cast<TH1F *>(source->Clone(name)));
00586 }
00587
00589 MonitorElement *
00590 DQMStore::book1D(const std::string &name, TH1F *source)
00591 {
00592 return book1D(pwd_, name, static_cast<TH1F *>(source->Clone(name.c_str())));
00593 }
00594
00596 MonitorElement *
00597 DQMStore::book1S(const char *name, TH1S *source)
00598 {
00599 return book1S(pwd_, name, static_cast<TH1S *>(source->Clone(name)));
00600 }
00601
00603 MonitorElement *
00604 DQMStore::book1S(const std::string &name, TH1S *source)
00605 {
00606 return book1S(pwd_, name, static_cast<TH1S *>(source->Clone(name.c_str())));
00607 }
00608
00610 MonitorElement *
00611 DQMStore::book1DD(const char *name, TH1D *source)
00612 {
00613 return book1DD(pwd_, name, static_cast<TH1D *>(source->Clone(name)));
00614 }
00615
00617 MonitorElement *
00618 DQMStore::book1DD(const std::string &name, TH1D *source)
00619 {
00620 return book1DD(pwd_, name, static_cast<TH1D *>(source->Clone(name.c_str())));
00621 }
00622
00623
00625 MonitorElement *
00626 DQMStore::book2D(const std::string &dir, const std::string &name, TH2F *h)
00627 {
00628 return book(dir, name, "book2D", MonitorElement::DQM_KIND_TH2F, h, collate2D);
00629 }
00630
00632 MonitorElement *
00633 DQMStore::book2S(const std::string &dir, const std::string &name, TH2S *h)
00634 {
00635 return book(dir, name, "book2S", MonitorElement::DQM_KIND_TH2S, h, collate2S);
00636 }
00637
00639 MonitorElement *
00640 DQMStore::book2DD(const std::string &dir, const std::string &name, TH2D *h)
00641 {
00642 return book(dir, name, "book2DD", MonitorElement::DQM_KIND_TH2D, h, collate2DD);
00643 }
00644
00646 MonitorElement *
00647 DQMStore::book2D(const char *name, const char *title,
00648 int nchX, double lowX, double highX,
00649 int nchY, double lowY, double highY)
00650 {
00651 return book2D(pwd_, name, new TH2F(name, title,
00652 nchX, lowX, highX,
00653 nchY, lowY, highY));
00654 }
00655
00657 MonitorElement *
00658 DQMStore::book2D(const std::string &name, const std::string &title,
00659 int nchX, double lowX, double highX,
00660 int nchY, double lowY, double highY)
00661 {
00662 return book2D(pwd_, name, new TH2F(name.c_str(), title.c_str(),
00663 nchX, lowX, highX,
00664 nchY, lowY, highY));
00665 }
00666
00668 MonitorElement *
00669 DQMStore::book2S(const char *name, const char *title,
00670 int nchX, double lowX, double highX,
00671 int nchY, double lowY, double highY)
00672 {
00673 return book2S(pwd_, name, new TH2S(name, title,
00674 nchX, lowX, highX,
00675 nchY, lowY, highY));
00676 }
00677
00679 MonitorElement *
00680 DQMStore::book2S(const std::string &name, const std::string &title,
00681 int nchX, double lowX, double highX,
00682 int nchY, double lowY, double highY)
00683 {
00684 return book2S(pwd_, name, new TH2S(name.c_str(), title.c_str(),
00685 nchX, lowX, highX,
00686 nchY, lowY, highY));
00687 }
00688
00690 MonitorElement *
00691 DQMStore::book2DD(const char *name, const char *title,
00692 int nchX, double lowX, double highX,
00693 int nchY, double lowY, double highY)
00694 {
00695 return book2DD(pwd_, name, new TH2D(name, title,
00696 nchX, lowX, highX,
00697 nchY, lowY, highY));
00698 }
00699
00701 MonitorElement *
00702 DQMStore::book2DD(const std::string &name, const std::string &title,
00703 int nchX, double lowX, double highX,
00704 int nchY, double lowY, double highY)
00705 {
00706 return book2DD(pwd_, name, new TH2D(name.c_str(), title.c_str(),
00707 nchX, lowX, highX,
00708 nchY, lowY, highY));
00709 }
00710
00712 MonitorElement *
00713 DQMStore::book2D(const char *name, const char *title,
00714 int nchX, float *xbinsize, int nchY, float *ybinsize)
00715 {
00716 return book2D(pwd_, name, new TH2F(name, title,
00717 nchX, xbinsize, nchY, ybinsize));
00718 }
00719
00721 MonitorElement *
00722 DQMStore::book2D(const std::string &name, const std::string &title,
00723 int nchX, float *xbinsize, int nchY, float *ybinsize)
00724 {
00725 return book2D(pwd_, name, new TH2F(name.c_str(), title.c_str(),
00726 nchX, xbinsize, nchY, ybinsize));
00727 }
00728
00730 MonitorElement *
00731 DQMStore::book2D(const char *name, TH2F *source)
00732 {
00733 return book2D(pwd_, name, static_cast<TH2F *>(source->Clone(name)));
00734 }
00735
00737 MonitorElement *
00738 DQMStore::book2D(const std::string &name, TH2F *source)
00739 {
00740 return book2D(pwd_, name, static_cast<TH2F *>(source->Clone(name.c_str())));
00741 }
00742
00744 MonitorElement *
00745 DQMStore::book2S(const char *name, TH2S *source)
00746 {
00747 return book2S(pwd_, name, static_cast<TH2S *>(source->Clone(name)));
00748 }
00749
00751 MonitorElement *
00752 DQMStore::book2S(const std::string &name, TH2S *source)
00753 {
00754 return book2S(pwd_, name, static_cast<TH2S *>(source->Clone(name.c_str())));
00755 }
00756
00758 MonitorElement *
00759 DQMStore::book2DD(const char *name, TH2D *source)
00760 {
00761 return book2DD(pwd_, name, static_cast<TH2D *>(source->Clone(name)));
00762 }
00763
00765 MonitorElement *
00766 DQMStore::book2DD(const std::string &name, TH2D *source)
00767 {
00768 return book2DD(pwd_, name, static_cast<TH2D *>(source->Clone(name.c_str())));
00769 }
00770
00771
00773 MonitorElement *
00774 DQMStore::book3D(const std::string &dir, const std::string &name, TH3F *h)
00775 {
00776 return book(dir, name, "book3D", MonitorElement::DQM_KIND_TH3F, h, collate3D);
00777 }
00778
00780 MonitorElement *
00781 DQMStore::book3D(const char *name, const char *title,
00782 int nchX, double lowX, double highX,
00783 int nchY, double lowY, double highY,
00784 int nchZ, double lowZ, double highZ)
00785 {
00786 return book3D(pwd_, name, new TH3F(name, title,
00787 nchX, lowX, highX,
00788 nchY, lowY, highY,
00789 nchZ, lowZ, highZ));
00790 }
00791
00793 MonitorElement *
00794 DQMStore::book3D(const std::string &name, const std::string &title,
00795 int nchX, double lowX, double highX,
00796 int nchY, double lowY, double highY,
00797 int nchZ, double lowZ, double highZ)
00798 {
00799 return book3D(pwd_, name, new TH3F(name.c_str(), title.c_str(),
00800 nchX, lowX, highX,
00801 nchY, lowY, highY,
00802 nchZ, lowZ, highZ));
00803 }
00804
00806 MonitorElement *
00807 DQMStore::book3D(const char *name, TH3F *source)
00808 {
00809 return book3D(pwd_, name, static_cast<TH3F *>(source->Clone(name)));
00810 }
00811
00813 MonitorElement *
00814 DQMStore::book3D(const std::string &name, TH3F *source)
00815 {
00816 return book3D(pwd_, name, static_cast<TH3F *>(source->Clone(name.c_str())));
00817 }
00818
00819
00821 MonitorElement *
00822 DQMStore::bookProfile(const std::string &dir, const std::string &name, TProfile *h)
00823 {
00824 return book(dir, name, "bookProfile",
00825 MonitorElement::DQM_KIND_TPROFILE,
00826 h, collateProfile);
00827 }
00828
00832 MonitorElement *
00833 DQMStore::bookProfile(const char *name, const char *title,
00834 int nchX, double lowX, double highX,
00835 int nchY, double lowY, double highY,
00836 const char *option )
00837 {
00838 return bookProfile(pwd_, name, new TProfile(name, title,
00839 nchX, lowX, highX,
00840 lowY, highY,
00841 option));
00842 }
00843
00847 MonitorElement *
00848 DQMStore::bookProfile(const std::string &name, const std::string &title,
00849 int nchX, double lowX, double highX,
00850 int nchY, double lowY, double highY,
00851 const char *option )
00852 {
00853 return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
00854 nchX, lowX, highX,
00855 lowY, highY,
00856 option));
00857 }
00858
00862 MonitorElement *
00863 DQMStore::bookProfile(const char *name, const char *title,
00864 int nchX, double lowX, double highX,
00865 double lowY, double highY,
00866 const char *option )
00867 {
00868 return bookProfile(pwd_, name, new TProfile(name, title,
00869 nchX, lowX, highX,
00870 lowY, highY,
00871 option));
00872 }
00873
00877 MonitorElement *
00878 DQMStore::bookProfile(const std::string &name, const std::string &title,
00879 int nchX, double lowX, double highX,
00880 double lowY, double highY,
00881 const char *option )
00882 {
00883 return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
00884 nchX, lowX, highX,
00885 lowY, highY,
00886 option));
00887 }
00888
00892 MonitorElement *
00893 DQMStore::bookProfile(const char *name, const char *title,
00894 int nchX, double *xbinsize,
00895 int nchY, double lowY, double highY,
00896 const char *option )
00897 {
00898 return bookProfile(pwd_, name, new TProfile(name, title,
00899 nchX, xbinsize,
00900 lowY, highY,
00901 option));
00902 }
00903
00907 MonitorElement *
00908 DQMStore::bookProfile(const std::string &name, const std::string &title,
00909 int nchX, double *xbinsize,
00910 int nchY, double lowY, double highY,
00911 const char *option )
00912 {
00913 return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
00914 nchX, xbinsize,
00915 lowY, highY,
00916 option));
00917 }
00918
00922 MonitorElement *
00923 DQMStore::bookProfile(const char *name, const char *title,
00924 int nchX, double *xbinsize,
00925 double lowY, double highY,
00926 const char *option )
00927 {
00928 return bookProfile(pwd_, name, new TProfile(name, title,
00929 nchX, xbinsize,
00930 lowY, highY,
00931 option));
00932 }
00933
00937 MonitorElement *
00938 DQMStore::bookProfile(const std::string &name, const std::string &title,
00939 int nchX, double *xbinsize,
00940 double lowY, double highY,
00941 const char *option )
00942 {
00943 return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
00944 nchX, xbinsize,
00945 lowY, highY,
00946 option));
00947 }
00948
00950 MonitorElement *
00951 DQMStore::bookProfile(const char *name, TProfile *source)
00952 {
00953 return bookProfile(pwd_, name, static_cast<TProfile *>(source->Clone(name)));
00954 }
00955
00957 MonitorElement *
00958 DQMStore::bookProfile(const std::string &name, TProfile *source)
00959 {
00960 return bookProfile(pwd_, name, static_cast<TProfile *>(source->Clone(name.c_str())));
00961 }
00962
00963
00965 MonitorElement *
00966 DQMStore::bookProfile2D(const std::string &dir, const std::string &name, TProfile2D *h)
00967 {
00968 return book(dir, name, "bookProfile2D",
00969 MonitorElement::DQM_KIND_TPROFILE2D,
00970 h, collateProfile2D);
00971 }
00972
00976 MonitorElement *
00977 DQMStore::bookProfile2D(const char *name, const char *title,
00978 int nchX, double lowX, double highX,
00979 int nchY, double lowY, double highY,
00980 int nchZ, double lowZ, double highZ,
00981 const char *option )
00982 {
00983 return bookProfile2D(pwd_, name, new TProfile2D(name, title,
00984 nchX, lowX, highX,
00985 nchY, lowY, highY,
00986 lowZ, highZ,
00987 option));
00988 }
00989
00993 MonitorElement *
00994 DQMStore::bookProfile2D(const std::string &name, const std::string &title,
00995 int nchX, double lowX, double highX,
00996 int nchY, double lowY, double highY,
00997 int nchZ, double lowZ, double highZ,
00998 const char *option )
00999 {
01000 return bookProfile2D(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
01001 nchX, lowX, highX,
01002 nchY, lowY, highY,
01003 lowZ, highZ,
01004 option));
01005 }
01006
01010 MonitorElement *
01011 DQMStore::bookProfile2D(const char *name, const char *title,
01012 int nchX, double lowX, double highX,
01013 int nchY, double lowY, double highY,
01014 double lowZ, double highZ,
01015 const char *option )
01016 {
01017 return bookProfile2D(pwd_, name, new TProfile2D(name, title,
01018 nchX, lowX, highX,
01019 nchY, lowY, highY,
01020 lowZ, highZ,
01021 option));
01022 }
01023
01027 MonitorElement *
01028 DQMStore::bookProfile2D(const std::string &name, const std::string &title,
01029 int nchX, double lowX, double highX,
01030 int nchY, double lowY, double highY,
01031 double lowZ, double highZ,
01032 const char *option )
01033 {
01034 return bookProfile2D(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
01035 nchX, lowX, highX,
01036 nchY, lowY, highY,
01037 lowZ, highZ,
01038 option));
01039 }
01040
01042 MonitorElement *
01043 DQMStore::bookProfile2D(const char *name, TProfile2D *source)
01044 {
01045 return bookProfile2D(pwd_, name, static_cast<TProfile2D *>(source->Clone(name)));
01046 }
01047
01049 MonitorElement *
01050 DQMStore::bookProfile2D(const std::string &name, TProfile2D *source)
01051 {
01052 return bookProfile2D(pwd_, name, static_cast<TProfile2D *>(source->Clone(name.c_str())));
01053 }
01054
01058 bool
01059 DQMStore::checkBinningMatches(MonitorElement *me, TH1 *h)
01060 {
01061 if (me->getTH1()->GetNbinsX() != h->GetNbinsX()
01062 || me->getTH1()->GetNbinsY() != h->GetNbinsY()
01063 || me->getTH1()->GetNbinsZ() != h->GetNbinsZ()
01064 || me->getTH1()->GetXaxis()->GetXmin() != h->GetXaxis()->GetXmin()
01065 || me->getTH1()->GetYaxis()->GetXmin() != h->GetYaxis()->GetXmin()
01066 || me->getTH1()->GetZaxis()->GetXmin() != h->GetZaxis()->GetXmin()
01067 || me->getTH1()->GetXaxis()->GetXmax() != h->GetXaxis()->GetXmax()
01068 || me->getTH1()->GetYaxis()->GetXmax() != h->GetYaxis()->GetXmax()
01069 || me->getTH1()->GetZaxis()->GetXmax() != h->GetZaxis()->GetXmax())
01070 {
01071
01072 std::cout << "*** DQMStore: WARNING:"
01073 << "checkBinningMatches: different binning - cannot add object '"
01074 << h->GetName() << "' of type "
01075 << h->IsA()->GetName() << " to existing ME: '"
01076 << me->getFullname() << "'\n";
01077 return false;
01078 }
01079 return true;
01080 }
01081
01082 void
01083 DQMStore::collate1D(MonitorElement *me, TH1F *h)
01084 {
01085 if (checkBinningMatches(me,h))
01086 me->getTH1F()->Add(h);
01087 }
01088
01089 void
01090 DQMStore::collate1S(MonitorElement *me, TH1S *h)
01091 {
01092 if (checkBinningMatches(me,h))
01093 me->getTH1S()->Add(h);
01094 }
01095
01096 void
01097 DQMStore::collate1DD(MonitorElement *me, TH1D *h)
01098 {
01099 if (checkBinningMatches(me,h))
01100 me->getTH1D()->Add(h);
01101 }
01102
01103 void
01104 DQMStore::collate2D(MonitorElement *me, TH2F *h)
01105 {
01106 if (checkBinningMatches(me,h))
01107 me->getTH2F()->Add(h);
01108 }
01109
01110 void
01111 DQMStore::collate2S(MonitorElement *me, TH2S *h)
01112 {
01113 if (checkBinningMatches(me,h))
01114 me->getTH2S()->Add(h);
01115 }
01116
01117 void
01118 DQMStore::collate2DD(MonitorElement *me, TH2D *h)
01119 {
01120 if (checkBinningMatches(me,h))
01121 me->getTH2D()->Add(h);
01122 }
01123
01124 void
01125 DQMStore::collate3D(MonitorElement *me, TH3F *h)
01126 {
01127 if (checkBinningMatches(me,h))
01128 me->getTH3F()->Add(h);
01129 }
01130
01131 void
01132 DQMStore::collateProfile(MonitorElement *me, TProfile *h)
01133 {
01134 if (checkBinningMatches(me,h))
01135 {
01136 TProfile *meh = me->getTProfile();
01137 me->addProfiles(h, meh, meh, 1, 1);
01138 }
01139 }
01140
01141 void
01142 DQMStore::collateProfile2D(MonitorElement *me, TProfile2D *h)
01143 {
01144 if (checkBinningMatches(me,h))
01145 {
01146 TProfile2D *meh = me->getTProfile2D();
01147 me->addProfiles(h, meh, meh, 1, 1);
01148 }
01149 }
01150
01155 void
01156 DQMStore::tag(MonitorElement *me, unsigned int myTag)
01157 {
01158 if (! myTag)
01159 raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
01160 " with a zero tag", me->getFullname().c_str());
01161 if ((me->data_.flags & DQMNet::DQM_PROP_TAGGED) && myTag != me->data_.tag)
01162 raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
01163 " twice with multiple tags", me->getFullname().c_str());
01164
01165 me->data_.tag = myTag;
01166 me->data_.flags |= DQMNet::DQM_PROP_TAGGED;
01167 }
01168
01170 void
01171 DQMStore::tag(const std::string &path, unsigned int myTag)
01172 {
01173 std::string dir;
01174 std::string name;
01175 splitPath(dir, name, path);
01176
01177 if (MonitorElement *me = findObject(dir, name))
01178 tag(me, myTag);
01179 else
01180 raiseDQMError("DQMStore", "Attempt to tag non-existent monitor element"
01181 " '%s' with tag %u", path.c_str(), myTag);
01182
01183 }
01184
01186 void
01187 DQMStore::tagContents(const std::string &path, unsigned int myTag)
01188 {
01189 MonitorElement proto(&path, std::string());
01190 MEMap::iterator e = data_.end();
01191 MEMap::iterator i = data_.lower_bound(proto);
01192 for ( ; i != e && path == *i->data_.dirname; ++i)
01193 tag(const_cast<MonitorElement *>(&*i), myTag);
01194 }
01195
01198 void
01199 DQMStore::tagAllContents(const std::string &path, unsigned int myTag)
01200 {
01201 std::string clean;
01202 const std::string *cleaned = 0;
01203 cleanTrailingSlashes(path, clean, cleaned);
01204 MonitorElement proto(cleaned, std::string());
01205
01206
01207 MEMap::iterator e = data_.end();
01208 MEMap::iterator i = data_.lower_bound(proto);
01209 while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
01210 {
01211 tag(const_cast<MonitorElement *>(&*i), myTag);
01212 ++i;
01213 }
01214 }
01215
01220 std::vector<std::string>
01221 DQMStore::getSubdirs(void) const
01222 {
01223 std::vector<std::string> result;
01224 std::set<std::string>::const_iterator e = dirs_.end();
01225 std::set<std::string>::const_iterator i = dirs_.find(pwd_);
01226
01227
01228 if (i == e)
01229 return result;
01230
01231
01232
01233
01234
01235 while (++i != e && isSubdirectory(pwd_, *i))
01236 if (i->find('/', pwd_.size()+1) == std::string::npos)
01237 result.push_back(*i);
01238
01239 return result;
01240 }
01241
01243 std::vector<std::string>
01244 DQMStore::getMEs(void) const
01245 {
01246 MonitorElement proto(&pwd_, std::string());
01247 std::vector<std::string> result;
01248 MEMap::const_iterator e = data_.end();
01249 MEMap::const_iterator i = data_.lower_bound(proto);
01250 for ( ; i != e && isSubdirectory(pwd_, *i->data_.dirname); ++i)
01251 if (pwd_ == *i->data_.dirname)
01252 result.push_back(i->getName());
01253
01254 return result;
01255 }
01256
01259 bool
01260 DQMStore::containsAnyMonitorable(const std::string &path) const
01261 {
01262 MonitorElement proto(&path, std::string());
01263 MEMap::const_iterator e = data_.end();
01264 MEMap::const_iterator i = data_.lower_bound(proto);
01265 return (i != e && isSubdirectory(path, *i->data_.dirname));
01266 }
01267
01269 MonitorElement *
01270 DQMStore::get(const std::string &path) const
01271 {
01272 std::string dir;
01273 std::string name;
01274 splitPath(dir, name, path);
01275 MonitorElement proto(&dir, name);
01276 MEMap::const_iterator mepos = data_.find(proto);
01277 return (mepos == data_.end() ? 0
01278 : const_cast<MonitorElement *>(&*mepos));
01279 }
01280
01282 std::vector<MonitorElement *>
01283 DQMStore::get(unsigned int tag) const
01284 {
01285
01286 std::vector<MonitorElement *> result;
01287 for (MEMap::const_iterator i = data_.begin(), e = data_.end(); i != e; ++i)
01288 {
01289 const MonitorElement &me = *i;
01290 if ((me.data_.flags & DQMNet::DQM_PROP_TAGGED) && me.data_.tag == tag)
01291 result.push_back(const_cast<MonitorElement *>(&me));
01292 }
01293 return result;
01294 }
01295
01298 std::vector<MonitorElement *>
01299 DQMStore::getContents(const std::string &path) const
01300 {
01301 std::string clean;
01302 const std::string *cleaned = 0;
01303 cleanTrailingSlashes(path, clean, cleaned);
01304 MonitorElement proto(cleaned, std::string());
01305
01306 std::vector<MonitorElement *> result;
01307 MEMap::const_iterator e = data_.end();
01308 MEMap::const_iterator i = data_.lower_bound(proto);
01309 for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
01310 if (*cleaned == *i->data_.dirname)
01311 result.push_back(const_cast<MonitorElement *>(&*i));
01312
01313 return result;
01314 }
01315
01317 std::vector<MonitorElement *>
01318 DQMStore::getContents(const std::string &path, unsigned int tag) const
01319 {
01320 std::string clean;
01321 const std::string *cleaned = 0;
01322 cleanTrailingSlashes(path, clean, cleaned);
01323 MonitorElement proto(cleaned, std::string());
01324
01325 std::vector<MonitorElement *> result;
01326 MEMap::const_iterator e = data_.end();
01327 MEMap::const_iterator i = data_.lower_bound(proto);
01328 for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
01329 if (*cleaned == *i->data_.dirname
01330 && (i->data_.flags & DQMNet::DQM_PROP_TAGGED)
01331 && i->data_.tag == tag)
01332 result.push_back(const_cast<MonitorElement *>(&*i));
01333
01334 return result;
01335 }
01336
01341 void
01342 DQMStore::getContents(std::vector<std::string> &into, bool showContents ) const
01343 {
01344 into.clear();
01345 into.reserve(dirs_.size());
01346
01347 MEMap::const_iterator me = data_.end();
01348 std::set<std::string>::const_iterator di = dirs_.begin();
01349 std::set<std::string>::const_iterator de = dirs_.end();
01350 for ( ; di != de; ++di)
01351 {
01352 MonitorElement proto(&*di, std::string());
01353 MEMap::const_iterator mi = data_.lower_bound(proto);
01354 MEMap::const_iterator m = mi;
01355 size_t sz = di->size() + 2;
01356 size_t nfound = 0;
01357 for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
01358 if (*di == *m->data_.dirname)
01359 {
01360 sz += m->data_.objname.size() + 1;
01361 ++nfound;
01362 }
01363
01364 if (! nfound)
01365 continue;
01366
01367 std::vector<std::string>::iterator istr
01368 = into.insert(into.end(), std::string());
01369
01370 if (showContents)
01371 {
01372 istr->reserve(sz);
01373
01374 *istr += *di;
01375 *istr += ':';
01376 for (sz = 0; mi != m; ++mi)
01377 {
01378 if (*di != *mi->data_.dirname)
01379 continue;
01380
01381 if (sz > 0)
01382 *istr += ',';
01383
01384 *istr += mi->data_.objname;
01385 ++sz;
01386 }
01387 }
01388 else
01389 {
01390 istr->reserve(di->size() + 2);
01391 *istr += *di;
01392 *istr += ':';
01393 }
01394 }
01395 }
01396
01399 MonitorElement *
01400 DQMStore::findObject(const std::string &dir, const std::string &name) const
01401 {
01402 if (dir.find_first_not_of(s_safe) != std::string::npos)
01403 raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
01404 " unacceptable characters", dir.c_str());
01405 if (name.find_first_not_of(s_safe) != std::string::npos)
01406 raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
01407 " unacceptable characters", name.c_str());
01408
01409 MonitorElement proto;
01410 proto.data_.dirname = &dir;
01411 proto.data_.objname = name;
01412
01413 MEMap::const_iterator mepos = data_.find(proto);
01414 return (mepos == data_.end() ? 0
01415 : const_cast<MonitorElement *>(&*mepos));
01416 }
01417
01420 void
01421 DQMStore::getAllTags(std::vector<std::string> &into) const
01422 {
01423 into.clear();
01424 into.reserve(dirs_.size());
01425
01426 MEMap::const_iterator me = data_.end();
01427 std::set<std::string>::const_iterator di = dirs_.begin();
01428 std::set<std::string>::const_iterator de = dirs_.end();
01429 char tagbuf[32];
01430
01431 for ( ; di != de; ++di)
01432 {
01433 MonitorElement proto(&*di, std::string());
01434 MEMap::const_iterator mi = data_.lower_bound(proto);
01435 MEMap::const_iterator m = mi;
01436 size_t sz = di->size() + 2;
01437 size_t nfound = 0;
01438 for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
01439 if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
01440 {
01441
01442 sz += 1 + m->data_.objname.size() + 11;
01443 ++nfound;
01444 }
01445
01446 if (! nfound)
01447 continue;
01448
01449 std::vector<std::string>::iterator istr
01450 = into.insert(into.end(), std::string());
01451
01452 istr->reserve(sz);
01453
01454 *istr += *di;
01455 *istr += ':';
01456 for (sz = 0; mi != m; ++mi)
01457 {
01458 if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
01459 {
01460 sprintf(tagbuf, "/%u", mi->data_.tag);
01461 if (sz > 0)
01462 *istr += ',';
01463 *istr += m->data_.objname;
01464 *istr += tagbuf;
01465 ++sz;
01466 }
01467 }
01468 }
01469 }
01470
01473 std::vector<MonitorElement*>
01474 DQMStore::getAllContents(const std::string &path) const
01475 {
01476 std::string clean;
01477 const std::string *cleaned = 0;
01478 cleanTrailingSlashes(path, clean, cleaned);
01479 MonitorElement proto(cleaned, std::string());
01480
01481 std::vector<MonitorElement *> result;
01482 MEMap::const_iterator e = data_.end();
01483 MEMap::const_iterator i = data_.lower_bound(proto);
01484 for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
01485 result.push_back(const_cast<MonitorElement *>(&*i));
01486
01487 return result;
01488 }
01489
01492 std::vector<MonitorElement*>
01493 DQMStore::getMatchingContents(const std::string &pattern, lat::Regexp::Syntax syntaxType ) const
01494 {
01495 lat::Regexp rx;
01496 try
01497 {
01498 rx = lat::Regexp(pattern, 0, syntaxType);
01499 rx.study();
01500 }
01501 catch (lat::Error &e)
01502 {
01503 raiseDQMError("DQMStore", "Invalid regular expression '%s': %s",
01504 pattern.c_str(), e.explain().c_str());
01505 }
01506
01507 std::string path;
01508 std::vector<MonitorElement *> result;
01509 MEMap::const_iterator i = data_.begin();
01510 MEMap::const_iterator e = data_.end();
01511 for ( ; i != e; ++i)
01512 {
01513 path.clear();
01514 mergePath(path, *i->data_.dirname, i->data_.objname);
01515 if (rx.match(path))
01516 result.push_back(const_cast<MonitorElement *>(&*i));
01517 }
01518
01519 return result;
01520 }
01521
01525
01528 void
01529 DQMStore::reset(void)
01530 {
01531 MEMap::iterator mi = data_.begin();
01532 MEMap::iterator me = data_.end();
01533 for ( ; mi != me; ++mi)
01534 {
01535 MonitorElement &me = const_cast<MonitorElement &>(*mi);
01536 if (mi->wasUpdated())
01537 {
01538 if (me.resetMe())
01539 me.Reset();
01540 me.resetUpdate();
01541 }
01542 }
01543
01544 reset_ = true;
01545 }
01546
01552 bool
01553 DQMStore::extract(TObject *obj, const std::string &dir, bool overwrite)
01554 {
01555
01556 MonitorElement *refcheck = 0;
01557 if (TProfile *h = dynamic_cast<TProfile *>(obj))
01558 {
01559 MonitorElement *me = findObject(dir, h->GetName());
01560 if (! me)
01561 me = bookProfile(dir, h->GetName(), (TProfile *) h->Clone());
01562 else if (overwrite)
01563 me->copyFrom(h);
01564 else if (isCollateME(me) || collateHistograms_)
01565 collateProfile(me, h);
01566 refcheck = me;
01567 }
01568 else if (TProfile2D *h = dynamic_cast<TProfile2D *>(obj))
01569 {
01570 MonitorElement *me = findObject(dir, h->GetName());
01571 if (! me)
01572 me = bookProfile2D(dir, h->GetName(), (TProfile2D *) h->Clone());
01573 else if (overwrite)
01574 me->copyFrom(h);
01575 else if (isCollateME(me) || collateHistograms_)
01576 collateProfile2D(me, h);
01577 refcheck = me;
01578 }
01579 else if (TH1F *h = dynamic_cast<TH1F *>(obj))
01580 {
01581 MonitorElement *me = findObject(dir, h->GetName());
01582 if (! me)
01583 me = book1D(dir, h->GetName(), (TH1F *) h->Clone());
01584 else if (overwrite)
01585 me->copyFrom(h);
01586 else if (isCollateME(me) || collateHistograms_)
01587 collate1D(me, h);
01588 refcheck = me;
01589 }
01590 else if (TH1S *h = dynamic_cast<TH1S *>(obj))
01591 {
01592 MonitorElement *me = findObject(dir, h->GetName());
01593 if (! me)
01594 me = book1S(dir, h->GetName(), (TH1S *) h->Clone());
01595 else if (overwrite)
01596 me->copyFrom(h);
01597 else if (isCollateME(me) || collateHistograms_)
01598 collate1S(me, h);
01599 refcheck = me;
01600 }
01601 else if (TH1D *h = dynamic_cast<TH1D *>(obj))
01602 {
01603 MonitorElement *me = findObject(dir, h->GetName());
01604 if (! me)
01605 me = book1DD(dir, h->GetName(), (TH1D *) h->Clone());
01606 else if (overwrite)
01607 me->copyFrom(h);
01608 else if (isCollateME(me) || collateHistograms_)
01609 collate1DD(me, h);
01610 refcheck = me;
01611 }
01612 else if (TH2F *h = dynamic_cast<TH2F *>(obj))
01613 {
01614 MonitorElement *me = findObject(dir, h->GetName());
01615 if (! me)
01616 me = book2D(dir, h->GetName(), (TH2F *) h->Clone());
01617 else if (overwrite)
01618 me->copyFrom(h);
01619 else if (isCollateME(me) || collateHistograms_)
01620 collate2D(me, h);
01621 refcheck = me;
01622 }
01623 else if (TH2S *h = dynamic_cast<TH2S *>(obj))
01624 {
01625 MonitorElement *me = findObject(dir, h->GetName());
01626 if (! me)
01627 me = book2S(dir, h->GetName(), (TH2S *) h->Clone());
01628 else if (overwrite)
01629 me->copyFrom(h);
01630 else if (isCollateME(me) || collateHistograms_)
01631 collate2S(me, h);
01632 refcheck = me;
01633 }
01634 else if (TH2D *h = dynamic_cast<TH2D *>(obj))
01635 {
01636 MonitorElement *me = findObject(dir, h->GetName());
01637 if (! me)
01638 me = book2DD(dir, h->GetName(), (TH2D *) h->Clone());
01639 else if (overwrite)
01640 me->copyFrom(h);
01641 else if (isCollateME(me) || collateHistograms_)
01642 collate2DD(me, h);
01643 refcheck = me;
01644 }
01645 else if (TH3F *h = dynamic_cast<TH3F *>(obj))
01646 {
01647 MonitorElement *me = findObject(dir, h->GetName());
01648 if (! me)
01649 me = book3D(dir, h->GetName(), (TH3F *) h->Clone());
01650 else if (overwrite)
01651 me->copyFrom(h);
01652 else if (isCollateME(me) || collateHistograms_)
01653 collate3D(me, h);
01654 refcheck = me;
01655 }
01656 else if (dynamic_cast<TObjString *>(obj))
01657 {
01658 lat::RegexpMatch m;
01659 if (! s_rxmeval.match(obj->GetName(), 0, 0, &m))
01660 {
01661 if (strstr(obj->GetName(), "CMSSW"))
01662 {
01663 if (verbose_)
01664 std::cout << "Input file version: " << obj->GetName() << std::endl;
01665 return true;
01666 }
01667 else if (strstr(obj->GetName(), "DQMPATCH"))
01668 {
01669 if (verbose_)
01670 std::cout << "DQM patch version: " << obj->GetName() << std::endl;
01671 return true;
01672 }
01673 else
01674 {
01675 std::cout << "*** DQMStore: WARNING: cannot extract object '"
01676 << obj->GetName() << "' of type '"
01677 << obj->IsA()->GetName() << "'\n";
01678 return false;
01679 }
01680 }
01681
01682 std::string label = m.matchString(obj->GetName(), 1);
01683 std::string kind = m.matchString(obj->GetName(), 2);
01684 std::string value = m.matchString(obj->GetName(), 3);
01685
01686 if (kind == "i")
01687 {
01688 MonitorElement *me = findObject(dir, label);
01689 if (! me || overwrite)
01690 {
01691 if (! me) me = bookInt(dir, label);
01692 me->Fill(atoll(value.c_str()));
01693 }
01694 }
01695 else if (kind == "f")
01696 {
01697 MonitorElement *me = findObject(dir, label);
01698 if (! me || overwrite)
01699 {
01700 if (! me) me = bookFloat(dir, label);
01701 me->Fill(atof(value.c_str()));
01702 }
01703 }
01704 else if (kind == "s")
01705 {
01706 MonitorElement *me = findObject(dir, label);
01707 if (! me)
01708 me = bookString(dir, label, value);
01709 else if (overwrite)
01710 me->Fill(value);
01711 }
01712 else if (kind == "t")
01713 {
01714 MonitorElement *me = findObject(dir, label);
01715 if (! me)
01716 {
01717 std::cout << "*** DQMStore: WARNING: no monitor element '"
01718 << label << "' in directory '"
01719 << dir << "' for a tag\n";
01720 return false;
01721 }
01722 errno = 0;
01723 char *endp = 0;
01724 unsigned long val = strtoul(value.c_str(), &endp, 10);
01725 if ((val == 0 && errno) || *endp || val > ~uint32_t(0))
01726 {
01727 std::cout << "*** DQMStore: WARNING: cannot restore tag '"
01728 << value << "' for monitor element '"
01729 << label << "' in directory '"
01730 << dir << "' - invalid value\n";
01731 return false;
01732 }
01733 tag(me, val);
01734 }
01735 else if (kind == "qr")
01736 {
01737
01738 if (! isSubdirectory(s_referenceDirName, dir))
01739 {
01740 size_t dot = label.find('.');
01741 if (dot == std::string::npos)
01742 {
01743 std::cout << "*** DQMStore: WARNING: quality report label in '" << label
01744 << "' is missing a '.' and cannot be extracted\n";
01745 return false;
01746 }
01747
01748 std::string mename (label, 0, dot);
01749 std::string qrname (label, dot+1, std::string::npos);
01750
01751 m.reset();
01752 DQMNet::QValue qv;
01753 if (s_rxmeqr1.match(value, 0, 0, &m))
01754 {
01755 qv.code = atoi(m.matchString(value, 1).c_str());
01756 qv.qtresult = strtod(m.matchString(value, 2).c_str(), 0);
01757 qv.message = m.matchString(value, 4);
01758 qv.qtname = qrname;
01759 qv.algorithm = m.matchString(value, 3);
01760 }
01761 else if (s_rxmeqr2.match(value, 0, 0, &m))
01762 {
01763 qv.code = atoi(m.matchString(value, 1).c_str());
01764 qv.qtresult = 0;
01765 qv.message = m.matchString(value, 2);
01766 qv.qtname = qrname;
01767
01768 }
01769 else
01770 {
01771 std::cout << "*** DQMStore: WARNING: quality test value '"
01772 << value << "' is incorrectly formatted\n";
01773 return false;
01774 }
01775
01776 MonitorElement *me = findObject(dir, mename);
01777 if (! me)
01778 {
01779 std::cout << "*** DQMStore: WARNING: no monitor element '"
01780 << mename << "' in directory '"
01781 << dir << "' for quality test '"
01782 << label << "'\n";
01783 return false;
01784 }
01785
01786 me->addQReport(qv, 0);
01787 }
01788 }
01789 else
01790 {
01791 std::cout << "*** DQMStore: WARNING: cannot extract object '"
01792 << obj->GetName() << "' of type '"
01793 << obj->IsA()->GetName() << "'\n";
01794 return false;
01795 }
01796 }
01797 else if (TNamed *n = dynamic_cast<TNamed *>(obj))
01798 {
01799
01800 std::string s;
01801 s.reserve(6 + strlen(n->GetTitle()) + 2*strlen(n->GetName()));
01802 s += '<'; s += n->GetName(); s += '>';
01803 s += n->GetTitle();
01804 s += '<'; s += '/'; s += n->GetName(); s += '>';
01805 TObjString os(s.c_str());
01806 return extract(&os, dir, overwrite);
01807 }
01808 else
01809 {
01810 std::cout << "*** DQMStore: WARNING: cannot extract object '"
01811 << obj->GetName() << "' of type '" << obj->IsA()->GetName()
01812 << "' and with title '" << obj->GetTitle() << "'\n";
01813 return false;
01814 }
01815
01816
01817
01818
01819 if (refcheck && isSubdirectory(s_referenceDirName, dir))
01820 {
01821 std::string mdir(dir, s_referenceDirName.size()+1, std::string::npos);
01822 if (MonitorElement *master = findObject(mdir, obj->GetName()))
01823 {
01824 master->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
01825 master->reference_ = refcheck->object_;
01826 }
01827 }
01828
01829 return true;
01830 }
01831
01835 bool
01836 DQMStore::cdInto(const std::string &path) const
01837 {
01838 assert(! path.empty());
01839
01840
01841 size_t start = 0;
01842 size_t end = path.find('/', start);
01843 if (end == std::string::npos)
01844 end = path.size();
01845
01846 while (true)
01847 {
01848
01849
01850 std::string part(path, start, end-start);
01851 TObject *o = gDirectory->Get(part.c_str());
01852 if (o && ! dynamic_cast<TDirectory *>(o))
01853 raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
01854 " fails because the part '%s' already exists and is not"
01855 " directory", path.c_str(), part.c_str());
01856 else if (! o)
01857 gDirectory->mkdir(part.c_str());
01858
01859 if (! gDirectory->cd(part.c_str()))
01860 raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
01861 " fails because could not cd into subdirectory '%s'",
01862 path.c_str(), part.c_str());
01863
01864
01865 if (end+1 >= path.size())
01866 break;
01867
01868
01869 start = end+1;
01870 end = path.find('/', start);
01871 if (end == std::string::npos)
01872 end = path.size();
01873 }
01874
01875 return true;
01876 }
01877
01882 void
01883 DQMStore::save(const std::string &filename,
01884 const std::string &path ,
01885 const std::string &pattern ,
01886 const std::string &rewrite ,
01887 SaveReferenceTag ref ,
01888 int minStatus ,
01889 const std::string &fileupdate )
01890 {
01891 std::set<std::string>::iterator di, de;
01892 MEMap::iterator mi, me = data_.end();
01893 DQMNet::QReports::const_iterator qi, qe;
01894 int nme=0;
01895
01896
01897
01898
01899
01900 class TFileNoSync : public TFile
01901 {
01902 public:
01903 TFileNoSync(const char *file, const char *opt) : TFile(file, opt) {}
01904 virtual Int_t SysSync(Int_t) { return 0; }
01905 };
01906
01907
01908 if (verbose_)
01909 std::cout << "\n DQMStore: Opening TFile '" << filename
01910 << "' with option '" << fileupdate <<"'\n";
01911
01912 TFileNoSync f(filename.c_str(), fileupdate.c_str());
01913 if(f.IsZombie())
01914 raiseDQMError("DQMStore", "Failed to create/update file '%s'", filename.c_str());
01915 f.cd();
01916
01917
01918 std::auto_ptr<lat::Regexp> rxpat;
01919 if (! pattern.empty())
01920 rxpat.reset(new lat::Regexp(pattern.c_str()));
01921
01922
01923 std::string refpath;
01924 refpath.reserve(s_referenceDirName.size() + path.size() + 2);
01925 refpath += s_referenceDirName;
01926 if (! path.empty())
01927 {
01928 refpath += '/';
01929 refpath += path;
01930 }
01931
01932
01933 for (di = dirs_.begin(), de = dirs_.end(); di != de; ++di)
01934 {
01935
01936
01937 if (! path.empty()
01938 && ! isSubdirectory(path, *di)
01939 && ! isSubdirectory(refpath, *di))
01940 continue;
01941
01942
01943 MonitorElement proto(&*di, std::string());
01944 mi = data_.lower_bound(proto);
01945 for ( ; mi != me && isSubdirectory(*di, *mi->data_.dirname); ++mi)
01946 {
01947
01948 if (*di != *mi->data_.dirname)
01949 continue;
01950
01951
01952
01953
01954
01955
01956
01957 if (isSubdirectory(refpath, *mi->data_.dirname))
01958 {
01959 if (ref == SaveWithoutReference)
01960
01961 continue;
01962 else if (ref == SaveWithReference)
01963
01964 ;
01965 else if (ref == SaveWithReferenceForQTest)
01966 {
01967
01968
01969 int status = -1;
01970 std::string mname(mi->getFullname(), s_referenceDirName.size()+1, std::string::npos);
01971 MonitorElement *master = get(mname);
01972 if (master)
01973 for (size_t i = 0, e = master->data_.qreports.size(); i != e; ++i)
01974 status = std::max(status, master->data_.qreports[i].code);
01975
01976 if (! master || status < minStatus)
01977 {
01978 if (verbose_ > 1)
01979 std::cout << "DQMStore::save: skipping monitor element '"
01980 << mi->data_.objname << "' while saving, status is "
01981 << status << ", required minimum status is "
01982 << minStatus << std::endl;
01983 continue;
01984 }
01985 }
01986 }
01987
01988 if (verbose_ > 1)
01989 std::cout << "DQMStore::save: saving monitor element '"
01990 << mi->data_.objname << "'\n";
01991 nme++;
01992
01993
01994 gDirectory->cd("/");
01995 if (di->empty())
01996 cdInto(s_monitorDirName);
01997 else if (rxpat.get())
01998 cdInto(s_monitorDirName + '/' + lat::StringOps::replace(*di, *rxpat, rewrite));
01999 else
02000 cdInto(s_monitorDirName + '/' + *di);
02001
02002
02003 switch (mi->kind())
02004 {
02005 case MonitorElement::DQM_KIND_INT:
02006 case MonitorElement::DQM_KIND_REAL:
02007 case MonitorElement::DQM_KIND_STRING:
02008 TObjString(mi->tagString().c_str()).Write();
02009 break;
02010
02011 default:
02012 mi->object_->Write();
02013 break;
02014 }
02015
02016
02017 if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
02018 {
02019 qi = mi->data_.qreports.begin();
02020 qe = mi->data_.qreports.end();
02021 for ( ; qi != qe; ++qi)
02022 TObjString(mi->qualityTagString(*qi).c_str()).Write();
02023 }
02024
02025
02026 if (mi->data_.flags & DQMNet::DQM_PROP_TAGGED)
02027 TObjString(mi->tagLabelString().c_str()).Write();
02028 }
02029 }
02030
02031 f.Close();
02032
02033
02034 if (verbose_)
02035 std::cout << "DQMStore::save: successfully wrote " << nme
02036 << " objects from path '" << path
02037 << "' into DQM file '" << filename << "'\n";
02038 }
02039
02042 unsigned int
02043 DQMStore::readDirectory(TFile *file,
02044 bool overwrite,
02045 const std::string &onlypath,
02046 const std::string &prepend,
02047 const std::string &curdir,
02048 OpenRunDirs stripdirs)
02049 {
02050 unsigned int ntot = 0;
02051 unsigned int count = 0;
02052
02053 if (! file->cd(curdir.c_str()))
02054 raiseDQMError("DQMStore", "Failed to process directory '%s' while"
02055 " reading file '%s'", curdir.c_str(), file->GetName());
02056
02057
02058
02059 std::string dirpart = curdir;
02060 if (dirpart.compare(0, s_monitorDirName.size(), s_monitorDirName) == 0)
02061 {
02062 if (dirpart.size() == s_monitorDirName.size())
02063 dirpart.clear();
02064 else if (dirpart[s_monitorDirName.size()] == '/')
02065 dirpart.erase(0, s_monitorDirName.size()+1);
02066 }
02067
02068
02069 bool skip = (! onlypath.empty() && ! isSubdirectory(onlypath, dirpart));
02070
02071 if (prepend == s_collateDirName ||
02072 prepend == s_referenceDirName ||
02073 stripdirs == StripRunDirs )
02074 {
02075
02076
02077
02078 size_t slash = dirpart.find('/');
02079 size_t pos = dirpart.find("/Run summary");
02080 if (slash != std::string::npos && pos !=std::string::npos)
02081 {
02082 dirpart.erase(pos,12);
02083
02084 pos = dirpart.find("Run ");
02085 size_t length = dirpart.find('/',pos+1)-pos+1;
02086 if (pos !=std::string::npos)
02087 dirpart.erase(pos,length);
02088 }
02089 }
02090
02091
02092
02093 if (prepend == s_collateDirName ||
02094 prepend == s_referenceDirName)
02095 {
02096 size_t slash = dirpart.find('/');
02097
02098 if (slash == std::string::npos
02099 && slash+1+s_referenceDirName.size() == dirpart.size()
02100 && dirpart.compare(slash+1, s_referenceDirName.size(), s_referenceDirName) == 0)
02101 return 0;
02102
02103 slash = dirpart.find('/');
02104
02105 if (slash != std::string::npos
02106 && slash + 10 == dirpart.size()
02107 && dirpart.compare( slash+1 , 9 , "EventInfo") == 0) {
02108 if (verbose_)
02109 std::cout << "DQMStore::readDirectory: skipping '" << dirpart << "'\n";
02110 return 0;
02111 }
02112
02113
02114 if (dirpart.empty())
02115 dirpart = prepend;
02116 else
02117 dirpart = prepend + '/' + dirpart;
02118 }
02119 else if (! prepend.empty())
02120 {
02121 if (dirpart.empty())
02122 dirpart = prepend;
02123 else
02124 dirpart = prepend + '/' + dirpart;
02125 }
02126
02127
02128
02129
02130
02131 TKey *key;
02132 TIter next (gDirectory->GetListOfKeys());
02133 std::list<TObject *> delayed;
02134 while ((key = (TKey *) next()))
02135 {
02136 std::auto_ptr<TObject> obj(key->ReadObj());
02137 if (dynamic_cast<TDirectory *>(obj.get()))
02138 {
02139 std::string subdir;
02140 subdir.reserve(curdir.size() + strlen(obj->GetName()) + 2);
02141 subdir += curdir;
02142 if (! curdir.empty())
02143 subdir += '/';
02144 subdir += obj->GetName();
02145
02146 ntot += readDirectory(file, overwrite, onlypath, prepend, subdir, stripdirs);
02147 }
02148 else if (skip)
02149 ;
02150 else if (dynamic_cast<TObjString *>(obj.get()))
02151 {
02152 delayed.push_back(obj.release());
02153 }
02154 else
02155 {
02156 if (verbose_ > 2)
02157 std::cout << "DQMStore: reading object '" << obj->GetName()
02158 << "' of type '" << obj->IsA()->GetName()
02159 << "' from '" << file->GetName()
02160 << "' into '" << dirpart << "'\n";
02161
02162 makeDirectory(dirpart);
02163 if (extract(obj.get(), dirpart, overwrite))
02164 ++count;
02165 }
02166 }
02167
02168 while (! delayed.empty())
02169 {
02170 if (verbose_ > 2)
02171 std::cout << "DQMStore: reading object '" << delayed.front()->GetName()
02172 << "' of type '" << delayed.front()->IsA()->GetName()
02173 << "' from '" << file->GetName()
02174 << "' into '" << dirpart << "'\n";
02175
02176 makeDirectory(dirpart);
02177 if (extract(delayed.front(), dirpart, overwrite))
02178 ++count;
02179
02180 delete delayed.front();
02181 delayed.pop_front();
02182 }
02183
02184 if (verbose_ > 1)
02185 std::cout << "DQMStore: read " << count << '/' << ntot
02186 << " objects from directory '" << dirpart << "'\n";
02187
02188 return ntot + count;
02189 }
02190
02197 bool
02198 DQMStore::open(const std::string &filename,
02199 bool overwrite ,
02200 const std::string &onlypath ,
02201 const std::string &prepend ,
02202 OpenRunDirs stripdirs ,
02203 bool fileMustExist )
02204 {
02205 return readFile(filename,overwrite,onlypath,prepend,stripdirs,fileMustExist);
02206 }
02207
02212 bool
02213 DQMStore::load(const std::string &filename,
02214 OpenRunDirs stripdirs ,
02215 bool fileMustExist )
02216 {
02217 bool overwrite = true;
02218 if (collateHistograms_) overwrite = false;
02219 if (verbose_)
02220 {
02221 std::cout << "DQMStore::load: reading from file '" << filename << "'\n";
02222 if (collateHistograms_)
02223 std::cout << "DQMStore::load: in collate mode " << "\n";
02224 else
02225 std::cout << "DQMStore::load: in overwrite mode " << "\n";
02226 }
02227
02228 return readFile(filename,overwrite,"","",stripdirs,fileMustExist);
02229
02230 }
02231
02237 bool
02238 DQMStore::readFile(const std::string &filename,
02239 bool overwrite ,
02240 const std::string &onlypath ,
02241 const std::string &prepend ,
02242 OpenRunDirs stripdirs ,
02243 bool fileMustExist )
02244 {
02245
02246 if (verbose_)
02247 std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
02248
02249 std::auto_ptr<TFile> f;
02250
02251 try
02252 {
02253 f.reset(TFile::Open(filename.c_str()));
02254 if (! f.get() || f->IsZombie())
02255 raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
02256 }
02257 catch (std::exception &)
02258 {
02259 if (fileMustExist)
02260 throw;
02261 else
02262 {
02263 if (verbose_)
02264 std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
02265 return false;
02266 }
02267 }
02268
02269 unsigned n = readDirectory(f.get(), overwrite, onlypath, prepend, "", stripdirs);
02270 f->Close();
02271
02272 MEMap::iterator mi = data_.begin();
02273 MEMap::iterator me = data_.end();
02274 for ( ; mi != me; ++mi)
02275 const_cast<MonitorElement &>(*mi).updateQReportStats();
02276
02277 if (verbose_)
02278 {
02279 std::cout << "DQMStore::open: successfully read " << n
02280 << " objects from file '" << filename << "'";
02281 if (! onlypath.empty())
02282 std::cout << " from directory '" << onlypath << "'";
02283 if (! prepend.empty())
02284 std::cout << " into directory '" << prepend << "'";
02285 std::cout << std::endl;
02286 }
02287 return true;
02288 }
02289
02295 void
02296 DQMStore::rmdir(const std::string &path)
02297 {
02298 std::string clean;
02299 const std::string *cleaned = 0;
02300 cleanTrailingSlashes(path, clean, cleaned);
02301 MonitorElement proto(cleaned, std::string());
02302
02303 MEMap::iterator e = data_.end();
02304 MEMap::iterator i = data_.lower_bound(proto);
02305 while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
02306 data_.erase(i++);
02307
02308 std::set<std::string>::iterator de = dirs_.end();
02309 std::set<std::string>::iterator di = dirs_.lower_bound(*cleaned);
02310 while (di != de && isSubdirectory(*cleaned, *di))
02311 dirs_.erase(di++);
02312 }
02313
02315 void
02316 DQMStore::removeContents(const std::string &dir)
02317 {
02318 MonitorElement proto(&dir, std::string());
02319 MEMap::iterator e = data_.end();
02320 MEMap::iterator i = data_.lower_bound(proto);
02321 while (i != e && isSubdirectory(dir, *i->data_.dirname))
02322 if (dir == *i->data_.dirname)
02323 data_.erase(i++);
02324 else
02325 ++i;
02326 }
02327
02329 void
02330 DQMStore::removeContents(void)
02331 {
02332 removeContents(pwd_);
02333 }
02334
02337 void
02338 DQMStore::removeElement(const std::string &name)
02339 {
02340 removeElement(pwd_, name);
02341 }
02342
02345 void
02346 DQMStore::removeElement(const std::string &dir, const std::string &name, bool warning )
02347 {
02348 MonitorElement proto(&dir, name);
02349 MEMap::iterator pos = data_.find(proto);
02350 if (pos == data_.end() && warning)
02351 std::cout << "DQMStore: WARNING: attempt to remove non-existent"
02352 << " monitor element '" << name << "' in '" << dir << "'\n";
02353 else
02354 data_.erase(pos);
02355 }
02356
02362 QCriterion *
02363 DQMStore::getQCriterion(const std::string &qtname) const
02364 {
02365 QCMap::const_iterator i = qtests_.find(qtname);
02366 QCMap::const_iterator e = qtests_.end();
02367 return (i == e ? 0 : i->second);
02368 }
02369
02373 QCriterion *
02374 DQMStore::createQTest(const std::string &algoname, const std::string &qtname)
02375 {
02376 if (qtests_.count(qtname))
02377 raiseDQMError("DQMStore", "Attempt to create duplicate quality test '%s'",
02378 qtname.c_str());
02379
02380 QAMap::iterator i = qalgos_.find(algoname);
02381 if (i == qalgos_.end())
02382 raiseDQMError("DQMStore", "Cannot create a quality test using unknown"
02383 " algorithm '%s'", algoname.c_str());
02384
02385 QCriterion *qc = i->second(qtname);
02386 qc->setVerbose(verboseQT_);
02387
02388 qtests_[qtname] = qc;
02389 return qc;
02390 }
02391
02394 void
02395 DQMStore::useQTest(const std::string &dir, const std::string &qtname)
02396 {
02397
02398 std::string clean;
02399 const std::string *cleaned = 0;
02400 cleanTrailingSlashes(dir, clean, cleaned);
02401
02402
02403 if (cleaned->find_first_not_of(s_safe) != std::string::npos)
02404 raiseDQMError("DQMStore", "Monitor element path name '%s'"
02405 " uses unacceptable characters", cleaned->c_str());
02406
02407
02408 useQTestByMatch(*cleaned + "/*", qtname);
02409 }
02410
02412 int
02413 DQMStore::useQTestByMatch(const std::string &pattern, const std::string &qtname)
02414 {
02415 QCriterion *qc = getQCriterion(qtname);
02416 if (! qc)
02417 raiseDQMError("DQMStore", "Cannot apply non-existent quality test '%s'",
02418 qtname.c_str());
02419
02420
02421 lat::Regexp *rx = 0;
02422 try
02423 {
02424 rx = new lat::Regexp(pattern, 0, lat::Regexp::Wildcard);
02425 rx->study();
02426 }
02427 catch (lat::Error &e)
02428 {
02429 delete rx;
02430 raiseDQMError("DQMStore", "Invalid wildcard pattern '%s' in quality"
02431 " test specification", pattern.c_str());
02432 }
02433
02434
02435 QTestSpec qts(rx, qc);
02436 qtestspecs_.push_back(qts);
02437
02438
02439 MEMap::iterator mi = data_.begin();
02440 MEMap::iterator me = data_.end();
02441 std::string path;
02442 int cases = 0;
02443 for ( ; mi != me; ++mi)
02444 {
02445 path.clear();
02446 mergePath(path, *mi->data_.dirname, mi->data_.objname);
02447 if (rx->match(path))
02448 {
02449 ++cases;
02450 const_cast<MonitorElement &>(*mi).addQReport(qts.second);
02451 }
02452 }
02453
02454
02455 return cases;
02456 }
02459 void
02460 DQMStore::runQTests(void)
02461 {
02462
02463 if (verbose_ > 0)
02464 std::cout << "DQMStore: running runQTests() with reset = "
02465 << ( reset_ ? "true" : "false" ) << std::endl;
02466
02467
02468 MEMap::iterator mi = data_.begin();
02469 MEMap::iterator me = data_.end();
02470 for ( ; mi != me; ++mi)
02471 if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
02472 const_cast<MonitorElement &>(*mi).runQTests();
02473
02474 reset_ = false;
02475 }
02476
02480 int
02481 DQMStore::getStatus(const std::string &path ) const
02482 {
02483 std::string clean;
02484 const std::string *cleaned = 0;
02485 cleanTrailingSlashes(path, clean, cleaned);
02486
02487 int status = dqm::qstatus::STATUS_OK;
02488 MEMap::const_iterator mi = data_.begin();
02489 MEMap::const_iterator me = data_.end();
02490 for ( ; mi != me; ++mi)
02491 {
02492 if (! cleaned->empty() && ! isSubdirectory(*cleaned, *mi->data_.dirname))
02493 continue;
02494
02495 if (mi->hasError())
02496 return dqm::qstatus::ERROR;
02497 else if (mi->hasWarning())
02498 status = dqm::qstatus::WARNING;
02499 else if (status < dqm::qstatus::WARNING
02500 && mi->hasOtherReport())
02501 status = dqm::qstatus::OTHER;
02502 }
02503 return status;
02504 }
02505
02511 void
02512 DQMStore::softReset(MonitorElement *me)
02513 {
02514 if (me)
02515 me->softReset();
02516 }
02517
02518
02519 void
02520 DQMStore::disableSoftReset(MonitorElement *me)
02521 {
02522 if (me)
02523 me->disableSoftReset();
02524 }
02525
02528 void
02529 DQMStore::setAccumulate(MonitorElement *me, bool flag)
02530 {
02531 if (me)
02532 me->setAccumulate(flag);
02533 }
02534
02538 void
02539 DQMStore::showDirStructure(void) const
02540 {
02541 std::vector<std::string> contents;
02542 getContents(contents);
02543
02544 std::cout << " ------------------------------------------------------------\n"
02545 << " Directory structure: \n"
02546 << " ------------------------------------------------------------\n";
02547
02548 std::copy(contents.begin(), contents.end(),
02549 std::ostream_iterator<std::string>(std::cout, "\n"));
02550
02551 std::cout << " ------------------------------------------------------------\n";
02552 }
02553
02557
02558 bool
02559 DQMStore::isCollateME(MonitorElement *me) const
02560 { return me && isSubdirectory(s_collateDirName, *me->data_.dirname); }