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