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 std::cout << __LINE__ << " DQMStore::DQMStore " << std::endl;
00272 }
00273
00274 DQMStore::DQMStore(const edm::ParameterSet &pset)
00275 : verbose_ (1),
00276 verboseQT_ (1),
00277 reset_ (false),
00278 collateHistograms_ (false),
00279 readSelectedDirectory_ (""),
00280 pwd_ ("")
00281 {
00282 initializeFrom(pset);
00283 }
00284
00285 DQMStore::~DQMStore(void)
00286 {
00287 for (QCMap::iterator i = qtests_.begin(), e = qtests_.end(); i != e; ++i)
00288 delete i->second;
00289
00290 for (QTestSpecs::iterator i = qtestspecs_.begin(), e = qtestspecs_.end(); i != e; ++i)
00291 delete i->first;
00292
00293 }
00294
00295 void
00296 DQMStore::initializeFrom(const edm::ParameterSet& pset) {
00297 makeDirectory("");
00298 reset();
00299
00300
00301 verbose_ = pset.getUntrackedParameter<int>("verbose", 0);
00302 if (verbose_ > 0)
00303 std::cout << "DQMStore: verbosity set to " << verbose_ << std::endl;
00304
00305 verboseQT_ = pset.getUntrackedParameter<int>("verboseQT", 0);
00306 if (verbose_ > 0)
00307 std::cout << "DQMStore: QTest verbosity set to " << verboseQT_ << std::endl;
00308
00309 collateHistograms_ = pset.getUntrackedParameter<bool>("collateHistograms", false);
00310 if (collateHistograms_)
00311 std::cout << "DQMStore: histogram collation is enabled\n";
00312
00313 std::string ref = pset.getUntrackedParameter<std::string>("referenceFileName", "");
00314 if (! ref.empty())
00315 {
00316 std::cout << "DQMStore: using reference file '" << ref << "'\n";
00317 readFile(ref, true, "", s_referenceDirName, StripRunDirs, false);
00318 }
00319
00320 initQCriterion<Comp2RefChi2>(qalgos_);
00321 initQCriterion<Comp2RefKolmogorov>(qalgos_);
00322 initQCriterion<ContentsXRange>(qalgos_);
00323 initQCriterion<ContentsYRange>(qalgos_);
00324 initQCriterion<MeanWithinExpected>(qalgos_);
00325 initQCriterion<Comp2RefEqualH>(qalgos_);
00326 initQCriterion<DeadChannel>(qalgos_);
00327 initQCriterion<NoisyChannel>(qalgos_);
00328 initQCriterion<ContentsWithinExpected>(qalgos_);
00329 initQCriterion<CompareToMedian>(qalgos_);
00330 initQCriterion<CompareLastFilledBin>(qalgos_);
00331
00332 scaleFlag_ = pset.getUntrackedParameter<double>("ScalingFlag", 0.0);
00333 if (verbose_ > 0)
00334 std::cout << "DQMStore: Scaling Flag set to " << scaleFlag_ << std::endl;
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 void
00347 DQMStore::print_trace (const std::string &dir, const std::string &name)
00348 {
00349 static std::ofstream stream("histogramBookingBT.log");
00350 void *array[10];
00351 size_t size;
00352 char **strings;
00353 int r=0;
00354 lat::RegexpMatch m;
00355 m.reset();
00356
00357 size = backtrace (array, 10);
00358 strings = backtrace_symbols (array, size);
00359
00360 if ((size > 4)
00361 &&s_rxtrace.match(strings[4], 0, 0, &m))
00362 {
00363 char * demangled = abi::__cxa_demangle(m.matchString(strings[4], 2).c_str(), 0, 0, &r);
00364 stream << "\"" << dir << "/"
00365 << name << "\" "
00366 << (r ? m.matchString(strings[4], 2) : demangled) << " "
00367 << m.matchString(strings[4], 1) << "\n";
00368 free(demangled);
00369 }
00370 else
00371 stream << "Skipping "<< dir << "/" << name
00372 << " with stack size " << size << "\n";
00373
00374
00375 if (verbose_ > 4)
00376 {
00377 size_t i;
00378 m.reset();
00379
00380 for (i = 0; i < size; i++)
00381 if (s_rxtrace.match(strings[i], 0, 0, &m))
00382 {
00383 char * demangled = abi::__cxa_demangle(m.matchString(strings[i], 2).c_str(), 0, 0, &r);
00384 stream << "\t\t" << i << "/" << size << " "
00385 << (r ? m.matchString(strings[i], 2) : demangled) << " "
00386 << m.matchString(strings[i], 1) << std::endl;
00387 free (demangled);
00388 }
00389 }
00390 free (strings);
00391 }
00392
00397 void
00398 DQMStore::setVerbose(unsigned )
00399 { return; }
00400
00405 const std::string &
00406 DQMStore::pwd(void) const
00407 { return pwd_; }
00408
00410 void
00411 DQMStore::cd(void)
00412 { setCurrentFolder(""); }
00413
00415 void
00416 DQMStore::cd(const std::string &subdir)
00417 {
00418 std::string clean;
00419 const std::string *cleaned = 0;
00420 cleanTrailingSlashes(subdir, clean, cleaned);
00421
00422 if (! dirExists(*cleaned))
00423 raiseDQMError("DQMStore", "Cannot 'cd' into non-existent directory '%s'",
00424 cleaned->c_str());
00425
00426 setCurrentFolder(*cleaned);
00427 }
00428
00433 void
00434 DQMStore::setCurrentFolder(const std::string &fullpath)
00435 {
00436 std::string clean;
00437 const std::string *cleaned = 0;
00438 cleanTrailingSlashes(fullpath, clean, cleaned);
00439 makeDirectory(*cleaned);
00440 pwd_ = *cleaned;
00441 }
00442
00444 void
00445 DQMStore::goUp(void)
00446 {
00447 size_t pos = pwd_.rfind('/');
00448 if (pos == std::string::npos)
00449 setCurrentFolder("");
00450 else
00451 setCurrentFolder(pwd_.substr(0, pos));
00452 }
00453
00454
00456 void
00457 DQMStore::makeDirectory(const std::string &path)
00458 {
00459 std::string prev;
00460 std::string subdir;
00461 std::string name;
00462 prev.reserve(path.size());
00463 subdir.reserve(path.size());
00464 name.reserve(path.size());
00465 size_t prevname = 0;
00466 size_t slash = 0;
00467
00468 while (true)
00469 {
00470
00471 subdir.clear();
00472 subdir.append(path, 0, slash);
00473 name.clear();
00474 name.append(subdir, prevname, std::string::npos);
00475 if (! prev.empty() && findObject(prev, name))
00476 raiseDQMError("DQMStore", "Attempt to create subdirectory '%s'"
00477 " which already exists as a monitor element",
00478 subdir.c_str());
00479
00480 if (! dirs_.count(subdir))
00481 dirs_.insert(subdir);
00482
00483
00484 if (slash+1 >= path.size())
00485 break;
00486
00487
00488
00489 prevname = slash ? slash+1 : slash;
00490 prev = subdir;
00491 if ((slash = path.find('/', ++slash)) == std::string::npos)
00492 slash = path.size();
00493 }
00494 }
00495
00497 bool
00498 DQMStore::dirExists(const std::string &path) const
00499 { return dirs_.count(path) > 0; }
00500
00504 template <class HISTO, class COLLATE>
00505 MonitorElement *
00506 DQMStore::book(const std::string &dir, const std::string &name,
00507 const char *context, int kind,
00508 HISTO *h, COLLATE collate)
00509 {
00510 assert(name.find('/') == std::string::npos);
00511 if (verbose_ > 3)
00512 print_trace(dir, name);
00513 std::string path;
00514 mergePath(path, dir, name);
00515
00516
00517 h->SetDirectory(0);
00518
00519
00520 MonitorElement *me = findObject(dir, name);
00521 if (me)
00522 {
00523 if (collateHistograms_)
00524 {
00525 collate(me, h);
00526 delete h;
00527 return me;
00528 }
00529 else
00530 {
00531 if (verbose_ > 1)
00532 std::cout << "DQMStore: "
00533 << context << ": monitor element '"
00534 << path << "' already exists, collating" << std::endl;
00535 me->Reset();
00536 collate(me, h);
00537 delete h;
00538 return me;
00539 }
00540 }
00541 else
00542 {
00543
00544 assert(dirs_.count(dir));
00545 MonitorElement proto(&*dirs_.find(dir), name);
00546 me = const_cast<MonitorElement &>(*data_.insert(proto).first)
00547 .initialise((MonitorElement::Kind)kind, h);
00548
00549
00550 QTestSpecs::iterator qi = qtestspecs_.begin();
00551 QTestSpecs::iterator qe = qtestspecs_.end();
00552 for ( ; qi != qe; ++qi)
00553 {
00554 if ( qi->first->match(path) )
00555 me->addQReport(qi->second);
00556 }
00557
00558
00559 std::string refdir;
00560 refdir.reserve(s_referenceDirName.size() + dir.size() + 2);
00561 refdir += s_referenceDirName;
00562 refdir += '/';
00563 refdir += dir;
00564
00565 if (MonitorElement *refme = findObject(refdir, name))
00566 {
00567 me->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
00568 me->reference_ = refme->object_;
00569 }
00570
00571
00572 return me;
00573 }
00574 }
00575
00576 MonitorElement *
00577 DQMStore::book(const std::string &dir,
00578 const std::string &name,
00579 const char *context)
00580 {
00581 assert(name.find('/') == std::string::npos);
00582 if (verbose_ > 3)
00583 print_trace(dir, name);
00584
00585
00586 if (MonitorElement *me = findObject(dir, name))
00587 {
00588 if (verbose_ > 1)
00589 {
00590 std::string path;
00591 mergePath(path, dir, name);
00592
00593 std::cout << "DQMStore: "
00594 << context << ": monitor element '"
00595 << path << "' already exists, resetting" << std::endl;
00596 }
00597 me->Reset();
00598 return me;
00599 }
00600 else
00601 {
00602
00603 assert(dirs_.count(dir));
00604 MonitorElement nme(&*dirs_.find(dir), name);
00605 return &const_cast<MonitorElement &>(*data_.insert(nme).first);
00606 }
00607 }
00608
00609
00611 MonitorElement *
00612 DQMStore::bookInt(const std::string &dir, const std::string &name)
00613 {
00614 if (collateHistograms_)
00615 {
00616 if (MonitorElement *me = findObject(dir, name))
00617 {
00618 me->Fill(0);
00619 return me;
00620 }
00621 }
00622
00623 return book(dir, name, "bookInt")
00624 ->initialise(MonitorElement::DQM_KIND_INT);
00625 }
00626
00628 MonitorElement *
00629 DQMStore::bookInt(const char *name)
00630 { return bookInt(pwd_, name); }
00631
00633 MonitorElement *
00634 DQMStore::bookInt(const std::string &name)
00635 {
00636 return bookInt(pwd_, name);
00637 }
00638
00639
00641 MonitorElement *
00642 DQMStore::bookFloat(const std::string &dir, const std::string &name)
00643 {
00644 if (collateHistograms_)
00645 {
00646 if (MonitorElement *me = findObject(dir, name))
00647 {
00648 me->Fill(0.);
00649 return me;
00650 }
00651 }
00652
00653 return book(dir, name, "bookFloat")
00654 ->initialise(MonitorElement::DQM_KIND_REAL);
00655 }
00656
00658 MonitorElement *
00659 DQMStore::bookFloat(const char *name)
00660 { return bookFloat(pwd_, name); }
00661
00663 MonitorElement *
00664 DQMStore::bookFloat(const std::string &name)
00665 {
00666 return bookFloat(pwd_, name);
00667 }
00668
00669
00671 MonitorElement *
00672 DQMStore::bookString(const std::string &dir,
00673 const std::string &name,
00674 const std::string &value)
00675 {
00676 if (collateHistograms_)
00677 {
00678 if (MonitorElement *me = findObject(dir, name))
00679 return me;
00680 }
00681
00682 return book(dir, name, "bookString")
00683 ->initialise(MonitorElement::DQM_KIND_STRING, value);
00684 }
00685
00687 MonitorElement *
00688 DQMStore::bookString(const char *name, const char *value)
00689 { return bookString(pwd_, name, value); }
00690
00692 MonitorElement *
00693 DQMStore::bookString(const std::string &name, const std::string &value)
00694 {
00695 return bookString(pwd_, name, value);
00696 }
00697
00698
00700 MonitorElement *
00701 DQMStore::book1D(const std::string &dir, const std::string &name, TH1F *h)
00702 {
00703 return book(dir, name, "book1D", MonitorElement::DQM_KIND_TH1F, h, collate1D);
00704 }
00705
00707 MonitorElement *
00708 DQMStore::book1S(const std::string &dir, const std::string &name, TH1S *h)
00709 {
00710 return book(dir, name, "book1S", MonitorElement::DQM_KIND_TH1S, h, collate1S);
00711 }
00712
00714 MonitorElement *
00715 DQMStore::book1DD(const std::string &dir, const std::string &name, TH1D *h)
00716 {
00717 return book(dir, name, "book1DD", MonitorElement::DQM_KIND_TH1D, h, collate1DD);
00718 }
00719
00721 MonitorElement *
00722 DQMStore::book1D(const char *name, const char *title,
00723 int nchX, double lowX, double highX)
00724 {
00725 return book1D(pwd_, name, new TH1F(name, title, nchX, lowX, highX));
00726 }
00727
00729 MonitorElement *
00730 DQMStore::book1D(const std::string &name, const std::string &title,
00731 int nchX, double lowX, double highX)
00732 {
00733 return book1D(pwd_, name, new TH1F(name.c_str(), title.c_str(), nchX, lowX, highX));
00734 }
00735
00737 MonitorElement *
00738 DQMStore::book1S(const char *name, const char *title,
00739 int nchX, double lowX, double highX)
00740 {
00741 return book1S(pwd_, name, new TH1S(name, title, nchX, lowX, highX));
00742 }
00743
00745 MonitorElement *
00746 DQMStore::book1S(const std::string &name, const std::string &title,
00747 int nchX, double lowX, double highX)
00748 {
00749 return book1S(pwd_, name, new TH1S(name.c_str(), title.c_str(), nchX, lowX, highX));
00750 }
00751
00753 MonitorElement *
00754 DQMStore::book1DD(const char *name, const char *title,
00755 int nchX, double lowX, double highX)
00756 {
00757 return book1DD(pwd_, name, new TH1D(name, title, nchX, lowX, highX));
00758 }
00759
00761 MonitorElement *
00762 DQMStore::book1DD(const std::string &name, const std::string &title,
00763 int nchX, double lowX, double highX)
00764 {
00765 return book1DD(pwd_, name, new TH1D(name.c_str(), title.c_str(), nchX, lowX, highX));
00766 }
00767
00769 MonitorElement *
00770 DQMStore::book1D(const char *name, const char *title,
00771 int nchX, float *xbinsize)
00772 {
00773 return book1D(pwd_, name, new TH1F(name, title, nchX, xbinsize));
00774 }
00775
00777 MonitorElement *
00778 DQMStore::book1D(const std::string &name, const std::string &title,
00779 int nchX, float *xbinsize)
00780 {
00781 return book1D(pwd_, name, new TH1F(name.c_str(), title.c_str(), nchX, xbinsize));
00782 }
00783
00785 MonitorElement *
00786 DQMStore::book1D(const char *name, TH1F *source)
00787 {
00788 return book1D(pwd_, name, static_cast<TH1F *>(source->Clone(name)));
00789 }
00790
00792 MonitorElement *
00793 DQMStore::book1D(const std::string &name, TH1F *source)
00794 {
00795 return book1D(pwd_, name, static_cast<TH1F *>(source->Clone(name.c_str())));
00796 }
00797
00799 MonitorElement *
00800 DQMStore::book1S(const char *name, TH1S *source)
00801 {
00802 return book1S(pwd_, name, static_cast<TH1S *>(source->Clone(name)));
00803 }
00804
00806 MonitorElement *
00807 DQMStore::book1S(const std::string &name, TH1S *source)
00808 {
00809 return book1S(pwd_, name, static_cast<TH1S *>(source->Clone(name.c_str())));
00810 }
00811
00813 MonitorElement *
00814 DQMStore::book1DD(const char *name, TH1D *source)
00815 {
00816 return book1DD(pwd_, name, static_cast<TH1D *>(source->Clone(name)));
00817 }
00818
00820 MonitorElement *
00821 DQMStore::book1DD(const std::string &name, TH1D *source)
00822 {
00823 return book1DD(pwd_, name, static_cast<TH1D *>(source->Clone(name.c_str())));
00824 }
00825
00826
00828 MonitorElement *
00829 DQMStore::book2D(const std::string &dir, const std::string &name, TH2F *h)
00830 {
00831 return book(dir, name, "book2D", MonitorElement::DQM_KIND_TH2F, h, collate2D);
00832 }
00833
00835 MonitorElement *
00836 DQMStore::book2S(const std::string &dir, const std::string &name, TH2S *h)
00837 {
00838 return book(dir, name, "book2S", MonitorElement::DQM_KIND_TH2S, h, collate2S);
00839 }
00840
00842 MonitorElement *
00843 DQMStore::book2DD(const std::string &dir, const std::string &name, TH2D *h)
00844 {
00845 return book(dir, name, "book2DD", MonitorElement::DQM_KIND_TH2D, h, collate2DD);
00846 }
00847
00849 MonitorElement *
00850 DQMStore::book2D(const char *name, const char *title,
00851 int nchX, double lowX, double highX,
00852 int nchY, double lowY, double highY)
00853 {
00854 return book2D(pwd_, name, new TH2F(name, title,
00855 nchX, lowX, highX,
00856 nchY, lowY, highY));
00857 }
00858
00860 MonitorElement *
00861 DQMStore::book2D(const std::string &name, const std::string &title,
00862 int nchX, double lowX, double highX,
00863 int nchY, double lowY, double highY)
00864 {
00865 return book2D(pwd_, name, new TH2F(name.c_str(), title.c_str(),
00866 nchX, lowX, highX,
00867 nchY, lowY, highY));
00868 }
00869
00871 MonitorElement *
00872 DQMStore::book2S(const char *name, const char *title,
00873 int nchX, double lowX, double highX,
00874 int nchY, double lowY, double highY)
00875 {
00876 return book2S(pwd_, name, new TH2S(name, title,
00877 nchX, lowX, highX,
00878 nchY, lowY, highY));
00879 }
00880
00882 MonitorElement *
00883 DQMStore::book2S(const std::string &name, const std::string &title,
00884 int nchX, double lowX, double highX,
00885 int nchY, double lowY, double highY)
00886 {
00887 return book2S(pwd_, name, new TH2S(name.c_str(), title.c_str(),
00888 nchX, lowX, highX,
00889 nchY, lowY, highY));
00890 }
00891
00893 MonitorElement *
00894 DQMStore::book2DD(const char *name, const char *title,
00895 int nchX, double lowX, double highX,
00896 int nchY, double lowY, double highY)
00897 {
00898 return book2DD(pwd_, name, new TH2D(name, title,
00899 nchX, lowX, highX,
00900 nchY, lowY, highY));
00901 }
00902
00904 MonitorElement *
00905 DQMStore::book2DD(const std::string &name, const std::string &title,
00906 int nchX, double lowX, double highX,
00907 int nchY, double lowY, double highY)
00908 {
00909 return book2DD(pwd_, name, new TH2D(name.c_str(), title.c_str(),
00910 nchX, lowX, highX,
00911 nchY, lowY, highY));
00912 }
00913
00915 MonitorElement *
00916 DQMStore::book2D(const char *name, const char *title,
00917 int nchX, float *xbinsize, int nchY, float *ybinsize)
00918 {
00919 return book2D(pwd_, name, new TH2F(name, title,
00920 nchX, xbinsize, nchY, ybinsize));
00921 }
00922
00924 MonitorElement *
00925 DQMStore::book2D(const std::string &name, const std::string &title,
00926 int nchX, float *xbinsize, int nchY, float *ybinsize)
00927 {
00928 return book2D(pwd_, name, new TH2F(name.c_str(), title.c_str(),
00929 nchX, xbinsize, nchY, ybinsize));
00930 }
00931
00933 MonitorElement *
00934 DQMStore::book2D(const char *name, TH2F *source)
00935 {
00936 return book2D(pwd_, name, static_cast<TH2F *>(source->Clone(name)));
00937 }
00938
00940 MonitorElement *
00941 DQMStore::book2D(const std::string &name, TH2F *source)
00942 {
00943 return book2D(pwd_, name, static_cast<TH2F *>(source->Clone(name.c_str())));
00944 }
00945
00947 MonitorElement *
00948 DQMStore::book2S(const char *name, TH2S *source)
00949 {
00950 return book2S(pwd_, name, static_cast<TH2S *>(source->Clone(name)));
00951 }
00952
00954 MonitorElement *
00955 DQMStore::book2S(const std::string &name, TH2S *source)
00956 {
00957 return book2S(pwd_, name, static_cast<TH2S *>(source->Clone(name.c_str())));
00958 }
00959
00961 MonitorElement *
00962 DQMStore::book2DD(const char *name, TH2D *source)
00963 {
00964 return book2DD(pwd_, name, static_cast<TH2D *>(source->Clone(name)));
00965 }
00966
00968 MonitorElement *
00969 DQMStore::book2DD(const std::string &name, TH2D *source)
00970 {
00971 return book2DD(pwd_, name, static_cast<TH2D *>(source->Clone(name.c_str())));
00972 }
00973
00974
00976 MonitorElement *
00977 DQMStore::book3D(const std::string &dir, const std::string &name, TH3F *h)
00978 {
00979 return book(dir, name, "book3D", MonitorElement::DQM_KIND_TH3F, h, collate3D);
00980 }
00981
00983 MonitorElement *
00984 DQMStore::book3D(const char *name, const char *title,
00985 int nchX, double lowX, double highX,
00986 int nchY, double lowY, double highY,
00987 int nchZ, double lowZ, double highZ)
00988 {
00989 return book3D(pwd_, name, new TH3F(name, title,
00990 nchX, lowX, highX,
00991 nchY, lowY, highY,
00992 nchZ, lowZ, highZ));
00993 }
00994
00996 MonitorElement *
00997 DQMStore::book3D(const std::string &name, const std::string &title,
00998 int nchX, double lowX, double highX,
00999 int nchY, double lowY, double highY,
01000 int nchZ, double lowZ, double highZ)
01001 {
01002 return book3D(pwd_, name, new TH3F(name.c_str(), title.c_str(),
01003 nchX, lowX, highX,
01004 nchY, lowY, highY,
01005 nchZ, lowZ, highZ));
01006 }
01007
01009 MonitorElement *
01010 DQMStore::book3D(const char *name, TH3F *source)
01011 {
01012 return book3D(pwd_, name, static_cast<TH3F *>(source->Clone(name)));
01013 }
01014
01016 MonitorElement *
01017 DQMStore::book3D(const std::string &name, TH3F *source)
01018 {
01019 return book3D(pwd_, name, static_cast<TH3F *>(source->Clone(name.c_str())));
01020 }
01021
01022
01024 MonitorElement *
01025 DQMStore::bookProfile(const std::string &dir, const std::string &name, TProfile *h)
01026 {
01027 return book(dir, name, "bookProfile",
01028 MonitorElement::DQM_KIND_TPROFILE,
01029 h, collateProfile);
01030 }
01031
01035 MonitorElement *
01036 DQMStore::bookProfile(const char *name, const char *title,
01037 int nchX, double lowX, double highX,
01038 int , double lowY, double highY,
01039 const char *option )
01040 {
01041 return bookProfile(pwd_, name, new TProfile(name, title,
01042 nchX, lowX, highX,
01043 lowY, highY,
01044 option));
01045 }
01046
01050 MonitorElement *
01051 DQMStore::bookProfile(const std::string &name, const std::string &title,
01052 int nchX, double lowX, double highX,
01053 int , double lowY, double highY,
01054 const char *option )
01055 {
01056 return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
01057 nchX, lowX, highX,
01058 lowY, highY,
01059 option));
01060 }
01061
01065 MonitorElement *
01066 DQMStore::bookProfile(const char *name, const char *title,
01067 int nchX, double lowX, double highX,
01068 double lowY, double highY,
01069 const char *option )
01070 {
01071 return bookProfile(pwd_, name, new TProfile(name, title,
01072 nchX, lowX, highX,
01073 lowY, highY,
01074 option));
01075 }
01076
01080 MonitorElement *
01081 DQMStore::bookProfile(const std::string &name, const std::string &title,
01082 int nchX, double lowX, double highX,
01083 double lowY, double highY,
01084 const char *option )
01085 {
01086 return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
01087 nchX, lowX, highX,
01088 lowY, highY,
01089 option));
01090 }
01091
01095 MonitorElement *
01096 DQMStore::bookProfile(const char *name, const char *title,
01097 int nchX, double *xbinsize,
01098 int , double lowY, double highY,
01099 const char *option )
01100 {
01101 return bookProfile(pwd_, name, new TProfile(name, title,
01102 nchX, xbinsize,
01103 lowY, highY,
01104 option));
01105 }
01106
01110 MonitorElement *
01111 DQMStore::bookProfile(const std::string &name, const std::string &title,
01112 int nchX, double *xbinsize,
01113 int , double lowY, double highY,
01114 const char *option )
01115 {
01116 return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
01117 nchX, xbinsize,
01118 lowY, highY,
01119 option));
01120 }
01121
01125 MonitorElement *
01126 DQMStore::bookProfile(const char *name, const char *title,
01127 int nchX, double *xbinsize,
01128 double lowY, double highY,
01129 const char *option )
01130 {
01131 return bookProfile(pwd_, name, new TProfile(name, title,
01132 nchX, xbinsize,
01133 lowY, highY,
01134 option));
01135 }
01136
01140 MonitorElement *
01141 DQMStore::bookProfile(const std::string &name, const std::string &title,
01142 int nchX, double *xbinsize,
01143 double lowY, double highY,
01144 const char *option )
01145 {
01146 return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
01147 nchX, xbinsize,
01148 lowY, highY,
01149 option));
01150 }
01151
01153 MonitorElement *
01154 DQMStore::bookProfile(const char *name, TProfile *source)
01155 {
01156 return bookProfile(pwd_, name, static_cast<TProfile *>(source->Clone(name)));
01157 }
01158
01160 MonitorElement *
01161 DQMStore::bookProfile(const std::string &name, TProfile *source)
01162 {
01163 return bookProfile(pwd_, name, static_cast<TProfile *>(source->Clone(name.c_str())));
01164 }
01165
01166
01168 MonitorElement *
01169 DQMStore::bookProfile2D(const std::string &dir, const std::string &name, TProfile2D *h)
01170 {
01171 return book(dir, name, "bookProfile2D",
01172 MonitorElement::DQM_KIND_TPROFILE2D,
01173 h, collateProfile2D);
01174 }
01175
01179 MonitorElement *
01180 DQMStore::bookProfile2D(const char *name, const char *title,
01181 int nchX, double lowX, double highX,
01182 int nchY, double lowY, double highY,
01183 int , double lowZ, double highZ,
01184 const char *option )
01185 {
01186 return bookProfile2D(pwd_, name, new TProfile2D(name, title,
01187 nchX, lowX, highX,
01188 nchY, lowY, highY,
01189 lowZ, highZ,
01190 option));
01191 }
01192
01196 MonitorElement *
01197 DQMStore::bookProfile2D(const std::string &name, const std::string &title,
01198 int nchX, double lowX, double highX,
01199 int nchY, double lowY, double highY,
01200 int , double lowZ, double highZ,
01201 const char *option )
01202 {
01203 return bookProfile2D(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
01204 nchX, lowX, highX,
01205 nchY, lowY, highY,
01206 lowZ, highZ,
01207 option));
01208 }
01209
01213 MonitorElement *
01214 DQMStore::bookProfile2D(const char *name, const char *title,
01215 int nchX, double lowX, double highX,
01216 int nchY, double lowY, double highY,
01217 double lowZ, double highZ,
01218 const char *option )
01219 {
01220 return bookProfile2D(pwd_, name, new TProfile2D(name, title,
01221 nchX, lowX, highX,
01222 nchY, lowY, highY,
01223 lowZ, highZ,
01224 option));
01225 }
01226
01230 MonitorElement *
01231 DQMStore::bookProfile2D(const std::string &name, const std::string &title,
01232 int nchX, double lowX, double highX,
01233 int nchY, double lowY, double highY,
01234 double lowZ, double highZ,
01235 const char *option )
01236 {
01237 return bookProfile2D(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
01238 nchX, lowX, highX,
01239 nchY, lowY, highY,
01240 lowZ, highZ,
01241 option));
01242 }
01243
01245 MonitorElement *
01246 DQMStore::bookProfile2D(const char *name, TProfile2D *source)
01247 {
01248 return bookProfile2D(pwd_, name, static_cast<TProfile2D *>(source->Clone(name)));
01249 }
01250
01252 MonitorElement *
01253 DQMStore::bookProfile2D(const std::string &name, TProfile2D *source)
01254 {
01255 return bookProfile2D(pwd_, name, static_cast<TProfile2D *>(source->Clone(name.c_str())));
01256 }
01257
01261 bool
01262 DQMStore::checkBinningMatches(MonitorElement *me, TH1 *h)
01263 {
01264 if (me->getTH1()->GetNbinsX() != h->GetNbinsX()
01265 || me->getTH1()->GetNbinsY() != h->GetNbinsY()
01266 || me->getTH1()->GetNbinsZ() != h->GetNbinsZ()
01267 || me->getTH1()->GetXaxis()->GetXmin() != h->GetXaxis()->GetXmin()
01268 || me->getTH1()->GetYaxis()->GetXmin() != h->GetYaxis()->GetXmin()
01269 || me->getTH1()->GetZaxis()->GetXmin() != h->GetZaxis()->GetXmin()
01270 || me->getTH1()->GetXaxis()->GetXmax() != h->GetXaxis()->GetXmax()
01271 || me->getTH1()->GetYaxis()->GetXmax() != h->GetYaxis()->GetXmax()
01272 || me->getTH1()->GetZaxis()->GetXmax() != h->GetZaxis()->GetXmax())
01273 {
01274
01275 std::cout << "*** DQMStore: WARNING:"
01276 << "checkBinningMatches: different binning - cannot add object '"
01277 << h->GetName() << "' of type "
01278 << h->IsA()->GetName() << " to existing ME: '"
01279 << me->getFullname() << "'\n";
01280 return false;
01281 }
01282 return true;
01283 }
01284
01285 void
01286 DQMStore::collate1D(MonitorElement *me, TH1F *h)
01287 {
01288 if (checkBinningMatches(me,h))
01289 me->getTH1F()->Add(h);
01290 }
01291
01292 void
01293 DQMStore::collate1S(MonitorElement *me, TH1S *h)
01294 {
01295 if (checkBinningMatches(me,h))
01296 me->getTH1S()->Add(h);
01297 }
01298
01299 void
01300 DQMStore::collate1DD(MonitorElement *me, TH1D *h)
01301 {
01302 if (checkBinningMatches(me,h))
01303 me->getTH1D()->Add(h);
01304 }
01305
01306 void
01307 DQMStore::collate2D(MonitorElement *me, TH2F *h)
01308 {
01309 if (checkBinningMatches(me,h))
01310 me->getTH2F()->Add(h);
01311 }
01312
01313 void
01314 DQMStore::collate2S(MonitorElement *me, TH2S *h)
01315 {
01316 if (checkBinningMatches(me,h))
01317 me->getTH2S()->Add(h);
01318 }
01319
01320 void
01321 DQMStore::collate2DD(MonitorElement *me, TH2D *h)
01322 {
01323 if (checkBinningMatches(me,h))
01324 me->getTH2D()->Add(h);
01325 }
01326
01327 void
01328 DQMStore::collate3D(MonitorElement *me, TH3F *h)
01329 {
01330 if (checkBinningMatches(me,h))
01331 me->getTH3F()->Add(h);
01332 }
01333
01334 void
01335 DQMStore::collateProfile(MonitorElement *me, TProfile *h)
01336 {
01337 if (checkBinningMatches(me,h))
01338 {
01339 TProfile *meh = me->getTProfile();
01340 me->addProfiles(h, meh, meh, 1, 1);
01341 }
01342 }
01343
01344 void
01345 DQMStore::collateProfile2D(MonitorElement *me, TProfile2D *h)
01346 {
01347 if (checkBinningMatches(me,h))
01348 {
01349 TProfile2D *meh = me->getTProfile2D();
01350 me->addProfiles(h, meh, meh, 1, 1);
01351 }
01352 }
01353
01358 void
01359 DQMStore::tag(MonitorElement *me, unsigned int myTag)
01360 {
01361 if (! myTag)
01362 raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
01363 " with a zero tag", me->getFullname().c_str());
01364 if ((me->data_.flags & DQMNet::DQM_PROP_TAGGED) && myTag != me->data_.tag)
01365 raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
01366 " twice with multiple tags", me->getFullname().c_str());
01367
01368 me->data_.tag = myTag;
01369 me->data_.flags |= DQMNet::DQM_PROP_TAGGED;
01370 }
01371
01373 void
01374 DQMStore::tag(const std::string &path, unsigned int myTag)
01375 {
01376 std::string dir;
01377 std::string name;
01378 splitPath(dir, name, path);
01379
01380 if (MonitorElement *me = findObject(dir, name))
01381 tag(me, myTag);
01382 else
01383 raiseDQMError("DQMStore", "Attempt to tag non-existent monitor element"
01384 " '%s' with tag %u", path.c_str(), myTag);
01385
01386 }
01387
01389 void
01390 DQMStore::tagContents(const std::string &path, unsigned int myTag)
01391 {
01392 MonitorElement proto(&path, std::string());
01393 MEMap::iterator e = data_.end();
01394 MEMap::iterator i = data_.lower_bound(proto);
01395 for ( ; i != e && path == *i->data_.dirname; ++i)
01396 tag(const_cast<MonitorElement *>(&*i), myTag);
01397 }
01398
01401 void
01402 DQMStore::tagAllContents(const std::string &path, unsigned int myTag)
01403 {
01404 std::string clean;
01405 const std::string *cleaned = 0;
01406 cleanTrailingSlashes(path, clean, cleaned);
01407 MonitorElement proto(cleaned, std::string());
01408
01409
01410 MEMap::iterator e = data_.end();
01411 MEMap::iterator i = data_.lower_bound(proto);
01412 while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
01413 {
01414 tag(const_cast<MonitorElement *>(&*i), myTag);
01415 ++i;
01416 }
01417 }
01418
01423 std::vector<std::string>
01424 DQMStore::getSubdirs(void) const
01425 {
01426 std::vector<std::string> result;
01427 std::set<std::string>::const_iterator e = dirs_.end();
01428 std::set<std::string>::const_iterator i = dirs_.find(pwd_);
01429
01430
01431 if (i == e)
01432 return result;
01433
01434
01435
01436
01437
01438 while (++i != e && isSubdirectory(pwd_, *i))
01439 if (i->find('/', pwd_.size()+1) == std::string::npos)
01440 result.push_back(*i);
01441
01442 return result;
01443 }
01444
01446 std::vector<std::string>
01447 DQMStore::getMEs(void) const
01448 {
01449 MonitorElement proto(&pwd_, std::string());
01450 std::vector<std::string> result;
01451 MEMap::const_iterator e = data_.end();
01452 MEMap::const_iterator i = data_.lower_bound(proto);
01453 for ( ; i != e && isSubdirectory(pwd_, *i->data_.dirname); ++i)
01454 if (pwd_ == *i->data_.dirname)
01455 result.push_back(i->getName());
01456
01457 return result;
01458 }
01459
01462 bool
01463 DQMStore::containsAnyMonitorable(const std::string &path) const
01464 {
01465 MonitorElement proto(&path, std::string());
01466 MEMap::const_iterator e = data_.end();
01467 MEMap::const_iterator i = data_.lower_bound(proto);
01468 return (i != e && isSubdirectory(path, *i->data_.dirname));
01469 }
01470
01472 MonitorElement *
01473 DQMStore::get(const std::string &path) const
01474 {
01475 std::string dir;
01476 std::string name;
01477 splitPath(dir, name, path);
01478 MonitorElement proto(&dir, name);
01479 MEMap::const_iterator mepos = data_.find(proto);
01480 return (mepos == data_.end() ? 0
01481 : const_cast<MonitorElement *>(&*mepos));
01482 }
01483
01485 std::vector<MonitorElement *>
01486 DQMStore::get(unsigned int tag) const
01487 {
01488
01489 std::vector<MonitorElement *> result;
01490 for (MEMap::const_iterator i = data_.begin(), e = data_.end(); i != e; ++i)
01491 {
01492 const MonitorElement &me = *i;
01493 if ((me.data_.flags & DQMNet::DQM_PROP_TAGGED) && me.data_.tag == tag)
01494 result.push_back(const_cast<MonitorElement *>(&me));
01495 }
01496 return result;
01497 }
01498
01501 std::vector<MonitorElement *>
01502 DQMStore::getContents(const std::string &path) const
01503 {
01504 std::string clean;
01505 const std::string *cleaned = 0;
01506 cleanTrailingSlashes(path, clean, cleaned);
01507 MonitorElement proto(cleaned, std::string());
01508
01509 std::vector<MonitorElement *> result;
01510 MEMap::const_iterator e = data_.end();
01511 MEMap::const_iterator i = data_.lower_bound(proto);
01512 for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
01513 if (*cleaned == *i->data_.dirname)
01514 result.push_back(const_cast<MonitorElement *>(&*i));
01515
01516 return result;
01517 }
01518
01520 std::vector<MonitorElement *>
01521 DQMStore::getContents(const std::string &path, unsigned int tag) const
01522 {
01523 std::string clean;
01524 const std::string *cleaned = 0;
01525 cleanTrailingSlashes(path, clean, cleaned);
01526 MonitorElement proto(cleaned, std::string());
01527
01528 std::vector<MonitorElement *> result;
01529 MEMap::const_iterator e = data_.end();
01530 MEMap::const_iterator i = data_.lower_bound(proto);
01531 for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
01532 if (*cleaned == *i->data_.dirname
01533 && (i->data_.flags & DQMNet::DQM_PROP_TAGGED)
01534 && i->data_.tag == tag)
01535 result.push_back(const_cast<MonitorElement *>(&*i));
01536
01537 return result;
01538 }
01539
01544 void
01545 DQMStore::getContents(std::vector<std::string> &into, bool showContents ) const
01546 {
01547 into.clear();
01548 into.reserve(dirs_.size());
01549
01550 MEMap::const_iterator me = data_.end();
01551 std::set<std::string>::const_iterator di = dirs_.begin();
01552 std::set<std::string>::const_iterator de = dirs_.end();
01553 for ( ; di != de; ++di)
01554 {
01555 MonitorElement proto(&*di, std::string());
01556 MEMap::const_iterator mi = data_.lower_bound(proto);
01557 MEMap::const_iterator m = mi;
01558 size_t sz = di->size() + 2;
01559 size_t nfound = 0;
01560 for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
01561 if (*di == *m->data_.dirname)
01562 {
01563 sz += m->data_.objname.size() + 1;
01564 ++nfound;
01565 }
01566
01567 if (! nfound)
01568 continue;
01569
01570 std::vector<std::string>::iterator istr
01571 = into.insert(into.end(), std::string());
01572
01573 if (showContents)
01574 {
01575 istr->reserve(sz);
01576
01577 *istr += *di;
01578 *istr += ':';
01579 for (sz = 0; mi != m; ++mi)
01580 {
01581 if (*di != *mi->data_.dirname)
01582 continue;
01583
01584 if (sz > 0)
01585 *istr += ',';
01586
01587 *istr += mi->data_.objname;
01588 ++sz;
01589 }
01590 }
01591 else
01592 {
01593 istr->reserve(di->size() + 2);
01594 *istr += *di;
01595 *istr += ':';
01596 }
01597 }
01598 }
01599
01602 MonitorElement *
01603 DQMStore::findObject(const std::string &dir, const std::string &name) const
01604 {
01605 if (dir.find_first_not_of(s_safe) != std::string::npos)
01606 raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
01607 " unacceptable characters", dir.c_str());
01608 if (name.find_first_not_of(s_safe) != std::string::npos)
01609 raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
01610 " unacceptable characters", name.c_str());
01611
01612 MonitorElement proto;
01613 proto.data_.dirname = &dir;
01614 proto.data_.objname = name;
01615
01616 MEMap::const_iterator mepos = data_.find(proto);
01617 return (mepos == data_.end() ? 0
01618 : const_cast<MonitorElement *>(&*mepos));
01619 }
01620
01623 void
01624 DQMStore::getAllTags(std::vector<std::string> &into) const
01625 {
01626 into.clear();
01627 into.reserve(dirs_.size());
01628
01629 MEMap::const_iterator me = data_.end();
01630 std::set<std::string>::const_iterator di = dirs_.begin();
01631 std::set<std::string>::const_iterator de = dirs_.end();
01632 char tagbuf[32];
01633
01634 for ( ; di != de; ++di)
01635 {
01636 MonitorElement proto(&*di, std::string());
01637 MEMap::const_iterator mi = data_.lower_bound(proto);
01638 MEMap::const_iterator m = mi;
01639 size_t sz = di->size() + 2;
01640 size_t nfound = 0;
01641 for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
01642 if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
01643 {
01644
01645 sz += 1 + m->data_.objname.size() + 11;
01646 ++nfound;
01647 }
01648
01649 if (! nfound)
01650 continue;
01651
01652 std::vector<std::string>::iterator istr
01653 = into.insert(into.end(), std::string());
01654
01655 istr->reserve(sz);
01656
01657 *istr += *di;
01658 *istr += ':';
01659 for (sz = 0; mi != m; ++mi)
01660 {
01661 if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
01662 {
01663 sprintf(tagbuf, "/%u", mi->data_.tag);
01664 if (sz > 0)
01665 *istr += ',';
01666 *istr += m->data_.objname;
01667 *istr += tagbuf;
01668 ++sz;
01669 }
01670 }
01671 }
01672 }
01673
01676 std::vector<MonitorElement*>
01677 DQMStore::getAllContents(const std::string &path) const
01678 {
01679 std::string clean;
01680 const std::string *cleaned = 0;
01681 cleanTrailingSlashes(path, clean, cleaned);
01682 MonitorElement proto(cleaned, std::string());
01683
01684 std::vector<MonitorElement *> result;
01685 MEMap::const_iterator e = data_.end();
01686 MEMap::const_iterator i = data_.lower_bound(proto);
01687 for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
01688 result.push_back(const_cast<MonitorElement *>(&*i));
01689
01690 return result;
01691 }
01692
01695 std::vector<MonitorElement*>
01696 DQMStore::getMatchingContents(const std::string &pattern, lat::Regexp::Syntax syntaxType ) const
01697 {
01698 lat::Regexp rx;
01699 try
01700 {
01701 rx = lat::Regexp(pattern, 0, syntaxType);
01702 rx.study();
01703 }
01704 catch (lat::Error &e)
01705 {
01706 raiseDQMError("DQMStore", "Invalid regular expression '%s': %s",
01707 pattern.c_str(), e.explain().c_str());
01708 }
01709
01710 std::string path;
01711 std::vector<MonitorElement *> result;
01712 MEMap::const_iterator i = data_.begin();
01713 MEMap::const_iterator e = data_.end();
01714 for ( ; i != e; ++i)
01715 {
01716 path.clear();
01717 mergePath(path, *i->data_.dirname, i->data_.objname);
01718 if (rx.match(path))
01719 result.push_back(const_cast<MonitorElement *>(&*i));
01720 }
01721
01722 return result;
01723 }
01724
01728
01731 void
01732 DQMStore::reset(void)
01733 {
01734 MEMap::iterator mi = data_.begin();
01735 MEMap::iterator me = data_.end();
01736 for ( ; mi != me; ++mi)
01737 {
01738 MonitorElement &me = const_cast<MonitorElement &>(*mi);
01739 if (mi->wasUpdated())
01740 {
01741 if (me.resetMe())
01742 me.Reset();
01743 me.resetUpdate();
01744 }
01745 }
01746
01747 reset_ = true;
01748 }
01749
01753
01755 void
01756 DQMStore::forceReset(void)
01757 {
01758 MEMap::iterator mi = data_.begin();
01759 MEMap::iterator me = data_.end();
01760 for ( ; mi != me; ++mi)
01761 {
01762 MonitorElement &me = const_cast<MonitorElement &>(*mi);
01763 me.Reset();
01764 me.resetUpdate();
01765 }
01766
01767 reset_ = true;
01768 }
01769
01775 bool
01776 DQMStore::extract(TObject *obj, const std::string &dir, bool overwrite)
01777 {
01778
01779 MonitorElement *refcheck = 0;
01780 if (TProfile *h = dynamic_cast<TProfile *>(obj))
01781 {
01782 MonitorElement *me = findObject(dir, h->GetName());
01783 if (! me)
01784 me = bookProfile(dir, h->GetName(), (TProfile *) h->Clone());
01785 else if (overwrite)
01786 me->copyFrom(h);
01787 else if (isCollateME(me) || collateHistograms_)
01788 collateProfile(me, h);
01789 refcheck = me;
01790 }
01791 else if (TProfile2D *h = dynamic_cast<TProfile2D *>(obj))
01792 {
01793 MonitorElement *me = findObject(dir, h->GetName());
01794 if (! me)
01795 me = bookProfile2D(dir, h->GetName(), (TProfile2D *) h->Clone());
01796 else if (overwrite)
01797 me->copyFrom(h);
01798 else if (isCollateME(me) || collateHistograms_)
01799 collateProfile2D(me, h);
01800 refcheck = me;
01801 }
01802 else if (TH1F *h = dynamic_cast<TH1F *>(obj))
01803 {
01804 MonitorElement *me = findObject(dir, h->GetName());
01805 if (! me)
01806 me = book1D(dir, h->GetName(), (TH1F *) h->Clone());
01807 else if (overwrite)
01808 me->copyFrom(h);
01809 else if (isCollateME(me) || collateHistograms_)
01810 collate1D(me, h);
01811 refcheck = me;
01812 }
01813 else if (TH1S *h = dynamic_cast<TH1S *>(obj))
01814 {
01815 MonitorElement *me = findObject(dir, h->GetName());
01816 if (! me)
01817 me = book1S(dir, h->GetName(), (TH1S *) h->Clone());
01818 else if (overwrite)
01819 me->copyFrom(h);
01820 else if (isCollateME(me) || collateHistograms_)
01821 collate1S(me, h);
01822 refcheck = me;
01823 }
01824 else if (TH1D *h = dynamic_cast<TH1D *>(obj))
01825 {
01826 MonitorElement *me = findObject(dir, h->GetName());
01827 if (! me)
01828 me = book1DD(dir, h->GetName(), (TH1D *) h->Clone());
01829 else if (overwrite)
01830 me->copyFrom(h);
01831 else if (isCollateME(me) || collateHistograms_)
01832 collate1DD(me, h);
01833 refcheck = me;
01834 }
01835 else if (TH2F *h = dynamic_cast<TH2F *>(obj))
01836 {
01837 MonitorElement *me = findObject(dir, h->GetName());
01838 if (! me)
01839 me = book2D(dir, h->GetName(), (TH2F *) h->Clone());
01840 else if (overwrite)
01841 me->copyFrom(h);
01842 else if (isCollateME(me) || collateHistograms_)
01843 collate2D(me, h);
01844 refcheck = me;
01845 }
01846 else if (TH2S *h = dynamic_cast<TH2S *>(obj))
01847 {
01848 MonitorElement *me = findObject(dir, h->GetName());
01849 if (! me)
01850 me = book2S(dir, h->GetName(), (TH2S *) h->Clone());
01851 else if (overwrite)
01852 me->copyFrom(h);
01853 else if (isCollateME(me) || collateHistograms_)
01854 collate2S(me, h);
01855 refcheck = me;
01856 }
01857 else if (TH2D *h = dynamic_cast<TH2D *>(obj))
01858 {
01859 MonitorElement *me = findObject(dir, h->GetName());
01860 if (! me)
01861 me = book2DD(dir, h->GetName(), (TH2D *) h->Clone());
01862 else if (overwrite)
01863 me->copyFrom(h);
01864 else if (isCollateME(me) || collateHistograms_)
01865 collate2DD(me, h);
01866 refcheck = me;
01867 }
01868 else if (TH3F *h = dynamic_cast<TH3F *>(obj))
01869 {
01870 MonitorElement *me = findObject(dir, h->GetName());
01871 if (! me)
01872 me = book3D(dir, h->GetName(), (TH3F *) h->Clone());
01873 else if (overwrite)
01874 me->copyFrom(h);
01875 else if (isCollateME(me) || collateHistograms_)
01876 collate3D(me, h);
01877 refcheck = me;
01878 }
01879 else if (dynamic_cast<TObjString *>(obj))
01880 {
01881 lat::RegexpMatch m;
01882 if (! s_rxmeval.match(obj->GetName(), 0, 0, &m))
01883 {
01884 if (strstr(obj->GetName(), "CMSSW"))
01885 {
01886 if (verbose_)
01887 std::cout << "Input file version: " << obj->GetName() << std::endl;
01888 return true;
01889 }
01890 else if (strstr(obj->GetName(), "DQMPATCH"))
01891 {
01892 if (verbose_)
01893 std::cout << "DQM patch version: " << obj->GetName() << std::endl;
01894 return true;
01895 }
01896 else
01897 {
01898 std::cout << "*** DQMStore: WARNING: cannot extract object '"
01899 << obj->GetName() << "' of type '"
01900 << obj->IsA()->GetName() << "'\n";
01901 return false;
01902 }
01903 }
01904
01905 std::string label = m.matchString(obj->GetName(), 1);
01906 std::string kind = m.matchString(obj->GetName(), 2);
01907 std::string value = m.matchString(obj->GetName(), 3);
01908
01909 if (kind == "i")
01910 {
01911 MonitorElement *me = findObject(dir, label);
01912 if (! me || overwrite)
01913 {
01914 if (! me) me = bookInt(dir, label);
01915 me->Fill(atoll(value.c_str()));
01916 }
01917 }
01918 else if (kind == "f")
01919 {
01920 MonitorElement *me = findObject(dir, label);
01921 if (! me || overwrite)
01922 {
01923 if (! me) me = bookFloat(dir, label);
01924 me->Fill(atof(value.c_str()));
01925 }
01926 }
01927 else if (kind == "s")
01928 {
01929 MonitorElement *me = findObject(dir, label);
01930 if (! me)
01931 me = bookString(dir, label, value);
01932 else if (overwrite)
01933 me->Fill(value);
01934 }
01935 else if (kind == "e")
01936 {
01937 MonitorElement *me = findObject(dir, label);
01938 if (! me)
01939 {
01940 std::cout << "*** DQMStore: WARNING: no monitor element '"
01941 << label << "' in directory '"
01942 << dir << "' to be marked as efficiency plot.\n";
01943 return false;
01944 }
01945 me->setEfficiencyFlag();
01946 }
01947 else if (kind == "t")
01948 {
01949 MonitorElement *me = findObject(dir, label);
01950 if (! me)
01951 {
01952 std::cout << "*** DQMStore: WARNING: no monitor element '"
01953 << label << "' in directory '"
01954 << dir << "' for a tag\n";
01955 return false;
01956 }
01957 errno = 0;
01958 char *endp = 0;
01959 unsigned long val = strtoul(value.c_str(), &endp, 10);
01960 if ((val == 0 && errno) || *endp || val > ~uint32_t(0))
01961 {
01962 std::cout << "*** DQMStore: WARNING: cannot restore tag '"
01963 << value << "' for monitor element '"
01964 << label << "' in directory '"
01965 << dir << "' - invalid value\n";
01966 return false;
01967 }
01968 tag(me, val);
01969 }
01970 else if (kind == "qr")
01971 {
01972
01973 if (! isSubdirectory(s_referenceDirName, dir))
01974 {
01975 size_t dot = label.find('.');
01976 if (dot == std::string::npos)
01977 {
01978 std::cout << "*** DQMStore: WARNING: quality report label in '" << label
01979 << "' is missing a '.' and cannot be extracted\n";
01980 return false;
01981 }
01982
01983 std::string mename (label, 0, dot);
01984 std::string qrname (label, dot+1, std::string::npos);
01985
01986 m.reset();
01987 DQMNet::QValue qv;
01988 if (s_rxmeqr1.match(value, 0, 0, &m))
01989 {
01990 qv.code = atoi(m.matchString(value, 1).c_str());
01991 qv.qtresult = strtod(m.matchString(value, 2).c_str(), 0);
01992 qv.message = m.matchString(value, 4);
01993 qv.qtname = qrname;
01994 qv.algorithm = m.matchString(value, 3);
01995 }
01996 else if (s_rxmeqr2.match(value, 0, 0, &m))
01997 {
01998 qv.code = atoi(m.matchString(value, 1).c_str());
01999 qv.qtresult = 0;
02000 qv.message = m.matchString(value, 2);
02001 qv.qtname = qrname;
02002
02003 }
02004 else
02005 {
02006 std::cout << "*** DQMStore: WARNING: quality test value '"
02007 << value << "' is incorrectly formatted\n";
02008 return false;
02009 }
02010
02011 MonitorElement *me = findObject(dir, mename);
02012 if (! me)
02013 {
02014 std::cout << "*** DQMStore: WARNING: no monitor element '"
02015 << mename << "' in directory '"
02016 << dir << "' for quality test '"
02017 << label << "'\n";
02018 return false;
02019 }
02020
02021 me->addQReport(qv, 0);
02022 }
02023 }
02024 else
02025 {
02026 std::cout << "*** DQMStore: WARNING: cannot extract object '"
02027 << obj->GetName() << "' of type '"
02028 << obj->IsA()->GetName() << "'\n";
02029 return false;
02030 }
02031 }
02032 else if (TNamed *n = dynamic_cast<TNamed *>(obj))
02033 {
02034
02035 std::string s;
02036 s.reserve(6 + strlen(n->GetTitle()) + 2*strlen(n->GetName()));
02037 s += '<'; s += n->GetName(); s += '>';
02038 s += n->GetTitle();
02039 s += '<'; s += '/'; s += n->GetName(); s += '>';
02040 TObjString os(s.c_str());
02041 return extract(&os, dir, overwrite);
02042 }
02043 else
02044 {
02045 std::cout << "*** DQMStore: WARNING: cannot extract object '"
02046 << obj->GetName() << "' of type '" << obj->IsA()->GetName()
02047 << "' and with title '" << obj->GetTitle() << "'\n";
02048 return false;
02049 }
02050
02051
02052
02053
02054 if (refcheck && isSubdirectory(s_referenceDirName, dir))
02055 {
02056 std::string mdir(dir, s_referenceDirName.size()+1, std::string::npos);
02057 if (MonitorElement *master = findObject(mdir, obj->GetName()))
02058 {
02059 master->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
02060 master->reference_ = refcheck->object_;
02061 }
02062 }
02063
02064 return true;
02065 }
02066
02070 bool
02071 DQMStore::cdInto(const std::string &path) const
02072 {
02073 assert(! path.empty());
02074
02075
02076 size_t start = 0;
02077 size_t end = path.find('/', start);
02078 if (end == std::string::npos)
02079 end = path.size();
02080
02081 while (true)
02082 {
02083
02084
02085 std::string part(path, start, end-start);
02086 TObject *o = gDirectory->Get(part.c_str());
02087 if (o && ! dynamic_cast<TDirectory *>(o))
02088 raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
02089 " fails because the part '%s' already exists and is not"
02090 " directory", path.c_str(), part.c_str());
02091 else if (! o)
02092 gDirectory->mkdir(part.c_str());
02093
02094 if (! gDirectory->cd(part.c_str()))
02095 raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
02096 " fails because could not cd into subdirectory '%s'",
02097 path.c_str(), part.c_str());
02098
02099
02100 if (end+1 >= path.size())
02101 break;
02102
02103
02104 start = end+1;
02105 end = path.find('/', start);
02106 if (end == std::string::npos)
02107 end = path.size();
02108 }
02109
02110 return true;
02111 }
02112
02117 void
02118 DQMStore::save(const std::string &filename,
02119 const std::string &path ,
02120 const std::string &pattern ,
02121 const std::string &rewrite ,
02122 SaveReferenceTag ref ,
02123 int minStatus ,
02124 const std::string &fileupdate )
02125 {
02126 std::set<std::string>::iterator di, de;
02127 MEMap::iterator mi, me = data_.end();
02128 DQMNet::QReports::const_iterator qi, qe;
02129 int nme=0;
02130
02131
02132
02133
02134
02135 class TFileNoSync : public TFile
02136 {
02137 public:
02138 TFileNoSync(const char *file, const char *opt) : TFile(file, opt) {}
02139 virtual Int_t SysSync(Int_t) { return 0; }
02140 };
02141
02142
02143 if (verbose_)
02144 std::cout << "\n DQMStore: Opening TFile '" << filename
02145 << "' with option '" << fileupdate <<"'\n";
02146
02147 TFileNoSync f(filename.c_str(), fileupdate.c_str());
02148 if(f.IsZombie())
02149 raiseDQMError("DQMStore", "Failed to create/update file '%s'", filename.c_str());
02150 f.cd();
02151
02152
02153 std::auto_ptr<lat::Regexp> rxpat;
02154 if (! pattern.empty())
02155 rxpat.reset(new lat::Regexp(pattern.c_str()));
02156
02157
02158 std::string refpath;
02159 refpath.reserve(s_referenceDirName.size() + path.size() + 2);
02160 refpath += s_referenceDirName;
02161 if (! path.empty())
02162 {
02163 refpath += '/';
02164 refpath += path;
02165 }
02166
02167
02168 for (di = dirs_.begin(), de = dirs_.end(); di != de; ++di)
02169 {
02170
02171
02172 if (! path.empty()
02173 && ! isSubdirectory(path, *di)
02174 && ! isSubdirectory(refpath, *di))
02175 continue;
02176
02177
02178 MonitorElement proto(&*di, std::string());
02179 mi = data_.lower_bound(proto);
02180 for ( ; mi != me && isSubdirectory(*di, *mi->data_.dirname); ++mi)
02181 {
02182
02183 if (*di != *mi->data_.dirname)
02184 continue;
02185
02186
02187
02188
02189
02190
02191
02192 if (isSubdirectory(refpath, *mi->data_.dirname))
02193 {
02194 if (ref == SaveWithoutReference)
02195
02196 continue;
02197 else if (ref == SaveWithReference)
02198
02199 ;
02200 else if (ref == SaveWithReferenceForQTest)
02201 {
02202
02203
02204 int status = -1;
02205 std::string mname(mi->getFullname(), s_referenceDirName.size()+1, std::string::npos);
02206 MonitorElement *master = get(mname);
02207 if (master)
02208 for (size_t i = 0, e = master->data_.qreports.size(); i != e; ++i)
02209 status = std::max(status, master->data_.qreports[i].code);
02210
02211 if (! master || status < minStatus)
02212 {
02213 if (verbose_ > 1)
02214 std::cout << "DQMStore::save: skipping monitor element '"
02215 << mi->data_.objname << "' while saving, status is "
02216 << status << ", required minimum status is "
02217 << minStatus << std::endl;
02218 continue;
02219 }
02220 }
02221 }
02222
02223 if (verbose_ > 1)
02224 std::cout << "DQMStore::save: saving monitor element '"
02225 << mi->data_.objname << "'\n";
02226 nme++;
02227
02228
02229 gDirectory->cd("/");
02230 if (di->empty())
02231 cdInto(s_monitorDirName);
02232 else if (rxpat.get())
02233 cdInto(s_monitorDirName + '/' + lat::StringOps::replace(*di, *rxpat, rewrite));
02234 else
02235 cdInto(s_monitorDirName + '/' + *di);
02236
02237
02238 switch (mi->kind())
02239 {
02240 case MonitorElement::DQM_KIND_INT:
02241 case MonitorElement::DQM_KIND_REAL:
02242 case MonitorElement::DQM_KIND_STRING:
02243 TObjString(mi->tagString().c_str()).Write();
02244 break;
02245
02246 default:
02247 mi->object_->Write();
02248 break;
02249 }
02250
02251
02252 if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
02253 {
02254 qi = mi->data_.qreports.begin();
02255 qe = mi->data_.qreports.end();
02256 for ( ; qi != qe; ++qi)
02257 TObjString(mi->qualityTagString(*qi).c_str()).Write();
02258 }
02259
02260
02261 if (mi->data_.flags & DQMNet::DQM_PROP_EFFICIENCY_PLOT)
02262 TObjString(mi->effLabelString().c_str()).Write();
02263
02264
02265 if (mi->data_.flags & DQMNet::DQM_PROP_TAGGED)
02266 TObjString(mi->tagLabelString().c_str()).Write();
02267 }
02268 }
02269
02270 f.Close();
02271
02272
02273 if (verbose_)
02274 std::cout << "DQMStore::save: successfully wrote " << nme
02275 << " objects from path '" << path
02276 << "' into DQM file '" << filename << "'\n";
02277 }
02278
02281 unsigned int
02282 DQMStore::readDirectory(TFile *file,
02283 bool overwrite,
02284 const std::string &onlypath,
02285 const std::string &prepend,
02286 const std::string &curdir,
02287 OpenRunDirs stripdirs)
02288 {
02289 unsigned int ntot = 0;
02290 unsigned int count = 0;
02291
02292 if (! file->cd(curdir.c_str()))
02293 raiseDQMError("DQMStore", "Failed to process directory '%s' while"
02294 " reading file '%s'", curdir.c_str(), file->GetName());
02295
02296
02297
02298 std::string dirpart = curdir;
02299 if (dirpart.compare(0, s_monitorDirName.size(), s_monitorDirName) == 0)
02300 {
02301 if (dirpart.size() == s_monitorDirName.size())
02302 dirpart.clear();
02303 else if (dirpart[s_monitorDirName.size()] == '/')
02304 dirpart.erase(0, s_monitorDirName.size()+1);
02305 }
02306
02307
02308 bool skip = (! onlypath.empty() && ! isSubdirectory(onlypath, dirpart));
02309
02310 if (prepend == s_collateDirName ||
02311 prepend == s_referenceDirName ||
02312 stripdirs == StripRunDirs )
02313 {
02314
02315
02316
02317 size_t slash = dirpart.find('/');
02318 size_t pos = dirpart.find("/Run summary");
02319 if (slash != std::string::npos && pos !=std::string::npos)
02320 {
02321 dirpart.erase(pos,12);
02322
02323 pos = dirpart.find("Run ");
02324 size_t length = dirpart.find('/',pos+1)-pos+1;
02325 if (pos !=std::string::npos)
02326 dirpart.erase(pos,length);
02327 }
02328 }
02329
02330
02331
02332 if (prepend == s_collateDirName ||
02333 prepend == s_referenceDirName)
02334 {
02335 size_t slash = dirpart.find('/');
02336
02337 if (slash == std::string::npos
02338 && slash+1+s_referenceDirName.size() == dirpart.size()
02339 && dirpart.compare(slash+1, s_referenceDirName.size(), s_referenceDirName) == 0)
02340 return 0;
02341
02342 slash = dirpart.find('/');
02343
02344 if (slash != std::string::npos
02345 && slash + 10 == dirpart.size()
02346 && dirpart.compare( slash+1 , 9 , "EventInfo") == 0) {
02347 if (verbose_)
02348 std::cout << "DQMStore::readDirectory: skipping '" << dirpart << "'\n";
02349 return 0;
02350 }
02351
02352
02353 if (dirpart.empty())
02354 dirpart = prepend;
02355 else
02356 dirpart = prepend + '/' + dirpart;
02357 }
02358 else if (! prepend.empty())
02359 {
02360 if (dirpart.empty())
02361 dirpart = prepend;
02362 else
02363 dirpart = prepend + '/' + dirpart;
02364 }
02365
02366
02367
02368
02369
02370 TKey *key;
02371 TIter next (gDirectory->GetListOfKeys());
02372 std::list<TObject *> delayed;
02373 while ((key = (TKey *) next()))
02374 {
02375 std::auto_ptr<TObject> obj(key->ReadObj());
02376 if (dynamic_cast<TDirectory *>(obj.get()))
02377 {
02378 std::string subdir;
02379 subdir.reserve(curdir.size() + strlen(obj->GetName()) + 2);
02380 subdir += curdir;
02381 if (! curdir.empty())
02382 subdir += '/';
02383 subdir += obj->GetName();
02384
02385 ntot += readDirectory(file, overwrite, onlypath, prepend, subdir, stripdirs);
02386 }
02387 else if (skip)
02388 ;
02389 else if (dynamic_cast<TObjString *>(obj.get()))
02390 {
02391 delayed.push_back(obj.release());
02392 }
02393 else
02394 {
02395 if (verbose_ > 2)
02396 std::cout << "DQMStore: reading object '" << obj->GetName()
02397 << "' of type '" << obj->IsA()->GetName()
02398 << "' from '" << file->GetName()
02399 << "' into '" << dirpart << "'\n";
02400
02401 makeDirectory(dirpart);
02402 if (extract(obj.get(), dirpart, overwrite))
02403 ++count;
02404 }
02405 }
02406
02407 while (! delayed.empty())
02408 {
02409 if (verbose_ > 2)
02410 std::cout << "DQMStore: reading object '" << delayed.front()->GetName()
02411 << "' of type '" << delayed.front()->IsA()->GetName()
02412 << "' from '" << file->GetName()
02413 << "' into '" << dirpart << "'\n";
02414
02415 makeDirectory(dirpart);
02416 if (extract(delayed.front(), dirpart, overwrite))
02417 ++count;
02418
02419 delete delayed.front();
02420 delayed.pop_front();
02421 }
02422
02423 if (verbose_ > 1)
02424 std::cout << "DQMStore: read " << count << '/' << ntot
02425 << " objects from directory '" << dirpart << "'\n";
02426
02427 return ntot + count;
02428 }
02429
02436 bool
02437 DQMStore::open(const std::string &filename,
02438 bool overwrite ,
02439 const std::string &onlypath ,
02440 const std::string &prepend ,
02441 OpenRunDirs stripdirs ,
02442 bool fileMustExist )
02443 {
02444 return readFile(filename,overwrite,onlypath,prepend,stripdirs,fileMustExist);
02445 }
02446
02451 bool
02452 DQMStore::load(const std::string &filename,
02453 OpenRunDirs stripdirs ,
02454 bool fileMustExist )
02455 {
02456 bool overwrite = true;
02457 if (collateHistograms_) overwrite = false;
02458 if (verbose_)
02459 {
02460 std::cout << "DQMStore::load: reading from file '" << filename << "'\n";
02461 if (collateHistograms_)
02462 std::cout << "DQMStore::load: in collate mode " << "\n";
02463 else
02464 std::cout << "DQMStore::load: in overwrite mode " << "\n";
02465 }
02466
02467 return readFile(filename,overwrite,"","",stripdirs,fileMustExist);
02468
02469 }
02470
02476 bool
02477 DQMStore::readFile(const std::string &filename,
02478 bool overwrite ,
02479 const std::string &onlypath ,
02480 const std::string &prepend ,
02481 OpenRunDirs stripdirs ,
02482 bool fileMustExist )
02483 {
02484
02485 if (verbose_)
02486 std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
02487
02488 std::auto_ptr<TFile> f;
02489
02490 try
02491 {
02492 f.reset(TFile::Open(filename.c_str()));
02493 if (! f.get() || f->IsZombie())
02494 raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
02495 }
02496 catch (std::exception &)
02497 {
02498 if (fileMustExist)
02499 throw;
02500 else
02501 {
02502 if (verbose_)
02503 std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
02504 return false;
02505 }
02506 }
02507
02508 unsigned n = readDirectory(f.get(), overwrite, onlypath, prepend, "", stripdirs);
02509 f->Close();
02510
02511 MEMap::iterator mi = data_.begin();
02512 MEMap::iterator me = data_.end();
02513 for ( ; mi != me; ++mi)
02514 const_cast<MonitorElement &>(*mi).updateQReportStats();
02515
02516 if (verbose_)
02517 {
02518 std::cout << "DQMStore::open: successfully read " << n
02519 << " objects from file '" << filename << "'";
02520 if (! onlypath.empty())
02521 std::cout << " from directory '" << onlypath << "'";
02522 if (! prepend.empty())
02523 std::cout << " into directory '" << prepend << "'";
02524 std::cout << std::endl;
02525 }
02526 return true;
02527 }
02528
02534 void
02535 DQMStore::rmdir(const std::string &path)
02536 {
02537 std::string clean;
02538 const std::string *cleaned = 0;
02539 cleanTrailingSlashes(path, clean, cleaned);
02540 MonitorElement proto(cleaned, std::string());
02541
02542 MEMap::iterator e = data_.end();
02543 MEMap::iterator i = data_.lower_bound(proto);
02544 while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
02545 data_.erase(i++);
02546
02547 std::set<std::string>::iterator de = dirs_.end();
02548 std::set<std::string>::iterator di = dirs_.lower_bound(*cleaned);
02549 while (di != de && isSubdirectory(*cleaned, *di))
02550 dirs_.erase(di++);
02551 }
02552
02554 void
02555 DQMStore::removeContents(const std::string &dir)
02556 {
02557 MonitorElement proto(&dir, std::string());
02558 MEMap::iterator e = data_.end();
02559 MEMap::iterator i = data_.lower_bound(proto);
02560 while (i != e && isSubdirectory(dir, *i->data_.dirname))
02561 if (dir == *i->data_.dirname)
02562 data_.erase(i++);
02563 else
02564 ++i;
02565 }
02566
02568 void
02569 DQMStore::removeContents(void)
02570 {
02571 removeContents(pwd_);
02572 }
02573
02576 void
02577 DQMStore::removeElement(const std::string &name)
02578 {
02579 removeElement(pwd_, name);
02580 }
02581
02584 void
02585 DQMStore::removeElement(const std::string &dir, const std::string &name, bool warning )
02586 {
02587 MonitorElement proto(&dir, name);
02588 MEMap::iterator pos = data_.find(proto);
02589 if (pos == data_.end() && warning)
02590 std::cout << "DQMStore: WARNING: attempt to remove non-existent"
02591 << " monitor element '" << name << "' in '" << dir << "'\n";
02592 else
02593 data_.erase(pos);
02594 }
02595
02601 QCriterion *
02602 DQMStore::getQCriterion(const std::string &qtname) const
02603 {
02604 QCMap::const_iterator i = qtests_.find(qtname);
02605 QCMap::const_iterator e = qtests_.end();
02606 return (i == e ? 0 : i->second);
02607 }
02608
02612 QCriterion *
02613 DQMStore::createQTest(const std::string &algoname, const std::string &qtname)
02614 {
02615 if (qtests_.count(qtname))
02616 raiseDQMError("DQMStore", "Attempt to create duplicate quality test '%s'",
02617 qtname.c_str());
02618
02619 QAMap::iterator i = qalgos_.find(algoname);
02620 if (i == qalgos_.end())
02621 raiseDQMError("DQMStore", "Cannot create a quality test using unknown"
02622 " algorithm '%s'", algoname.c_str());
02623
02624 QCriterion *qc = i->second(qtname);
02625 qc->setVerbose(verboseQT_);
02626
02627 qtests_[qtname] = qc;
02628 return qc;
02629 }
02630
02633 void
02634 DQMStore::useQTest(const std::string &dir, const std::string &qtname)
02635 {
02636
02637 std::string clean;
02638 const std::string *cleaned = 0;
02639 cleanTrailingSlashes(dir, clean, cleaned);
02640
02641
02642 if (cleaned->find_first_not_of(s_safe) != std::string::npos)
02643 raiseDQMError("DQMStore", "Monitor element path name '%s'"
02644 " uses unacceptable characters", cleaned->c_str());
02645
02646
02647 useQTestByMatch(*cleaned + "/*", qtname);
02648 }
02649
02651 int
02652 DQMStore::useQTestByMatch(const std::string &pattern, const std::string &qtname)
02653 {
02654 QCriterion *qc = getQCriterion(qtname);
02655 if (! qc)
02656 raiseDQMError("DQMStore", "Cannot apply non-existent quality test '%s'",
02657 qtname.c_str());
02658
02659 fastmatch * fm = new fastmatch( pattern );
02660
02661
02662 QTestSpec qts(fm, qc);
02663 qtestspecs_.push_back(qts);
02664
02665
02666 MEMap::iterator mi = data_.begin();
02667 MEMap::iterator me = data_.end();
02668 std::string path;
02669 int cases = 0;
02670 for ( ; mi != me; ++mi)
02671 {
02672 path.clear();
02673 mergePath(path, *mi->data_.dirname, mi->data_.objname);
02674 if (fm->match(path))
02675 {
02676 ++cases;
02677 const_cast<MonitorElement &>(*mi).addQReport(qts.second);
02678 }
02679 }
02680
02681
02682 return cases;
02683 }
02686 void
02687 DQMStore::runQTests(void)
02688 {
02689
02690 if (verbose_ > 0)
02691 std::cout << "DQMStore: running runQTests() with reset = "
02692 << ( reset_ ? "true" : "false" ) << std::endl;
02693
02694
02695 MEMap::iterator mi = data_.begin();
02696 MEMap::iterator me = data_.end();
02697 for ( ; mi != me; ++mi)
02698 if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
02699 const_cast<MonitorElement &>(*mi).runQTests();
02700
02701 reset_ = false;
02702 }
02703
02707 int
02708 DQMStore::getStatus(const std::string &path ) const
02709 {
02710 std::string clean;
02711 const std::string *cleaned = 0;
02712 cleanTrailingSlashes(path, clean, cleaned);
02713
02714 int status = dqm::qstatus::STATUS_OK;
02715 MEMap::const_iterator mi = data_.begin();
02716 MEMap::const_iterator me = data_.end();
02717 for ( ; mi != me; ++mi)
02718 {
02719 if (! cleaned->empty() && ! isSubdirectory(*cleaned, *mi->data_.dirname))
02720 continue;
02721
02722 if (mi->hasError())
02723 return dqm::qstatus::ERROR;
02724 else if (mi->hasWarning())
02725 status = dqm::qstatus::WARNING;
02726 else if (status < dqm::qstatus::WARNING
02727 && mi->hasOtherReport())
02728 status = dqm::qstatus::OTHER;
02729 }
02730 return status;
02731 }
02732
02738 void
02739 DQMStore::softReset(MonitorElement *me)
02740 {
02741 if (me)
02742 me->softReset();
02743 }
02744
02745
02746 void
02747 DQMStore::disableSoftReset(MonitorElement *me)
02748 {
02749 if (me)
02750 me->disableSoftReset();
02751 }
02752
02755 void
02756 DQMStore::setAccumulate(MonitorElement *me, bool flag)
02757 {
02758 if (me)
02759 me->setAccumulate(flag);
02760 }
02761
02765 void
02766 DQMStore::showDirStructure(void) const
02767 {
02768 std::vector<std::string> contents;
02769 getContents(contents);
02770
02771 std::cout << " ------------------------------------------------------------\n"
02772 << " Directory structure: \n"
02773 << " ------------------------------------------------------------\n";
02774
02775 std::copy(contents.begin(), contents.end(),
02776 std::ostream_iterator<std::string>(std::cout, "\n"));
02777
02778 std::cout << " ------------------------------------------------------------\n";
02779 }
02780
02784
02785 bool
02786 DQMStore::isCollate(void) const
02787 {
02788 return collateHistograms_;
02789 }
02793
02794 bool
02795 DQMStore::isCollateME(MonitorElement *me) const
02796 { return me && isSubdirectory(s_collateDirName, *me->data_.dirname); }
02800
02802 void
02803 DQMStore::scaleElements(void)
02804 {
02805 if (scaleFlag_ == 0.0) return;
02806 if (verbose_ > 0)
02807 std::cout << " =========== " << " ScaleFlag " << scaleFlag_ << std::endl;
02808 double factor = scaleFlag_;
02809 int events = 1;
02810 if (dirExists("Info/EventInfo")) {
02811 if ( scaleFlag_ == -1.0) {
02812 MonitorElement * scale_me = get("Info/EventInfo/ScaleFactor");
02813 if (scale_me && scale_me->kind()==MonitorElement::DQM_KIND_REAL) factor = scale_me->getFloatValue();
02814 }
02815 MonitorElement * event_me = get("Info/EventInfo/processedEvents");
02816 if (event_me && event_me->kind()==MonitorElement::DQM_KIND_INT) events = event_me->getIntValue();
02817 }
02818 factor = factor/(events*1.0);
02819
02820 MEMap::iterator mi = data_.begin();
02821 MEMap::iterator me = data_.end();
02822 for ( ; mi != me; ++mi)
02823 {
02824 MonitorElement &me = const_cast<MonitorElement &>(*mi);
02825 switch (me.kind())
02826 {
02827 case MonitorElement::DQM_KIND_TH1F:
02828 {
02829 me.getTH1F()->Scale(factor);
02830 break;
02831 }
02832 case MonitorElement::DQM_KIND_TH1S:
02833 {
02834 me.getTH1S()->Scale(factor);
02835 break;
02836 }
02837 case MonitorElement::DQM_KIND_TH1D:
02838 {
02839 me.getTH1D()->Scale(factor);
02840 break;
02841 }
02842 case MonitorElement::DQM_KIND_TH2F:
02843 {
02844 me.getTH2F()->Scale(factor);
02845 break;
02846 }
02847 case MonitorElement::DQM_KIND_TH2S:
02848 {
02849 me.getTH2S()->Scale(factor);
02850 break;
02851 }
02852 case MonitorElement::DQM_KIND_TH2D:
02853 {
02854 me.getTH2D()->Scale(factor);
02855 break;
02856 }
02857 case MonitorElement::DQM_KIND_TH3F:
02858 {
02859 me.getTH3F()->Scale(factor);
02860 break;
02861 }
02862 case MonitorElement::DQM_KIND_TPROFILE:
02863 {
02864 me.getTProfile()->Scale(factor);
02865 break;
02866 }
02867 case MonitorElement::DQM_KIND_TPROFILE2D:
02868 {
02869 me.getTProfile2D()->Scale(factor);
02870 break;
02871 }
02872 default:
02873 if (verbose_ > 0)
02874 std::cout << " The DQM object '" << me.getFullname() << "' is not scalable object " << std::endl;
02875 continue;
02876 }
02877 }
02878 }