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