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