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 #if !WITHOUT_CMS_FRAMEWORK
380  forceResetOnBeginLumi_ = true;
381  ar.watchPreSourceLumi([this](edm::LuminosityBlockIndex){ forceReset(); });
382 #endif
383  }
384  ar.watchPostGlobalBeginLumi(this, &DQMStore::postGlobalBeginLumi);
385 }
386 
388 {
389  initializeFrom(pset);
390 }
391 
393 {
394  for (auto& qtest : qtests_)
395  delete qtest.second;
396 
397  for (auto& qtestspec : qtestspecs_)
398  delete qtestspec.first;
399 }
400 
401 void
403 {
404  makeDirectory("");
405  reset();
406 
407  // set steerable parameters
408  verbose_ = pset.getUntrackedParameter<int>("verbose", 0);
409  if (verbose_ > 0)
410  std::cout << "DQMStore: verbosity set to " << verbose_ << std::endl;
411 
412  verboseQT_ = pset.getUntrackedParameter<int>("verboseQT", 0);
413  if (verbose_ > 0)
414  std::cout << "DQMStore: QTest verbosity set to " << verboseQT_ << std::endl;
415 
416  collateHistograms_ = pset.getUntrackedParameter<bool>("collateHistograms", false);
417  if (collateHistograms_)
418  std::cout << "DQMStore: histogram collation is enabled\n";
419 
420  enableMultiThread_ = pset.getUntrackedParameter<bool>("enableMultiThread", false);
421  if (enableMultiThread_)
422  std::cout << "DQMStore: MultiThread option is enabled\n";
423 
424  LSbasedMode_ = pset.getUntrackedParameter<bool>("LSbasedMode", false);
425  if (LSbasedMode_)
426  std::cout << "DQMStore: LSbasedMode option is enabled\n";
427 
428  doSaveByLumi_ = pset.getUntrackedParameter<bool>("saveByLumi", false);
429  if (doSaveByLumi_)
430  std::cout << "DQMStore: saveByLumi option is enabled\n";
431 
432  std::string ref = pset.getUntrackedParameter<std::string>("referenceFileName", "");
433  if (! ref.empty()) {
434  std::cout << "DQMStore: using reference file '" << ref << "'\n";
435  readFile(ref, true, "", s_referenceDirName, StripRunDirs, false);
436  }
437 
438  initQCriterion<Comp2RefChi2>(qalgos_);
439  initQCriterion<Comp2Ref2DChi2>(qalgos_);
440  initQCriterion<Comp2RefKolmogorov>(qalgos_);
441  initQCriterion<ContentsXRange>(qalgos_);
442  initQCriterion<ContentsYRange>(qalgos_);
443  initQCriterion<MeanWithinExpected>(qalgos_);
444  initQCriterion<Comp2RefEqualH>(qalgos_);
445  initQCriterion<DeadChannel>(qalgos_);
446  initQCriterion<NoisyChannel>(qalgos_);
447  initQCriterion<ContentSigma>(qalgos_);
448  initQCriterion<ContentsWithinExpected>(qalgos_);
449  initQCriterion<CompareToMedian>(qalgos_);
450  initQCriterion<CompareLastFilledBin>(qalgos_);
451  initQCriterion<CheckVariance>(qalgos_);
452 
453  scaleFlag_ = pset.getUntrackedParameter<double>("ScalingFlag", 0.0);
454  if (verbose_ > 0)
455  std::cout << "DQMStore: Scaling Flag set to " << scaleFlag_ << std::endl;
456 }
457 
458 /* Generic method to do a backtrace and print it to stdout. It is
459  customised to properly get the routine that called the booking of the
460  histograms, which, following the usual stack, is at position 4. The
461  name of the calling function is properly demangled and the original
462  shared library including this function is also printed. For a more
463  detailed explanation of the routines involved, see here:
464  http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
465  http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html.*/
466 
467 void
469 {
470  // the access to the member stream_ is implicitely protected against
471  // concurrency problems because the print_trace method is always called behind
472  // a lock (see bookTransaction).
473  if (!stream_)
474  stream_ = std::make_unique<std::ofstream>("histogramBookingBT.log");
475 
476  void* array[10];
477  size_t size;
478  char** strings;
479  int r = 0;
480  lat::RegexpMatch m;
481  m.reset();
482 
483  size = backtrace(array, 10);
484  strings = backtrace_symbols(array, size);
485 
486  size_t level = 1;
487  char* demangled = nullptr;
488  for (; level < size; ++level) {
489  if (!s_rxtrace.match(strings[level], 0, 0, &m)) continue;
490  demangled = abi::__cxa_demangle(m.matchString(strings[level], 2).c_str(), nullptr, nullptr, &r);
491  if (!demangled) continue;
492  if (!s_rxself.match(demangled, 0, 0)) break;
493  free(demangled);
494  demangled = nullptr;
495  }
496 
497  if (demangled != nullptr) {
498  *stream_ << "\"" << dir << "/"
499  << name << "\" "
500  << (r ? m.matchString(strings[level], 2) : demangled) << " "
501  << m.matchString(strings[level], 1) << "\n";
502  free(demangled);
503  } else {
504  *stream_ << "Skipping "<< dir << "/" << name
505  << " with stack size " << size << "\n";
506  }
507 
508  /* In this case print the full stack trace, up to main or to the
509  * maximum stack size, i.e. 10. */
510  if (verbose_ > 4 || demangled == nullptr) {
511  size_t i;
512  m.reset();
513 
514  for (i = 0; i < size; ++i)
515  if (s_rxtrace.match(strings[i], 0, 0, &m)) {
516  char* demangled = abi::__cxa_demangle(m.matchString(strings[i], 2).c_str(), nullptr, nullptr, &r);
517  *stream_ << "\t\t" << i << "/" << size << " "
518  << (r ? m.matchString(strings[i], 2) : demangled) << " "
519  << m.matchString(strings[i], 1) << std::endl;
520  free (demangled);
521  }
522  }
523  free (strings);
524 }
525 
530 void
531 DQMStore::setVerbose(unsigned /* level */)
532 {}
533 
538 std::string const&
540 {
541  return pwd_;
542 }
543 
545 void
547 {
548  setCurrentFolder("");
549 }
550 
552 void
553 DQMStore::cd(std::string const& subdir)
554 {
556  std::string const* cleaned = nullptr;
557  cleanTrailingSlashes(subdir, clean, cleaned);
558 
559  if (! dirExists(*cleaned))
560  raiseDQMError("DQMStore", "Cannot 'cd' into non-existent directory '%s'",
561  cleaned->c_str());
562 
563  setCurrentFolder(*cleaned);
564 }
565 
570 void
572 {
574  std::string const* cleaned = nullptr;
575  cleanTrailingSlashes(fullpath, clean, cleaned);
576  makeDirectory(*cleaned);
577  pwd_ = *cleaned;
578 }
579 
581 void
583 {
584  size_t pos = pwd_.rfind('/');
585  if (pos == std::string::npos)
586  setCurrentFolder("");
587  else
588  setCurrentFolder(pwd_.substr(0, pos));
589 }
590 
591 // -------------------------------------------------------------------
594 void
596 {
597  std::string prev;
598  std::string subdir;
600  prev.reserve(path.size());
601  subdir.reserve(path.size());
602  name.reserve(path.size());
603  size_t prevname = 0;
604  size_t slash = 0;
605 
606  while (true) {
607  // Create this subdirectory component.
608  subdir.clear();
609  subdir.append(path, 0, slash);
610  name.clear();
611  name.append(subdir, prevname, std::string::npos);
612  if (! prev.empty() && findObject(0, 0, 0, prev, name))
613  raiseDQMError("DQMStore", "Attempt to create subdirectory '%s'"
614  " which already exists as a monitor element",
615  subdir.c_str());
616 
617  if (! dirs_.count(subdir))
618  dirs_.insert(subdir);
619 
620  // Stop if we've reached the end (including possibly a trailing slash).
621  if (slash+1 >= path.size())
622  break;
623 
624  // Find the next slash, making sure we progress. If reach the end,
625  // process the last path component; the next loop round will terminate.
626  prevname = slash ? slash+1 : slash;
627  prev = subdir;
628  if ((slash = path.find('/', ++slash)) == std::string::npos)
629  slash = path.size();
630  }
631 }
632 
634 bool
636 {
637  return dirs_.count(path) > 0;
638 }
639 
640 // //====================================================
641 // // Global-histogram booking
642 // MonitorElement*
643 // DQMStore::bookInt(char_string const& name)
644 // {
645 // return bookInt(0, 0, pwd_, name);
646 // }
647 
648 // MonitorElement*
649 // DQMStore::bookFloat(char_string const& name)
650 // {
651 // return bookFloat(0, 0, pwd_, name);
652 // }
653 
654 // MonitorElement*
655 // DQMStore::bookString(char_string const& name,
656 // char_string const& value)
657 // {
658 // return bookString(0, 0, pwd_, name, value);
659 // }
660 
661 // MonitorElement*
662 // DQMStore::book1D(char_string const& name,
663 // char_string const& title,
664 // int const nchX, double const lowX, double const highX)
665 // {
666 // return book1D(0, 0, pwd_, name, title, nchX, lowX, highX);
667 // }
668 
669 // MonitorElement*
670 // DQMStore::book1D(char_string const& name,
671 // char_string const& title,
672 // int const nchX, float const* xbinsize)
673 // {
674 // return book1D(0, 0, pwd_, name, title, nchX, xbinsize);
675 // }
676 
677 // MonitorElement*
678 // DQMStore::book1D(char_string const& name, TH1F* h)
679 // {
680 // return book1D(0, 0, pwd_, name, h);
681 // }
682 
683 // MonitorElement*
684 // DQMStore::book1S(char_string const& name,
685 // char_string const& title,
686 // int const nchX, double const lowX, double const highX)
687 // {
688 // return book1S(0, 0, pwd_, name, title, nchX, lowX, highX);
689 // }
690 
691 // MonitorElement*
692 // DQMStore::book1S(char_string const& name,
693 // char_string const& title,
694 // int const nchX, float const* xbinsize)
695 // {
696 // return book1S(0, 0, pwd_, name, title, nchX, xbinsize);
697 // }
698 
699 // MonitorElement*
700 // DQMStore::book1S(char_string const& name, TH1S* h)
701 // {
702 // return book1S(0, 0, pwd_, name, h);
703 // }
704 
705 // MonitorElement*
706 // DQMStore::book1DD(char_string const& name,
707 // char_string const& title,
708 // int const nchX, double const lowX, double const highX)
709 // {
710 // return book1DD(0, 0, pwd_, name, title, nchX, lowX, highX);
711 // }
712 
713 // MonitorElement*
714 // DQMStore::book1DD(char_string const& name,
715 // char_string const& title,
716 // int const nchX, float const* xbinsize)
717 // {
718 // return book1DD(0, 0, pwd_, name, title, nchX, xbinsize);
719 // }
720 
721 // MonitorElement*
722 // DQMStore::book1DD(char_string const& name, TH1D* h)
723 // {
724 // return book1DD(0, 0, pwd_, name, h);
725 // }
726 
727 // MonitorElement*
728 // DQMStore::book2D(char_string const& name,
729 // char_string const& title,
730 // int const nchX, double const lowX, double const highX,
731 // int const nchY, double const lowY, double const highY)
732 // {
733 // return book2D(0, 0, pwd_, name, title, nchX, lowX, highX, nchY, lowY, highY);
734 // }
735 
736 // MonitorElement*
737 // DQMStore::book2D(char_string const& name,
738 // char_string const& title,
739 // int const nchX, float const* xbinsize,
740 // int const nchY, float const* ybinsize)
741 // {
742 // return book2D(0, 0, pwd_, name, title, nchX, xbinsize, nchY, ybinsize);
743 // }
744 
745 // MonitorElement*
746 // DQMStore::book2D(char_string const& name, TH2F* h)
747 // {
748 // return book2D(0, 0, pwd_, name, h);
749 // }
750 
751 // MonitorElement*
752 // DQMStore::book2S(char_string const& name,
753 // char_string const& title,
754 // int const nchX, double const lowX, double const highX,
755 // int const nchY, double const lowY, double const highY)
756 // {
757 // return book2S(0, 0, pwd_, name, title, nchX, lowX, highX, nchY, lowY, highY);
758 // }
759 
760 // MonitorElement*
761 // DQMStore::book2S(char_string const& name,
762 // char_string const& title,
763 // int const nchX, float const* xbinsize,
764 // int const nchY, float const* ybinsize)
765 // {
766 // return book2S(0, 0, pwd_, name, title, nchX, xbinsize, nchY, ybinsize);
767 // }
768 
769 // MonitorElement*
770 // DQMStore::book2S(char_string const& name, TH2S* h)
771 // {
772 // return book2S(0, 0, pwd_, name, h);
773 // }
774 
775 // MonitorElement*
776 // DQMStore::book2DD(char_string const& name,
777 // char_string const& title,
778 // int const nchX, double const lowX, double const highX,
779 // int const nchY, double const lowY, double const highY)
780 // {
781 // return book2DD(0, 0, pwd_, name, title, nchX, lowX, highX, nchY, lowY, highY);
782 // }
783 
784 // MonitorElement*
785 // DQMStore::book2DD(char_string const& name,
786 // char_string const& title,
787 // int const nchX, float const* xbinsize,
788 // int const nchY, float const* ybinsize)
789 // {
790 // return book2DD(0, 0, pwd_, name, title, nchX, xbinsize, nchY, ybinsize);
791 // }
792 
793 // MonitorElement*
794 // DQMStore::book2DD(char_string const& name, TH2D* h)
795 // {
796 // return book2DD(0, 0, pwd_, name, h);
797 // }
798 
799 // MonitorElement*
800 // DQMStore::book3D(char_string const& name,
801 // char_string const& title,
802 // int const nchX, double const lowX, double const highX,
803 // int const nchY, double const lowY, double const highY,
804 // int const nchZ, double const lowZ, double const highZ)
805 // {
806 // return book3D(0, 0, pwd_, name, title,
807 // nchX, lowX, highX,
808 // nchY, lowY, highY,
809 // nchZ, lowZ, highZ);
810 // }
811 
812 // MonitorElement*
813 // DQMStore::book3D(char_string const& name, TH3F* h)
814 // {
815 // return book3D(0, 0, pwd_, name, h);
816 // }
817 
818 // MonitorElement*
819 // DQMStore::bookProfile(char_string const& name,
820 // char_string const& title,
821 // int const nchX, double const lowX, double const highX,
822 // int const nchY, double const lowY, double const highY,
823 // char const* option)
824 // {
825 // return bookProfile(0, 0, pwd_, name, title, nchX, lowX, highX, nchY, lowY, highY, option);
826 // }
827 
828 // MonitorElement*
829 // DQMStore::bookProfile(char_string const& name,
830 // char_string const& title,
831 // int const nchX, double const lowX, double const highX,
832 // double const lowY, double const highY,
833 // char const* option)
834 // {
835 // return bookProfile(0, 0, pwd_, name, title, nchX, lowX, highX, lowY, highY, option);
836 // }
837 
838 // MonitorElement*
839 // DQMStore::bookProfile(char_string const& name,
840 // char_string const& title,
841 // int const nchX, double const* xbinsize,
842 // int const nchY, double const lowY, double const highY,
843 // char const* option)
844 // {
845 // return bookProfile(0, 0, pwd_, name, title, nchX, xbinsize, nchY, lowY, highY, option);
846 // }
847 
848 // MonitorElement*
849 // DQMStore::bookProfile(char_string const& name,
850 // char_string const& title,
851 // int const nchX, double const* xbinsize,
852 // double const lowY, double const highY,
853 // char const* option)
854 // {
855 // return bookProfile(0, 0, pwd_, name, title, nchX, xbinsize, lowY, highY, option);
856 // }
857 
858 // MonitorElement*
859 // DQMStore::bookProfile(char_string const& name, TProfile* h)
860 // {
861 // return bookProfile(0, 0, pwd_, name, h);
862 // }
863 
864 // MonitorElement*
865 // DQMStore::bookProfile2D(char_string const& name,
866 // char_string const& title,
867 // int const nchX, double const lowX, double const highX,
868 // int const nchY, double const lowY, double const highY,
869 // int const nchZ, double const lowZ, double const highZ,
870 // char const* option)
871 // {
872 // return bookProfile2D(0, 0, pwd_, name, title,
873 // nchX, lowX, highX,
874 // nchY, lowY, highY,
875 // nchZ, lowZ, highZ, option);
876 // }
877 
878 // MonitorElement*
879 // DQMStore::bookProfile2D(char_string const& name,
880 // char_string const& title,
881 // int const nchX, double const lowX, double const highX,
882 // int const nchY, double const lowY, double const highY,
883 // double const lowZ, double const highZ,
884 // char const* option)
885 // {
886 // return bookProfile2D(0, 0, pwd_, name, title,
887 // nchX, lowX, highX,
888 // nchY, lowY, highY,
889 // lowZ, highZ, option);
890 // }
891 
892 // MonitorElement*
893 // DQMStore::bookProfile2D(char_string const& name, TProfile2D* h)
894 // {
895 // return bookProfile2D(0, 0, pwd_, name, h);
896 // }
897 
898 
902 template <class HISTO, class COLLATE>
905  std::string const& name,
906  char const* context,
907  int const kind,
908  HISTO* h,
909  COLLATE collate)
910 {
911  assert(name.find('/') == std::string::npos);
912  if (verbose_ > 3)
913  print_trace(dir, name);
915  mergePath(path, dir, name);
916 
917  // Put us in charge of h.
918  h->SetDirectory(nullptr);
919 
920  // Check if the request monitor element already exists.
921  MonitorElement* me = findObject(run_, 0, moduleId_, dir, name);
922  if (me) {
923  if (collateHistograms_) {
924  collate(me, h, verbose_);
925  delete h;
926  return me;
927  }
928  else {
929  if (verbose_ > 1)
930  std::cout << "DQMStore: "
931  << context << ": monitor element '"
932  << path << "' already exists, collating" << std::endl;
933  me->Reset();
934  collate(me, h, verbose_);
935  delete h;
936  return me;
937  }
938  }
939  else {
940  // Create and initialise core object.
941  assert(dirs_.count(dir));
942  MonitorElement proto(&*dirs_.find(dir), name, run_, moduleId_);
943  if (doSaveByLumi_ && canSaveByLumi_) {
944  // for legacy (not DQMEDAnalyzer) this is not save.
945  proto.setLumiFlag(); // default to per-lumi mode for all non-legacy MEs.
946  }
947  me = const_cast<MonitorElement&>(*data_.insert(std::move(proto)).first)
949 
950  // Initialise quality test information.
951  for (auto const& q : qtestspecs_) {
952  if (q.first->match(path))
953  me->addQReport(q.second);
954  }
955 
956  // If we just booked a (plain) MonitorElement, and there is a reference
957  // MonitorElement with the same name, link the two together.
958  // The other direction is handled by the extract method.
959  std::string refdir;
960  refdir.reserve(s_referenceDirName.size() + dir.size() + 1);
961  refdir += s_referenceDirName;
962  refdir += '/';
963  refdir += dir;
964  MonitorElement* referenceME = findObject(0, 0, 0, refdir, name);
965  if (referenceME) {
966  // We have booked a new MonitorElement with a specific dir and name.
967  // Then, if we can find the corresponding MonitorElement in the reference
968  // dir we assign the object_ of the reference MonitorElement to the
969  // reference_ property of our new MonitorElement.
971  me->reference_ = referenceME->object_;
972  }
973 
974  // Return the monitor element.
975  return me;
976  }
977 }
978 
981  std::string const& name,
982  char const* context)
983 {
984  assert(name.find('/') == std::string::npos);
985  if (verbose_ > 3)
986  print_trace(dir, name);
987 
988  // Check if the request monitor element already exists.
989  if (MonitorElement* me = findObject(run_, 0, moduleId_, dir, name)) {
990  if (verbose_ > 1) {
992  mergePath(path, dir, name);
993 
994  std::cout << "DQMStore: "
995  << context << ": monitor element '"
996  << path << "' already exists, resetting" << std::endl;
997  }
998  me->Reset();
999  return me;
1000  }
1001  else {
1002  // Create it and return for initialisation.
1003  assert(dirs_.count(dir));
1004  MonitorElement proto(&*dirs_.find(dir), name, run_, moduleId_);
1005  // this is used only for Int/String/Float. We don't save these by lumi by
1006  // default, since we can't merge them properly.
1007  return &const_cast<MonitorElement&>(*data_.insert(std::move(proto)).first);
1008  }
1009 }
1010 
1011 // -------------------------------------------------------------------
1015 {
1016  if (collateHistograms_) {
1017  if (MonitorElement* me = findObject(run_, 0, moduleId_, dir, name)) {
1018  me->Fill(0);
1019  return me;
1020  }
1021  }
1022  return book_(dir, name, "bookInt")->initialise(MonitorElement::DQM_KIND_INT);
1023 }
1024 
1028 {
1029  return bookInt_(pwd_, name);
1030 }
1031 
1032 // -------------------------------------------------------------------
1036 {
1037  if (collateHistograms_) {
1038  if (MonitorElement* me = findObject(run_, 0, moduleId_, dir, name)) {
1039  me->Fill(0.);
1040  return me;
1041  }
1042  }
1043  return book_(dir, name, "bookFloat")->initialise(MonitorElement::DQM_KIND_REAL);
1044 }
1045 
1049 {
1050  return bookFloat_(pwd_, name);
1051 }
1052 
1053 // -------------------------------------------------------------------
1057  std::string const& name,
1058  std::string const& value)
1059 {
1060  if (collateHistograms_) {
1061  if (MonitorElement* me = findObject(run_, 0, moduleId_, dir, name))
1062  return me;
1063  }
1064  return book_(dir, name, "bookString")->initialise(MonitorElement::DQM_KIND_STRING, value);
1065 }
1066 
1070 {
1071  return bookString_(pwd_, name, value);
1072 }
1073 
1074 // -------------------------------------------------------------------
1077 DQMStore::book1D_(std::string const& dir, std::string const& name, TH1F* h)
1078 {
1079  return book_(dir, name, "book1D", MonitorElement::DQM_KIND_TH1F, h, collate1D);
1080 }
1081 
1084 DQMStore::book1S_(std::string const& dir, std::string const& name, TH1S* h)
1085 {
1086  return book_(dir, name, "book1S", MonitorElement::DQM_KIND_TH1S, h, collate1S);
1087 }
1088 
1091 DQMStore::book1DD_(std::string const& dir, std::string const& name, TH1D* h)
1092 {
1093  return book_(dir, name, "book1DD", MonitorElement::DQM_KIND_TH1D, h, collate1DD);
1094 }
1095 
1099  int const nchX, double const lowX, double const highX)
1100 {
1101  return book1D_(pwd_, name, new TH1F(name, title, nchX, lowX, highX));
1102 }
1103 
1107  int const nchX, double const lowX, double const highX)
1108 {
1109  return book1S_(pwd_, name, new TH1S(name, title, nchX, lowX, highX));
1110 }
1111 
1115  int const nchX, double const lowX, double const highX)
1116 {
1117  return book1DD_(pwd_, name, new TH1D(name, title, nchX, lowX, highX));
1118 }
1119 
1122 DQMStore::book1D(char_string const& name, char_string const& title,
1123  int const nchX, const float* xbinsize)
1124 {
1125  return book1D_(pwd_, name, new TH1F(name, title, nchX, xbinsize));
1126 }
1127 
1131 {
1132  return book1D_(pwd_, name, static_cast<TH1F*>(source->Clone(name)));
1133 }
1134 
1138 {
1139  return book1S_(pwd_, name, static_cast<TH1S*>(source->Clone(name)));
1140 }
1141 
1145 {
1146  return book1DD_(pwd_, name, static_cast<TH1D*>(source->Clone(name)));
1147 }
1148 
1149 // -------------------------------------------------------------------
1152 DQMStore::book2D_(std::string const& dir, std::string const& name, TH2F* h)
1153 {
1154  return book_(dir, name, "book2D", MonitorElement::DQM_KIND_TH2F, h, collate2D);
1155 }
1156 
1159 DQMStore::book2S_(std::string const& dir, std::string const& name, TH2S* h)
1160 {
1161  return book_(dir, name, "book2S", MonitorElement::DQM_KIND_TH2S, h, collate2S);
1162 }
1163 
1166 DQMStore::book2DD_(std::string const& dir, std::string const& name, TH2D* h)
1167 {
1168  return book_(dir, name, "book2DD", MonitorElement::DQM_KIND_TH2D, h, collate2DD);
1169 }
1170 
1173 DQMStore::book2D(char_string const& name, char_string const& title,
1174  int const nchX, double const lowX, double const highX,
1175  int const nchY, double const lowY, double const highY)
1176 {
1177  return book2D_(pwd_, name, new TH2F(name, title,
1178  nchX, lowX, highX,
1179  nchY, lowY, highY));
1180 }
1181 
1184 DQMStore::book2S(char_string const& name, char_string const& title,
1185  int const nchX, double const lowX, double const highX,
1186  int const nchY, double const lowY, double const highY)
1187 {
1188  return book2S_(pwd_, name, new TH2S(name, title,
1189  nchX, lowX, highX,
1190  nchY, lowY, highY));
1191 }
1192 
1195 DQMStore::book2DD(char_string const& name, char_string const& title,
1196  int const nchX, double const lowX, double const highX,
1197  int const nchY, double const lowY, double const highY)
1198 {
1199  return book2DD_(pwd_, name, new TH2D(name, title,
1200  nchX, lowX, highX,
1201  nchY, lowY, highY));
1202 }
1203 
1206 DQMStore::book2D(char_string const& name, char_string const& title,
1207  int const nchX, const float* xbinsize, int const nchY, const float* ybinsize)
1208 {
1209  return book2D_(pwd_, name, new TH2F(name, title,
1210  nchX, xbinsize, nchY, ybinsize));
1211 }
1212 
1215 DQMStore::book2S(char_string const& name, char_string const& title,
1216  int const nchX, const float* xbinsize, int const nchY, const float* ybinsize)
1217 {
1218  return book2S_(pwd_, name, new TH2S(name, title,
1219  nchX, xbinsize, nchY, ybinsize));
1220 }
1221 
1225 {
1226  return book2D_(pwd_, name, static_cast<TH2F*>(source->Clone(name)));
1227 }
1228 
1232 {
1233  return book2S_(pwd_, name, static_cast<TH2S*>(source->Clone(name)));
1234 }
1235 
1239 {
1240  return book2DD_(pwd_, name, static_cast<TH2D*>(source->Clone(name)));
1241 }
1242 
1243 // -------------------------------------------------------------------
1246 DQMStore::book3D_(std::string const& dir, std::string const& name, TH3F* h)
1247 {
1248  return book_(dir, name, "book3D", MonitorElement::DQM_KIND_TH3F, h, collate3D);
1249 }
1250 
1253 DQMStore::book3D(char_string const& name, char_string const& title,
1254  int const nchX, double const lowX, double const highX,
1255  int const nchY, double const lowY, double const highY,
1256  int const nchZ, double const lowZ, double const highZ)
1257 {
1258  return book3D_(pwd_, name, new TH3F(name, title,
1259  nchX, lowX, highX,
1260  nchY, lowY, highY,
1261  nchZ, lowZ, highZ));
1262 }
1263 
1267 {
1268  return book3D_(pwd_, name, static_cast<TH3F*>(source->Clone(name)));
1269 }
1270 
1271 // -------------------------------------------------------------------
1274 DQMStore::bookProfile_(std::string const& dir, std::string const& name, TProfile* h)
1275 {
1276  return book_(dir, name, "bookProfile",
1278  h, collateProfile);
1279 }
1280 
1286  int const nchX, double const lowX, double const highX,
1287  int /* nchY */, double const lowY, double const highY,
1288  char const* option /* = "s" */)
1289 {
1290  return bookProfile_(pwd_, name, new TProfile(name, title,
1291  nchX, lowX, highX,
1292  lowY, highY,
1293  option));
1294 }
1295 
1301  int const nchX, double const lowX, double const highX,
1302  double const lowY, double const highY,
1303  char const* option /* = "s" */)
1304 {
1305  return bookProfile_(pwd_, name, new TProfile(name, title,
1306  nchX, lowX, highX,
1307  lowY, highY,
1308  option));
1309 }
1310 
1316  int const nchX, double const* xbinsize,
1317  int /* nchY */, double const lowY, double const highY,
1318  char const* option /* = "s" */)
1319 {
1320  return bookProfile_(pwd_, name, new TProfile(name, title,
1321  nchX, xbinsize,
1322  lowY, highY,
1323  option));
1324 }
1325 
1331  int const nchX, double const* xbinsize,
1332  double const lowY, double const highY,
1333  char const* option /* = "s" */)
1334 {
1335  return bookProfile_(pwd_, name, new TProfile(name, title,
1336  nchX, xbinsize,
1337  lowY, highY,
1338  option));
1339 }
1340 
1344 {
1345  return bookProfile_(pwd_, name, static_cast<TProfile*>(source->Clone(name)));
1346 }
1347 
1348 // -------------------------------------------------------------------
1351 DQMStore::bookProfile2D_(std::string const& dir, std::string const& name, TProfile2D* h)
1352 {
1353  return book_(dir, name, "bookProfile2D",
1355  h, collateProfile2D);
1356 }
1357 
1363  int const nchX, double const lowX, double const highX,
1364  int const nchY, double const lowY, double const highY,
1365  int /* nchZ */, double const lowZ, double const highZ,
1366  char const* option /* = "s" */)
1367 {
1368  return bookProfile2D_(pwd_, name, new TProfile2D(name, title,
1369  nchX, lowX, highX,
1370  nchY, lowY, highY,
1371  lowZ, highZ,
1372  option));
1373 }
1374 
1380  int const nchX, double const lowX, double const highX,
1381  int const nchY, double const lowY, double const highY,
1382  double const lowZ, double const highZ,
1383  char const* option /* = "s" */)
1384 {
1385  return bookProfile2D_(pwd_, name, new TProfile2D(name, title,
1386  nchX, lowX, highX,
1387  nchY, lowY, highY,
1388  lowZ, highZ,
1389  option));
1390 }
1391 
1394 DQMStore::bookProfile2D(char_string const& name, TProfile2D* source)
1395 {
1396  return bookProfile2D_(pwd_, name, static_cast<TProfile2D*>(source->Clone(name)));
1397 }
1398 
1402 bool
1404 {
1405  if (me->getTH1()->GetNbinsX() != h->GetNbinsX()
1406  || me->getTH1()->GetNbinsY() != h->GetNbinsY()
1407  || me->getTH1()->GetNbinsZ() != h->GetNbinsZ()
1408  || me->getTH1()->GetXaxis()->GetXmin() != h->GetXaxis()->GetXmin()
1409  || me->getTH1()->GetYaxis()->GetXmin() != h->GetYaxis()->GetXmin()
1410  || me->getTH1()->GetZaxis()->GetXmin() != h->GetZaxis()->GetXmin()
1411  || me->getTH1()->GetXaxis()->GetXmax() != h->GetXaxis()->GetXmax()
1412  || me->getTH1()->GetYaxis()->GetXmax() != h->GetYaxis()->GetXmax()
1413  || me->getTH1()->GetZaxis()->GetXmax() != h->GetZaxis()->GetXmax()
1414  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetXaxis(),(TAxis*)h->GetXaxis())
1415  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetYaxis(),(TAxis*)h->GetYaxis())
1416  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetZaxis(),(TAxis*)h->GetZaxis())) {
1417  if(verbose > 0)
1418  std::cout << "*** DQMStore: WARNING:"
1419  << "checkBinningMatches: different binning - cannot add object '"
1420  << h->GetName() << "' of type "
1421  << h->IsA()->GetName() << " to existing ME: '"
1422  << me->getFullname() << "'\n";
1423  return false;
1424  }
1425  return true;
1426 }
1427 
1428 void
1429 DQMStore::collate1D(MonitorElement* me, TH1F* h, unsigned const verbose)
1430 {
1431  if (checkBinningMatches(me,h,verbose))
1432  me->getTH1F()->Add(h);
1433 }
1434 
1435 void
1436 DQMStore::collate1S(MonitorElement* me, TH1S* h, unsigned const verbose)
1437 {
1438  if (checkBinningMatches(me,h,verbose))
1439  me->getTH1S()->Add(h);
1440 }
1441 
1442 void
1443 DQMStore::collate1DD(MonitorElement* me, TH1D* h, unsigned const verbose)
1444 {
1445  if (checkBinningMatches(me,h,verbose))
1446  me->getTH1D()->Add(h);
1447 }
1448 
1449 void
1450 DQMStore::collate2D(MonitorElement* me, TH2F* h, unsigned const verbose)
1451 {
1452  if (checkBinningMatches(me,h,verbose))
1453  me->getTH2F()->Add(h);
1454 }
1455 
1456 void
1457 DQMStore::collate2S(MonitorElement* me, TH2S* h, unsigned const verbose)
1458 {
1459  if (checkBinningMatches(me,h,verbose))
1460  me->getTH2S()->Add(h);
1461 }
1462 
1463 void
1464 DQMStore::collate2DD(MonitorElement* me, TH2D* h, unsigned const verbose)
1465 {
1466  if (checkBinningMatches(me,h,verbose))
1467  me->getTH2D()->Add(h);
1468 }
1469 
1470 void
1471 DQMStore::collate3D(MonitorElement* me, TH3F* h, unsigned const verbose)
1472 {
1473  if (checkBinningMatches(me,h,verbose))
1474  me->getTH3F()->Add(h);
1475 }
1476 
1477 void
1478 DQMStore::collateProfile(MonitorElement* me, TProfile* h, unsigned const verbose)
1479 {
1480  if (checkBinningMatches(me,h,verbose)) {
1481  TProfile* meh = me->getTProfile();
1482  me->addProfiles(h, meh, meh, 1, 1);
1483  }
1484 }
1485 
1486 void
1487 DQMStore::collateProfile2D(MonitorElement* me, TProfile2D* h, unsigned const verbose)
1488 {
1489  if (checkBinningMatches(me,h,verbose)) {
1490  TProfile2D* meh = me->getTProfile2D();
1491  me->addProfiles(h, meh, meh, 1, 1);
1492  }
1493 }
1494 
1499 void
1500 DQMStore::tag(MonitorElement* me, unsigned int const myTag)
1501 {
1502  if (! myTag)
1503  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1504  " with a zero tag", me->getFullname().c_str());
1505  if ((me->data_.flags & DQMNet::DQM_PROP_TAGGED) && myTag != me->data_.tag)
1506  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1507  " twice with multiple tags", me->getFullname().c_str());
1508 
1509  me->data_.tag = myTag;
1511 }
1512 
1514 void
1515 DQMStore::tag(std::string const& path, unsigned int const myTag)
1516 {
1517  std::string dir;
1518  std::string name;
1519  splitPath(dir, name, path);
1520 
1521  if (MonitorElement* me = findObject(0, 0, 0, dir, name))
1522  tag(me, myTag);
1523  else
1524  raiseDQMError("DQMStore", "Attempt to tag non-existent monitor element"
1525  " '%s' with tag %u", path.c_str(), myTag);
1526 
1527 }
1528 
1530 void
1531 DQMStore::tagContents(std::string const& path, unsigned int const myTag)
1532 {
1533  MonitorElement proto(&path, std::string());
1534  auto e = data_.end();
1535  auto i = data_.lower_bound(proto);
1536  for ( ; i != e && path == *i->data_.dirname; ++i)
1537  tag(const_cast<MonitorElement *>(&*i), myTag);
1538 }
1539 
1542 void
1543 DQMStore::tagAllContents(std::string const& path, unsigned int const myTag)
1544 {
1546  std::string const* cleaned = nullptr;
1547  cleanTrailingSlashes(path, clean, cleaned);
1548  MonitorElement proto(cleaned, std::string());
1549 
1550  // FIXME: WILDCARDS? Old one supported them, but nobody seemed to use them.
1551  auto e = data_.end();
1552  auto i = data_.lower_bound(proto);
1553  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname)) {
1554  tag(const_cast<MonitorElement*>(&*i), myTag);
1555  ++i;
1556  }
1557 }
1558 
1563 std::vector<std::string>
1565 {
1566  std::vector<std::string> result;
1567  auto e = dirs_.end();
1568  auto i = dirs_.find(pwd_);
1569 
1570  // If we didn't find current directory, the tree is empty, so quit.
1571  if (i == e)
1572  return result;
1573 
1574  // Skip the current directory and then start looking for immediate
1575  // subdirectories in the dirs_ list. Stop when we are no longer in
1576  // (direct or indirect) subdirectories of pwd_. Note that we don't
1577  // "know" which order the set will sort A/B, A/B/C and A/D.
1578  while (++i != e && isSubdirectory(pwd_, *i))
1579  if (i->find('/', pwd_.size()+1) == std::string::npos)
1580  result.push_back(*i);
1581 
1582  return result;
1583 }
1584 
1586 std::vector<std::string>
1588 {
1589  MonitorElement proto(&pwd_, std::string());
1590  std::vector<std::string> result;
1591  auto e = data_.end();
1592  auto i = data_.lower_bound(proto);
1593  for ( ; i != e && isSubdirectory(pwd_, *i->data_.dirname); ++i)
1594  if (pwd_ == *i->data_.dirname)
1595  result.push_back(i->getName());
1596 
1597  return result;
1598 }
1599 
1602 bool
1604 {
1605  MonitorElement proto(&path, std::string());
1606  auto e = data_.end();
1607  auto i = data_.lower_bound(proto);
1608  return (i != e && isSubdirectory(path, *i->data_.dirname));
1609 }
1610 
1613 DQMStore::get(std::string const& path) const
1614 {
1615  std::string dir;
1616  std::string name;
1617  splitPath(dir, name, path);
1618  MonitorElement proto(&dir, name);
1619  auto mepos = data_.find(proto);
1620  return (mepos == data_.end() ? nullptr
1621  : const_cast<MonitorElement *>(&*mepos));
1622 }
1623 
1625 std::vector<MonitorElement*>
1626 DQMStore::get(unsigned int const tag) const
1627 {
1628  // FIXME: Use reverse map [tag -> path] / [tag -> dir]?
1629  std::vector<MonitorElement*> result;
1630  for (auto const& me : data_) {
1631  if ((me.data_.flags & DQMNet::DQM_PROP_TAGGED) && me.data_.tag == tag)
1632  result.push_back(const_cast<MonitorElement*>(&me));
1633  }
1634  return result;
1635 }
1636 
1639 std::vector<MonitorElement*>
1641 {
1643  std::string const* cleaned = nullptr;
1644  cleanTrailingSlashes(path, clean, cleaned);
1645  MonitorElement proto(cleaned, std::string());
1646 
1647  std::vector<MonitorElement*> result;
1648  auto e = data_.end();
1649  auto i = data_.lower_bound(proto);
1650  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1651  if (*cleaned == *i->data_.dirname)
1652  result.push_back(const_cast<MonitorElement *>(&*i));
1653 
1654  return result;
1655 }
1656 
1658 std::vector<MonitorElement*>
1659 DQMStore::getContents(std::string const& path, unsigned int const tag) const
1660 {
1662  std::string const* cleaned = nullptr;
1663  cleanTrailingSlashes(path, clean, cleaned);
1664  MonitorElement proto(cleaned, std::string());
1665 
1666  std::vector<MonitorElement*> result;
1667  auto e = data_.end();
1668  auto i = data_.lower_bound(proto);
1669  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1670  if (*cleaned == *i->data_.dirname
1671  && (i->data_.flags & DQMNet::DQM_PROP_TAGGED)
1672  && i->data_.tag == tag)
1673  result.push_back(const_cast<MonitorElement *>(&*i));
1674 
1675  return result;
1676 }
1677 
1682 void
1683 DQMStore::getContents(std::vector<std::string>& into, bool const showContents /* = true */) const
1684 {
1685  into.clear();
1686  into.reserve(dirs_.size());
1687 
1688  auto me = data_.end();
1689  for (auto const& dir : dirs_)
1690  {
1691  MonitorElement proto(&dir, std::string());
1692  auto mi = data_.lower_bound(proto);
1693  auto m = mi;
1694  size_t sz = dir.size() + 2;
1695  size_t nfound = 0;
1696  for ( ; m != me && isSubdirectory(dir, *m->data_.dirname); ++m)
1697  if (dir == *m->data_.dirname)
1698  {
1699  sz += m->data_.objname.size() + 1;
1700  ++nfound;
1701  }
1702 
1703  if (! nfound)
1704  continue;
1705 
1706  auto istr
1707  = into.insert(into.end(), std::string());
1708 
1709  if (showContents)
1710  {
1711  istr->reserve(sz);
1712 
1713  *istr += dir;
1714  *istr += ':';
1715  for (sz = 0; mi != m; ++mi)
1716  {
1717  if (dir != *mi->data_.dirname)
1718  continue;
1719 
1720  if (sz > 0)
1721  *istr += ',';
1722 
1723  *istr += mi->data_.objname;
1724  ++sz;
1725  }
1726  }
1727  else
1728  {
1729  istr->reserve(dir.size() + 2);
1730  *istr += dir;
1731  *istr += ':';
1732  }
1733  }
1734 }
1735 
1739 DQMStore::findObject(uint32_t const run,
1740  uint32_t const lumi,
1741  uint32_t const moduleId,
1742  std::string const& dir,
1743  std::string const& name) const
1744 {
1745  if (dir.find_first_not_of(s_safe) != std::string::npos)
1746  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1747  " unacceptable characters", dir.c_str());
1748  if (name.find_first_not_of(s_safe) != std::string::npos)
1749  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1750  " unacceptable characters", name.c_str());
1751 
1752  MonitorElement proto;
1753  proto.data_.dirname = &dir;
1754  proto.data_.objname = name;
1755  proto.data_.run = run;
1756  proto.data_.lumi = lumi;
1757  proto.data_.moduleId = moduleId;
1758 
1759  auto mepos = data_.find(proto);
1760  return (mepos == data_.end() ? nullptr
1761  : const_cast<MonitorElement *>(&*mepos));
1762 }
1763 
1766 std::vector<MonitorElement*>
1768  uint32_t const run /* = 0 */,
1769  uint32_t const lumi /* = 0 */) const
1770 {
1772  std::string const* cleaned = nullptr;
1773  cleanTrailingSlashes(path, clean, cleaned);
1774  MonitorElement proto(cleaned, std::string(), run, 0);
1775  proto.setLumi(lumi);
1776 
1777  std::vector<MonitorElement*> result;
1778  auto e = data_.end();
1779  auto i = data_.lower_bound(proto);
1780  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
1781  if (run != 0) {
1782  if (i->data_.run > run // TODO[rovere]: pleonastic? first we encounter local ME of the same run ...
1783  || i->data_.moduleId != 0)
1784  break;
1785  }
1786  if (lumi != 0) {
1787  if (i->data_.lumi > lumi
1788  || i->data_.moduleId != 0)
1789  break;
1790  }
1791  if (run != 0 or lumi !=0) {
1792  assert(i->data_.moduleId == 0);
1793  }
1794  result.push_back(const_cast<MonitorElement*>(&*i));
1795  }
1796 
1797  if (enableMultiThread_) {
1798  //save legacy modules when running MT
1799  i = data_.begin();
1800  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
1801  if (i->data_.run != 0 or i->data_.moduleId != 0)
1802  break;
1803  result.push_back(const_cast<MonitorElement*>(&*i));
1804  }
1805  }
1806 
1807  return result;
1808 }
1809 
1812 std::vector<MonitorElement*>
1813 DQMStore::getMatchingContents(std::string const& pattern, lat::Regexp::Syntax const syntaxType /* = Wildcard */) const
1814 {
1815  lat::Regexp rx;
1816  try {
1817  rx = lat::Regexp(pattern, 0, syntaxType);
1818  rx.study();
1819  }
1820  catch (lat::Error& e) {
1821  raiseDQMError("DQMStore", "Invalid regular expression '%s': %s",
1822  pattern.c_str(), e.explain().c_str());
1823  }
1824 
1825  std::string path;
1826  std::vector<MonitorElement *> result;
1827  for (auto const& me : data_) {
1828  path.clear();
1829  mergePath(path, *me.data_.dirname, me.data_.objname);
1830  if (rx.match(path))
1831  result.push_back(const_cast<MonitorElement*>(&me));
1832  }
1833 
1834  return result;
1835 }
1836 
1840 
1843 void
1845 {
1846  for (auto const& m : data_) {
1847  auto& me = const_cast<MonitorElement&>(m);
1848  if (me.wasUpdated()) {
1849  if (me.resetMe())
1850  me.Reset();
1851  me.resetUpdate();
1852  }
1853  }
1854 
1855  reset_ = true;
1856 }
1857 
1861 
1863 void
1865 {
1866  for (auto const& m : data_) {
1867  if (forceResetOnBeginLumi_ && (m.getLumiFlag() == false))
1868  continue;
1869  auto& me = const_cast<MonitorElement&>(m);
1870  me.Reset();
1871  me.resetUpdate();
1872  }
1873 
1874  reset_ = true;
1875 }
1876 
1877 
1881 
1885 void
1887 {
1888  static const std::string null_str("");
1889 
1890  auto const& lumiblock = gc.luminosityBlockID();
1891  uint32_t run = lumiblock.run();
1892 
1893  // find the range of non-legacy global MEs for the current run:
1894  // run != 0, lumi == 0 (implicit), stream id == 0, module id == 0
1895  const MonitorElement begin(&null_str, null_str, run, 0);
1896  const MonitorElement end(&null_str, null_str, run, 1);
1897  auto i = data_.lower_bound(begin);
1898  const auto e = data_.lower_bound(end);
1899  while (i != e) {
1900  auto& me = const_cast<MonitorElement&>(*i++);
1901  // skip per-run MEs
1902  if (not LSbasedMode_ and not me.getLumiFlag())
1903  continue;
1904  me.Reset();
1905  me.resetUpdate();
1906  }
1907 }
1908 
1912 
1919 void
1920 DQMStore::cloneLumiHistograms(uint32_t const run, uint32_t const lumi, uint32_t const moduleId)
1921 {
1922  if (verbose_ > 1) {
1923  std::cout << "DQMStore::cloneLumiHistograms - Preparing lumi histograms for run: "
1924  << run << ", lumi: " << lumi << ", module: " << moduleId << std::endl;
1925  }
1926 
1927  // acquire the global lock since this accesses the undelying data structure
1928  std::lock_guard<std::mutex> guard(book_mutex_);
1929 
1930  // MEs are sorted by (run, lumi, stream id, module id, directory, name)
1931  // lumi deafults to 0
1932  // stream id is always 0
1933  std::string null_str("");
1934  auto i = data_.lower_bound(MonitorElement(&null_str, null_str, run, moduleId));
1935  auto e = data_.lower_bound(MonitorElement(&null_str, null_str, run, moduleId + 1));
1936  // we will later modify data_, so better do two passes.
1937  auto tobehandled = std::vector<MonitorElement const*>();
1938  for (; i != e; ++i) {
1939  tobehandled.push_back(&*i);
1940  }
1941  for (auto i : tobehandled) {
1942  // handle only lumisection-based histograms
1943  if (not LSbasedMode_ and not i->getLumiFlag())
1944  continue;
1945 
1946  // clone the lumisection-based histograms
1948  clone.globalize();
1949  clone.setLumi(lumi);
1950  clone.markToDelete();
1951  data_.insert(std::move(clone));
1952 
1953  // reset the ME for the next lumisection
1954  const_cast<MonitorElement*>(&*i)->Reset();
1955  }
1956 }
1957 
1961 void
1962 DQMStore::cloneRunHistograms(uint32_t const run, uint32_t const moduleId)
1963 {
1964  if (verbose_ > 1) {
1965  std::cout << "DQMStore::cloneRunHistograms - Preparing run histograms for run: "
1966  << run << ", module: " << moduleId << std::endl;
1967  }
1968 
1969  // acquire the global lock since this accesses the undelying data structure
1970  std::lock_guard<std::mutex> guard(book_mutex_);
1971 
1972  // MEs are sorted by (run, lumi, stream id, module id, directory, name)
1973  // lumi deafults to 0
1974  // stream id is always 0
1975  std::string null_str("");
1976  auto i = data_.lower_bound(MonitorElement(&null_str, null_str, run, moduleId));
1977  auto e = data_.lower_bound(MonitorElement(&null_str, null_str, run, moduleId + 1));
1978  // we will later modify data_, so better do two passes.
1979  auto tobehandled = std::vector<MonitorElement const*>();
1980  for (; i != e; ++i) {
1981  tobehandled.push_back(&*i);
1982  }
1983  for (auto i : tobehandled) {
1984  // handle only non lumisection-based histograms
1985  if (LSbasedMode_ or i->getLumiFlag())
1986  continue;
1987 
1988  // clone the lumisection-based histograms
1990  clone.globalize();
1991  clone.markToDelete();
1992  data_.insert(std::move(clone));
1993 
1994  // reset the ME for the next lumisection
1995  const_cast<MonitorElement*>(&*i)->Reset();
1996  }
1997 }
1998 
1999 
2004 void
2005 DQMStore::deleteUnusedLumiHistograms(uint32_t const run, uint32_t const lumi)
2006 {
2007  if (!enableMultiThread_)
2008  return;
2009 
2010  std::lock_guard<std::mutex> guard(book_mutex_);
2011 
2012  std::string null_str("");
2013  MonitorElement proto(&null_str, null_str, run, 0);
2014  proto.setLumi(lumi);
2015 
2016  auto e = data_.end();
2017  auto i = data_.lower_bound(proto);
2018 
2019  while (i != e) {
2020  if (i->data_.moduleId != 0)
2021  break;
2022  if (i->data_.lumi != lumi)
2023  break;
2024  if (i->data_.run != run)
2025  break;
2026  if (not i->markedToDelete()) {
2027  ++i;
2028  continue;
2029  }
2030 
2031  if (verbose_ > 1) {
2032  std::cout << "DQMStore::deleteUnusedLumiHistograms: deleted monitor element '"
2033  << *i->data_.dirname << "/" << i->data_.objname << "'"
2034  << "flags " << i->data_.flags << "\n";
2035  }
2036 
2037  i = data_.erase(i);
2038  }
2039 }
2040 
2046 bool
2048  std::string const& dir,
2049  bool const overwrite,
2050  bool const collateHistograms)
2051 {
2052  // NB: Profile histograms inherit from TH*D, checking order matters.
2053  MonitorElement *refcheck = nullptr;
2054  if (auto* h = dynamic_cast<TProfile*>(obj)) {
2055  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2056  if (! me)
2057  me = bookProfile_(dir, h->GetName(), (TProfile*) h->Clone());
2058  else if (overwrite)
2059  me->copyFrom(h);
2060  else if (isCollateME(me) || collateHistograms)
2061  collateProfile(me, h, verbose_);
2062  refcheck = me;
2063  }
2064  else if (auto* h = dynamic_cast<TProfile2D*>(obj)) {
2065  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2066  if (! me)
2067  me = bookProfile2D_(dir, h->GetName(), (TProfile2D*) h->Clone());
2068  else if (overwrite)
2069  me->copyFrom(h);
2070  else if (isCollateME(me) || collateHistograms)
2071  collateProfile2D(me, h, verbose_);
2072  refcheck = me;
2073  }
2074  else if (auto* h = dynamic_cast<TH1F*>(obj)) {
2075  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2076  if (! me)
2077  me = book1D_(dir, h->GetName(), (TH1F*) h->Clone());
2078  else if (overwrite)
2079  me->copyFrom(h);
2080  else if (isCollateME(me) || collateHistograms)
2081  collate1D(me, h, verbose_);
2082  refcheck = me;
2083  }
2084  else if (auto* h = dynamic_cast<TH1S*>(obj)) {
2085  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2086  if (! me)
2087  me = book1S_(dir, h->GetName(), (TH1S*) h->Clone());
2088  else if (overwrite)
2089  me->copyFrom(h);
2090  else if (isCollateME(me) || collateHistograms)
2091  collate1S(me, h, verbose_);
2092  refcheck = me;
2093  }
2094  else if (auto* h = dynamic_cast<TH1D*>(obj)) {
2095  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2096  if (! me)
2097  me = book1DD_(dir, h->GetName(), (TH1D*) h->Clone());
2098  else if (overwrite)
2099  me->copyFrom(h);
2100  else if (isCollateME(me) || collateHistograms)
2101  collate1DD(me, h, verbose_);
2102  refcheck = me;
2103  }
2104  else if (auto* h = dynamic_cast<TH2F*>(obj)) {
2105  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2106  if (! me)
2107  me = book2D_(dir, h->GetName(), (TH2F*) h->Clone());
2108  else if (overwrite)
2109  me->copyFrom(h);
2110  else if (isCollateME(me) || collateHistograms)
2111  collate2D(me, h, verbose_);
2112  refcheck = me;
2113  }
2114  else if (auto* h = dynamic_cast<TH2S*>(obj)) {
2115  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2116  if (! me)
2117  me = book2S_(dir, h->GetName(), (TH2S*) h->Clone());
2118  else if (overwrite)
2119  me->copyFrom(h);
2120  else if (isCollateME(me) || collateHistograms)
2121  collate2S(me, h, verbose_);
2122  refcheck = me;
2123  }
2124  else if (auto* h = dynamic_cast<TH2D*>(obj)) {
2125  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2126  if (! me)
2127  me = book2DD_(dir, h->GetName(), (TH2D*) h->Clone());
2128  else if (overwrite)
2129  me->copyFrom(h);
2130  else if (isCollateME(me) || collateHistograms)
2131  collate2DD(me, h, verbose_);
2132  refcheck = me;
2133  }
2134  else if (auto* h = dynamic_cast<TH3F*>(obj)) {
2135  MonitorElement* me = findObject(0, 0, 0, dir, h->GetName());
2136  if (! me)
2137  me = book3D_(dir, h->GetName(), (TH3F*) h->Clone());
2138  else if (overwrite)
2139  me->copyFrom(h);
2140  else if (isCollateME(me) || collateHistograms)
2141  collate3D(me, h, verbose_);
2142  refcheck = me;
2143  }
2144  else if (dynamic_cast<TObjString*>(obj)) {
2145  lat::RegexpMatch m;
2146  if (! s_rxmeval.match(obj->GetName(), 0, 0, &m)) {
2147  if (strstr(obj->GetName(), "CMSSW")) {
2148  if (verbose_)
2149  std::cout << "Input file version: " << obj->GetName() << std::endl;
2150  return true;
2151  }
2152  else if (strstr(obj->GetName(), "DQMPATCH")) {
2153  if (verbose_)
2154  std::cout << "DQM patch version: " << obj->GetName() << std::endl;
2155  return true;
2156  }
2157  else {
2158  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2159  << obj->GetName() << "' of type '"
2160  << obj->IsA()->GetName() << "'\n";
2161  return false;
2162  }
2163  }
2164 
2165  std::string label = m.matchString(obj->GetName(), 1);
2166  std::string kind = m.matchString(obj->GetName(), 2);
2167  std::string value = m.matchString(obj->GetName(), 3);
2168 
2169  if (kind == "i") {
2170  MonitorElement* me = findObject(0, 0, 0, dir, label);
2171  if (! me || overwrite) {
2172  if (! me) me = bookInt_(dir, label);
2173  me->Fill(atoll(value.c_str()));
2174  }
2175  }
2176  else if (kind == "f") {
2177  MonitorElement* me = findObject(0, 0, 0, dir, label);
2178  if (! me || overwrite) {
2179  if (! me) me = bookFloat_(dir, label);
2180  me->Fill(atof(value.c_str()));
2181  }
2182  }
2183  else if (kind == "s") {
2184  MonitorElement* me = findObject(0, 0, 0, dir, label);
2185  if (! me)
2186  me = bookString_(dir, label, value);
2187  else if (overwrite)
2188  me->Fill(value);
2189  }
2190  else if (kind == "e") {
2191  MonitorElement* me = findObject(0, 0, 0, dir, label);
2192  if (! me) {
2193  std::cout << "*** DQMStore: WARNING: no monitor element '"
2194  << label << "' in directory '"
2195  << dir << "' to be marked as efficiency plot.\n";
2196  return false;
2197  }
2198  me->setEfficiencyFlag();
2199  }
2200  else if (kind == "t") {
2201  MonitorElement* me = findObject(0, 0, 0, dir, label);
2202  if (! me) {
2203  std::cout << "*** DQMStore: WARNING: no monitor element '"
2204  << label << "' in directory '"
2205  << dir << "' for a tag\n";
2206  return false;
2207  }
2208  errno = 0;
2209  char* endp = nullptr;
2210  unsigned long val = strtoul(value.c_str(), &endp, 10);
2211  if ((val == 0 && errno) || *endp || val > ~uint32_t(0)) {
2212  std::cout << "*** DQMStore: WARNING: cannot restore tag '"
2213  << value << "' for monitor element '"
2214  << label << "' in directory '"
2215  << dir << "' - invalid value\n";
2216  return false;
2217  }
2218  tag(me, val);
2219  }
2220  else if (kind == "qr") {
2221  // Handle qreports, but skip them while reading in references.
2222  if (! isSubdirectory(s_referenceDirName, dir)) {
2223  size_t dot = label.find('.');
2224  if (dot == std::string::npos) {
2225  std::cout << "*** DQMStore: WARNING: quality report label in '" << label
2226  << "' is missing a '.' and cannot be extracted\n";
2227  return false;
2228  }
2229 
2230  std::string mename (label, 0, dot);
2231  std::string qrname (label, dot+1, std::string::npos);
2232 
2233  m.reset();
2234  DQMNet::QValue qv;
2235  if (s_rxmeqr1.match(value, 0, 0, &m)) {
2236  qv.code = atoi(m.matchString(value, 1).c_str());
2237  qv.qtresult = strtod(m.matchString(value, 2).c_str(), nullptr);
2238  qv.message = m.matchString(value, 4);
2239  qv.qtname = qrname;
2240  qv.algorithm = m.matchString(value, 3);
2241  }
2242  else if (s_rxmeqr2.match(value, 0, 0, &m)) {
2243  qv.code = atoi(m.matchString(value, 1).c_str());
2244  qv.qtresult = 0; // unavailable in old format
2245  qv.message = m.matchString(value, 2);
2246  qv.qtname = qrname;
2247  // qv.algorithm unavailable in old format
2248  }
2249  else {
2250  std::cout << "*** DQMStore: WARNING: quality test value '"
2251  << value << "' is incorrectly formatted\n";
2252  return false;
2253  }
2254 
2255  MonitorElement* me = findObject(0, 0, 0, dir, mename);
2256  if (! me) {
2257  std::cout << "*** DQMStore: WARNING: no monitor element '"
2258  << mename << "' in directory '"
2259  << dir << "' for quality test '"
2260  << label << "'\n";
2261  return false;
2262  }
2263 
2264  me->addQReport(qv, /* FIXME: getQTest(qv.qtname)? */ nullptr);
2265  }
2266  }
2267  else {
2268  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2269  << obj->GetName() << "' of type '"
2270  << obj->IsA()->GetName() << "'\n";
2271  return false;
2272  }
2273  }
2274  else if (auto* n = dynamic_cast<TNamed*>(obj)) {
2275  // For old DQM data.
2276  std::string s;
2277  s.reserve(6 + strlen(n->GetTitle()) + 2*strlen(n->GetName()));
2278  s += '<'; s += n->GetName(); s += '>';
2279  s += n->GetTitle();
2280  s += '<'; s += '/'; s += n->GetName(); s += '>';
2281  TObjString os(s.c_str());
2282  return extract(&os, dir, overwrite, collateHistograms_);
2283  }
2284  else {
2285  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2286  << obj->GetName() << "' of type '" << obj->IsA()->GetName()
2287  << "' and with title '" << obj->GetTitle() << "'\n";
2288  return false;
2289  }
2290 
2291  // If we just read in a reference MonitorElement, and there is a
2292  // MonitorElement with the same name, link the two together.
2293  // The other direction is handled by the book() method.
2294  if (refcheck && isSubdirectory(s_referenceDirName, dir)) {
2295  std::string mdir(dir, s_referenceDirName.size()+1, std::string::npos);
2296  if (MonitorElement* master = findObject(0, 0, 0, mdir, obj->GetName())) {
2297  // We have extracted a MonitorElement, and it's located in the reference
2298  // dir. Then we find the corresponding MonitorElement in the
2299  // non-reference dir and assign the object_ of the reference
2300  // MonitorElement to the reference_ property of the corresponding
2301  // non-reference MonitorElement.
2302  master->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
2303  master->reference_ = refcheck->object_;
2304  }
2305  }
2306 
2307  return true;
2308 }
2309 
2313 bool
2314 DQMStore::cdInto(std::string const& path) const
2315 {
2316  assert(! path.empty());
2317 
2318  // Find the first path component.
2319  size_t start = 0;
2320  size_t end = path.find('/', start);
2321  if (end == std::string::npos)
2322  end = path.size();
2323 
2324  while (true) {
2325  // Check if this subdirectory component exists. If yes, make sure
2326  // it is actually a subdirectory. Otherwise create or cd into it.
2327  std::string part(path, start, end-start);
2328  TObject* o = gDirectory->Get(part.c_str());
2329  if (o && ! dynamic_cast<TDirectory*>(o))
2330  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2331  " fails because the part '%s' already exists and is not"
2332  " directory", path.c_str(), part.c_str());
2333  else if (! o)
2334  gDirectory->mkdir(part.c_str());
2335 
2336  if (! gDirectory->cd(part.c_str()))
2337  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2338  " fails because could not cd into subdirectory '%s'",
2339  path.c_str(), part.c_str());
2340 
2341  // Stop if we reached the end, ignoring any trailing '/'.
2342  if (end+1 >= path.size())
2343  break;
2344 
2345  // Find the next path component.
2346  start = end+1;
2347  end = path.find('/', start);
2348  if (end == std::string::npos)
2349  end = path.size();
2350  }
2351 
2352  return true;
2353 }
2354 
2355 void
2357  TFile& file)
2358 {
2359  // Save the object.
2360  if (me.kind() < MonitorElement::DQM_KIND_TH1F) {
2361  TObjString(me.tagString().c_str()).Write();
2362  } else {
2363  me.object_->Write();
2364  }
2365 
2366  // Save quality reports if this is not in reference section.
2367  if (not isSubdirectory(s_referenceDirName, *me.data_.dirname)) {
2368  for (auto const& report: me.data_.qreports) {
2369  TObjString(me.qualityTagString(report).c_str()).Write();
2370  }
2371  }
2372 
2373  // Save efficiency tag, if any.
2375  TObjString(me.effLabelString().c_str()).Write();
2376  }
2377 
2378  // Save tag if any.
2379  if (me.data_.flags & DQMNet::DQM_PROP_TAGGED) {
2380  TObjString(me.tagLabelString().c_str()).Write();
2381  }
2382 }
2383 
2384 void
2386  std::string const& refpath,
2387  SaveReferenceTag const ref,
2388  int const minStatus,
2389  unsigned int const run,
2390  MEMap::const_iterator const begin,
2391  MEMap::const_iterator const end,
2392  TFile& file,
2393  unsigned int& counter)
2394 {
2395  for (auto const& me: boost::make_iterator_range(begin, end)) {
2396  if (not isSubdirectory(dir, *me.data_.dirname))
2397  break;
2398 
2399  if (verbose_ > 1)
2400  std::cout << "DQMStore::save:"
2401  << " run: " << me.run()
2402  << " lumi: " << me.lumi()
2403  << " lumiFlag: " << me.getLumiFlag()
2404  << " moduleId: " << me.moduleId()
2405  << " fullpathname: " << me.getFullname()
2406  << " flags: " << std::hex << me.data_.flags
2407  << std::endl;
2408 
2409  // Skip MonitorElements in a subdirectory of the current one.
2410  if (dir != *me.data_.dirname) {
2411  if (verbose_ > 1) {
2412  std::cout << "DQMStore::save: skipping monitor element in a subfolder of " << dir << "/" << std::endl;
2413  }
2414  continue;
2415  }
2416 
2417  // Handle reference histograms, with three distinct cases:
2418  // 1) Skip all references entirely on saving.
2419  // 2) Blanket saving of all references.
2420  // 3) Save only references for monitor elements with qtests.
2421  // The latter two are affected by "path" sub-tree selection,
2422  // i.e. references are saved only in the selected tree part.
2423  if (isSubdirectory(refpath, *me.data_.dirname)) {
2424  if (ref == SaveWithoutReference)
2425  // Skip the reference entirely.
2426  continue;
2427  else if (ref == SaveWithReference)
2428  // Save all references regardless of qtests.
2429  ;
2430  else if (ref == SaveWithReferenceForQTest) {
2431  // Save only references for monitor elements with qtests
2432  // with an optional cut on minimum quality test result.
2433  int status = -1;
2434  std::string mname(me.getFullname(), s_referenceDirName.size()+1, std::string::npos);
2435  MonitorElement* master = get(mname);
2436  if (master)
2437  for (auto const& qreport : master->data_.qreports)
2438  status = std::max(status, qreport.code);
2439 
2440  if (not master or status < minStatus) {
2441  if (verbose_ > 1)
2442  std::cout << "DQMStore::save: skipping monitor element '"
2443  << me.data_.objname << "' while saving, status is "
2444  << status << ", required minimum status is "
2445  << minStatus << std::endl;
2446  continue;
2447  }
2448  }
2449  }
2450 
2451  if (verbose_ > 1) {
2452  std::cout << "DQMStore::save: saving monitor element" << std::endl;
2453  }
2454 
2455  saveMonitorElementToROOT(me, file);
2456 
2457  // Count saved histograms
2458  ++counter;
2459  }
2460 }
2461 
2464 void
2466  std::string const& path /* = "" */,
2467  std::string const& pattern /* = "" */,
2468  std::string const& rewrite /* = "" */,
2469  uint32_t const run /* = 0 */,
2470  uint32_t const lumi /* = 0 */,
2471  SaveReferenceTag const ref /* = SaveWithReference */,
2472  int const minStatus /* = dqm::qstatus::STATUS_OK */,
2473  std::string const& fileupdate /* = RECREATE */)
2474 {
2475  // TFile flushes to disk with fsync() on every TDirectory written to
2476  // the file. This makes DQM file saving painfully slow, and
2477  // ironically makes it _more_ likely the file saving gets
2478  // interrupted and corrupts the file. The utility class below
2479  // simply ignores the flush synchronisation.
2480  class TFileNoSync : public TFile {
2481  public:
2482  TFileNoSync(char const* file, char const* opt) : TFile{file, opt} {}
2483  Int_t SysSync(Int_t) override { return 0; }
2484  };
2485 
2486  std::lock_guard<std::mutex> guard(book_mutex_);
2487 
2488  unsigned int nme = 0;
2489 
2490  // open output file, on 1st save recreate, later update
2491  if (verbose_) {
2492  std::cout << "DQMStore::save: Opening TFile '" << filename
2493  << "' with option '" << fileupdate << "'"
2494  << std::endl;
2495  }
2496 
2497  TFileNoSync f(filename.c_str(), fileupdate.c_str()); // open file
2498  if(f.IsZombie())
2499  raiseDQMError("DQMStore", "Failed to create/update file '%s'", filename.c_str());
2500  f.cd();
2501 
2502  // Construct a regular expression from the pattern string.
2503  std::unique_ptr<lat::Regexp> rxpat;
2504  if (not pattern.empty())
2505  rxpat = std::make_unique<lat::Regexp>(pattern);
2506 
2507  // Prepare a path for the reference object selection.
2508  std::string refpath;
2509  refpath.reserve(s_referenceDirName.size() + path.size() + 2);
2510  refpath += s_referenceDirName;
2511  if (not path.empty()) {
2512  refpath += '/';
2513  refpath += path;
2514  }
2515 
2516  // Loop over the directory structure.
2517  for (auto const& dir: dirs_) {
2518  // Check if we should process this directory. We process the
2519  // requested part of the object tree, including references.
2520  if (not path.empty()
2521  and not isSubdirectory(refpath, dir)
2522  and not isSubdirectory(path, dir))
2523  continue;
2524 
2525  if (verbose_ > 1) {
2526  std::cout << "DQMStore::save: DQM folder " << dir << "/" << std::endl;
2527  }
2528 
2529  // Create the directory.
2530  gDirectory->cd("/");
2531  if (dir.empty())
2532  cdInto(s_monitorDirName);
2533  else if (rxpat.get())
2534  cdInto(s_monitorDirName + '/' + lat::StringOps::replace(dir, *rxpat, rewrite));
2535  else
2536  cdInto(s_monitorDirName + '/' + dir);
2537 
2538  // Loop over monitor elements in this directory.
2539  if (not enableMultiThread_) {
2540  MonitorElement proto(&dir, std::string(), run, 0);
2541  auto begin = data_.lower_bound(proto);
2542  auto end = data_.end();
2543  saveMonitorElementRangeToROOT(dir, refpath, ref, minStatus, run, begin, end, f, nme);
2544  } else {
2545  // Restrict the loop to the monitor elements for the current lumisection
2546  MonitorElement proto(&dir, std::string(), run, 0);
2547  proto.setLumi(lumi);
2548  auto begin = data_.lower_bound(proto);
2549  proto.setLumi(lumi+1);
2550  auto end = data_.lower_bound(proto);
2551  saveMonitorElementRangeToROOT(dir, refpath, ref, minStatus, run, begin, end, f, nme);
2552  }
2553 
2554  // In LSbasedMode, loop also over the (run, 0) global histograms;
2555  // these could be the merged global histrograms of their per-stream
2556  // counterparts after the streamEndRun transition - but they are not
2557  // produced in LSbasedMode.
2558  if (enableMultiThread_ and LSbasedMode_ and lumi != 0) {
2559  auto begin = data_.lower_bound(MonitorElement(&dir, std::string(), run, 0));
2560  auto end = data_.lower_bound(MonitorElement(&dir, std::string(), run, 1));
2561  saveMonitorElementRangeToROOT(dir, refpath, ref, minStatus, run, begin, end, f, nme);
2562  }
2563  }
2564 
2565  f.Close();
2566 
2567  // Maybe make some noise.
2568  if (verbose_) {
2569  std::cout << "DQMStore::save: successfully wrote " << nme
2570  << " objects from path '" << path << "/"
2571  << "' into DQM file '" << filename << "'\n";
2572  }
2573 }
2574 
2575 void
2578 {
2579  // Save the object.
2580  TBufferFile buffer(TBufferFile::kWrite);
2581  if (me.kind() < MonitorElement::DQM_KIND_TH1F) {
2582  TObjString object(me.tagString().c_str());
2583  buffer.WriteObject(&object);
2584  } else {
2585  buffer.WriteObject(me.object_);
2586  }
2588  histo.set_full_pathname(*me.data_.dirname + '/' + me.data_.objname);
2589  histo.set_flags(me.data_.flags);
2590  histo.set_size(buffer.Length());
2591  histo.set_streamed_histo((void const*)buffer.Buffer(), buffer.Length());
2592 
2593  // Save quality reports if this is not in reference section.
2594  // XXX not supported by protobuf files.
2595 
2596  // Save efficiency tag, if any.
2597  // XXX not supported by protobuf files.
2598 
2599  // Save tag if any.
2600  // XXX not supported by protobuf files.
2601 }
2602 
2603 void
2605  unsigned int const run,
2606  MEMap::const_iterator const begin,
2607  MEMap::const_iterator const end,
2609  unsigned int& counter)
2610 {
2611  for (auto const& me: boost::make_iterator_range(begin, end)) {
2612  if (not isSubdirectory(dir, *me.data_.dirname))
2613  break;
2614 
2615  if (verbose_ > 1)
2616  std::cout << "DQMStore::savePB:"
2617  << " run: " << me.run()
2618  << " lumi: " << me.lumi()
2619  << " lumiFlag: " << me.getLumiFlag()
2620  << " moduleId: " << me.moduleId()
2621  << " fullpathname: " << me.getFullname()
2622  << " flags: " << std::hex << me.data_.flags
2623  << std::endl;
2624 
2625  // Skip MonitorElements in a subdirectory of the current one.
2626  if (dir != *me.data_.dirname) {
2627  if (verbose_ > 1) {
2628  std::cout << "DQMStore::savePB: skipping monitor element in a subfolder of " << dir << "/" << std::endl;
2629  }
2630  continue;
2631  }
2632 
2633  // Handle reference histograms, with three distinct cases:
2634  // XXX not supported by protobuf files.
2635 
2636  if (verbose_ > 1) {
2637  std::cout << "DQMStore::savePB: saving monitor element" << std::endl;
2638  }
2639 
2640  saveMonitorElementToPB(me, file);
2641 
2642  // Count saved histograms
2643  ++counter;
2644  }
2645 }
2646 
2649 void
2651  std::string const& path /* = "" */,
2652  uint32_t const run /* = 0 */,
2653  uint32_t const lumi /* = 0 */)
2654 {
2655  using google::protobuf::io::FileOutputStream;
2656  using google::protobuf::io::GzipOutputStream;
2657  using google::protobuf::io::StringOutputStream;
2658 
2659  std::lock_guard<std::mutex> guard(book_mutex_);
2660 
2661  unsigned int nme = 0;
2662 
2663  if (verbose_) {
2664  std::cout << "DQMStore::savePB: Opening PBFile '" << filename << "'"
2665  << std::endl;
2666  }
2667  dqmstorepb::ROOTFilePB dqmstore_message;
2668 
2669  // Loop over the directory structure.
2670  for (auto const& dir: dirs_) {
2671  // Check if we should process this directory. We process the
2672  // requested part of the object tree, including references.
2673  if (not path.empty()
2674  and not isSubdirectory(path, dir))
2675  continue;
2676 
2677  if (verbose_ > 1) {
2678  std::cout << "DQMStore::savePB: DQM folder " << dir << "/" << std::endl;
2679  }
2680 
2681  // Loop over monitor elements in this directory.
2682  if (not enableMultiThread_) {
2683  MonitorElement proto(&dir, std::string(), run, 0);
2684  auto begin = data_.lower_bound(proto);
2685  auto end = data_.end();
2686  saveMonitorElementRangeToPB(dir, run, begin, end, dqmstore_message, nme);
2687  } else {
2688  // Restrict the loop to the monitor elements for the current lumisection
2689  MonitorElement proto(&dir, std::string(), run, 0);
2690  proto.setLumi(lumi);
2691  auto begin = data_.lower_bound(proto);
2692  proto.setLumi(lumi+1);
2693  auto end = data_.lower_bound(proto);
2694  saveMonitorElementRangeToPB(dir, run, begin, end, dqmstore_message, nme);
2695  }
2696 
2697  // In LSbasedMode, loop also over the (run, 0) global histograms;
2698  // these could be the merged global histrograms of their per-stream
2699  // counterparts after the streamEndRun transition - but they are not
2700  // produced in LSbasedMode.
2701  if (enableMultiThread_ and LSbasedMode_ and lumi != 0) {
2702  auto begin = data_.lower_bound(MonitorElement(&dir, std::string(), run, 0));
2703  auto end = data_.lower_bound(MonitorElement(&dir, std::string(), run, 1));
2704  saveMonitorElementRangeToPB(dir, run, begin, end, dqmstore_message, nme);
2705  }
2706  }
2707 
2708  int filedescriptor = ::open(filename.c_str(),
2709  O_WRONLY | O_CREAT | O_TRUNC,
2710  S_IRUSR | S_IWUSR |
2711  S_IRGRP | S_IWGRP |
2712  S_IROTH);
2713  FileOutputStream file_stream(filedescriptor);
2715  options.format = GzipOutputStream::GZIP;
2716  options.compression_level = 1;
2717  GzipOutputStream gzip_stream(&file_stream, options);
2718  dqmstore_message.SerializeToZeroCopyStream(&gzip_stream);
2719 
2720  // Flush the internal streams before closing the fd.
2721  gzip_stream.Close();
2722  file_stream.Close();
2723  ::close(filedescriptor);
2724 
2725  // Maybe make some noise.
2726  if (verbose_) {
2727  std::cout << "DQMStore::savePB: successfully wrote " << nme
2728  << " objects from path '" << path << "/"
2729  << "' into DQM file '" << filename << "'\n";
2730  }
2731 }
2732 
2733 
2736 unsigned int
2738  bool const overwrite,
2739  std::string const& onlypath,
2740  std::string const& prepend,
2741  std::string const& curdir,
2742  OpenRunDirs const stripdirs)
2743 {
2744  unsigned int ntot = 0;
2745  unsigned int count = 0;
2746 
2747  if (! file->cd(curdir.c_str()))
2748  raiseDQMError("DQMStore", "Failed to process directory '%s' while"
2749  " reading file '%s'", curdir.c_str(), file->GetName());
2750 
2751  // Figure out current directory name, but strip out the top
2752  // directory into which we dump everything.
2753  std::string dirpart = curdir;
2754  if (dirpart.compare(0, s_monitorDirName.size(), s_monitorDirName) == 0) {
2755  if (dirpart.size() == s_monitorDirName.size())
2756  dirpart.clear();
2757  else if (dirpart[s_monitorDirName.size()] == '/')
2758  dirpart.erase(0, s_monitorDirName.size()+1);
2759  }
2760 
2761  // See if we are going to skip this directory.
2762  bool skip = (! onlypath.empty() && ! isSubdirectory(onlypath, dirpart));
2763 
2764  if (prepend == s_collateDirName ||
2765  prepend == s_referenceDirName ||
2766  stripdirs == StripRunDirs ) {
2767  // Remove Run # and RunSummary dirs
2768  // first look for Run summary,
2769  // if that is found and erased, also erase Run dir
2770  size_t slash = dirpart.find('/');
2771  size_t pos = dirpart.find("/Run summary");
2772  if (slash != std::string::npos && pos !=std::string::npos) {
2773  dirpart.erase(pos,12);
2774 
2775  pos = dirpart.find("Run ");
2776  size_t length = dirpart.find('/',pos+1)-pos+1;
2777  if (pos !=std::string::npos)
2778  dirpart.erase(pos,length);
2779  }
2780  }
2781 
2782  // If we are prepending, add it to the directory name,
2783  // and suppress reading of already existing reference histograms
2784  if (prepend == s_collateDirName ||
2785  prepend == s_referenceDirName) {
2786  size_t slash = dirpart.find('/');
2787  // If we are reading reference, skip previous reference.
2788  if (slash == std::string::npos // skip if Reference is toplevel folder, i.e. no slash
2789  && slash+1+s_referenceDirName.size() == dirpart.size()
2790  && dirpart.compare(slash+1, s_referenceDirName.size(), s_referenceDirName) == 0)
2791  return 0;
2792 
2793  slash = dirpart.find('/');
2794  // Skip reading of EventInfo subdirectory.
2795  if (slash != std::string::npos
2796  && slash + 10 == dirpart.size()
2797  && dirpart.compare( slash+1 , 9 , "EventInfo") == 0) {
2798  if (verbose_)
2799  std::cout << "DQMStore::readDirectory: skipping '" << dirpart << "'\n";
2800  return 0;
2801  }
2802 
2803  // Add prefix.
2804  if (dirpart.empty())
2805  dirpart = prepend;
2806  else
2807  dirpart = prepend + '/' + dirpart;
2808  }
2809  else if (! prepend.empty()) {
2810  if (dirpart.empty())
2811  dirpart = prepend;
2812  else
2813  dirpart = prepend + '/' + dirpart;
2814  }
2815 
2816  // Loop over the contents of this directory in the file.
2817  // Post-pone string object handling to happen after other
2818  // objects have been read in so we are guaranteed to have
2819  // histograms by the time we read in quality tests and tags.
2820  TKey* key;
2821  TIter next (gDirectory->GetListOfKeys());
2822  std::list<TObject*> delayed;
2823  while ((key = (TKey*) next()))
2824  {
2825  std::unique_ptr<TObject> obj(key->ReadObj());
2826  if (dynamic_cast<TDirectory*>(obj.get())) {
2827  std::string subdir;
2828  subdir.reserve(curdir.size() + strlen(obj->GetName()) + 2);
2829  subdir += curdir;
2830  if (! curdir.empty())
2831  subdir += '/';
2832  subdir += obj->GetName();
2833 
2834  ntot += readDirectory(file, overwrite, onlypath, prepend, subdir, stripdirs);
2835  }
2836  else if (skip)
2837  ;
2838  else if (dynamic_cast<TObjString*>(obj.get())) {
2839  delayed.push_back(obj.release());
2840  }
2841  else {
2842  if (verbose_ > 2)
2843  std::cout << "DQMStore: reading object '" << obj->GetName()
2844  << "' of type '" << obj->IsA()->GetName()
2845  << "' from '" << file->GetName()
2846  << "' into '" << dirpart << "'\n";
2847 
2848  makeDirectory(dirpart);
2849  if (extract(obj.get(), dirpart, overwrite, collateHistograms_))
2850  ++count;
2851  }
2852  }
2853 
2854  while (! delayed.empty()) {
2855  if (verbose_ > 2)
2856  std::cout << "DQMStore: reading object '" << delayed.front()->GetName()
2857  << "' of type '" << delayed.front()->IsA()->GetName()
2858  << "' from '" << file->GetName()
2859  << "' into '" << dirpart << "'\n";
2860 
2861  makeDirectory(dirpart);
2862  if (extract(delayed.front(), dirpart, overwrite, collateHistograms_))
2863  ++count;
2864 
2865  delete delayed.front();
2866  delayed.pop_front();
2867  }
2868 
2869  if (verbose_ > 1)
2870  std::cout << "DQMStore: read " << count << '/' << ntot
2871  << " objects from directory '" << dirpart << "'\n";
2872 
2873  return ntot + count;
2874 }
2875 
2882 bool
2884  bool const overwrite /* = false */,
2885  std::string const& onlypath /* ="" */,
2886  std::string const& prepend /* ="" */,
2887  OpenRunDirs const stripdirs /* =KeepRunDirs */,
2888  bool const fileMustExist /* =true */)
2889 {
2890  return readFile(filename,overwrite,onlypath,prepend,stripdirs,fileMustExist);
2891 }
2892 
2897 bool
2899  OpenRunDirs const stripdirs /* =StripRunDirs */,
2900  bool const fileMustExist /* =true */)
2901 {
2902  bool overwrite = true;
2903  if (collateHistograms_) overwrite = false;
2904  if (verbose_)
2905  {
2906  std::cout << "DQMStore::load: reading from file '" << filename << "'\n";
2907  if (collateHistograms_)
2908  std::cout << "DQMStore::load: in collate mode " << "\n";
2909  else
2910  std::cout << "DQMStore::load: in overwrite mode " << "\n";
2911  }
2912 
2913  if (!s_rxpbfile.match(filename, 0, 0))
2914  return readFile(filename, overwrite, "", "", stripdirs, fileMustExist);
2915  else
2916  return readFilePB(filename, overwrite, "", "", stripdirs, fileMustExist);
2917 }
2918 
2924 bool
2926  bool const overwrite /* = false */,
2927  std::string const& onlypath /* ="" */,
2928  std::string const& prepend /* ="" */,
2929  OpenRunDirs const stripdirs /* =StripRunDirs */,
2930  bool const fileMustExist /* =true */)
2931 {
2932 
2933  if (verbose_)
2934  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
2935 
2936  std::unique_ptr<TFile> f;
2937 
2938  try {
2939  f.reset(TFile::Open(filename.c_str()));
2940  if (! f.get() || f->IsZombie())
2941  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
2942  }
2943  catch (std::exception &) {
2944  if (fileMustExist)
2945  throw;
2946  else {
2947  if (verbose_)
2948  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
2949  return false;
2950  }
2951  }
2952 
2953  unsigned n = readDirectory(f.get(), overwrite, onlypath, prepend, "", stripdirs);
2954  f->Close();
2955 
2956  for (auto const& me : data_)
2957  const_cast<MonitorElement &>(me).updateQReportStats();
2958 
2959  if (verbose_) {
2960  std::cout << "DQMStore::open: successfully read " << n
2961  << " objects from file '" << filename << "'";
2962  if (! onlypath.empty())
2963  std::cout << " from directory '" << onlypath << "'";
2964  if (! prepend.empty())
2965  std::cout << " into directory '" << prepend << "'";
2966  std::cout << std::endl;
2967  }
2968  return true;
2969 }
2970 
2974 inline TObject* DQMStore::extractNextObject(TBufferFile& buf) const
2975 {
2976  if (buf.Length() == buf.BufferSize())
2977  return nullptr;
2978  buf.InitMap();
2979  void* ptr = buf.ReadObjectAny(nullptr);
2980  return reinterpret_cast<TObject*>(ptr);
2981 }
2982 
2985  std::string& objname,
2986  TObject** obj)
2987 {
2988  size_t slash = h.full_pathname().rfind('/');
2989  size_t dirpos = (slash == std::string::npos ? 0 : slash);
2990  size_t namepos = (slash == std::string::npos ? 0 : slash+1);
2991  dirname.assign(h.full_pathname(), 0, dirpos);
2992  objname.assign(h.full_pathname(), namepos, std::string::npos);
2993  TBufferFile buf(TBufferFile::kRead, h.size(),
2994  (void*)h.streamed_histo().data(),
2995  kFALSE);
2996  buf.Reset();
2997  *obj = extractNextObject(buf);
2998  if (!*obj) {
2999  raiseDQMError("DQMStore", "Error reading element:'%s'" , h.full_pathname().c_str());
3000  }
3001 }
3002 
3003 bool
3005  bool const overwrite /* = false */,
3006  std::string const& onlypath /* ="" */,
3007  std::string const& prepend /* ="" */,
3008  OpenRunDirs const stripdirs /* =StripRunDirs */,
3009  bool const fileMustExist /* =true */)
3010 {
3011  using google::protobuf::io::FileInputStream;
3012  using google::protobuf::io::FileOutputStream;
3013  using google::protobuf::io::GzipInputStream;
3014  using google::protobuf::io::GzipOutputStream;
3015  using google::protobuf::io::CodedInputStream;
3016  using google::protobuf::io::ArrayInputStream;
3017 
3018  if (verbose_)
3019  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
3020 
3021  int filedescriptor;
3022  if ((filedescriptor = ::open(filename.c_str(), O_RDONLY)) == -1) {
3023  if (fileMustExist)
3024  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
3025  else
3026  if (verbose_)
3027  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
3028  return false;
3029  }
3030 
3031  dqmstorepb::ROOTFilePB dqmstore_message;
3032  FileInputStream fin(filedescriptor);
3033  GzipInputStream input(&fin);
3034  CodedInputStream input_coded(&input);
3035  input_coded.SetTotalBytesLimit(1024*1024*1024, -1);
3036  if (!dqmstore_message.ParseFromCodedStream(&input_coded)) {
3037  raiseDQMError("DQMStore", "Fatal parsing file '%s'", filename.c_str());
3038  return false;
3039  }
3040  ::close(filedescriptor);
3041 
3042  for (int i = 0; i < dqmstore_message.histo_size(); ++i) {
3043  std::string path;
3044  std::string objname;
3045 
3046  TObject* obj = nullptr;
3047  dqmstorepb::ROOTFilePB::Histo const& h = dqmstore_message.histo(i);
3048  get_info(h, path, objname, &obj);
3049 
3050  setCurrentFolder(path);
3051  if (obj) {
3052  /* Before calling the extract() check if histogram exists:
3053  * if it does - flags for the given monitor are already set (and merged)
3054  * else - set the flags after the histogram is created.
3055  */
3056  MonitorElement* me = findObject(0, 0, 0, path, objname);
3057 
3058  /* Run histograms should be collated and not overwritten,
3059  * Lumi histograms should be overwritten (and collate flag is not checked)
3060  */
3061  bool overwrite = h.flags() & DQMNet::DQM_PROP_LUMI;
3062  bool collate = !(h.flags() & DQMNet::DQM_PROP_LUMI);
3063  extract(static_cast<TObject*>(obj), path, overwrite, collate);
3064 
3065  if (me == nullptr) {
3066  me = findObject(0, 0, 0, path, objname);
3067  me->data_.flags = h.flags();
3068  }
3069 
3070  delete obj;
3071  }
3072  }
3073 
3074  cd();
3075  return true;
3076 }
3077 
3083 void
3085 {
3087  std::string const* cleaned = nullptr;
3088  cleanTrailingSlashes(path, clean, cleaned);
3089  MonitorElement proto(cleaned, std::string());
3090 
3091  auto e = data_.end();
3092  auto i = data_.lower_bound(proto);
3093  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
3094  data_.erase(i++);
3095 
3096  auto de = dirs_.end();
3097  auto di = dirs_.lower_bound(*cleaned);
3098  while (di != de && isSubdirectory(*cleaned, *di))
3099  dirs_.erase(di++);
3100 }
3101 
3103 void
3105 {
3106  MonitorElement proto(&dir, std::string());
3107  auto e = data_.end();
3108  auto i = data_.lower_bound(proto);
3109  while (i != e && isSubdirectory(dir, *i->data_.dirname))
3110  if (dir == *i->data_.dirname)
3111  data_.erase(i++);
3112  else
3113  ++i;
3114 }
3115 
3117 void
3119 {
3121 }
3122 
3125 void
3127 {
3128  removeElement(pwd_, name);
3129 }
3130 
3133 void
3134 DQMStore::removeElement(std::string const& dir, std::string const& name, bool const warning /* = true */)
3135 {
3136  MonitorElement proto(&dir, name);
3137  auto pos = data_.find(proto);
3138  if (pos != data_.end())
3139  data_.erase(pos);
3140  else if (warning) {
3141  std::cout << "DQMStore: WARNING: attempt to remove non-existent"
3142  << " monitor element '" << name << "' in '" << dir << "'\n";
3143  }
3144 }
3145 
3151 QCriterion*
3153 {
3154  auto i = qtests_.find(qtname);
3155  auto e = qtests_.end();
3156  return (i == e ? nullptr : i->second);
3157 }
3158 
3162 QCriterion*
3164 {
3165  if (qtests_.count(qtname))
3166  raiseDQMError("DQMStore", "Attempt to create duplicate quality test '%s'",
3167  qtname.c_str());
3168 
3169  auto i = qalgos_.find(algoname);
3170  if (i == qalgos_.end())
3171  raiseDQMError("DQMStore", "Cannot create a quality test using unknown"
3172  " algorithm '%s'", algoname.c_str());
3173 
3174  QCriterion* qc = i->second(qtname);
3175  qc->setVerbose(verboseQT_);
3176 
3177  qtests_[qtname] = qc;
3178  return qc;
3179 }
3180 
3183 void
3184 DQMStore::useQTest(std::string const& dir, std::string const& qtname)
3185 {
3186  // Clean the path
3188  std::string const* cleaned = nullptr;
3189  cleanTrailingSlashes(dir, clean, cleaned);
3190 
3191  // Validate the path.
3192  if (cleaned->find_first_not_of(s_safe) != std::string::npos)
3193  raiseDQMError("DQMStore", "Monitor element path name '%s'"
3194  " uses unacceptable characters", cleaned->c_str());
3195 
3196  // Redirect to the pattern match version.
3197  useQTestByMatch(*cleaned + "/*", qtname);
3198 }
3199 
3201 int
3203 {
3204  QCriterion* qc = getQCriterion(qtname);
3205  if (! qc)
3206  raiseDQMError("DQMStore", "Cannot apply non-existent quality test '%s'",
3207  qtname.c_str());
3208 
3209  auto* fm = new fastmatch(pattern);
3210 
3211  // Record the test for future reference.
3212  QTestSpec qts(fm, qc);
3213  qtestspecs_.push_back(qts);
3214 
3215  // Apply the quality test.
3216  std::string path;
3217  int cases = 0;
3218  for (auto const& me : data_) {
3219  path.clear();
3220  mergePath(path, *me.data_.dirname, me.data_.objname);
3221  if (fm->match(path)) {
3222  ++cases;
3223  const_cast<MonitorElement &>(me).addQReport(qts.second);
3224  }
3225  }
3226 
3227  //return the number of matched cases
3228  return cases;
3229 }
3232 void
3234 {
3235 
3236  if (verbose_ > 0)
3237  std::cout << "DQMStore: running runQTests() with reset = "
3238  << ( reset_ ? "true" : "false" ) << std::endl;
3239 
3240  // Apply quality tests to each monitor element, skipping references.
3241  for (auto const& me : data_)
3242  if (! isSubdirectory(s_referenceDirName, *me.data_.dirname))
3243  const_cast<MonitorElement &>(me).runQTests();
3244 
3245  reset_ = false;
3246 }
3247 
3251 int
3252 DQMStore::getStatus(std::string const& path /* = "" */) const
3253 {
3255  std::string const* cleaned = nullptr;
3256  cleanTrailingSlashes(path, clean, cleaned);
3257 
3259  for (auto const& me : data_) {
3260  if (! cleaned->empty() && ! isSubdirectory(*cleaned, *me.data_.dirname))
3261  continue;
3262 
3263  if (me.hasError())
3264  return dqm::qstatus::ERROR;
3265  else if (me.hasWarning())
3266  status = dqm::qstatus::WARNING;
3267  else if (status < dqm::qstatus::WARNING
3268  && me.hasOtherReport())
3269  status = dqm::qstatus::OTHER;
3270  }
3271  return status;
3272 }
3273 
3279 void
3281 {
3282  if (me)
3283  me->softReset();
3284 }
3285 
3286 // reverts action of softReset
3287 void
3289 {
3290  if (me)
3291  me->disableSoftReset();
3292 }
3293 
3296 void
3298 {
3299  if (me)
3300  me->setAccumulate(flag);
3301 }
3302 
3306 void
3308 {
3309  std::vector<std::string> contents;
3310  getContents(contents);
3311 
3312  std::cout << " ------------------------------------------------------------\n"
3313  << " Directory structure: \n"
3314  << " ------------------------------------------------------------\n";
3315 
3316  std::copy(contents.begin(), contents.end(),
3317  std::ostream_iterator<std::string>(std::cout, "\n"));
3318 
3319  std::cout << " ------------------------------------------------------------\n";
3320 }
3321 
3325 // check if the collate option is active on the DQMStore
3326 bool
3328 {
3329  return collateHistograms_;
3330 }
3334 // check if the monitor element is in auto-collation folder
3335 bool
3337 {
3338  return me && isSubdirectory(s_collateDirName, *me->data_.dirname);
3339 }
3340 
3344 
3346 void
3348 {
3349  if (scaleFlag_ == 0.0) return;
3350  if (verbose_ > 0)
3351  std::cout << " =========== " << " ScaleFlag " << scaleFlag_ << std::endl;
3352  double factor = scaleFlag_;
3353  int events = 1;
3354  if (dirExists("Info/EventInfo")) {
3355  if ( scaleFlag_ == -1.0) {
3356  MonitorElement* scale_me = get("Info/EventInfo/ScaleFactor");
3357  if (scale_me && scale_me->kind()==MonitorElement::DQM_KIND_REAL) factor = scale_me->getFloatValue();
3358  }
3359  MonitorElement* event_me = get("Info/EventInfo/processedEvents");
3360  if (event_me && event_me->kind()==MonitorElement::DQM_KIND_INT) events = event_me->getIntValue();
3361  }
3362  factor = factor/(events*1.0);
3363 
3364  for (auto const& m : data_) {
3365  auto& me = const_cast<MonitorElement&>(m);
3366  switch (me.kind()) {
3368  {
3369  me.getTH1F()->Scale(factor);
3370  break;
3371  }
3373  {
3374  me.getTH1S()->Scale(factor);
3375  break;
3376  }
3378  {
3379  me.getTH1D()->Scale(factor);
3380  break;
3381  }
3383  {
3384  me.getTH2F()->Scale(factor);
3385  break;
3386  }
3388  {
3389  me.getTH2S()->Scale(factor);
3390  break;
3391  }
3393  {
3394  me.getTH2D()->Scale(factor);
3395  break;
3396  }
3398  {
3399  me.getTH3F()->Scale(factor);
3400  break;
3401  }
3403  {
3404  me.getTProfile()->Scale(factor);
3405  break;
3406  }
3408  {
3409  me.getTProfile2D()->Scale(factor);
3410  break;
3411  }
3412  default:
3413  if (verbose_ > 0)
3414  std::cout << " The DQM object '" << me.getFullname() << "' is not scalable object " << std::endl;
3415  continue;
3416  }
3417  }
3418 }
size
Write out results.
~DQMStore()
Definition: DQMStore.cc:392
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:1173
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:1379
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:1166
uint32_t moduleId
Definition: DQMNet.h:105
void rmdir(std::string const &fullpath)
Definition: DQMStore.cc:3084
::google::protobuf::uint32 size() const
int64_t getIntValue() const
bool isCollateME(MonitorElement *me) const
Definition: DQMStore.cc:3336
MonitorElement * bookProfile2D_(std::string const &dir, std::string const &name, TProfile2D *h)
Book 2D profile histogram based on TProfile2D.
Definition: DQMStore.cc:1351
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:1640
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:2650
def copy(args, dbName)
static void collate3D(MonitorElement *me, TH3F *h, unsigned verbose)
Definition: DQMStore.cc:1471
bool match(std::string const &s) const
Definition: DQMStore.cc:240
void removeElement(std::string const &name)
Definition: DQMStore.cc:3126
MonitorElement * bookString_(std::string const &dir, std::string const &name, std::string const &value)
Book string.
Definition: DQMStore.cc:1056
MonitorElement * book_(std::string const &dir, std::string const &name, char const *context)
Definition: DQMStore.cc:980
static void collateProfile(MonitorElement *me, TProfile *h, unsigned verbose)
Definition: DQMStore.cc:1478
TH1F * getTH1F() const
TH2S * getTH2S() const
void scaleElements()
Definition: DQMStore.cc:3347
double getFloatValue() const
void setLumi(uint32_t ls)
void postGlobalBeginLumi(const edm::GlobalContext &)
Definition: DQMStore.cc:1886
std::vector< MonitorElement * > getMatchingContents(std::string const &pattern, lat::Regexp::Syntax syntaxType=lat::Regexp::Wildcard) const
Definition: DQMStore.cc:1813
void tagContents(std::string const &path, unsigned int myTag)
tag all children of folder (does NOT include subfolders)
Definition: DQMStore.cc:1531
std::string qualityTagString(const DQMNet::QValue &qv) const
uint32_t flags
Definition: DQMNet.h:99
LuminosityBlockID const & luminosityBlockID() const
Definition: GlobalContext.h:55
MonitorElement * book1DD(char_string const &name, char_string const &title, int nchX, double lowX, double highX)
Book 1S histogram.
Definition: DQMStore.cc:1114
void makeDirectory(std::string const &path)
Definition: DQMStore.cc:595
TH1 * getTH1() const
static void collate2DD(MonitorElement *me, TH2D *h, unsigned verbose)
Definition: DQMStore.cc:1464
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:634
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:1077
bool extract(TObject *obj, std::string const &dir, bool overwrite, bool collateHistograms)
Definition: DQMStore.cc:2047
void initializeFrom(const edm::ParameterSet &)
Definition: DQMStore.cc:402
MonitorElement * bookProfile_(std::string const &dir, std::string const &name, TProfile *h)
Book profile histogram based on TProfile.
Definition: DQMStore.cc:1274
MonitorElement * bookInt(char_string const &name)
Book int.
Definition: DQMStore.cc:1027
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:1098
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:2983
uint32_t moduleId_
Definition: DQMStore.h:642
const ::std::string & streamed_histo() const
bool cdInto(std::string const &path) const
Definition: DQMStore.cc:2314
QCMap qtests_
Definition: DQMStore.h:653
fastmatch(std::string fastString)
Definition: DQMStore.cc:141
void forceReset()
Definition: DQMStore.cc:1864
std::mutex book_mutex_
Definition: DQMStore.h:657
MonitorElement * bookFloat(char_string const &name)
Book float.
Definition: DQMStore.cc:1048
DQMStore(edm::ParameterSet const &pset, edm::ActivityRegistry &)
Definition: DQMStore.cc:367
static std::string const input
Definition: EdmProvDump.cc:48
SaveReferenceTag
Definition: DQMStore.h:78
void Fill(long long x)
void tag(MonitorElement *me, unsigned int myTag)
Definition: DQMStore.cc:1500
void disableSoftReset(MonitorElement *me)
Definition: DQMStore.cc:3288
unsigned int maxNumberOfStreams() const
Definition: SystemBounds.h:35
void useQTest(std::string const &dir, std::string const &qtname)
Definition: DQMStore.cc:3184
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:2385
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:1195
std::pair< fastmatch *, QCriterion * > QTestSpec
Definition: DQMStore.h:605
char const * label
void saveMonitorElementToROOT(MonitorElement const &me, TFile &file)
Definition: DQMStore.cc:2356
MonitorElement * getElement(std::string const &path)
Definition: DQMStore.cc:309
unsigned verboseQT_
Definition: DQMStore.h:633
void setEfficiencyFlag()
static const uint32_t DQM_PROP_HAS_REFERENCE
Definition: DQMNet.h:54
QTestSpecs qtestspecs_
Definition: DQMStore.h:655
void print_trace(std::string const &dir, std::string const &name)
Definition: DQMStore.cc:468
void setLumiFlag()
this ME is meant to be stored for each luminosity section
void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:268
double scaleFlag_
Definition: DQMStore.h:635
void deleteUnusedLumiHistograms(uint32_t run, uint32_t lumi)
Definition: DQMStore.cc:2005
MonitorElement * book2D_(std::string const &dir, std::string const &name, TH2F *h)
Book 2D histogram based on TH2F.
Definition: DQMStore.cc:1152
bool dirExists(std::string const &path) const
true if directory exists
Definition: DQMStore.cc:635
bool isCollate() const
Definition: DQMStore.cc:3327
MonitorElement * book1DD_(std::string const &dir, std::string const &name, TH1D *h)
Book 1D histogram based on TH1D.
Definition: DQMStore.cc:1091
MonitorElement * get(std::string const &path) const
get ME from full pathname (e.g. "my/long/dir/my_histo")
Definition: DQMStore.cc:1613
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:1487
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:1246
bool doSaveByLumi_
Definition: DQMStore.h:646
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:2604
double f[11][100]
uint32_t run_
Definition: DQMStore.h:641
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:2883
#define end
Definition: vmac.h:39
void setVerbose(unsigned level)
Definition: DQMStore.cc:531
Definition: value.py:1
void softReset(MonitorElement *me)
Definition: DQMStore.cc:3280
std::string pwd_
Definition: DQMStore.h:649
TObject * extractNextObject(TBufferFile &) const
Definition: DQMStore.cc:2974
void Reset()
reset ME (ie. contents, errors, etc)
QCriterion * getQCriterion(std::string const &qtname) const
Definition: DQMStore.cc:3152
QAMap qalgos_
Definition: DQMStore.h:654
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:2737
std::vector< std::string > getSubdirs() const
Definition: DQMStore.cc:1564
MonitorElement * bookString(char_string const &name, char_string const &value)
Book string.
Definition: DQMStore.cc:1069
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:154
std::string qtname
Definition: DQMNet.h:93
int getStatus(std::string const &path="") const
Definition: DQMStore.cc:3252
std::string const & pwd() const
Definition: DQMStore.cc:539
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:1184
MonitorElement * book1S_(std::string const &dir, std::string const &name, TH1S *h)
Book 1D histogram based on TH1S.
Definition: DQMStore.cc:1084
void saveMonitorElementToPB(MonitorElement const &me, dqmstorepb::ROOTFilePB &file)
Definition: DQMStore.cc:2576
static void collate1DD(MonitorElement *me, TH1D *h, unsigned verbose)
Definition: DQMStore.cc:1443
void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:571
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:1285
void showDirStructure() const
Definition: DQMStore.cc:3307
void cd()
go to top directory (ie. root)
Definition: DQMStore.cc:546
QCriterion * createQTest(std::string const &algoname, std::string const &qtname)
Definition: DQMStore.cc:3163
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:632
void set_size(::google::protobuf::uint32 value)
std::string const & pwd()
Definition: DQMStore.cc:278
TH3F * getTH3F() const
MEMap data_
Definition: DQMStore.h:650
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:1159
std::string tagLabelString() const
return label string for the monitor element tag (eg. <name>t=12345</name>)
bool canSaveByLumi_
Definition: DQMStore.h:644
static void collate1D(MonitorElement *me, TH1F *h, unsigned verbose)
Definition: DQMStore.cc:1429
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:1587
MonitorElement * bookFloat_(std::string const &dir, std::string const &name)
Book float.
Definition: DQMStore.cc:1035
tuple msg
Definition: mps_check.py:285
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:3004
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:2465
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:3118
bool forceResetOnBeginLumi_
Definition: DQMStore.h:639
#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:1962
static std::atomic< unsigned int > counter
void cloneLumiHistograms(uint32_t run, uint32_t lumi, uint32_t moduleId)
Definition: DQMStore.cc:1920
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:2925
MonitorElement * book1S(char_string const &name, char_string const &title, int nchX, double lowX, double highX)
Book 1S histogram.
Definition: DQMStore.cc:1106
std::vector< std::string > getSubdirs()
Definition: DQMStore.cc:325
std::unique_ptr< std::ostream > stream_
Definition: DQMStore.h:647
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:1253
void setAccumulate(MonitorElement *me, bool flag)
Definition: DQMStore.cc:3297
MonitorElement * bookInt_(std::string const &dir, std::string const &name)
Book int.
Definition: DQMStore.cc:1014
static void collate1S(MonitorElement *me, TH1S *h, unsigned verbose)
Definition: DQMStore.cc:1436
void Reset(std::vector< TH2F > &depth)
static bool checkBinningMatches(MonitorElement *me, TH1 *h, unsigned verbose)
Definition: DQMStore.cc:1403
dbl *** dir
Definition: mlp_gen.cc:35
void goUp()
equivalent to "cd .."
Definition: DQMStore.cc:582
MonitorElement * findObject(uint32_t run, uint32_t lumi, uint32_t moduleId, std::string const &dir, std::string const &name) const
Definition: DQMStore.cc:1739
bool load(std::string const &filename, OpenRunDirs stripdirs=StripRunDirs, bool fileMustExist=true)
Definition: DQMStore.cc:2898
static void collate2D(MonitorElement *me, TH2F *h, unsigned verbose)
Definition: DQMStore.cc:1450
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:651
bool collateHistograms_
Definition: DQMStore.h:636
static const uint32_t DQM_PROP_LUMI
Definition: DQMNet.h:61
static std::string const source
Definition: EdmProvDump.cc:47
bool LSbasedMode_
Definition: DQMStore.h:638
void addQReport(const DQMNet::QValue &desc, QCriterion *qc)
Add quality report, from DQMStore.
void runQTests()
Definition: DQMStore.cc:3233
Kind kind() const
Get the type of the monitor element.
void reset()
Definition: DQMStore.cc:1844
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:3202
std::vector< MonitorElement * > getAllContents(std::string const &path, uint32_t runNumber=0, uint32_t lumi=0) const
Definition: DQMStore.cc:1767
static void collate2S(MonitorElement *me, TH2S *h, unsigned verbose)
Definition: DQMStore.cc:1457
bool containsAnyMonitorable(std::string const &path) const
Definition: DQMStore.cc:1603
std::unique_ptr< lat::Regexp > regexp_
Definition: DQMStore.h:70
static const int ERROR
bool enableMultiThread_
Definition: DQMStore.h:637
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:1543
void raiseDQMError(const char *context, const char *fmt,...)
Definition: DQMError.cc:11