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