CMS 3D CMS Logo

DQMStore.cc
Go to the documentation of this file.
7 #include "classlib/utils/RegexpMatch.h"
8 #include "classlib/utils/Regexp.h"
9 #include "classlib/utils/StringOps.h"
10 #include <google/protobuf/io/coded_stream.h>
11 #include <google/protobuf/io/gzip_stream.h>
12 #include <google/protobuf/io/zero_copy_stream_impl.h>
13 #include "TFile.h"
14 #include "TROOT.h"
15 #include "TKey.h"
16 #include "TClass.h"
17 #include "TSystem.h"
18 #include "TBufferFile.h"
19 #include <boost/algorithm/string.hpp>
20 #include <boost/range/iterator_range_core.hpp>
21 
22 #include <iterator>
23 #include <cerrno>
24 #include <exception>
25 #include <fstream>
26 #include <sstream>
27 #include <utility>
28 
55 namespace {
56 
59  std::string const s_monitorDirName{"DQMData"};
60  std::string const s_referenceDirName{"Reference"};
61  std::string const s_collateDirName{"Collate"};
62  std::string const s_safe{"/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+=_()# "};
63 
64  lat::Regexp const s_rxmeval{"^<(.*)>(i|f|s|e|t|qr)=(.*)</\\1>$"};
65  lat::Regexp const s_rxmeqr1{"^st:(\\d+):([-+e.\\d]+):([^:]*):(.*)$"};
66  lat::Regexp const s_rxmeqr2{"^st\\.(\\d+)\\.(.*)$"};
67  lat::Regexp const s_rxtrace{"(.*)\\((.*)\\+0x.*\\).*"};
68  lat::Regexp const s_rxself{"^[^()]*DQMStore::.*"};
69  lat::Regexp const s_rxpbfile{".*\\.pb$"};
70 
71  std::string const empty_str{};
72 
76  bool
77  isSubdirectory(std::string const& ofdir, std::string const& path)
78  {
79  return (ofdir.empty()
80  || (path.size() >= ofdir.size()
81  && path.compare(0, ofdir.size(), ofdir) == 0
82  && (path.size() == ofdir.size()
83  || path[ofdir.size()] == '/')));
84  }
85 
86  void
87  cleanTrailingSlashes(std::string const& path, std::string& clean, std::string const*& cleaned)
88  {
89  clean.clear();
90  cleaned = &path;
91 
92  size_t len = path.size();
93  for ( ; len > 0 && path[len-1] == '/'; --len)
94  ;
95 
96  if (len != path.size()) {
97  clean = path.substr(0, len);
98  cleaned = &clean;
99  }
100  }
101 
102  void
103  splitPath(std::string& dir, std::string& name, std::string const& path)
104  {
105  size_t slash = path.rfind('/');
106  if (slash != std::string::npos) {
107  dir.append(path, 0, slash);
108  name.append(path, slash+1, std::string::npos);
109  }
110  else
111  name = path;
112  }
113 
114  void
115  mergePath(std::string& path, std::string const& dir, std::string const& name)
116  {
117  path.reserve(dir.size() + name.size() + 2);
118  path += dir;
119  if (! path.empty())
120  path += '/';
121  path += name;
122  }
123 
124  template <class T>
125  QCriterion*
126  makeQCriterion(std::string const& qtname)
127  {
128  return new T{qtname};
129  }
130 
131  template <class T>
132  void
133  initQCriterion(std::map<std::string, QCriterion* (*)(std::string const&)>& m)
134  {
135  m[T::getAlgoName()] = &makeQCriterion<T>;
136  }
137 
138 } // anonymous namespace
139 
142  fastString_{move(fastString)}, matching_{UseFull}
143 {
144  try {
145  regexp_ = std::make_unique<lat::Regexp>(fastString_, 0, lat::Regexp::Wildcard);
146  regexp_->study();
147  }
148  catch (lat::Error&e) {
149  raiseDQMError("DQMStore", "Invalid wildcard pattern '%s' in quality"
150  " test specification", fastString_.c_str());
151  }
152 
153  // count stars ( "*" )
154  size_t starCount = 0;
155  int pos = -1;
156  while (true) {
157  pos = fastString_.find('*', pos + 1 );
158  if ((size_t)pos == std::string::npos)
159  break;
160  ++starCount;
161  }
162 
163  // investigate for heuristics
164  if ((fastString_.find('"') != std::string::npos) ||
165  (fastString_.find(']') != std::string::npos) ||
166  (fastString_.find('?') != std::string::npos) ||
167  (fastString_.find('\\') != std::string::npos) ||
168  (starCount > 2)) {
169  // no fast version can be used
170  return;
171  }
172 
173  // match for pattern "*MyString" and "MyString*"
174  if (starCount == 1) {
175  if (boost::algorithm::starts_with(fastString_, "*")) {
177  fastString_.erase(0,1);
178  return;
179  }
180 
181  if (boost::algorithm::ends_with(fastString_, "*")) {
183  fastString_.erase(fastString_.length()-1,1);
184  return;
185  }
186  }
187 
188  // match for pattern "*MyString*"
189  if (starCount == 2) {
190  if (boost::algorithm::starts_with(fastString_, "*") &&
191  boost::algorithm::ends_with(fastString_, "*")) {
192  matching_ = TwoStar;
193  fastString_.erase(0,1);
194  fastString_.erase(fastString_.size() - 1, 1);
195  return;
196  }
197  }
198 }
199 
201  std::string const& input) const
202 {
203  if (input.size() < pattern.size())
204  return false;
205 
206  // compare the two strings character by character for equalness:
207  // this does not create uneeded copies of std::string. The
208  // boost::algorithm implementation does
209  auto rit_pattern = pattern.crbegin();
210  auto rit_input = input.crbegin();
211 
212  for (; rit_pattern < pattern.rend(); ++rit_pattern, ++rit_input) {
213  if (*rit_pattern != *rit_input)
214  // found a difference, fail
215  return false;
216  }
217  return true;
218 }
219 
221  std::string const& input) const
222 {
223  if (input.size() < pattern.size())
224  return false;
225 
226  // compare the two strings character by character for equalness:
227  // this does not create uneeded copies of std::string. The
228  // boost::algorithm implementation does.
229  auto rit_pattern = pattern.cbegin();
230  auto rit_input = input.cbegin();
231 
232  for (; rit_pattern < pattern.end(); ++rit_pattern, ++rit_input) {
233  if (*rit_pattern != *rit_input)
234  // found a difference, fail
235  return false;
236  }
237  return true;
238 }
239 
240 bool fastmatch::match(std::string const& s) const
241 {
242  switch (matching_) {
243  case OneStarStart:
245 
246  case OneStarEnd:
247  return compare_strings(fastString_, s);
248 
249  case TwoStar:
250  return (s.find(fastString_) != std::string::npos);
251 
252  default:
253  return regexp_->match(s);
254  }
255 }
256 
257 //IBooker methods
259 {
260  owner_->cd();
261 }
262 
264 {
265  owner_->cd(dir);
266 }
267 
269 {
270  owner_->setCurrentFolder(fullpath);
271 }
272 
274 {
275  owner_->goUp();
276 }
277 
279 {
280  return owner_->pwd();
281 }
282 
283 void DQMStore::IBooker::tag(MonitorElement* me, unsigned int const tag)
284 {
285  owner_->tag(me, tag);
286 }
287 
288 void DQMStore::IBooker::tagContents(std::string const& path, unsigned int const myTag)
289 {
290  owner_->tagContents(path, myTag);
291 }
292 
293 //IGetter methods
294 std::vector<MonitorElement*>
296  uint32_t const run /* = 0 */,
297  uint32_t const lumi /* = 0 */)
298 {
299  return owner_->getAllContents(path, run, lumi);
300 }
301 
304 {
305  return owner_->get(path);
306 }
307 
310 {
311  MonitorElement* ptr = this->get(path);
312  if (ptr == nullptr) {
313  std::stringstream msg;
314  msg << "DQM object not found";
315 
316  msg << ": " << path;
317 
318  // can't use cms::Exception inside DQMStore
319  throw std::out_of_range(msg.str());
320  }
321  return ptr;
322 }
323 
324 std::vector<std::string>
326 {
327  return owner_->getSubdirs();
328 }
329 
330 std::vector<std::string>
332 {
333  return owner_->getMEs();
334 }
335 
336 bool
338 {
339  return owner_->containsAnyMonitorable(path);
340 }
341 
342 bool
344 {
345  return owner_->dirExists(path);
346 }
347 
348 void
350 {
351  owner_->cd();
352 }
353 
354 void
356 {
357  owner_->cd(dir);
358 }
359 
360 void
362 {
363  owner_->setCurrentFolder(fullpath);
364 }
365 
368  : DQMStore{pset}
369 {
370  ar.preallocateSignal_.connect([this](edm::service::SystemBounds const& iBounds) {
371  if(iBounds.maxNumberOfStreams() > 1 ) {
372  enableMultiThread_ = true;
373  }
374  });
375  if(pset.getUntrackedParameter<bool>("forceResetOnBeginRun",false)) {
376  ar.watchPostSourceRun([this](edm::RunIndex){ forceReset(); });
377  }
378  if(pset.getUntrackedParameter<bool>("forceResetOnBeginLumi",false) && enableMultiThread_ == false) {
379  forceResetOnBeginLumi_ = true;
380  ar.watchPostSourceLumi([this](edm::LuminosityBlockIndex){ forceReset(); });
381  }
382  ar.watchPostGlobalBeginLumi(this, &DQMStore::postGlobalBeginLumi);
383 }
384 
386 {
387  initializeFrom(pset);
388 }
389 
391 {
392  for (auto& qtest : qtests_)
393  delete qtest.second;
394 
395  for (auto& qtestspec : qtestspecs_)
396  delete qtestspec.first;
397 }
398 
399 void
401 {
402  makeDirectory("");
403  reset();
404 
405  // set steerable parameters
406  verbose_ = pset.getUntrackedParameter<int>("verbose", 0);
407  if (verbose_ > 0)
408  std::cout << "DQMStore: verbosity set to " << verbose_ << std::endl;
409 
410  verboseQT_ = pset.getUntrackedParameter<int>("verboseQT", 0);
411  if (verbose_ > 0)
412  std::cout << "DQMStore: QTest verbosity set to " << verboseQT_ << std::endl;
413 
414  collateHistograms_ = pset.getUntrackedParameter<bool>("collateHistograms", false);
415  if (collateHistograms_)
416  std::cout << "DQMStore: histogram collation is enabled\n";
417 
418  enableMultiThread_ = pset.getUntrackedParameter<bool>("enableMultiThread", false);
419  if (enableMultiThread_)
420  std::cout << "DQMStore: MultiThread option is enabled\n";
421 
422  LSbasedMode_ = pset.getUntrackedParameter<bool>("LSbasedMode", false);
423  if (LSbasedMode_)
424  std::cout << "DQMStore: LSbasedMode option is enabled\n";
425 
426  std::string ref = pset.getUntrackedParameter<std::string>("referenceFileName", "");
427  if (! ref.empty()) {
428  std::cout << "DQMStore: using reference file '" << ref << "'\n";
429  readFile(ref, true, "", s_referenceDirName, StripRunDirs, false);
430  }
431 
432  initQCriterion<Comp2RefChi2>(qalgos_);
433  initQCriterion<Comp2Ref2DChi2>(qalgos_);
434  initQCriterion<Comp2RefKolmogorov>(qalgos_);
435  initQCriterion<ContentsXRange>(qalgos_);
436  initQCriterion<ContentsYRange>(qalgos_);
437  initQCriterion<MeanWithinExpected>(qalgos_);
438  initQCriterion<Comp2RefEqualH>(qalgos_);
439  initQCriterion<DeadChannel>(qalgos_);
440  initQCriterion<NoisyChannel>(qalgos_);
441  initQCriterion<ContentSigma>(qalgos_);
442  initQCriterion<ContentsWithinExpected>(qalgos_);
443  initQCriterion<CompareToMedian>(qalgos_);
444  initQCriterion<CompareLastFilledBin>(qalgos_);
445  initQCriterion<CheckVariance>(qalgos_);
446 
447  scaleFlag_ = pset.getUntrackedParameter<double>("ScalingFlag", 0.0);
448  if (verbose_ > 0)
449  std::cout << "DQMStore: Scaling Flag set to " << scaleFlag_ << std::endl;
450 }
451 
452 /* Generic method to do a backtrace and print it to stdout. It is
453  customised to properly get the routine that called the booking of the
454  histograms, which, following the usual stack, is at position 4. The
455  name of the calling function is properly demangled and the original
456  shared library including this function is also printed. For a more
457  detailed explanation of the routines involved, see here:
458  http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
459  http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html.*/
460 
461 void
463 {
464  // the access to the member stream_ is implicitely protected against
465  // concurrency problems because the print_trace method is always called behind
466  // a lock (see bookTransaction).
467  if (!stream_)
468  stream_ = std::make_unique<std::ofstream>("histogramBookingBT.log");
469 
470  void* array[10];
471  size_t size;
472  char** strings;
473  int r = 0;
474  lat::RegexpMatch m;
475  m.reset();
476 
477  size = backtrace(array, 10);
478  strings = backtrace_symbols(array, size);
479 
480  size_t level = 1;
481  char* demangled = nullptr;
482  for (; level < size; ++level) {
483  if (!s_rxtrace.match(strings[level], 0, 0, &m)) continue;
484  demangled = abi::__cxa_demangle(m.matchString(strings[level], 2).c_str(), nullptr, nullptr, &r);
485  if (!demangled) continue;
486  if (!s_rxself.match(demangled, 0, 0)) break;
487  free(demangled);
488  demangled = nullptr;
489  }
490 
491  if (demangled != nullptr) {
492  *stream_ << "\"" << dir << "/"
493  << name << "\" "
494  << (r ? m.matchString(strings[level], 2) : demangled) << " "
495  << m.matchString(strings[level], 1) << "\n";
496  free(demangled);
497  } else {
498  *stream_ << "Skipping "<< dir << "/" << name
499  << " with stack size " << size << "\n";
500  }
501 
502  /* In this case print the full stack trace, up to main or to the
503  * maximum stack size, i.e. 10. */
504  if (verbose_ > 4 || demangled == nullptr) {
505  size_t i;
506  m.reset();
507 
508  for (i = 0; i < size; ++i)
509  if (s_rxtrace.match(strings[i], 0, 0, &m)) {
510  char* demangled = abi::__cxa_demangle(m.matchString(strings[i], 2).c_str(), nullptr, nullptr, &r);
511  *stream_ << "\t\t" << i << "/" << size << " "
512  << (r ? m.matchString(strings[i], 2) : demangled) << " "
513  << m.matchString(strings[i], 1) << std::endl;
514  free (demangled);
515  }
516  }
517  free (strings);
518 }
519 
524 void
525 DQMStore::setVerbose(unsigned /* level */)
526 {}
527 
532 std::string const&
534 {
535  return pwd_;
536 }
537 
539 void
541 {
542  setCurrentFolder("");
543 }
544 
546 void
547 DQMStore::cd(std::string const& subdir)
548 {
550  std::string const* cleaned = nullptr;
551  cleanTrailingSlashes(subdir, clean, cleaned);
552 
553  if (! dirExists(*cleaned))
554  raiseDQMError("DQMStore", "Cannot 'cd' into non-existent directory '%s'",
555  cleaned->c_str());
556 
557  setCurrentFolder(*cleaned);
558 }
559 
564 void
566 {
568  std::string const* cleaned = nullptr;
569  cleanTrailingSlashes(fullpath, clean, cleaned);
570  makeDirectory(*cleaned);
571  pwd_ = *cleaned;
572 }
573 
575 void
577 {
578  size_t pos = pwd_.rfind('/');
579  if (pos == std::string::npos)
580  setCurrentFolder("");
581  else
582  setCurrentFolder(pwd_.substr(0, pos));
583 }
584 
585 // -------------------------------------------------------------------
588 void
590 {
591  std::string prev;
592  std::string subdir;
594  prev.reserve(path.size());
595  subdir.reserve(path.size());
596  name.reserve(path.size());
597  size_t prevname = 0;
598  size_t slash = 0;
599 
600  while (true) {
601  // Create this subdirectory component.
602  subdir.clear();
603  subdir.append(path, 0, slash);
604  name.clear();
605  name.append(subdir, prevname, std::string::npos);
606  if (! prev.empty() && findObject(0, 0, 0, prev, name))
607  raiseDQMError("DQMStore", "Attempt to create subdirectory '%s'"
608  " which already exists as a monitor element",
609  subdir.c_str());
610 
611  if (! dirs_.count(subdir))
612  dirs_.insert(subdir);
613 
614  // Stop if we've reached the end (including possibly a trailing slash).
615  if (slash+1 >= path.size())
616  break;
617 
618  // Find the next slash, making sure we progress. If reach the end,
619  // process the last path component; the next loop round will terminate.
620  prevname = slash ? slash+1 : slash;
621  prev = subdir;
622  if ((slash = path.find('/', ++slash)) == std::string::npos)
623  slash = path.size();
624  }
625 }
626 
628 bool
630 {
631  return dirs_.count(path) > 0;
632 }
633 
634 // //====================================================
635 // // Global-histogram booking
636 // MonitorElement*
637 // DQMStore::bookInt(char_string const& name)
638 // {
639 // return bookInt(0, 0, pwd_, name);
640 // }
641 
642 // MonitorElement*
643 // DQMStore::bookFloat(char_string const& name)
644 // {
645 // return bookFloat(0, 0, pwd_, name);
646 // }
647 
648 // MonitorElement*
649 // DQMStore::bookString(char_string const& name,
650 // char_string const& value)
651 // {
652 // return bookString(0, 0, pwd_, name, value);
653 // }
654 
655 // MonitorElement*
656 // DQMStore::book1D(char_string const& name,
657 // char_string const& title,
658 // int const nchX, double const lowX, double const highX)
659 // {
660 // return book1D(0, 0, pwd_, name, title, nchX, lowX, highX);
661 // }
662 
663 // MonitorElement*
664 // DQMStore::book1D(char_string const& name,
665 // char_string const& title,
666 // int const nchX, float const* xbinsize)
667 // {
668 // return book1D(0, 0, pwd_, name, title, nchX, xbinsize);
669 // }
670 
671 // MonitorElement*
672 // DQMStore::book1D(char_string const& name, TH1F* h)
673 // {
674 // return book1D(0, 0, pwd_, name, h);
675 // }
676 
677 // MonitorElement*
678 // DQMStore::book1S(char_string const& name,
679 // char_string const& title,
680 // int const nchX, double const lowX, double const highX)
681 // {
682 // return book1S(0, 0, pwd_, name, title, nchX, lowX, highX);
683 // }
684 
685 // MonitorElement*
686 // DQMStore::book1S(char_string const& name,
687 // char_string const& title,
688 // int const nchX, float const* xbinsize)
689 // {
690 // return book1S(0, 0, pwd_, name, title, nchX, xbinsize);
691 // }
692 
693 // MonitorElement*
694 // DQMStore::book1S(char_string const& name, TH1S* h)
695 // {
696 // return book1S(0, 0, pwd_, name, h);
697 // }
698 
699 // MonitorElement*
700 // DQMStore::book1DD(char_string const& name,
701 // char_string const& title,
702 // int const nchX, double const lowX, double const highX)
703 // {
704 // return book1DD(0, 0, pwd_, name, title, nchX, lowX, highX);
705 // }
706 
707 // MonitorElement*
708 // DQMStore::book1DD(char_string const& name,
709 // char_string const& title,
710 // int const nchX, float const* xbinsize)
711 // {
712 // return book1DD(0, 0, pwd_, name, title, nchX, xbinsize);
713 // }
714 
715 // MonitorElement*
716 // DQMStore::book1DD(char_string const& name, TH1D* h)
717 // {
718 // return book1DD(0, 0, pwd_, name, h);
719 // }
720 
721 // MonitorElement*
722 // DQMStore::book2D(char_string const& name,
723 // char_string const& title,
724 // int const nchX, double const lowX, double const highX,
725 // int const nchY, double const lowY, double const highY)
726 // {
727 // return book2D(0, 0, pwd_, name, title, nchX, lowX, highX, nchY, lowY, highY);
728 // }
729 
730 // MonitorElement*
731 // DQMStore::book2D(char_string const& name,
732 // char_string const& title,
733 // int const nchX, float const* xbinsize,
734 // int const nchY, float const* ybinsize)
735 // {
736 // return book2D(0, 0, pwd_, name, title, nchX, xbinsize, nchY, ybinsize);
737 // }
738 
739 // MonitorElement*
740 // DQMStore::book2D(char_string const& name, TH2F* h)
741 // {
742 // return book2D(0, 0, pwd_, name, h);
743 // }
744 
745 // MonitorElement*
746 // DQMStore::book2S(char_string const& name,
747 // char_string const& title,
748 // int const nchX, double const lowX, double const highX,
749 // int const nchY, double const lowY, double const highY)
750 // {
751 // return book2S(0, 0, pwd_, name, title, nchX, lowX, highX, nchY, lowY, highY);
752 // }
753 
754 // MonitorElement*
755 // DQMStore::book2S(char_string const& name,
756 // char_string const& title,
757 // int const nchX, float const* xbinsize,
758 // int const nchY, float const* ybinsize)
759 // {
760 // return book2S(0, 0, pwd_, name, title, nchX, xbinsize, nchY, ybinsize);
761 // }
762 
763 // MonitorElement*
764 // DQMStore::book2S(char_string const& name, TH2S* h)
765 // {
766 // return book2S(0, 0, pwd_, name, h);
767 // }
768 
769 // MonitorElement*
770 // DQMStore::book2DD(char_string const& name,
771 // char_string const& title,
772 // int const nchX, double const lowX, double const highX,
773 // int const nchY, double const lowY, double const highY)
774 // {
775 // return book2DD(0, 0, pwd_, name, title, nchX, lowX, highX, nchY, lowY, highY);
776 // }
777 
778 // MonitorElement*
779 // DQMStore::book2DD(char_string const& name,
780 // char_string const& title,
781 // int const nchX, float const* xbinsize,
782 // int const nchY, float const* ybinsize)
783 // {
784 // return book2DD(0, 0, pwd_, name, title, nchX, xbinsize, nchY, ybinsize);
785 // }
786 
787 // MonitorElement*
788 // DQMStore::book2DD(char_string const& name, TH2D* h)
789 // {
790 // return book2DD(0, 0, pwd_, name, h);
791 // }
792 
793 // MonitorElement*
794 // DQMStore::book3D(char_string const& name,
795 // char_string const& title,
796 // int const nchX, double const lowX, double const highX,
797 // int const nchY, double const lowY, double const highY,
798 // int const nchZ, double const lowZ, double const highZ)
799 // {
800 // return book3D(0, 0, pwd_, name, title,
801 // nchX, lowX, highX,
802 // nchY, lowY, highY,
803 // nchZ, lowZ, highZ);
804 // }
805 
806 // MonitorElement*
807 // DQMStore::book3D(char_string const& name, TH3F* h)
808 // {
809 // return book3D(0, 0, pwd_, name, h);
810 // }
811 
812 // MonitorElement*
813 // DQMStore::bookProfile(char_string const& name,
814 // char_string const& title,
815 // int const nchX, double const lowX, double const highX,
816 // int const nchY, double const lowY, double const highY,
817 // char const* option)
818 // {
819 // return bookProfile(0, 0, pwd_, name, title, nchX, lowX, highX, nchY, lowY, highY, option);
820 // }
821 
822 // MonitorElement*
823 // DQMStore::bookProfile(char_string const& name,
824 // char_string const& title,
825 // int const nchX, double const lowX, double const highX,
826 // double const lowY, double const highY,
827 // char const* option)
828 // {
829 // return bookProfile(0, 0, pwd_, name, title, nchX, lowX, highX, lowY, highY, option);
830 // }
831 
832 // MonitorElement*
833 // DQMStore::bookProfile(char_string const& name,
834 // char_string const& title,
835 // int const nchX, double const* xbinsize,
836 // int const nchY, double const lowY, double const highY,
837 // char const* option)
838 // {
839 // return bookProfile(0, 0, pwd_, name, title, nchX, xbinsize, nchY, lowY, highY, option);
840 // }
841 
842 // MonitorElement*
843 // DQMStore::bookProfile(char_string const& name,
844 // char_string const& title,
845 // int const nchX, double const* xbinsize,
846 // double const lowY, double const highY,
847 // char const* option)
848 // {
849 // return bookProfile(0, 0, pwd_, name, title, nchX, xbinsize, lowY, highY, option);
850 // }
851 
852 // MonitorElement*
853 // DQMStore::bookProfile(char_string const& name, TProfile* h)
854 // {
855 // return bookProfile(0, 0, pwd_, name, h);
856 // }
857 
858 // MonitorElement*
859 // DQMStore::bookProfile2D(char_string const& name,
860 // char_string const& title,
861 // int const nchX, double const lowX, double const highX,
862 // int const nchY, double const lowY, double const highY,
863 // int const nchZ, double const lowZ, double const highZ,
864 // char const* option)
865 // {
866 // return bookProfile2D(0, 0, pwd_, name, title,
867 // nchX, lowX, highX,
868 // nchY, lowY, highY,
869 // nchZ, lowZ, highZ, option);
870 // }
871 
872 // MonitorElement*
873 // DQMStore::bookProfile2D(char_string const& name,
874 // char_string const& title,
875 // int const nchX, double const lowX, double const highX,
876 // int const nchY, double const lowY, double const highY,
877 // double const lowZ, double const highZ,
878 // char const* option)
879 // {
880 // return bookProfile2D(0, 0, pwd_, name, title,
881 // nchX, lowX, highX,
882 // nchY, lowY, highY,
883 // lowZ, highZ, option);
884 // }
885 
886 // MonitorElement*
887 // DQMStore::bookProfile2D(char_string const& name, TProfile2D* h)
888 // {
889 // return bookProfile2D(0, 0, pwd_, name, h);
890 // }
891 
892 
896 template <class HISTO, class COLLATE>
899  std::string const& name,
900  char const* context,
901  int const kind,
902  HISTO* h,
903  COLLATE collate)
904 {
905  assert(name.find('/') == std::string::npos);
906  if (verbose_ > 3)
907  print_trace(dir, name);
909  mergePath(path, dir, name);
910 
911  // Put us in charge of h.
912  h->SetDirectory(nullptr);
913 
914  // Check if the request monitor element already exists.
915  MonitorElement* me = findObject(run_, 0, moduleId_, dir, name);
916  if (me) {
917  if (collateHistograms_) {
918  collate(me, h, verbose_);
919  delete h;
920  return me;
921  }
922  else {
923  if (verbose_ > 1)
924  std::cout << "DQMStore: "
925  << context << ": monitor element '"
926  << path << "' already exists, collating" << std::endl;
927  me->Reset();
928  collate(me, h, verbose_);
929  delete h;
930  return me;
931  }
932  }
933  else {
934  // Create and initialise core object.
935  assert(dirs_.count(dir));
936  MonitorElement proto(&*dirs_.find(dir), name, run_, moduleId_);
937  me = const_cast<MonitorElement&>(*data_.insert(std::move(proto)).first)
939 
940  // Initialise quality test information.
941  for (auto const& q : qtestspecs_) {
942  if (q.first->match(path))
943  me->addQReport(q.second);
944  }
945 
946  // If we just booked a (plain) MonitorElement, and there is a reference
947  // MonitorElement with the same name, link the two together.
948  // The other direction is handled by the extract method.
949  std::string refdir;
950  refdir.reserve(s_referenceDirName.size() + dir.size() + 1);
951  refdir += s_referenceDirName;
952  refdir += '/';
953  refdir += dir;
954  MonitorElement* referenceME = findObject(0, 0, 0, refdir, name);
955  if (referenceME) {
956  // We have booked a new MonitorElement with a specific dir and name.
957  // Then, if we can find the corresponding MonitorElement in the reference
958  // dir we assign the object_ of the reference MonitorElement to the
959  // reference_ property of our new MonitorElement.
960  me->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
961  me->reference_ = referenceME->object_;
962  }
963 
964  // Return the monitor element.
965  return me;
966  }
967 }
968 
971  std::string const& name,
972  char const* context)
973 {
974  assert(name.find('/') == std::string::npos);
975  if (verbose_ > 3)
976  print_trace(dir, name);
977 
978  // Check if the request monitor element already exists.
979  if (MonitorElement* me = findObject(run_, 0, moduleId_, dir, name)) {
980  if (verbose_ > 1) {
982  mergePath(path, dir, name);
983 
984  std::cout << "DQMStore: "
985  << context << ": monitor element '"
986  << path << "' already exists, resetting" << std::endl;
987  }
988  me->Reset();
989  return me;
990  }
991  else {
992  // Create it and return for initialisation.
993  assert(dirs_.count(dir));
994  MonitorElement proto(&*dirs_.find(dir), name, run_, moduleId_);
995  return &const_cast<MonitorElement&>(*data_.insert(std::move(proto)).first);
996  }
997 }
998 
999 // -------------------------------------------------------------------
1003 {
1004  if (collateHistograms_) {
1005  if (MonitorElement* me = findObject(run_, 0, moduleId_, dir, name)) {
1006  me->Fill(0);
1007  return me;
1008  }
1009  }
1010  return book_(dir, name, "bookInt")->initialise(MonitorElement::DQM_KIND_INT);
1011 }
1012 
1016 {
1017  return bookInt_(pwd_, name);
1018 }
1019 
1020 // -------------------------------------------------------------------
1024 {
1025  if (collateHistograms_) {
1026  if (MonitorElement* me = findObject(run_, 0, moduleId_, dir, name)) {
1027  me->Fill(0.);
1028  return me;
1029  }
1030  }
1031  return book_(dir, name, "bookFloat")->initialise(MonitorElement::DQM_KIND_REAL);
1032 }
1033 
1037 {
1038  return bookFloat_(pwd_, name);
1039 }
1040 
1041 // -------------------------------------------------------------------
1045  std::string const& name,
1046  std::string const& value)
1047 {
1048  if (collateHistograms_) {
1049  if (MonitorElement* me = findObject(run_, 0, moduleId_, dir, name))
1050  return me;
1051  }
1052  return book_(dir, name, "bookString")->initialise(MonitorElement::DQM_KIND_STRING, value);
1053 }
1054 
1058 {
1059  return bookString_(pwd_, name, value);
1060 }
1061 
1062 // -------------------------------------------------------------------
1065 DQMStore::book1D_(std::string const& dir, std::string const& name, TH1F* h)
1066 {
1067  return book_(dir, name, "book1D", MonitorElement::DQM_KIND_TH1F, h, collate1D);
1068 }
1069 
1072 DQMStore::book1S_(std::string const& dir, std::string const& name, TH1S* h)
1073 {
1074  return book_(dir, name, "book1S", MonitorElement::DQM_KIND_TH1S, h, collate1S);
1075 }
1076 
1079 DQMStore::book1DD_(std::string const& dir, std::string const& name, TH1D* h)
1080 {
1081  return book_(dir, name, "book1DD", MonitorElement::DQM_KIND_TH1D, h, collate1DD);
1082 }
1083 
1087  int const nchX, double const lowX, double const highX)
1088 {
1089  return book1D_(pwd_, name, new TH1F(name, title, nchX, lowX, highX));
1090 }
1091 
1095  int const nchX, double const lowX, double const highX)
1096 {
1097  return book1S_(pwd_, name, new TH1S(name, title, nchX, lowX, highX));
1098 }
1099 
1103  int const nchX, double const lowX, double const highX)
1104 {
1105  return book1DD_(pwd_, name, new TH1D(name, title, nchX, lowX, highX));
1106 }
1107 
1110 DQMStore::book1D(char_string const& name, char_string const& title,
1111  int const nchX, const float* xbinsize)
1112 {
1113  return book1D_(pwd_, name, new TH1F(name, title, nchX, xbinsize));
1114 }
1115 
1119 {
1120  return book1D_(pwd_, name, static_cast<TH1F*>(source->Clone(name)));
1121 }
1122 
1126 {
1127  return book1S_(pwd_, name, static_cast<TH1S*>(source->Clone(name)));
1128 }
1129 
1133 {
1134  return book1DD_(pwd_, name, static_cast<TH1D*>(source->Clone(name)));
1135 }
1136 
1137 // -------------------------------------------------------------------
1140 DQMStore::book2D_(std::string const& dir, std::string const& name, TH2F* h)
1141 {
1142  return book_(dir, name, "book2D", MonitorElement::DQM_KIND_TH2F, h, collate2D);
1143 }
1144 
1147 DQMStore::book2S_(std::string const& dir, std::string const& name, TH2S* h)
1148 {
1149  return book_(dir, name, "book2S", MonitorElement::DQM_KIND_TH2S, h, collate2S);
1150 }
1151 
1154 DQMStore::book2DD_(std::string const& dir, std::string const& name, TH2D* h)
1155 {
1156  return book_(dir, name, "book2DD", MonitorElement::DQM_KIND_TH2D, h, collate2DD);
1157 }
1158 
1161 DQMStore::book2D(char_string const& name, char_string const& title,
1162  int const nchX, double const lowX, double const highX,
1163  int const nchY, double const lowY, double const highY)
1164 {
1165  return book2D_(pwd_, name, new TH2F(name, title,
1166  nchX, lowX, highX,
1167  nchY, lowY, highY));
1168 }
1169 
1172 DQMStore::book2S(char_string const& name, char_string const& title,
1173  int const nchX, double const lowX, double const highX,
1174  int const nchY, double const lowY, double const highY)
1175 {
1176  return book2S_(pwd_, name, new TH2S(name, title,
1177  nchX, lowX, highX,
1178  nchY, lowY, highY));
1179 }
1180 
1183 DQMStore::book2DD(char_string const& name, char_string const& title,
1184  int const nchX, double const lowX, double const highX,
1185  int const nchY, double const lowY, double const highY)
1186 {
1187  return book2DD_(pwd_, name, new TH2D(name, title,
1188  nchX, lowX, highX,
1189  nchY, lowY, highY));
1190 }
1191 
1194 DQMStore::book2D(char_string const& name, char_string const& title,
1195  int const nchX, const float* xbinsize, int const nchY, const float* ybinsize)
1196 {
1197  return book2D_(pwd_, name, new TH2F(name, title,
1198  nchX, xbinsize, nchY, ybinsize));
1199 }
1200 
1203 DQMStore::book2S(char_string const& name, char_string const& title,
1204  int const nchX, const float* xbinsize, int const nchY, const float* ybinsize)
1205 {
1206  return book2S_(pwd_, name, new TH2S(name, title,
1207  nchX, xbinsize, nchY, ybinsize));
1208 }
1209 
1213 {
1214  return book2D_(pwd_, name, static_cast<TH2F*>(source->Clone(name)));
1215 }
1216 
1220 {
1221  return book2S_(pwd_, name, static_cast<TH2S*>(source->Clone(name)));
1222 }
1223 
1227 {
1228  return book2DD_(pwd_, name, static_cast<TH2D*>(source->Clone(name)));
1229 }
1230 
1231 // -------------------------------------------------------------------
1234 DQMStore::book3D_(std::string const& dir, std::string const& name, TH3F* h)
1235 {
1236  return book_(dir, name, "book3D", MonitorElement::DQM_KIND_TH3F, h, collate3D);
1237 }
1238 
1241 DQMStore::book3D(char_string const& name, char_string const& title,
1242  int const nchX, double const lowX, double const highX,
1243  int const nchY, double const lowY, double const highY,
1244  int const nchZ, double const lowZ, double const highZ)
1245 {
1246  return book3D_(pwd_, name, new TH3F(name, title,
1247  nchX, lowX, highX,
1248  nchY, lowY, highY,
1249  nchZ, lowZ, highZ));
1250 }
1251 
1255 {
1256  return book3D_(pwd_, name, static_cast<TH3F*>(source->Clone(name)));
1257 }
1258 
1259 // -------------------------------------------------------------------
1262 DQMStore::bookProfile_(std::string const& dir, std::string const& name, TProfile* h)
1263 {
1264  return book_(dir, name, "bookProfile",
1266  h, collateProfile);
1267 }
1268 
1274  int const nchX, double const lowX, double const highX,
1275  int /* nchY */, double const lowY, double const highY,
1276  char const* option /* = "s" */)
1277 {
1278  return bookProfile_(pwd_, name, new TProfile(name, title,
1279  nchX, lowX, highX,
1280  lowY, highY,
1281  option));
1282 }
1283 
1289  int const nchX, double const lowX, double const highX,
1290  double const lowY, double const highY,
1291  char const* option /* = "s" */)
1292 {
1293  return bookProfile_(pwd_, name, new TProfile(name, title,
1294  nchX, lowX, highX,
1295  lowY, highY,
1296  option));
1297 }
1298 
1304  int const nchX, double const* xbinsize,
1305  int /* nchY */, double const lowY, double const highY,
1306  char const* option /* = "s" */)
1307 {
1308  return bookProfile_(pwd_, name, new TProfile(name, title,
1309  nchX, xbinsize,
1310  lowY, highY,
1311  option));
1312 }
1313 
1319  int const nchX, double const* xbinsize,
1320  double const lowY, double const highY,
1321  char const* option /* = "s" */)
1322 {
1323  return bookProfile_(pwd_, name, new TProfile(name, title,
1324  nchX, xbinsize,
1325  lowY, highY,
1326  option));
1327 }
1328 
1332 {
1333  return bookProfile_(pwd_, name, static_cast<TProfile*>(source->Clone(name)));
1334 }
1335 
1336 // -------------------------------------------------------------------
1339 DQMStore::bookProfile2D_(std::string const& dir, std::string const& name, TProfile2D* h)
1340 {
1341  return book_(dir, name, "bookProfile2D",
1343  h, collateProfile2D);
1344 }
1345 
1351  int const nchX, double const lowX, double const highX,
1352  int const nchY, double const lowY, double const highY,
1353  int /* nchZ */, double const lowZ, double const highZ,
1354  char const* option /* = "s" */)
1355 {
1356  return bookProfile2D_(pwd_, name, new TProfile2D(name, title,
1357  nchX, lowX, highX,
1358  nchY, lowY, highY,
1359  lowZ, highZ,
1360  option));
1361 }
1362 
1368  int const nchX, double const lowX, double const highX,
1369  int const nchY, double const lowY, double const highY,
1370  double const lowZ, double const highZ,
1371  char const* option /* = "s" */)
1372 {
1373  return bookProfile2D_(pwd_, name, new TProfile2D(name, title,
1374  nchX, lowX, highX,
1375  nchY, lowY, highY,
1376  lowZ, highZ,
1377  option));
1378 }
1379 
1382 DQMStore::bookProfile2D(char_string const& name, TProfile2D* source)
1383 {
1384  return bookProfile2D_(pwd_, name, static_cast<TProfile2D*>(source->Clone(name)));
1385 }
1386 
1390 bool
1392 {
1393  if (me->getTH1()->GetNbinsX() != h->GetNbinsX()
1394  || me->getTH1()->GetNbinsY() != h->GetNbinsY()
1395  || me->getTH1()->GetNbinsZ() != h->GetNbinsZ()
1396  || me->getTH1()->GetXaxis()->GetXmin() != h->GetXaxis()->GetXmin()
1397  || me->getTH1()->GetYaxis()->GetXmin() != h->GetYaxis()->GetXmin()
1398  || me->getTH1()->GetZaxis()->GetXmin() != h->GetZaxis()->GetXmin()
1399  || me->getTH1()->GetXaxis()->GetXmax() != h->GetXaxis()->GetXmax()
1400  || me->getTH1()->GetYaxis()->GetXmax() != h->GetYaxis()->GetXmax()
1401  || me->getTH1()->GetZaxis()->GetXmax() != h->GetZaxis()->GetXmax()
1402  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetXaxis(),(TAxis*)h->GetXaxis())
1403  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetYaxis(),(TAxis*)h->GetYaxis())
1404  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetZaxis(),(TAxis*)h->GetZaxis())) {
1405  if(verbose > 0)
1406  std::cout << "*** DQMStore: WARNING:"
1407  << "checkBinningMatches: different binning - cannot add object '"
1408  << h->GetName() << "' of type "
1409  << h->IsA()->GetName() << " to existing ME: '"
1410  << me->getFullname() << "'\n";
1411  return false;
1412  }
1413  return true;
1414 }
1415 
1416 void
1417 DQMStore::collate1D(MonitorElement* me, TH1F* h, unsigned const verbose)
1418 {
1419  if (checkBinningMatches(me,h,verbose))
1420  me->getTH1F()->Add(h);
1421 }
1422 
1423 void
1424 DQMStore::collate1S(MonitorElement* me, TH1S* h, unsigned const verbose)
1425 {
1426  if (checkBinningMatches(me,h,verbose))
1427  me->getTH1S()->Add(h);
1428 }
1429 
1430 void
1431 DQMStore::collate1DD(MonitorElement* me, TH1D* h, unsigned const verbose)
1432 {
1433  if (checkBinningMatches(me,h,verbose))
1434  me->getTH1D()->Add(h);
1435 }
1436 
1437 void
1438 DQMStore::collate2D(MonitorElement* me, TH2F* h, unsigned const verbose)
1439 {
1440  if (checkBinningMatches(me,h,verbose))
1441  me->getTH2F()->Add(h);
1442 }
1443 
1444 void
1445 DQMStore::collate2S(MonitorElement* me, TH2S* h, unsigned const verbose)
1446 {
1447  if (checkBinningMatches(me,h,verbose))
1448  me->getTH2S()->Add(h);
1449 }
1450 
1451 void
1452 DQMStore::collate2DD(MonitorElement* me, TH2D* h, unsigned const verbose)
1453 {
1454  if (checkBinningMatches(me,h,verbose))
1455  me->getTH2D()->Add(h);
1456 }
1457 
1458 void
1459 DQMStore::collate3D(MonitorElement* me, TH3F* h, unsigned const verbose)
1460 {
1461  if (checkBinningMatches(me,h,verbose))
1462  me->getTH3F()->Add(h);
1463 }
1464 
1465 void
1466 DQMStore::collateProfile(MonitorElement* me, TProfile* h, unsigned const verbose)
1467 {
1468  if (checkBinningMatches(me,h,verbose)) {
1469  TProfile* meh = me->getTProfile();
1470  me->addProfiles(h, meh, meh, 1, 1);
1471  }
1472 }
1473 
1474 void
1475 DQMStore::collateProfile2D(MonitorElement* me, TProfile2D* h, unsigned const verbose)
1476 {
1477  if (checkBinningMatches(me,h,verbose)) {
1478  TProfile2D* meh = me->getTProfile2D();
1479  me->addProfiles(h, meh, meh, 1, 1);
1480  }
1481 }
1482 
1487 void
1488 DQMStore::tag(MonitorElement* me, unsigned int const myTag)
1489 {
1490  if (! myTag)
1491  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1492  " with a zero tag", me->getFullname().c_str());
1493  if ((me->data_.flags & DQMNet::DQM_PROP_TAGGED) && myTag != me->data_.tag)
1494  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1495  " twice with multiple tags", me->getFullname().c_str());
1496 
1497  me->data_.tag = myTag;
1499 }
1500 
1502 void
1503 DQMStore::tag(std::string const& path, unsigned int const myTag)
1504 {
1505  std::string dir;
1506  std::string name;
1507  splitPath(dir, name, path);
1508 
1509  if (MonitorElement* me = findObject(0, 0, 0, dir, name))
1510  tag(me, myTag);
1511  else
1512  raiseDQMError("DQMStore", "Attempt to tag non-existent monitor element"
1513  " '%s' with tag %u", path.c_str(), myTag);
1514 
1515 }
1516 
1518 void
1519 DQMStore::tagContents(std::string const& path, unsigned int const myTag)
1520 {
1521  MonitorElement proto(&path, std::string());
1522  auto e = data_.end();
1523  auto i = data_.lower_bound(proto);
1524  for ( ; i != e && path == *i->data_.dirname; ++i)
1525  tag(const_cast<MonitorElement *>(&*i), myTag);
1526 }
1527 
1530 void
1531 DQMStore::tagAllContents(std::string const& path, unsigned int const myTag)
1532 {
1534  std::string const* cleaned = nullptr;
1535  cleanTrailingSlashes(path, clean, cleaned);
1536  MonitorElement proto(cleaned, std::string());
1537 
1538  // FIXME: WILDCARDS? Old one supported them, but nobody seemed to use them.
1539  auto e = data_.end();
1540  auto i = data_.lower_bound(proto);
1541  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname)) {
1542  tag(const_cast<MonitorElement*>(&*i), myTag);
1543  ++i;
1544  }
1545 }
1546 
1551 std::vector<std::string>
1553 {
1554  std::vector<std::string> result;
1555  auto e = dirs_.end();
1556  auto i = dirs_.find(pwd_);
1557 
1558  // If we didn't find current directory, the tree is empty, so quit.
1559  if (i == e)
1560  return result;
1561 
1562  // Skip the current directory and then start looking for immediate
1563  // subdirectories in the dirs_ list. Stop when we are no longer in
1564  // (direct or indirect) subdirectories of pwd_. Note that we don't
1565  // "know" which order the set will sort A/B, A/B/C and A/D.
1566  while (++i != e && isSubdirectory(pwd_, *i))
1567  if (i->find('/', pwd_.size()+1) == std::string::npos)
1568  result.push_back(*i);
1569 
1570  return result;
1571 }
1572 
1574 std::vector<std::string>
1576 {
1577  MonitorElement proto(&pwd_, std::string());
1578  std::vector<std::string> result;
1579  auto e = data_.end();
1580  auto i = data_.lower_bound(proto);
1581  for ( ; i != e && isSubdirectory(pwd_, *i->data_.dirname); ++i)
1582  if (pwd_ == *i->data_.dirname)
1583  result.push_back(i->getName());
1584 
1585  return result;
1586 }
1587 
1590 bool
1592 {
1593  MonitorElement proto(&path, std::string());
1594  auto e = data_.end();
1595  auto i = data_.lower_bound(proto);
1596  return (i != e && isSubdirectory(path, *i->data_.dirname));
1597 }
1598 
1601 DQMStore::get(std::string const& path) const
1602 {
1603  std::string dir;
1604  std::string name;
1605  splitPath(dir, name, path);
1606  MonitorElement proto(&dir, name);
1607  auto mepos = data_.find(proto);
1608  return (mepos == data_.end() ? nullptr
1609  : const_cast<MonitorElement *>(&*mepos));
1610 }
1611 
1613 std::vector<MonitorElement*>
1614 DQMStore::get(unsigned int const tag) const
1615 {
1616  // FIXME: Use reverse map [tag -> path] / [tag -> dir]?
1617  std::vector<MonitorElement*> result;
1618  for (auto const& me : data_) {
1619  if ((me.data_.flags & DQMNet::DQM_PROP_TAGGED) && me.data_.tag == tag)
1620  result.push_back(const_cast<MonitorElement*>(&me));
1621  }
1622  return result;
1623 }
1624 
1627 std::vector<MonitorElement*>
1629 {
1631  std::string const* cleaned = nullptr;
1632  cleanTrailingSlashes(path, clean, cleaned);
1633  MonitorElement proto(cleaned, std::string());
1634 
1635  std::vector<MonitorElement*> result;
1636  auto e = data_.end();
1637  auto i = data_.lower_bound(proto);
1638  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1639  if (*cleaned == *i->data_.dirname)
1640  result.push_back(const_cast<MonitorElement *>(&*i));
1641 
1642  return result;
1643 }
1644 
1646 std::vector<MonitorElement*>
1647 DQMStore::getContents(std::string const& path, unsigned int const tag) const
1648 {
1650  std::string const* cleaned = nullptr;
1651  cleanTrailingSlashes(path, clean, cleaned);
1652  MonitorElement proto(cleaned, std::string());
1653 
1654  std::vector<MonitorElement*> result;
1655  auto e = data_.end();
1656  auto i = data_.lower_bound(proto);
1657  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1658  if (*cleaned == *i->data_.dirname
1659  && (i->data_.flags & DQMNet::DQM_PROP_TAGGED)
1660  && i->data_.tag == tag)
1661  result.push_back(const_cast<MonitorElement *>(&*i));
1662 
1663  return result;
1664 }
1665 
1670 void
1671 DQMStore::getContents(std::vector<std::string>& into, bool const showContents /* = true */) const
1672 {
1673  into.clear();
1674  into.reserve(dirs_.size());
1675 
1676  auto me = data_.end();
1677  for (auto const& dir : dirs_)
1678  {
1679  MonitorElement proto(&dir, std::string());
1680  auto mi = data_.lower_bound(proto);
1681  auto m = mi;
1682  size_t sz = dir.size() + 2;
1683  size_t nfound = 0;
1684  for ( ; m != me && isSubdirectory(dir, *m->data_.dirname); ++m)
1685  if (dir == *m->data_.dirname)
1686  {
1687  sz += m->data_.objname.size() + 1;
1688  ++nfound;
1689  }
1690 
1691  if (! nfound)
1692  continue;
1693 
1694  auto istr
1695  = into.insert(into.end(), std::string());
1696 
1697  if (showContents)
1698  {
1699  istr->reserve(sz);
1700 
1701  *istr += dir;
1702  *istr += ':';
1703  for (sz = 0; mi != m; ++mi)
1704  {
1705  if (dir != *mi->data_.dirname)
1706  continue;
1707 
1708  if (sz > 0)
1709  *istr += ',';
1710 
1711  *istr += mi->data_.objname;
1712  ++sz;
1713  }
1714  }
1715  else
1716  {
1717  istr->reserve(dir.size() + 2);
1718  *istr += dir;
1719  *istr += ':';
1720  }
1721  }
1722 }
1723 
1727 DQMStore::findObject(uint32_t const run,
1728  uint32_t const lumi,
1729  uint32_t const moduleId,
1730  std::string const& dir,
1731  std::string const& name) const
1732 {
1733  if (dir.find_first_not_of(s_safe) != std::string::npos)
1734  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1735  " unacceptable characters", dir.c_str());
1736  if (name.find_first_not_of(s_safe) != std::string::npos)
1737  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1738  " unacceptable characters", name.c_str());
1739 
1740  MonitorElement proto;
1741  proto.data_.dirname = &dir;
1742  proto.data_.objname = name;
1743  proto.data_.run = run;
1744  proto.data_.lumi = lumi;
1745  proto.data_.moduleId = moduleId;
1746 
1747  auto mepos = data_.find(proto);
1748  return (mepos == data_.end() ? nullptr
1749  : const_cast<MonitorElement *>(&*mepos));
1750 }
1751 
1754 std::vector<MonitorElement*>
1756  uint32_t const run /* = 0 */,
1757  uint32_t const lumi /* = 0 */) const
1758 {
1760  std::string const* cleaned = nullptr;
1761  cleanTrailingSlashes(path, clean, cleaned);
1762  MonitorElement proto(cleaned, std::string(), run, 0);
1763  proto.setLumi(lumi);
1764 
1765  std::vector<MonitorElement*> result;
1766  auto e = data_.end();
1767  auto i = data_.lower_bound(proto);
1768  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
1769  if (run != 0) {
1770  if (i->data_.run > run // TODO[rovere]: pleonastic? first we encounter local ME of the same run ...
1771  || i->data_.moduleId != 0)
1772  break;
1773  }
1774  if (lumi != 0) {
1775  if (i->data_.lumi > lumi
1776  || i->data_.moduleId != 0)
1777  break;
1778  }
1779  if (run != 0 or lumi !=0) {
1780  assert(i->data_.moduleId == 0);
1781  }
1782  result.push_back(const_cast<MonitorElement*>(&*i));
1783  }
1784 
1785  if (enableMultiThread_) {
1786  //save legacy modules when running MT
1787  i = data_.begin();
1788  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
1789  if (i->data_.run != 0 or i->data_.moduleId != 0)
1790  break;
1791  result.push_back(const_cast<MonitorElement*>(&*i));
1792  }
1793  }
1794 
1795  return result;
1796 }
1797 
1800 std::vector<MonitorElement*>
1801 DQMStore::getMatchingContents(std::string const& pattern, lat::Regexp::Syntax const syntaxType /* = Wildcard */) const
1802 {
1803  lat::Regexp rx;
1804  try {
1805  rx = lat::Regexp(pattern, 0, syntaxType);
1806  rx.study();
1807  }
1808  catch (lat::Error& e) {
1809  raiseDQMError("DQMStore", "Invalid regular expression '%s': %s",
1810  pattern.c_str(), e.explain().c_str());
1811  }
1812 
1813  std::string path;
1814  std::vector<MonitorElement *> result;
1815  for (auto const& me : data_) {
1816  path.clear();
1817  mergePath(path, *me.data_.dirname, me.data_.objname);
1818  if (rx.match(path))
1819  result.push_back(const_cast<MonitorElement*>(&me));
1820  }
1821 
1822  return result;
1823 }
1824 
1828 
1831 void
1833 {
1834  for (auto const& m : data_) {
1835  auto& me = const_cast<MonitorElement&>(m);
1836  if (me.wasUpdated()) {
1837  if (me.resetMe())
1838  me.Reset();
1839  me.resetUpdate();
1840  }
1841  }
1842 
1843  reset_ = true;
1844 }
1845 
1849 
1851 void
1853 {
1854  for (auto const& m : data_) {
1855  if (forceResetOnBeginLumi_ && (m.getLumiFlag() == false))
1856  continue;
1857  auto& me = const_cast<MonitorElement&>(m);
1858  me.Reset();
1859  me.resetUpdate();
1860  }
1861 
1862  reset_ = true;
1863 }
1864 
1865 
1869 
1873 void
1875 {
1876  static const std::string null_str("");
1877 
1878  auto const& lumiblock = gc.luminosityBlockID();
1879  uint32_t run = lumiblock.run();
1880 
1881  // find the range of non-legacy global MEs for the current run:
1882  // run != 0, lumi == 0 (implicit), stream id == 0, module id == 0
1883  const MonitorElement begin(&null_str, null_str, run, 0);
1884  const MonitorElement end(&null_str, null_str, run, 1);
1885  auto i = data_.lower_bound(begin);
1886  const auto e = data_.lower_bound(end);
1887  while (i != e) {
1888  auto& me = const_cast<MonitorElement&>(*i++);
1889  // skip per-run MEs
1890  if (not LSbasedMode_ and not me.getLumiFlag())
1891  continue;
1892  me.Reset();
1893  me.resetUpdate();
1894  }
1895 }
1896 
1900 
1907 void
1908 DQMStore::cloneLumiHistograms(uint32_t const run, uint32_t const lumi, uint32_t const moduleId)
1909 {
1910  if (verbose_ > 1) {
1911  std::cout << "DQMStore::cloneLumiHistograms - Preparing lumi histograms for run: "
1912  << run << ", lumi: " << lumi << ", module: " << moduleId << std::endl;
1913  }
1914 
1915  // acquire the global lock since this accesses the undelying data structure
1916  std::lock_guard<std::mutex> guard(book_mutex_);
1917 
1918  // MEs are sorted by (run, lumi, stream id, module id, directory, name)
1919  // lumi deafults to 0
1920  // stream id is always 0
1921  std::string null_str("");
1922  auto i = data_.lower_bound(MonitorElement(&null_str, null_str, run, moduleId));
1923  auto e = data_.lower_bound(MonitorElement(&null_str, null_str, run, moduleId + 1));
1924  for (; i != e; ++i) {
1925  // handle only lumisection-based histograms
1926  if (not LSbasedMode_ and not i->getLumiFlag())
1927  continue;
1928 
1929  // clone the lumisection-based histograms
1931  clone.globalize();
1932  clone.setLumi(lumi);
1933  clone.markToDelete();
1934  data_.insert(std::move(clone));
1935 
1936  // reset the ME for the next lumisection
1937  const_cast<MonitorElement*>(&*i)->Reset();
1938  }
1939 }
1940 
1944 void
1945 DQMStore::cloneRunHistograms(uint32_t const run, uint32_t const moduleId)
1946 {
1947  if (verbose_ > 1) {
1948  std::cout << "DQMStore::cloneRunHistograms - Preparing run histograms for run: "
1949  << run << ", module: " << moduleId << std::endl;
1950  }
1951 
1952  // acquire the global lock since this accesses the undelying data structure
1953  std::lock_guard<std::mutex> guard(book_mutex_);
1954 
1955  // MEs are sorted by (run, lumi, stream id, module id, directory, name)
1956  // lumi deafults to 0
1957  // stream id is always 0
1958  std::string null_str("");
1959  auto i = data_.lower_bound(MonitorElement(&null_str, null_str, run, moduleId));
1960  auto e = data_.lower_bound(MonitorElement(&null_str, null_str, run, moduleId + 1));
1961  for (; i != e; ++i) {
1962  // handle only non lumisection-based histograms
1963  if (LSbasedMode_ or i->getLumiFlag())
1964  continue;
1965 
1966  // clone the lumisection-based histograms
1968  clone.globalize();
1969  clone.markToDelete();
1970  data_.insert(std::move(clone));
1971 
1972  // reset the ME for the next lumisection
1973  const_cast<MonitorElement*>(&*i)->Reset();
1974  }
1975 }
1976 
1977 
1982 void
1983 DQMStore::deleteUnusedLumiHistograms(uint32_t const run, uint32_t const lumi)
1984 {
1985  if (!enableMultiThread_)
1986  return;
1987 
1988  std::lock_guard<std::mutex> guard(book_mutex_);
1989 
1990  std::string null_str("");
1991  MonitorElement proto(&null_str, null_str, run, 0);
1992  proto.setLumi(lumi);
1993 
1994  auto e = data_.end();
1995  auto i = data_.lower_bound(proto);
1996 
1997  while (i != e) {
1998  if (i->data_.moduleId != 0)
1999  break;
2000  if (i->data_.lumi != lumi)
2001  break;
2002  if (i->data_.run != run)
2003  break;
2004  if (not i->markedToDelete()) {
2005  ++i;
2006  continue;
2007  }
2008 
2009  if (verbose_ > 1) {
2010  std::cout << "DQMStore::deleteUnusedLumiHistograms: deleted monitor element '"
2011  << *i->data_.dirname << "/" << i->data_.objname << "'"
2012  << "flags " << i->data_.flags << "\n";
2013  }
2014 
2015  i = data_.erase(i);
2016  }
2017 }
2018 
2024 bool
2026  std::string const& dir,
2027  bool const overwrite,
2028  bool const collateHistograms)
2029 {
2030  // NB: Profile histograms inherit from TH*D, checking order matters.
2031  MonitorElement *refcheck = nullptr;
2032  if (auto* h = dynamic_cast<TProfile*>(obj)) {
2033  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2034  if (! me)
2035  me = bookProfile_(dir, h->GetName(), (TProfile*) h->Clone());
2036  else if (overwrite)
2037  me->copyFrom(h);
2038  else if (isCollateME(me) || collateHistograms)
2039  collateProfile(me, h, verbose_);
2040  refcheck = me;
2041  }
2042  else if (auto* h = dynamic_cast<TProfile2D*>(obj)) {
2043  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2044  if (! me)
2045  me = bookProfile2D_(dir, h->GetName(), (TProfile2D*) h->Clone());
2046  else if (overwrite)
2047  me->copyFrom(h);
2048  else if (isCollateME(me) || collateHistograms)
2049  collateProfile2D(me, h, verbose_);
2050  refcheck = me;
2051  }
2052  else if (auto* h = dynamic_cast<TH1F*>(obj)) {
2053  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2054  if (! me)
2055  me = book1D_(dir, h->GetName(), (TH1F*) h->Clone());
2056  else if (overwrite)
2057  me->copyFrom(h);
2058  else if (isCollateME(me) || collateHistograms)
2059  collate1D(me, h, verbose_);
2060  refcheck = me;
2061  }
2062  else if (auto* h = dynamic_cast<TH1S*>(obj)) {
2063  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2064  if (! me)
2065  me = book1S_(dir, h->GetName(), (TH1S*) h->Clone());
2066  else if (overwrite)
2067  me->copyFrom(h);
2068  else if (isCollateME(me) || collateHistograms)
2069  collate1S(me, h, verbose_);
2070  refcheck = me;
2071  }
2072  else if (auto* h = dynamic_cast<TH1D*>(obj)) {
2073  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2074  if (! me)
2075  me = book1DD_(dir, h->GetName(), (TH1D*) h->Clone());
2076  else if (overwrite)
2077  me->copyFrom(h);
2078  else if (isCollateME(me) || collateHistograms)
2079  collate1DD(me, h, verbose_);
2080  refcheck = me;
2081  }
2082  else if (auto* h = dynamic_cast<TH2F*>(obj)) {
2083  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2084  if (! me)
2085  me = book2D_(dir, h->GetName(), (TH2F*) h->Clone());
2086  else if (overwrite)
2087  me->copyFrom(h);
2088  else if (isCollateME(me) || collateHistograms)
2089  collate2D(me, h, verbose_);
2090  refcheck = me;
2091  }
2092  else if (auto* h = dynamic_cast<TH2S*>(obj)) {
2093  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2094  if (! me)
2095  me = book2S_(dir, h->GetName(), (TH2S*) h->Clone());
2096  else if (overwrite)
2097  me->copyFrom(h);
2098  else if (isCollateME(me) || collateHistograms)
2099  collate2S(me, h, verbose_);
2100  refcheck = me;
2101  }
2102  else if (auto* h = dynamic_cast<TH2D*>(obj)) {
2103  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2104  if (! me)
2105  me = book2DD_(dir, h->GetName(), (TH2D*) h->Clone());
2106  else if (overwrite)
2107  me->copyFrom(h);
2108  else if (isCollateME(me) || collateHistograms)
2109  collate2DD(me, h, verbose_);
2110  refcheck = me;
2111  }
2112  else if (auto* h = dynamic_cast<TH3F*>(obj)) {
2113  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2114  if (! me)
2115  me = book3D_(dir, h->GetName(), (TH3F*) h->Clone());
2116  else if (overwrite)
2117  me->copyFrom(h);
2118  else if (isCollateME(me) || collateHistograms)
2119  collate3D(me, h, verbose_);
2120  refcheck = me;
2121  }
2122  else if (dynamic_cast<TObjString*>(obj)) {
2123  lat::RegexpMatch m;
2124  if (! s_rxmeval.match(obj->GetName(), 0, 0, &m)) {
2125  if (strstr(obj->GetName(), "CMSSW")) {
2126  if (verbose_)
2127  std::cout << "Input file version: " << obj->GetName() << std::endl;
2128  return true;
2129  }
2130  else if (strstr(obj->GetName(), "DQMPATCH")) {
2131  if (verbose_)
2132  std::cout << "DQM patch version: " << obj->GetName() << std::endl;
2133  return true;
2134  }
2135  else {
2136  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2137  << obj->GetName() << "' of type '"
2138  << obj->IsA()->GetName() << "'\n";
2139  return false;
2140  }
2141  }
2142 
2143  std::string label = m.matchString(obj->GetName(), 1);
2144  std::string kind = m.matchString(obj->GetName(), 2);
2145  std::string value = m.matchString(obj->GetName(), 3);
2146 
2147  if (kind == "i") {
2148  MonitorElement* me = findObject(0, 0, 0, dir, label);
2149  if (! me || overwrite) {
2150  if (! me) me = bookInt_(dir, label);
2151  me->Fill(atoll(value.c_str()));
2152  }
2153  }
2154  else if (kind == "f") {
2155  MonitorElement* me = findObject(0, 0, 0, dir, label);
2156  if (! me || overwrite) {
2157  if (! me) me = bookFloat_(dir, label);
2158  me->Fill(atof(value.c_str()));
2159  }
2160  }
2161  else if (kind == "s") {
2162  MonitorElement* me = findObject(0, 0, 0, dir, label);
2163  if (! me)
2164  me = bookString_(dir, label, value);
2165  else if (overwrite)
2166  me->Fill(value);
2167  }
2168  else if (kind == "e") {
2169  MonitorElement* me = findObject(0, 0, 0, dir, label);
2170  if (! me) {
2171  std::cout << "*** DQMStore: WARNING: no monitor element '"
2172  << label << "' in directory '"
2173  << dir << "' to be marked as efficiency plot.\n";
2174  return false;
2175  }
2176  me->setEfficiencyFlag();
2177  }
2178  else if (kind == "t") {
2179  MonitorElement* me = findObject(0, 0, 0, dir, label);
2180  if (! me) {
2181  std::cout << "*** DQMStore: WARNING: no monitor element '"
2182  << label << "' in directory '"
2183  << dir << "' for a tag\n";
2184  return false;
2185  }
2186  errno = 0;
2187  char* endp = nullptr;
2188  unsigned long val = strtoul(value.c_str(), &endp, 10);
2189  if ((val == 0 && errno) || *endp || val > ~uint32_t(0)) {
2190  std::cout << "*** DQMStore: WARNING: cannot restore tag '"
2191  << value << "' for monitor element '"
2192  << label << "' in directory '"
2193  << dir << "' - invalid value\n";
2194  return false;
2195  }
2196  tag(me, val);
2197  }
2198  else if (kind == "qr") {
2199  // Handle qreports, but skip them while reading in references.
2200  if (! isSubdirectory(s_referenceDirName, dir)) {
2201  size_t dot = label.find('.');
2202  if (dot == std::string::npos) {
2203  std::cout << "*** DQMStore: WARNING: quality report label in '" << label
2204  << "' is missing a '.' and cannot be extracted\n";
2205  return false;
2206  }
2207 
2208  std::string mename (label, 0, dot);
2209  std::string qrname (label, dot+1, std::string::npos);
2210 
2211  m.reset();
2212  DQMNet::QValue qv;
2213  if (s_rxmeqr1.match(value, 0, 0, &m)) {
2214  qv.code = atoi(m.matchString(value, 1).c_str());
2215  qv.qtresult = strtod(m.matchString(value, 2).c_str(), nullptr);
2216  qv.message = m.matchString(value, 4);
2217  qv.qtname = qrname;
2218  qv.algorithm = m.matchString(value, 3);
2219  }
2220  else if (s_rxmeqr2.match(value, 0, 0, &m)) {
2221  qv.code = atoi(m.matchString(value, 1).c_str());
2222  qv.qtresult = 0; // unavailable in old format
2223  qv.message = m.matchString(value, 2);
2224  qv.qtname = qrname;
2225  // qv.algorithm unavailable in old format
2226  }
2227  else {
2228  std::cout << "*** DQMStore: WARNING: quality test value '"
2229  << value << "' is incorrectly formatted\n";
2230  return false;
2231  }
2232 
2233  MonitorElement* me = findObject(0, 0, 0, dir, mename);
2234  if (! me) {
2235  std::cout << "*** DQMStore: WARNING: no monitor element '"
2236  << mename << "' in directory '"
2237  << dir << "' for quality test '"
2238  << label << "'\n";
2239  return false;
2240  }
2241 
2242  me->addQReport(qv, /* FIXME: getQTest(qv.qtname)? */ nullptr);
2243  }
2244  }
2245  else {
2246  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2247  << obj->GetName() << "' of type '"
2248  << obj->IsA()->GetName() << "'\n";
2249  return false;
2250  }
2251  }
2252  else if (auto* n = dynamic_cast<TNamed*>(obj)) {
2253  // For old DQM data.
2254  std::string s;
2255  s.reserve(6 + strlen(n->GetTitle()) + 2*strlen(n->GetName()));
2256  s += '<'; s += n->GetName(); s += '>';
2257  s += n->GetTitle();
2258  s += '<'; s += '/'; s += n->GetName(); s += '>';
2259  TObjString os(s.c_str());
2260  return extract(&os, dir, overwrite, collateHistograms_);
2261  }
2262  else {
2263  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2264  << obj->GetName() << "' of type '" << obj->IsA()->GetName()
2265  << "' and with title '" << obj->GetTitle() << "'\n";
2266  return false;
2267  }
2268 
2269  // If we just read in a reference MonitorElement, and there is a
2270  // MonitorElement with the same name, link the two together.
2271  // The other direction is handled by the book() method.
2272  if (refcheck && isSubdirectory(s_referenceDirName, dir)) {
2273  std::string mdir(dir, s_referenceDirName.size()+1, std::string::npos);
2274  if (MonitorElement* master = findObject(0, 0, 0, mdir, obj->GetName())) {
2275  // We have extracted a MonitorElement, and it's located in the reference
2276  // dir. Then we find the corresponding MonitorElement in the
2277  // non-reference dir and assign the object_ of the reference
2278  // MonitorElement to the reference_ property of the corresponding
2279  // non-reference MonitorElement.
2280  master->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
2281  master->reference_ = refcheck->object_;
2282  }
2283  }
2284 
2285  return true;
2286 }
2287 
2291 bool
2292 DQMStore::cdInto(std::string const& path) const
2293 {
2294  assert(! path.empty());
2295 
2296  // Find the first path component.
2297  size_t start = 0;
2298  size_t end = path.find('/', start);
2299  if (end == std::string::npos)
2300  end = path.size();
2301 
2302  while (true) {
2303  // Check if this subdirectory component exists. If yes, make sure
2304  // it is actually a subdirectory. Otherwise create or cd into it.
2305  std::string part(path, start, end-start);
2306  TObject* o = gDirectory->Get(part.c_str());
2307  if (o && ! dynamic_cast<TDirectory*>(o))
2308  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2309  " fails because the part '%s' already exists and is not"
2310  " directory", path.c_str(), part.c_str());
2311  else if (! o)
2312  gDirectory->mkdir(part.c_str());
2313 
2314  if (! gDirectory->cd(part.c_str()))
2315  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2316  " fails because could not cd into subdirectory '%s'",
2317  path.c_str(), part.c_str());
2318 
2319  // Stop if we reached the end, ignoring any trailing '/'.
2320  if (end+1 >= path.size())
2321  break;
2322 
2323  // Find the next path component.
2324  start = end+1;
2325  end = path.find('/', start);
2326  if (end == std::string::npos)
2327  end = path.size();
2328  }
2329 
2330  return true;
2331 }
2332 
2333 void
2335  TFile& file)
2336 {
2337  // Save the object.
2338  if (me.kind() < MonitorElement::DQM_KIND_TH1F) {
2339  TObjString(me.tagString().c_str()).Write();
2340  } else {
2341  me.object_->Write();
2342  }
2343 
2344  // Save quality reports if this is not in reference section.
2345  if (not isSubdirectory(s_referenceDirName, *me.data_.dirname)) {
2346  for (auto const& report: me.data_.qreports) {
2347  TObjString(me.qualityTagString(report).c_str()).Write();
2348  }
2349  }
2350 
2351  // Save efficiency tag, if any.
2353  TObjString(me.effLabelString().c_str()).Write();
2354  }
2355 
2356  // Save tag if any.
2357  if (me.data_.flags & DQMNet::DQM_PROP_TAGGED) {
2358  TObjString(me.tagLabelString().c_str()).Write();
2359  }
2360 }
2361 
2362 void
2364  std::string const& refpath,
2365  SaveReferenceTag const ref,
2366  int const minStatus,
2367  unsigned int const run,
2368  MEMap::const_iterator const begin,
2369  MEMap::const_iterator const end,
2370  TFile& file,
2371  unsigned int& counter)
2372 {
2373  for (auto const& me: boost::make_iterator_range(begin, end)) {
2374  if (not isSubdirectory(dir, *me.data_.dirname))
2375  break;
2376 
2377  if (verbose_ > 1)
2378  std::cout << "DQMStore::save:"
2379  << " run: " << me.run()
2380  << " lumi: " << me.lumi()
2381  << " lumiFlag: " << me.getLumiFlag()
2382  << " moduleId: " << me.moduleId()
2383  << " fullpathname: " << me.getFullname()
2384  << " flags: " << std::hex << me.data_.flags
2385  << std::endl;
2386 
2387  // Skip MonitorElements in a subdirectory of the current one.
2388  if (dir != *me.data_.dirname) {
2389  if (verbose_ > 1) {
2390  std::cout << "DQMStore::save: skipping monitor element in a subfolder of " << dir << "/" << std::endl;
2391  }
2392  continue;
2393  }
2394 
2395  // Handle reference histograms, with three distinct cases:
2396  // 1) Skip all references entirely on saving.
2397  // 2) Blanket saving of all references.
2398  // 3) Save only references for monitor elements with qtests.
2399  // The latter two are affected by "path" sub-tree selection,
2400  // i.e. references are saved only in the selected tree part.
2401  if (isSubdirectory(refpath, *me.data_.dirname)) {
2402  if (ref == SaveWithoutReference)
2403  // Skip the reference entirely.
2404  continue;
2405  else if (ref == SaveWithReference)
2406  // Save all references regardless of qtests.
2407  ;
2408  else if (ref == SaveWithReferenceForQTest) {
2409  // Save only references for monitor elements with qtests
2410  // with an optional cut on minimum quality test result.
2411  int status = -1;
2412  std::string mname(me.getFullname(), s_referenceDirName.size()+1, std::string::npos);
2413  MonitorElement* master = get(mname);
2414  if (master)
2415  for (auto const& qreport : master->data_.qreports)
2416  status = std::max(status, qreport.code);
2417 
2418  if (not master or status < minStatus) {
2419  if (verbose_ > 1)
2420  std::cout << "DQMStore::save: skipping monitor element '"
2421  << me.data_.objname << "' while saving, status is "
2422  << status << ", required minimum status is "
2423  << minStatus << std::endl;
2424  continue;
2425  }
2426  }
2427  }
2428 
2429  if (verbose_ > 1) {
2430  std::cout << "DQMStore::save: saving monitor element" << std::endl;
2431  }
2432 
2433  saveMonitorElementToROOT(me, file);
2434 
2435  // Count saved histograms
2436  ++counter;
2437  }
2438 }
2439 
2442 void
2444  std::string const& path /* = "" */,
2445  std::string const& pattern /* = "" */,
2446  std::string const& rewrite /* = "" */,
2447  uint32_t const run /* = 0 */,
2448  uint32_t const lumi /* = 0 */,
2449  SaveReferenceTag const ref /* = SaveWithReference */,
2450  int const minStatus /* = dqm::qstatus::STATUS_OK */,
2451  std::string const& fileupdate /* = RECREATE */)
2452 {
2453  // TFile flushes to disk with fsync() on every TDirectory written to
2454  // the file. This makes DQM file saving painfully slow, and
2455  // ironically makes it _more_ likely the file saving gets
2456  // interrupted and corrupts the file. The utility class below
2457  // simply ignores the flush synchronisation.
2458  class TFileNoSync : public TFile {
2459  public:
2460  TFileNoSync(char const* file, char const* opt) : TFile{file, opt} {}
2461  Int_t SysSync(Int_t) override { return 0; }
2462  };
2463 
2464  std::lock_guard<std::mutex> guard(book_mutex_);
2465 
2466  unsigned int nme = 0;
2467 
2468  // open output file, on 1st save recreate, later update
2469  if (verbose_) {
2470  std::cout << "DQMStore::save: Opening TFile '" << filename
2471  << "' with option '" << fileupdate << "'"
2472  << std::endl;
2473  }
2474 
2475  TFileNoSync f(filename.c_str(), fileupdate.c_str()); // open file
2476  if(f.IsZombie())
2477  raiseDQMError("DQMStore", "Failed to create/update file '%s'", filename.c_str());
2478  f.cd();
2479 
2480  // Construct a regular expression from the pattern string.
2481  std::unique_ptr<lat::Regexp> rxpat;
2482  if (not pattern.empty())
2483  rxpat = std::make_unique<lat::Regexp>(pattern);
2484 
2485  // Prepare a path for the reference object selection.
2486  std::string refpath;
2487  refpath.reserve(s_referenceDirName.size() + path.size() + 2);
2488  refpath += s_referenceDirName;
2489  if (not path.empty()) {
2490  refpath += '/';
2491  refpath += path;
2492  }
2493 
2494  // Loop over the directory structure.
2495  for (auto const& dir: dirs_) {
2496  // Check if we should process this directory. We process the
2497  // requested part of the object tree, including references.
2498  if (not path.empty()
2499  and not isSubdirectory(refpath, dir)
2500  and not isSubdirectory(path, dir))
2501  continue;
2502 
2503  if (verbose_ > 1) {
2504  std::cout << "DQMStore::save: DQM folder " << dir << "/" << std::endl;
2505  }
2506 
2507  // Create the directory.
2508  gDirectory->cd("/");
2509  if (dir.empty())
2510  cdInto(s_monitorDirName);
2511  else if (rxpat.get())
2512  cdInto(s_monitorDirName + '/' + lat::StringOps::replace(dir, *rxpat, rewrite));
2513  else
2514  cdInto(s_monitorDirName + '/' + dir);
2515 
2516  // Loop over monitor elements in this directory.
2517  if (not enableMultiThread_) {
2518  MonitorElement proto(&dir, std::string(), run, 0);
2519  auto begin = data_.lower_bound(proto);
2520  auto end = data_.end();
2521  saveMonitorElementRangeToROOT(dir, refpath, ref, minStatus, run, begin, end, f, nme);
2522  } else {
2523  // Restrict the loop to the monitor elements for the current lumisection
2524  MonitorElement proto(&dir, std::string(), run, 0);
2525  proto.setLumi(lumi);
2526  auto begin = data_.lower_bound(proto);
2527  proto.setLumi(lumi+1);
2528  auto end = data_.lower_bound(proto);
2529  saveMonitorElementRangeToROOT(dir, refpath, ref, minStatus, run, begin, end, f, nme);
2530  }
2531 
2532  // In LSbasedMode, loop also over the (run, 0) global histograms;
2533  // these could be the merged global histrograms of their per-stream
2534  // counterparts after the streamEndRun transition - but they are not
2535  // produced in LSbasedMode.
2536  if (enableMultiThread_ and LSbasedMode_ and lumi != 0) {
2537  auto begin = data_.lower_bound(MonitorElement(&dir, std::string(), run, 0));
2538  auto end = data_.lower_bound(MonitorElement(&dir, std::string(), run, 1));
2539  saveMonitorElementRangeToROOT(dir, refpath, ref, minStatus, run, begin, end, f, nme);
2540  }
2541  }
2542 
2543  f.Close();
2544 
2545  // Maybe make some noise.
2546  if (verbose_) {
2547  std::cout << "DQMStore::save: successfully wrote " << nme
2548  << " objects from path '" << path << "/"
2549  << "' into DQM file '" << filename << "'\n";
2550  }
2551 }
2552 
2553 void
2556 {
2557  // Save the object.
2558  TBufferFile buffer(TBufferFile::kWrite);
2559  if (me.kind() < MonitorElement::DQM_KIND_TH1F) {
2560  TObjString object(me.tagString().c_str());
2561  buffer.WriteObject(&object);
2562  } else {
2563  buffer.WriteObject(me.object_);
2564  }
2566  histo.set_full_pathname(*me.data_.dirname + '/' + me.data_.objname);
2567  histo.set_flags(me.data_.flags);
2568  histo.set_size(buffer.Length());
2569  histo.set_streamed_histo((void const*)buffer.Buffer(), buffer.Length());
2570 
2571  // Save quality reports if this is not in reference section.
2572  // XXX not supported by protobuf files.
2573 
2574  // Save efficiency tag, if any.
2575  // XXX not supported by protobuf files.
2576 
2577  // Save tag if any.
2578  // XXX not supported by protobuf files.
2579 }
2580 
2581 void
2583  unsigned int const run,
2584  MEMap::const_iterator const begin,
2585  MEMap::const_iterator const end,
2587  unsigned int& counter)
2588 {
2589  for (auto const& me: boost::make_iterator_range(begin, end)) {
2590  if (not isSubdirectory(dir, *me.data_.dirname))
2591  break;
2592 
2593  if (verbose_ > 1)
2594  std::cout << "DQMStore::savePB:"
2595  << " run: " << me.run()
2596  << " lumi: " << me.lumi()
2597  << " lumiFlag: " << me.getLumiFlag()
2598  << " moduleId: " << me.moduleId()
2599  << " fullpathname: " << me.getFullname()
2600  << " flags: " << std::hex << me.data_.flags
2601  << std::endl;
2602 
2603  // Skip MonitorElements in a subdirectory of the current one.
2604  if (dir != *me.data_.dirname) {
2605  if (verbose_ > 1) {
2606  std::cout << "DQMStore::savePB: skipping monitor element in a subfolder of " << dir << "/" << std::endl;
2607  }
2608  continue;
2609  }
2610 
2611  // Handle reference histograms, with three distinct cases:
2612  // XXX not supported by protobuf files.
2613 
2614  if (verbose_ > 1) {
2615  std::cout << "DQMStore::savePB: saving monitor element" << std::endl;
2616  }
2617 
2618  saveMonitorElementToPB(me, file);
2619 
2620  // Count saved histograms
2621  ++counter;
2622  }
2623 }
2624 
2627 void
2629  std::string const& path /* = "" */,
2630  uint32_t const run /* = 0 */,
2631  uint32_t const lumi /* = 0 */)
2632 {
2633  using google::protobuf::io::FileOutputStream;
2634  using google::protobuf::io::GzipOutputStream;
2635  using google::protobuf::io::StringOutputStream;
2636 
2637  std::lock_guard<std::mutex> guard(book_mutex_);
2638 
2639  unsigned int nme = 0;
2640 
2641  if (verbose_) {
2642  std::cout << "DQMStore::savePB: Opening PBFile '" << filename << "'"
2643  << std::endl;
2644  }
2645  dqmstorepb::ROOTFilePB dqmstore_message;
2646 
2647  // Loop over the directory structure.
2648  for (auto const& dir: dirs_) {
2649  // Check if we should process this directory. We process the
2650  // requested part of the object tree, including references.
2651  if (not path.empty()
2652  and not isSubdirectory(path, dir))
2653  continue;
2654 
2655  if (verbose_ > 1) {
2656  std::cout << "DQMStore::savePB: DQM folder " << dir << "/" << std::endl;
2657  }
2658 
2659  // Loop over monitor elements in this directory.
2660  if (not enableMultiThread_) {
2661  MonitorElement proto(&dir, std::string(), run, 0);
2662  auto begin = data_.lower_bound(proto);
2663  auto end = data_.end();
2664  saveMonitorElementRangeToPB(dir, run, begin, end, dqmstore_message, nme);
2665  } else {
2666  // Restrict the loop to the monitor elements for the current lumisection
2667  MonitorElement proto(&dir, std::string(), run, 0);
2668  proto.setLumi(lumi);
2669  auto begin = data_.lower_bound(proto);
2670  proto.setLumi(lumi+1);
2671  auto end = data_.lower_bound(proto);
2672  saveMonitorElementRangeToPB(dir, run, begin, end, dqmstore_message, nme);
2673  }
2674 
2675  // In LSbasedMode, loop also over the (run, 0) global histograms;
2676  // these could be the merged global histrograms of their per-stream
2677  // counterparts after the streamEndRun transition - but they are not
2678  // produced in LSbasedMode.
2679  if (enableMultiThread_ and LSbasedMode_ and lumi != 0) {
2680  auto begin = data_.lower_bound(MonitorElement(&dir, std::string(), run, 0));
2681  auto end = data_.lower_bound(MonitorElement(&dir, std::string(), run, 1));
2682  saveMonitorElementRangeToPB(dir, run, begin, end, dqmstore_message, nme);
2683  }
2684  }
2685 
2686  int filedescriptor = ::open(filename.c_str(),
2687  O_WRONLY | O_CREAT | O_TRUNC,
2688  S_IRUSR | S_IWUSR |
2689  S_IRGRP | S_IWGRP |
2690  S_IROTH);
2691  FileOutputStream file_stream(filedescriptor);
2693  options.format = GzipOutputStream::GZIP;
2694  options.compression_level = 1;
2695  GzipOutputStream gzip_stream(&file_stream, options);
2696  dqmstore_message.SerializeToZeroCopyStream(&gzip_stream);
2697 
2698  // Flush the internal streams before closing the fd.
2699  gzip_stream.Close();
2700  file_stream.Close();
2701  ::close(filedescriptor);
2702 
2703  // Maybe make some noise.
2704  if (verbose_) {
2705  std::cout << "DQMStore::savePB: successfully wrote " << nme
2706  << " objects from path '" << path << "/"
2707  << "' into DQM file '" << filename << "'\n";
2708  }
2709 }
2710 
2711 
2714 unsigned int
2716  bool const overwrite,
2717  std::string const& onlypath,
2718  std::string const& prepend,
2719  std::string const& curdir,
2720  OpenRunDirs const stripdirs)
2721 {
2722  unsigned int ntot = 0;
2723  unsigned int count = 0;
2724 
2725  if (! file->cd(curdir.c_str()))
2726  raiseDQMError("DQMStore", "Failed to process directory '%s' while"
2727  " reading file '%s'", curdir.c_str(), file->GetName());
2728 
2729  // Figure out current directory name, but strip out the top
2730  // directory into which we dump everything.
2731  std::string dirpart = curdir;
2732  if (dirpart.compare(0, s_monitorDirName.size(), s_monitorDirName) == 0) {
2733  if (dirpart.size() == s_monitorDirName.size())
2734  dirpart.clear();
2735  else if (dirpart[s_monitorDirName.size()] == '/')
2736  dirpart.erase(0, s_monitorDirName.size()+1);
2737  }
2738 
2739  // See if we are going to skip this directory.
2740  bool skip = (! onlypath.empty() && ! isSubdirectory(onlypath, dirpart));
2741 
2742  if (prepend == s_collateDirName ||
2743  prepend == s_referenceDirName ||
2744  stripdirs == StripRunDirs ) {
2745  // Remove Run # and RunSummary dirs
2746  // first look for Run summary,
2747  // if that is found and erased, also erase Run dir
2748  size_t slash = dirpart.find('/');
2749  size_t pos = dirpart.find("/Run summary");
2750  if (slash != std::string::npos && pos !=std::string::npos) {
2751  dirpart.erase(pos,12);
2752 
2753  pos = dirpart.find("Run ");
2754  size_t length = dirpart.find('/',pos+1)-pos+1;
2755  if (pos !=std::string::npos)
2756  dirpart.erase(pos,length);
2757  }
2758  }
2759 
2760  // If we are prepending, add it to the directory name,
2761  // and suppress reading of already existing reference histograms
2762  if (prepend == s_collateDirName ||
2763  prepend == s_referenceDirName) {
2764  size_t slash = dirpart.find('/');
2765  // If we are reading reference, skip previous reference.
2766  if (slash == std::string::npos // skip if Reference is toplevel folder, i.e. no slash
2767  && slash+1+s_referenceDirName.size() == dirpart.size()
2768  && dirpart.compare(slash+1, s_referenceDirName.size(), s_referenceDirName) == 0)
2769  return 0;
2770 
2771  slash = dirpart.find('/');
2772  // Skip reading of EventInfo subdirectory.
2773  if (slash != std::string::npos
2774  && slash + 10 == dirpart.size()
2775  && dirpart.compare( slash+1 , 9 , "EventInfo") == 0) {
2776  if (verbose_)
2777  std::cout << "DQMStore::readDirectory: skipping '" << dirpart << "'\n";
2778  return 0;
2779  }
2780 
2781  // Add prefix.
2782  if (dirpart.empty())
2783  dirpart = prepend;
2784  else
2785  dirpart = prepend + '/' + dirpart;
2786  }
2787  else if (! prepend.empty()) {
2788  if (dirpart.empty())
2789  dirpart = prepend;
2790  else
2791  dirpart = prepend + '/' + dirpart;
2792  }
2793 
2794  // Loop over the contents of this directory in the file.
2795  // Post-pone string object handling to happen after other
2796  // objects have been read in so we are guaranteed to have
2797  // histograms by the time we read in quality tests and tags.
2798  TKey* key;
2799  TIter next (gDirectory->GetListOfKeys());
2800  std::list<TObject*> delayed;
2801  while ((key = (TKey*) next()))
2802  {
2803  std::unique_ptr<TObject> obj(key->ReadObj());
2804  if (dynamic_cast<TDirectory*>(obj.get())) {
2805  std::string subdir;
2806  subdir.reserve(curdir.size() + strlen(obj->GetName()) + 2);
2807  subdir += curdir;
2808  if (! curdir.empty())
2809  subdir += '/';
2810  subdir += obj->GetName();
2811 
2812  ntot += readDirectory(file, overwrite, onlypath, prepend, subdir, stripdirs);
2813  }
2814  else if (skip)
2815  ;
2816  else if (dynamic_cast<TObjString*>(obj.get())) {
2817  delayed.push_back(obj.release());
2818  }
2819  else {
2820  if (verbose_ > 2)
2821  std::cout << "DQMStore: reading object '" << obj->GetName()
2822  << "' of type '" << obj->IsA()->GetName()
2823  << "' from '" << file->GetName()
2824  << "' into '" << dirpart << "'\n";
2825 
2826  makeDirectory(dirpart);
2827  if (extract(obj.get(), dirpart, overwrite, collateHistograms_))
2828  ++count;
2829  }
2830  }
2831 
2832  while (! delayed.empty()) {
2833  if (verbose_ > 2)
2834  std::cout << "DQMStore: reading object '" << delayed.front()->GetName()
2835  << "' of type '" << delayed.front()->IsA()->GetName()
2836  << "' from '" << file->GetName()
2837  << "' into '" << dirpart << "'\n";
2838 
2839  makeDirectory(dirpart);
2840  if (extract(delayed.front(), dirpart, overwrite, collateHistograms_))
2841  ++count;
2842 
2843  delete delayed.front();
2844  delayed.pop_front();
2845  }
2846 
2847  if (verbose_ > 1)
2848  std::cout << "DQMStore: read " << count << '/' << ntot
2849  << " objects from directory '" << dirpart << "'\n";
2850 
2851  return ntot + count;
2852 }
2853 
2860 bool
2862  bool const overwrite /* = false */,
2863  std::string const& onlypath /* ="" */,
2864  std::string const& prepend /* ="" */,
2865  OpenRunDirs const stripdirs /* =KeepRunDirs */,
2866  bool const fileMustExist /* =true */)
2867 {
2868  return readFile(filename,overwrite,onlypath,prepend,stripdirs,fileMustExist);
2869 }
2870 
2875 bool
2877  OpenRunDirs const stripdirs /* =StripRunDirs */,
2878  bool const fileMustExist /* =true */)
2879 {
2880  bool overwrite = true;
2881  if (collateHistograms_) overwrite = false;
2882  if (verbose_)
2883  {
2884  std::cout << "DQMStore::load: reading from file '" << filename << "'\n";
2885  if (collateHistograms_)
2886  std::cout << "DQMStore::load: in collate mode " << "\n";
2887  else
2888  std::cout << "DQMStore::load: in overwrite mode " << "\n";
2889  }
2890 
2891  if (!s_rxpbfile.match(filename, 0, 0))
2892  return readFile(filename, overwrite, "", "", stripdirs, fileMustExist);
2893  else
2894  return readFilePB(filename, overwrite, "", "", stripdirs, fileMustExist);
2895 }
2896 
2902 bool
2904  bool const overwrite /* = false */,
2905  std::string const& onlypath /* ="" */,
2906  std::string const& prepend /* ="" */,
2907  OpenRunDirs const stripdirs /* =StripRunDirs */,
2908  bool const fileMustExist /* =true */)
2909 {
2910 
2911  if (verbose_)
2912  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
2913 
2914  std::unique_ptr<TFile> f;
2915 
2916  try {
2917  f.reset(TFile::Open(filename.c_str()));
2918  if (! f.get() || f->IsZombie())
2919  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
2920  }
2921  catch (std::exception &) {
2922  if (fileMustExist)
2923  throw;
2924  else {
2925  if (verbose_)
2926  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
2927  return false;
2928  }
2929  }
2930 
2931  unsigned n = readDirectory(f.get(), overwrite, onlypath, prepend, "", stripdirs);
2932  f->Close();
2933 
2934  for (auto const& me : data_)
2935  const_cast<MonitorElement &>(me).updateQReportStats();
2936 
2937  if (verbose_) {
2938  std::cout << "DQMStore::open: successfully read " << n
2939  << " objects from file '" << filename << "'";
2940  if (! onlypath.empty())
2941  std::cout << " from directory '" << onlypath << "'";
2942  if (! prepend.empty())
2943  std::cout << " into directory '" << prepend << "'";
2944  std::cout << std::endl;
2945  }
2946  return true;
2947 }
2948 
2952 inline TObject* DQMStore::extractNextObject(TBufferFile& buf) const
2953 {
2954  if (buf.Length() == buf.BufferSize())
2955  return nullptr;
2956  buf.InitMap();
2957  void* ptr = buf.ReadObjectAny(nullptr);
2958  return reinterpret_cast<TObject*>(ptr);
2959 }
2960 
2963  std::string& objname,
2964  TObject** obj)
2965 {
2966  size_t slash = h.full_pathname().rfind('/');
2967  size_t dirpos = (slash == std::string::npos ? 0 : slash);
2968  size_t namepos = (slash == std::string::npos ? 0 : slash+1);
2969  dirname.assign(h.full_pathname(), 0, dirpos);
2970  objname.assign(h.full_pathname(), namepos, std::string::npos);
2971  TBufferFile buf(TBufferFile::kRead, h.size(),
2972  (void*)h.streamed_histo().data(),
2973  kFALSE);
2974  buf.Reset();
2975  *obj = extractNextObject(buf);
2976  if (!*obj) {
2977  raiseDQMError("DQMStore", "Error reading element:'%s'" , h.full_pathname().c_str());
2978  }
2979 }
2980 
2981 bool
2983  bool const overwrite /* = false */,
2984  std::string const& onlypath /* ="" */,
2985  std::string const& prepend /* ="" */,
2986  OpenRunDirs const stripdirs /* =StripRunDirs */,
2987  bool const fileMustExist /* =true */)
2988 {
2989  using google::protobuf::io::FileInputStream;
2990  using google::protobuf::io::FileOutputStream;
2991  using google::protobuf::io::GzipInputStream;
2992  using google::protobuf::io::GzipOutputStream;
2993  using google::protobuf::io::CodedInputStream;
2994  using google::protobuf::io::ArrayInputStream;
2995 
2996  if (verbose_)
2997  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
2998 
2999  int filedescriptor;
3000  if ((filedescriptor = ::open(filename.c_str(), O_RDONLY)) == -1) {
3001  if (fileMustExist)
3002  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
3003  else
3004  if (verbose_)
3005  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
3006  return false;
3007  }
3008 
3009  dqmstorepb::ROOTFilePB dqmstore_message;
3010  FileInputStream fin(filedescriptor);
3011  GzipInputStream input(&fin);
3012  CodedInputStream input_coded(&input);
3013  input_coded.SetTotalBytesLimit(1024*1024*1024, -1);
3014  if (!dqmstore_message.ParseFromCodedStream(&input_coded)) {
3015  raiseDQMError("DQMStore", "Fatal parsing file '%s'", filename.c_str());
3016  return false;
3017  }
3018  ::close(filedescriptor);
3019 
3020  for (int i = 0; i < dqmstore_message.histo_size(); ++i) {
3021  std::string path;
3022  std::string objname;
3023 
3024  TObject* obj = nullptr;
3025  dqmstorepb::ROOTFilePB::Histo const& h = dqmstore_message.histo(i);
3026  get_info(h, path, objname, &obj);
3027 
3028  setCurrentFolder(path);
3029  if (obj) {
3030  /* Before calling the extract() check if histogram exists:
3031  * if it does - flags for the given monitor are already set (and merged)
3032  * else - set the flags after the histogram is created.
3033  */
3034  MonitorElement* me = findObject(0, 0, 0, path, objname);
3035 
3036  /* Run histograms should be collated and not overwritten,
3037  * Lumi histograms should be overwritten (and collate flag is not checked)
3038  */
3039  bool overwrite = h.flags() & DQMNet::DQM_PROP_LUMI;
3040  bool collate = !(h.flags() & DQMNet::DQM_PROP_LUMI);
3041  extract(static_cast<TObject*>(obj), path, overwrite, collate);
3042 
3043  if (me == nullptr) {
3044  me = findObject(0, 0, 0, path, objname);
3045  me->data_.flags = h.flags();
3046  }
3047 
3048  delete obj;
3049  }
3050  }
3051 
3052  cd();
3053  return true;
3054 }
3055 
3061 void
3063 {
3065  std::string const* cleaned = nullptr;
3066  cleanTrailingSlashes(path, clean, cleaned);
3067  MonitorElement proto(cleaned, std::string());
3068 
3069  auto e = data_.end();
3070  auto i = data_.lower_bound(proto);
3071  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
3072  data_.erase(i++);
3073 
3074  auto de = dirs_.end();
3075  auto di = dirs_.lower_bound(*cleaned);
3076  while (di != de && isSubdirectory(*cleaned, *di))
3077  dirs_.erase(di++);
3078 }
3079 
3081 void
3083 {
3084  MonitorElement proto(&dir, std::string());
3085  auto e = data_.end();
3086  auto i = data_.lower_bound(proto);
3087  while (i != e && isSubdirectory(dir, *i->data_.dirname))
3088  if (dir == *i->data_.dirname)
3089  data_.erase(i++);
3090  else
3091  ++i;
3092 }
3093 
3095 void
3097 {
3099 }
3100 
3103 void
3105 {
3106  removeElement(pwd_, name);
3107 }
3108 
3111 void
3112 DQMStore::removeElement(std::string const& dir, std::string const& name, bool const warning /* = true */)
3113 {
3114  MonitorElement proto(&dir, name);
3115  auto pos = data_.find(proto);
3116  if (pos != data_.end())
3117  data_.erase(pos);
3118  else if (warning) {
3119  std::cout << "DQMStore: WARNING: attempt to remove non-existent"
3120  << " monitor element '" << name << "' in '" << dir << "'\n";
3121  }
3122 }
3123 
3129 QCriterion*
3131 {
3132  auto i = qtests_.find(qtname);
3133  auto e = qtests_.end();
3134  return (i == e ? nullptr : i->second);
3135 }
3136 
3140 QCriterion*
3142 {
3143  if (qtests_.count(qtname))
3144  raiseDQMError("DQMStore", "Attempt to create duplicate quality test '%s'",
3145  qtname.c_str());
3146 
3147  auto i = qalgos_.find(algoname);
3148  if (i == qalgos_.end())
3149  raiseDQMError("DQMStore", "Cannot create a quality test using unknown"
3150  " algorithm '%s'", algoname.c_str());
3151 
3152  QCriterion* qc = i->second(qtname);
3153  qc->setVerbose(verboseQT_);
3154 
3155  qtests_[qtname] = qc;
3156  return qc;
3157 }
3158 
3161 void
3162 DQMStore::useQTest(std::string const& dir, std::string const& qtname)
3163 {
3164  // Clean the path
3166  std::string const* cleaned = nullptr;
3167  cleanTrailingSlashes(dir, clean, cleaned);
3168 
3169  // Validate the path.
3170  if (cleaned->find_first_not_of(s_safe) != std::string::npos)
3171  raiseDQMError("DQMStore", "Monitor element path name '%s'"
3172  " uses unacceptable characters", cleaned->c_str());
3173 
3174  // Redirect to the pattern match version.
3175  useQTestByMatch(*cleaned + "/*", qtname);
3176 }
3177 
3179 int
3181 {
3182  QCriterion* qc = getQCriterion(qtname);
3183  if (! qc)
3184  raiseDQMError("DQMStore", "Cannot apply non-existent quality test '%s'",
3185  qtname.c_str());
3186 
3187  auto* fm = new fastmatch(pattern);
3188 
3189  // Record the test for future reference.
3190  QTestSpec qts(fm, qc);
3191  qtestspecs_.push_back(qts);
3192 
3193  // Apply the quality test.
3194  std::string path;
3195  int cases = 0;
3196  for (auto const& me : data_) {
3197  path.clear();
3198  mergePath(path, *me.data_.dirname, me.data_.objname);
3199  if (fm->match(path)) {
3200  ++cases;
3201  const_cast<MonitorElement &>(me).addQReport(qts.second);
3202  }
3203  }
3204 
3205  //return the number of matched cases
3206  return cases;
3207 }
3210 void
3212 {
3213 
3214  if (verbose_ > 0)
3215  std::cout << "DQMStore: running runQTests() with reset = "
3216  << ( reset_ ? "true" : "false" ) << std::endl;
3217 
3218  // Apply quality tests to each monitor element, skipping references.
3219  for (auto const& me : data_)
3220  if (! isSubdirectory(s_referenceDirName, *me.data_.dirname))
3221  const_cast<MonitorElement &>(me).runQTests();
3222 
3223  reset_ = false;
3224 }
3225 
3229 int
3230 DQMStore::getStatus(std::string const& path /* = "" */) const
3231 {
3233  std::string const* cleaned = nullptr;
3234  cleanTrailingSlashes(path, clean, cleaned);
3235 
3237  for (auto const& me : data_) {
3238  if (! cleaned->empty() && ! isSubdirectory(*cleaned, *me.data_.dirname))
3239  continue;
3240 
3241  if (me.hasError())
3242  return dqm::qstatus::ERROR;
3243  else if (me.hasWarning())
3244  status = dqm::qstatus::WARNING;
3245  else if (status < dqm::qstatus::WARNING
3246  && me.hasOtherReport())
3247  status = dqm::qstatus::OTHER;
3248  }
3249  return status;
3250 }
3251 
3257 void
3259 {
3260  if (me)
3261  me->softReset();
3262 }
3263 
3264 // reverts action of softReset
3265 void
3267 {
3268  if (me)
3269  me->disableSoftReset();
3270 }
3271 
3274 void
3276 {
3277  if (me)
3278  me->setAccumulate(flag);
3279 }
3280 
3284 void
3286 {
3287  std::vector<std::string> contents;
3288  getContents(contents);
3289 
3290  std::cout << " ------------------------------------------------------------\n"
3291  << " Directory structure: \n"
3292  << " ------------------------------------------------------------\n";
3293 
3294  std::copy(contents.begin(), contents.end(),
3295  std::ostream_iterator<std::string>(std::cout, "\n"));
3296 
3297  std::cout << " ------------------------------------------------------------\n";
3298 }
3299 
3303 // check if the collate option is active on the DQMStore
3304 bool
3306 {
3307  return collateHistograms_;
3308 }
3312 // check if the monitor element is in auto-collation folder
3313 bool
3315 {
3316  return me && isSubdirectory(s_collateDirName, *me->data_.dirname);
3317 }
3318 
3322 
3324 void
3326 {
3327  if (scaleFlag_ == 0.0) return;
3328  if (verbose_ > 0)
3329  std::cout << " =========== " << " ScaleFlag " << scaleFlag_ << std::endl;
3330  double factor = scaleFlag_;
3331  int events = 1;
3332  if (dirExists("Info/EventInfo")) {
3333  if ( scaleFlag_ == -1.0) {
3334  MonitorElement* scale_me = get("Info/EventInfo/ScaleFactor");
3335  if (scale_me && scale_me->kind()==MonitorElement::DQM_KIND_REAL) factor = scale_me->getFloatValue();
3336  }
3337  MonitorElement* event_me = get("Info/EventInfo/processedEvents");
3338  if (event_me && event_me->kind()==MonitorElement::DQM_KIND_INT) events = event_me->getIntValue();
3339  }
3340  factor = factor/(events*1.0);
3341 
3342  for (auto const& m : data_) {
3343  auto& me = const_cast<MonitorElement&>(m);
3344  switch (me.kind()) {
3346  {
3347  me.getTH1F()->Scale(factor);
3348  break;
3349  }
3351  {
3352  me.getTH1S()->Scale(factor);
3353  break;
3354  }
3356  {
3357  me.getTH1D()->Scale(factor);
3358  break;
3359  }
3361  {
3362  me.getTH2F()->Scale(factor);
3363  break;
3364  }
3366  {
3367  me.getTH2S()->Scale(factor);
3368  break;
3369  }
3371  {
3372  me.getTH2D()->Scale(factor);
3373  break;
3374  }
3376  {
3377  me.getTH3F()->Scale(factor);
3378  break;
3379  }
3381  {
3382  me.getTProfile()->Scale(factor);
3383  break;
3384  }
3386  {
3387  me.getTProfile2D()->Scale(factor);
3388  break;
3389  }
3390  default:
3391  if (verbose_ > 0)
3392  std::cout << " The DQM object '" << me.getFullname() << "' is not scalable object " << std::endl;
3393  continue;
3394  }
3395  }
3396 }
size
Write out results.
~DQMStore()
Definition: DQMStore.cc:390
bool compare_strings_reverse(std::string const &pattern, std::string const &input) const
Definition: DQMStore.cc:200
MonitorElement * book2D(char_string const &name, char_string const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY)
Book 2D histogram.
Definition: DQMStore.cc:1161
MonitorElement * bookProfile2D(char_string const &name, char_string const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, double lowZ, double highZ, char const *option="s")
Definition: DQMStore.cc:1367
Definition: start.py:1
TProfile * getTProfile() const
edm::ErrorSummaryEntry Error
Master< F > master(const F &f)
Definition: FunctClone.h:68
T getUntrackedParameter(std::string const &, T const &) const
MonitorElement * book2DD_(std::string const &dir, std::string const &name, TH2D *h)
Book 2D histogram based on TH2D.
Definition: DQMStore.cc:1154
uint32_t moduleId
Definition: DQMNet.h:105
void rmdir(std::string const &fullpath)
Definition: DQMStore.cc:3062
::google::protobuf::uint32 size() const
int64_t getIntValue() const
bool isCollateME(MonitorElement *me) const
Definition: DQMStore.cc:3314
MonitorElement * bookProfile2D_(std::string const &dir, std::string const &name, TProfile2D *h)
Book 2D profile histogram based on TProfile2D.
Definition: DQMStore.cc:1339
QReports qreports
Definition: DQMNet.h:108
const ::std::string & full_pathname() const
void copyFrom(TH1 *from)
std::vector< MonitorElement * > getAllContents(std::string const &path, uint32_t runNumber=0, uint32_t lumi=0)
Definition: DQMStore.cc:295
std::vector< MonitorElement * > getContents(std::string const &path) const
Definition: DQMStore.cc:1628
MonitorElement * initialise(Kind kind)
static const int OTHER
TProfile2D * getTProfile2D() const
std::string algorithm
Definition: DQMNet.h:94
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
void savePB(std::string const &filename, std::string const &path="", uint32_t run=0, uint32_t lumi=0)
Definition: DQMStore.cc:2628
def copy(args, dbName)
static void collate3D(MonitorElement *me, TH3F *h, unsigned verbose)
Definition: DQMStore.cc:1459
bool match(std::string const &s) const
Definition: DQMStore.cc:240
void removeElement(std::string const &name)
Definition: DQMStore.cc:3104
MonitorElement * bookString_(std::string const &dir, std::string const &name, std::string const &value)
Book string.
Definition: DQMStore.cc:1044
MonitorElement * book_(std::string const &dir, std::string const &name, char const *context)
Definition: DQMStore.cc:970
static void collateProfile(MonitorElement *me, TProfile *h, unsigned verbose)
Definition: DQMStore.cc:1466
TH1F * getTH1F() const
TH2S * getTH2S() const
void scaleElements()
Definition: DQMStore.cc:3325
double getFloatValue() const
void setLumi(uint32_t ls)
void postGlobalBeginLumi(const edm::GlobalContext &)
Definition: DQMStore.cc:1874
std::vector< MonitorElement * > getMatchingContents(std::string const &pattern, lat::Regexp::Syntax syntaxType=lat::Regexp::Wildcard) const
Definition: DQMStore.cc:1801
void tagContents(std::string const &path, unsigned int myTag)
tag all children of folder (does NOT include subfolders)
Definition: DQMStore.cc:1519
std::string qualityTagString(const DQMNet::QValue &qv) const
uint32_t flags
Definition: DQMNet.h:99
LuminosityBlockID const & luminosityBlockID() const
Definition: GlobalContext.h:57
MonitorElement * book1DD(char_string const &name, char_string const &title, int nchX, double lowX, double highX)
Book 1S histogram.
Definition: DQMStore.cc:1102
void makeDirectory(std::string const &path)
Definition: DQMStore.cc:589
TH1 * getTH1() const
static void collate2DD(MonitorElement *me, TH2D *h, unsigned verbose)
Definition: DQMStore.cc:1452
static const int WARNING
def replace(string, replacements)
void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:361
static const uint32_t DQM_PROP_TAGGED
Definition: DQMNet.h:55
MatchingHeuristicEnum matching_
Definition: DQMStore.h:72
static const uint32_t DQM_PROP_EFFICIENCY_PLOT
Definition: DQMNet.h:64
uint32_t tag
Definition: DQMNet.h:100
bool reset_
Definition: DQMStore.h:632
const std::string * dirname
Definition: DQMNet.h:106
MonitorElement * book1D_(std::string const &dir, std::string const &name, TH1F *h)
Book 1D histogram based on TH1F.
Definition: DQMStore.cc:1065
bool extract(TObject *obj, std::string const &dir, bool overwrite, bool collateHistograms)
Definition: DQMStore.cc:2025
void initializeFrom(const edm::ParameterSet &)
Definition: DQMStore.cc:400
MonitorElement * bookProfile_(std::string const &dir, std::string const &name, TProfile *h)
Book profile histogram based on TProfile.
Definition: DQMStore.cc:1262
MonitorElement * bookInt(char_string const &name)
Book int.
Definition: DQMStore.cc:1015
OpenRunDirs
Definition: DQMStore.h:83
MonitorElement * book1D(char_string const &name, char_string const &title, int const nchX, double const lowX, double const highX)
Book 1D histogram.
Definition: DQMStore.cc:1086
void set_flags(::google::protobuf::uint32 value)
void disableSoftReset()
reverts action of softReset
uint32_t run
Definition: DQMNet.h:102
void get_info(dqmstorepb::ROOTFilePB_Histo const &, std::string &dirname, std::string &objname, TObject **obj)
Definition: DQMStore.cc:2961
uint32_t moduleId_
Definition: DQMStore.h:640
const ::std::string & streamed_histo() const
bool cdInto(std::string const &path) const
Definition: DQMStore.cc:2292
QCMap qtests_
Definition: DQMStore.h:647
fastmatch(std::string fastString)
Definition: DQMStore.cc:141
void forceReset()
Definition: DQMStore.cc:1852
std::mutex book_mutex_
Definition: DQMStore.h:651
MonitorElement * bookFloat(char_string const &name)
Book float.
Definition: DQMStore.cc:1036
DQMStore(edm::ParameterSet const &pset, edm::ActivityRegistry &)
Definition: DQMStore.cc:367
static std::string const input
Definition: EdmProvDump.cc:45
SaveReferenceTag
Definition: DQMStore.h:78
void Fill(long long x)
void tag(MonitorElement *me, unsigned int myTag)
Definition: DQMStore.cc:1488
void disableSoftReset(MonitorElement *me)
Definition: DQMStore.cc:3266
unsigned int maxNumberOfStreams() const
Definition: SystemBounds.h:43
void useQTest(std::string const &dir, std::string const &qtname)
Definition: DQMStore.cc:3162
void saveMonitorElementRangeToROOT(std::string const &dir, std::string const &refpath, SaveReferenceTag ref, int minStatus, unsigned int run, MEMap::const_iterator begin, MEMap::const_iterator end, TFile &file, unsigned int &counter)
Definition: DQMStore.cc:2363
MonitorElement * book2DD(char_string const &name, char_string const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY)
Book 2D histogram.
Definition: DQMStore.cc:1183
std::pair< fastmatch *, QCriterion * > QTestSpec
Definition: DQMStore.h:603
void saveMonitorElementToROOT(MonitorElement const &me, TFile &file)
Definition: DQMStore.cc:2334
MonitorElement * getElement(std::string const &path)
Definition: DQMStore.cc:309
unsigned verboseQT_
Definition: DQMStore.h:631
void setEfficiencyFlag()
static const uint32_t DQM_PROP_HAS_REFERENCE
Definition: DQMNet.h:54
QTestSpecs qtestspecs_
Definition: DQMStore.h:649
void print_trace(std::string const &dir, std::string const &name)
Definition: DQMStore.cc:462
void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:268
double scaleFlag_
Definition: DQMStore.h:633
void deleteUnusedLumiHistograms(uint32_t run, uint32_t lumi)
Definition: DQMStore.cc:1983
MonitorElement * book2D_(std::string const &dir, std::string const &name, TH2F *h)
Book 2D histogram based on TH2F.
Definition: DQMStore.cc:1140
bool dirExists(std::string const &path) const
true if directory exists
Definition: DQMStore.cc:629
bool isCollate() const
Definition: DQMStore.cc:3305
MonitorElement * book1DD_(std::string const &dir, std::string const &name, TH1D *h)
Book 1D histogram based on TH1D.
Definition: DQMStore.cc:1079
MonitorElement * get(std::string const &path) const
get ME from full pathname (e.g. "my/long/dir/my_histo")
Definition: DQMStore.cc:1601
void setAccumulate(bool)
uint32_t lumi
Definition: DQMNet.h:103
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void addProfiles(TProfile *h1, TProfile *h2, TProfile *sum, float c1, float c2)
static void collateProfile2D(MonitorElement *me, TProfile2D *h, unsigned verbose)
Definition: DQMStore.cc:1475
std::string tagString() const
MonitorElement * book3D_(std::string const &dir, std::string const &name, TH3F *h)
Book 3D histogram based on TH3F.
Definition: DQMStore.cc:1234
TH2D * getTH2D() const
void tag(MonitorElement *, unsigned int)
Definition: DQMStore.cc:283
std::vector< std::shared_ptr< fireworks::OptionNode > > Options
void saveMonitorElementRangeToPB(std::string const &dir, unsigned int run, MEMap::const_iterator begin, MEMap::const_iterator end, dqmstorepb::ROOTFilePB &file, unsigned int &counter)
Definition: DQMStore.cc:2582
double f[11][100]
uint32_t run_
Definition: DQMStore.h:639
bool open(std::string const &filename, bool overwrite=false, std::string const &path="", std::string const &prepend="", OpenRunDirs stripdirs=KeepRunDirs, bool fileMustExist=true)
Definition: DQMStore.cc:2861
#define end
Definition: vmac.h:39
void setVerbose(unsigned level)
Definition: DQMStore.cc:525
Definition: value.py:1
void softReset(MonitorElement *me)
Definition: DQMStore.cc:3258
std::string pwd_
Definition: DQMStore.h:643
TObject * extractNextObject(TBufferFile &) const
Definition: DQMStore.cc:2952
void Reset()
reset ME (ie. contents, errors, etc)
QCriterion * getQCriterion(std::string const &qtname) const
Definition: DQMStore.cc:3130
QAMap qalgos_
Definition: DQMStore.h:648
bool containsAnyMonitorable(std::string const &path)
Definition: DQMStore.cc:337
unsigned int readDirectory(TFile *file, bool overwrite, std::string const &path, std::string const &prepend, std::string const &curdir, OpenRunDirs stripdirs)
Definition: DQMStore.cc:2715
std::vector< std::string > getSubdirs() const
Definition: DQMStore.cc:1552
MonitorElement * bookString(char_string const &name, char_string const &value)
Book string.
Definition: DQMStore.cc:1057
std::string objname
Definition: DQMNet.h:107
std::string fastString_
Definition: DQMStore.h:71
TH2F * getTH2F() const
MonitorElement * get(std::string const &path)
Definition: DQMStore.cc:303
std::vector< T * > clean
Definition: MVATrainer.cc:156
std::string qtname
Definition: DQMNet.h:93
int getStatus(std::string const &path="") const
Definition: DQMStore.cc:3230
std::string const & pwd() const
Definition: DQMStore.cc:533
DQMNet::CoreObject data_
const std::string getFullname() const
get full name of ME including Pathname
MonitorElement * book2S(char_string const &name, char_string const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY)
Book 2S histogram.
Definition: DQMStore.cc:1172
MonitorElement * book1S_(std::string const &dir, std::string const &name, TH1S *h)
Book 1D histogram based on TH1S.
Definition: DQMStore.cc:1072
void saveMonitorElementToPB(MonitorElement const &me, dqmstorepb::ROOTFilePB &file)
Definition: DQMStore.cc:2554
static void collate1DD(MonitorElement *me, TH1D *h, unsigned verbose)
Definition: DQMStore.cc:1431
void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:565
demangled
Definition: symbols.py:62
MonitorElement * bookProfile(char_string const &name, char_string const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, char const *option="s")
Definition: DQMStore.cc:1273
void showDirStructure() const
Definition: DQMStore.cc:3285
void cd()
go to top directory (ie. root)
Definition: DQMStore.cc:540
QCriterion * createQTest(std::string const &algoname, std::string const &qtname)
Definition: DQMStore.cc:3141
std::string effLabelString() const
return label string for the monitor element tag (eg. <name>t=12345</name>)
const ::dqmstorepb::ROOTFilePB_Histo & histo(int index) const
unsigned verbose_
Definition: DQMStore.h:630
void set_size(::google::protobuf::uint32 value)
std::string const & pwd()
Definition: DQMStore.cc:278
TH3F * getTH3F() const
MEMap data_
Definition: DQMStore.h:644
part
Definition: HCALResponse.h:20
MonitorElement * book2S_(std::string const &dir, std::string const &name, TH2S *h)
Book 2D histogram based on TH2S.
Definition: DQMStore.cc:1147
std::string tagLabelString() const
return label string for the monitor element tag (eg. <name>t=12345</name>)
static void collate1D(MonitorElement *me, TH1F *h, unsigned verbose)
Definition: DQMStore.cc:1417
bool dirExists(std::string const &path)
Definition: DQMStore.cc:343
std::vector< std::string > getMEs() const
get list of (non-dir) MEs of current directory
Definition: DQMStore.cc:1575
MonitorElement * bookFloat_(std::string const &dir, std::string const &name)
Book float.
Definition: DQMStore.cc:1023
tuple msg
Definition: mps_check.py:278
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
bool readFilePB(std::string const &filename, bool overwrite=false, std::string const &path="", std::string const &prepend="", OpenRunDirs stripdirs=StripRunDirs, bool fileMustExist=true)
Definition: DQMStore.cc:2982
void save(std::string const &filename, std::string const &path="", std::string const &pattern="", std::string const &rewrite="", uint32_t run=0, uint32_t lumi=0, SaveReferenceTag ref=SaveWithReference, int minStatus=dqm::qstatus::STATUS_OK, std::string const &fileupdate="RECREATE")
Definition: DQMStore.cc:2443
static const Regexp s_rxmeval("<(.*)>(i|f|s|qr)=(.*)</\\1>")
void set_full_pathname(const ::std::string &value)
void setVerbose(int verbose)
probability limits for warnings, errors
Definition: QTest.h:119
void removeContents()
erase all monitoring elements in current directory (not including subfolders);
Definition: DQMStore.cc:3096
bool forceResetOnBeginLumi_
Definition: DQMStore.h:637
#define begin
Definition: vmac.h:32
T dot(const Basic3DVector &v) const
Scalar product, or "dot" product, with a vector of same type.
::dqmstorepb::ROOTFilePB_Histo * add_histo()
void cloneRunHistograms(uint32_t run, uint32_t moduleId)
Definition: DQMStore.cc:1945
static std::atomic< unsigned int > counter
void cloneLumiHistograms(uint32_t run, uint32_t lumi, uint32_t moduleId)
Definition: DQMStore.cc:1908
bool readFile(std::string const &filename, bool overwrite=false, std::string const &path="", std::string const &prepend="", OpenRunDirs stripdirs=StripRunDirs, bool fileMustExist=true)
Definition: DQMStore.cc:2903
MonitorElement * book1S(char_string const &name, char_string const &title, int nchX, double lowX, double highX)
Book 1S histogram.
Definition: DQMStore.cc:1094
std::vector< std::string > getSubdirs()
Definition: DQMStore.cc:325
std::unique_ptr< std::ostream > stream_
Definition: DQMStore.h:641
std::string message
Definition: DQMNet.h:92
TH1D * getTH1D() const
::google::protobuf::uint32 flags() const
static const int STATUS_OK
void tagContents(std::string const &, unsigned int)
Definition: DQMStore.cc:288
TH1S * getTH1S() const
MonitorElement * book3D(char_string const &name, char_string const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, int nchZ, double lowZ, double highZ)
Book 3D histogram.
Definition: DQMStore.cc:1241
void setAccumulate(MonitorElement *me, bool flag)
Definition: DQMStore.cc:3275
MonitorElement * bookInt_(std::string const &dir, std::string const &name)
Book int.
Definition: DQMStore.cc:1002
static void collate1S(MonitorElement *me, TH1S *h, unsigned verbose)
Definition: DQMStore.cc:1424
void Reset(std::vector< TH2F > &depth)
static bool checkBinningMatches(MonitorElement *me, TH1 *h, unsigned verbose)
Definition: DQMStore.cc:1391
dbl *** dir
Definition: mlp_gen.cc:35
void goUp()
equivalent to "cd .."
Definition: DQMStore.cc:576
MonitorElement * findObject(uint32_t run, uint32_t lumi, uint32_t moduleId, std::string const &dir, std::string const &name) const
Definition: DQMStore.cc:1727
bool load(std::string const &filename, OpenRunDirs stripdirs=StripRunDirs, bool fileMustExist=true)
Definition: DQMStore.cc:2876
static void collate2D(MonitorElement *me, TH2F *h, unsigned verbose)
Definition: DQMStore.cc:1438
std::vector< std::string > getMEs()
Definition: DQMStore.cc:331
long double T
float qtresult
Definition: DQMNet.h:91
MonitorElement * initialise(MonitorElement *me, std::string const &path)
std::set< std::string > dirs_
Definition: DQMStore.h:645
bool collateHistograms_
Definition: DQMStore.h:634
static const uint32_t DQM_PROP_LUMI
Definition: DQMNet.h:61
static std::string const source
Definition: EdmProvDump.cc:44
bool LSbasedMode_
Definition: DQMStore.h:636
void addQReport(const DQMNet::QValue &desc, QCriterion *qc)
Add quality report, from DQMStore.
void runQTests()
Definition: DQMStore.cc:3211
Kind kind() const
Get the type of the monitor element.
void reset()
Definition: DQMStore.cc:1832
def move(src, dest)
Definition: eostools.py:511
bool compare_strings(std::string const &pattern, std::string const &input) const
Definition: DQMStore.cc:220
int useQTestByMatch(std::string const &pattern, std::string const &qtname)
attach quality test <qc> to monitor elements matching <pattern>.
Definition: DQMStore.cc:3180
std::vector< MonitorElement * > getAllContents(std::string const &path, uint32_t runNumber=0, uint32_t lumi=0) const
Definition: DQMStore.cc:1755
static void collate2S(MonitorElement *me, TH2S *h, unsigned verbose)
Definition: DQMStore.cc:1445
bool containsAnyMonitorable(std::string const &path) const
Definition: DQMStore.cc:1591
std::unique_ptr< lat::Regexp > regexp_
Definition: DQMStore.h:70
static const int ERROR
bool enableMultiThread_
Definition: DQMStore.h:635
void set_streamed_histo(const ::std::string &value)
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check the consistency of the axis labels.
void tagAllContents(std::string const &path, unsigned int myTag)
Definition: DQMStore.cc:1531
void raiseDQMError(const char *context, const char *fmt,...)
Definition: DQMError.cc:11