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 runNumber /* = 0 */,
303  uint32_t lumi /* = 0 */) {
304  return owner_->getAllContents(path, runNumber, 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 
363  uint32_t streamId,
364  uint32_t moduleId) {
365  if (verbose_ > 1)
366  std::cout << "DQMStore::mergeAndResetMEsRunSummaryCache - Merging objects from run: "
367  << run
368  << ", stream: " << streamId
369  << " module: " << moduleId << std::endl;
370 
371  if (LSbasedMode_) {
372  return;
373  }
374 
375  std::string null_str("");
376  MonitorElement proto(&null_str, null_str, run, streamId, moduleId);
377  // Since this accesses the data, the operation must be
378  // be locked.
379  std::lock_guard<std::mutex> guard(book_mutex_);
380 
381  auto e = data_.end();
382  auto i = data_.lower_bound(proto);
383  while (i != e) {
384  if (i->data_.run != run
385  || i->data_.streamId != streamId
386  || i->data_.moduleId != moduleId)
387  break;
388 
389  // Handle Run-based histograms only.
390  if (i->getLumiFlag() || LSbasedMode_) {
391  ++i;
392  continue;
393  }
394 
395  // don't call the copy constructor
396  // we are just searching for a global histogram - a copy is not necessary
398  global_me.globalize();
399 
400  auto me = data_.find(global_me);
401  if (me != data_.end()) {
402  if (verbose_ > 1)
403  std::cout << "Found global Object, using it --> " << me->getFullname() << std::endl;
404 
405  //don't take any action if the ME is an INT || FLOAT || STRING
406  if(me->kind() >= MonitorElement::DQM_KIND_TH1F)
407  {
408  if(me->getTH1()->CanExtendAllAxes() && i->getTH1()->CanExtendAllAxes()) {
409  TList list;
410  list.Add(i->getTH1());
411  if( -1 == me->getTH1()->Merge(&list)) {
412  std::cout << "mergeAndResetMEsRunSummaryCache: Failed to merge DQM element "<<me->getFullname();
413  }
414  }
415  else {
416  if (i->getTH1()->GetEntries())
417  me->getTH1()->Add(i->getTH1());
418  }
419  }
420  } else {
421  if (verbose_ > 1)
422  std::cout << "No global Object found. " << std::endl;
423  std::pair<std::set<MonitorElement>::const_iterator, bool> gme;
424 
425  // this makes an actual and a single copy with Clone()'ed th1
426  MonitorElement actual_global_me(*i);
427  actual_global_me.globalize();
428  actual_global_me.markToDelete();
429  gme = data_.insert(std::move(actual_global_me));
430  assert(gme.second);
431  }
432  // TODO(rovere): eventually reset the local object and mark it as reusable??
433  ++i;
434  }
435 }
436 
438  uint32_t lumi,
439  uint32_t streamId,
440  uint32_t moduleId) {
441  if (verbose_ > 1)
442  std::cout << "DQMStore::mergeAndResetMEsLuminositySummaryCache - Merging objects from run: "
443  << run << " lumi: " << lumi
444  << ", stream: " << streamId
445  << " module: " << moduleId << std::endl;
446  std::string null_str("");
447  MonitorElement proto(&null_str, null_str, run, streamId, moduleId);
448 
449  // Since this accesses the data, the operation must be
450  // be locked.
451  std::lock_guard<std::mutex> guard(book_mutex_);
452 
453  auto e = data_.end();
454  auto i = data_.lower_bound(proto);
455 
456  while (i != e) {
457  if (i->data_.run != run
458  || i->data_.streamId != streamId
459  || i->data_.moduleId != moduleId)
460  break;
461 
462  // Handle LS-based histograms only.
463  if (not (i->getLumiFlag() || LSbasedMode_)) {
464  ++i;
465  continue;
466  }
467 
469  global_me.globalize();
470  global_me.setLumi(lumi);
471  auto me = data_.find(global_me);
472  if (me != data_.end()) {
473  if (verbose_ > 1)
474  std::cout << "Found global Object, using it --> " << me->getFullname() << std::endl;
475 
476  //don't take any action if the ME is an INT || FLOAT || STRING
477  if(me->kind() >= MonitorElement::DQM_KIND_TH1F)
478  {
479  if(me->getTH1()->CanExtendAllAxes() && i->getTH1()->CanExtendAllAxes()) {
480  TList list;
481  list.Add(i->getTH1());
482  if( -1 == me->getTH1()->Merge(&list)) {
483  std::cout << "mergeAndResetMEsLuminositySummaryCache: Failed to merge DQM element "<<me->getFullname();
484  }
485  }
486  else {
487  if (i->getTH1()->GetEntries())
488  me->getTH1()->Add(i->getTH1());
489  }
490  }
491  } else {
492  if (verbose_ > 1)
493  std::cout << "No global Object found. " << std::endl;
494  std::pair<std::set<MonitorElement>::const_iterator, bool> gme;
495 
496  // this makes an actual and a single copy with Clone()'ed th1
497  MonitorElement actual_global_me(*i);
498  actual_global_me.globalize();
499  actual_global_me.setLumi(lumi);
500  actual_global_me.markToDelete();
501  gme = data_.insert(std::move(actual_global_me));
502  assert(gme.second);
503  }
504  // make the ME reusable for the next LS
505  const_cast<MonitorElement*>(&*i)->Reset();
506  ++i;
507  }
508 }
509 
512  : verbose_ (1),
513  verboseQT_ (1),
514  reset_ (false),
515  collateHistograms_ (false),
516  enableMultiThread_(false),
517  forceResetOnBeginLumi_(false),
518  readSelectedDirectory_ (""),
519  run_(0),
520  streamId_(0),
521  moduleId_(0),
522  stream_(nullptr),
523  pwd_ (""),
524  ibooker_(nullptr),
525  igetter_(nullptr)
526 {
527  if (!ibooker_)
528  ibooker_ = new DQMStore::IBooker(this);
529  if (!igetter_)
530  igetter_ = new DQMStore::IGetter(this);
531  initializeFrom(pset);
532 
533  ar.preallocateSignal_.connect([this](edm::service::SystemBounds const& iBounds) {
534  if(iBounds.maxNumberOfStreams() > 1 ) {
535  enableMultiThread_ = true;
536  }
537  });
538  if(pset.getUntrackedParameter<bool>("forceResetOnBeginRun",false)) {
540  }
541  if(pset.getUntrackedParameter<bool>("forceResetOnBeginLumi",false) && enableMultiThread_ == false) {
542  forceResetOnBeginLumi_ = true;
544  }
546 }
547 
549  : verbose_ (1),
550  verboseQT_ (1),
551  reset_ (false),
555  run_(0),
556  streamId_(0),
557  moduleId_(0),
558  stream_(nullptr),
559  pwd_ (""),
560  ibooker_(nullptr),
562 {
563  if (!ibooker_)
564  ibooker_ = new DQMStore::IBooker(this);
565  if (!igetter_)
566  igetter_ = new DQMStore::IGetter(this);
567  initializeFrom(pset);
568 }
569 
571 {
572  for (auto & qtest : qtests_)
573  delete qtest.second;
574 
575  for (auto & qtestspec : qtestspecs_)
576  delete qtestspec.first;
577 
578  if (stream_)
579  stream_->close();
580  delete stream_;
581 }
582 
583 void
585  makeDirectory("");
586  reset();
587 
588  // set steerable parameters
589  verbose_ = pset.getUntrackedParameter<int>("verbose", 0);
590  if (verbose_ > 0)
591  std::cout << "DQMStore: verbosity set to " << verbose_ << std::endl;
592 
593  verboseQT_ = pset.getUntrackedParameter<int>("verboseQT", 0);
594  if (verbose_ > 0)
595  std::cout << "DQMStore: QTest verbosity set to " << verboseQT_ << std::endl;
596 
597  collateHistograms_ = pset.getUntrackedParameter<bool>("collateHistograms", false);
598  if (collateHistograms_)
599  std::cout << "DQMStore: histogram collation is enabled\n";
600 
601  enableMultiThread_ = pset.getUntrackedParameter<bool>("enableMultiThread", false);
602  if (enableMultiThread_)
603  std::cout << "DQMStore: MultiThread option is enabled\n";
604 
605  LSbasedMode_ = pset.getUntrackedParameter<bool>("LSbasedMode", false);
606  if (LSbasedMode_)
607  std::cout << "DQMStore: LSbasedMode option is enabled\n";
608 
609  std::string ref = pset.getUntrackedParameter<std::string>("referenceFileName", "");
610  if (! ref.empty())
611  {
612  std::cout << "DQMStore: using reference file '" << ref << "'\n";
613  readFile(ref, true, "", s_referenceDirName, StripRunDirs, false);
614  }
615 
616  initQCriterion<Comp2RefChi2>(qalgos_);
617  initQCriterion<Comp2Ref2DChi2>(qalgos_);
618  initQCriterion<Comp2RefKolmogorov>(qalgos_);
619  initQCriterion<ContentsXRange>(qalgos_);
620  initQCriterion<ContentsYRange>(qalgos_);
621  initQCriterion<MeanWithinExpected>(qalgos_);
622  initQCriterion<Comp2RefEqualH>(qalgos_);
623  initQCriterion<DeadChannel>(qalgos_);
624  initQCriterion<NoisyChannel>(qalgos_);
625  initQCriterion<ContentsWithinExpected>(qalgos_);
626  initQCriterion<CompareToMedian>(qalgos_);
627  initQCriterion<CompareLastFilledBin>(qalgos_);
628  initQCriterion<CheckVariance>(qalgos_);
629 
630  scaleFlag_ = pset.getUntrackedParameter<double>("ScalingFlag", 0.0);
631  if (verbose_ > 0)
632  std::cout << "DQMStore: Scaling Flag set to " << scaleFlag_ << std::endl;
633 }
634 
635 /* Generic method to do a backtrace and print it to stdout. It is
636  customised to properly get the routine that called the booking of the
637  histograms, which, following the usual stack, is at position 4. The
638  name of the calling function is properly demangled and the original
639  shared library including this function is also printed. For a more
640  detailed explanation of the routines involved, see here:
641  http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
642  http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html.*/
643 
644 void
646 {
647  // the access to the member stream_ is implicitely protected against
648  // concurrency problems because the print_trace method is always called behind
649  // a lock (see bookTransaction).
650  if (!stream_)
651  stream_ = new std::ofstream("histogramBookingBT.log");
652 
653  void *array[10];
654  size_t size;
655  char **strings;
656  int r=0;
657  lat::RegexpMatch m;
658  m.reset();
659 
660  size = backtrace (array, 10);
661  strings = backtrace_symbols (array, size);
662 
663  size_t level = 1;
664  char * demangled = nullptr;
665  for (; level < size; level++) {
666  if (!s_rxtrace.match(strings[level], 0, 0, &m)) continue;
667  demangled = abi::__cxa_demangle(m.matchString(strings[level], 2).c_str(), nullptr, nullptr, &r);
668  if (!demangled) continue;
669  if (!s_rxself.match(demangled, 0, 0)) break;
670  free(demangled);
671  demangled = nullptr;
672  }
673 
674  if (demangled != nullptr) {
675  *stream_ << "\"" << dir << "/"
676  << name << "\" "
677  << (r ? m.matchString(strings[level], 2) : demangled) << " "
678  << m.matchString(strings[level], 1) << "\n";
679  free(demangled);
680  } else {
681  *stream_ << "Skipping "<< dir << "/" << name
682  << " with stack size " << size << "\n";
683  }
684 
685  /* In this case print the full stack trace, up to main or to the
686  * maximum stack size, i.e. 10. */
687  if (verbose_ > 4 || demangled == nullptr)
688  {
689  size_t i;
690  m.reset();
691 
692  for (i = 0; i < size; i++)
693  if (s_rxtrace.match(strings[i], 0, 0, &m))
694  {
695  char * demangled = abi::__cxa_demangle(m.matchString(strings[i], 2).c_str(), nullptr, nullptr, &r);
696  *stream_ << "\t\t" << i << "/" << size << " "
697  << (r ? m.matchString(strings[i], 2) : demangled) << " "
698  << m.matchString(strings[i], 1) << std::endl;
699  free (demangled);
700  }
701  }
702  free (strings);
703 }
704 
709 void
710 DQMStore::setVerbose(unsigned /* level */)
711 { return; }
712 
717 const std::string &
719 { return pwd_; }
720 
722 void
724 { setCurrentFolder(""); }
725 
727 void
728 DQMStore::cd(const std::string &subdir)
729 {
731  const std::string *cleaned = nullptr;
732  cleanTrailingSlashes(subdir, clean, cleaned);
733 
734  if (! dirExists(*cleaned))
735  raiseDQMError("DQMStore", "Cannot 'cd' into non-existent directory '%s'",
736  cleaned->c_str());
737 
738  setCurrentFolder(*cleaned);
739 }
740 
745 void
747 {
749  const std::string *cleaned = nullptr;
750  cleanTrailingSlashes(fullpath, clean, cleaned);
751  makeDirectory(*cleaned);
752  pwd_ = *cleaned;
753 }
754 
756 void
758 {
759  size_t pos = pwd_.rfind('/');
760  if (pos == std::string::npos)
761  setCurrentFolder("");
762  else
763  setCurrentFolder(pwd_.substr(0, pos));
764 }
765 
766 // -------------------------------------------------------------------
769 void
771 {
772  std::string prev;
773  std::string subdir;
775  prev.reserve(path.size());
776  subdir.reserve(path.size());
777  name.reserve(path.size());
778  size_t prevname = 0;
779  size_t slash = 0;
780 
781  while (true)
782  {
783  // Create this subdirectory component.
784  subdir.clear();
785  subdir.append(path, 0, slash);
786  name.clear();
787  name.append(subdir, prevname, std::string::npos);
788  if (! prev.empty() && findObject(prev, name))
789  raiseDQMError("DQMStore", "Attempt to create subdirectory '%s'"
790  " which already exists as a monitor element",
791  subdir.c_str());
792 
793  if (! dirs_.count(subdir))
794  dirs_.insert(subdir);
795 
796  // Stop if we've reached the end (including possibly a trailing slash).
797  if (slash+1 >= path.size())
798  break;
799 
800  // Find the next slash, making sure we progress. If reach the end,
801  // process the last path component; the next loop round will terminate.
802  prevname = slash ? slash+1 : slash;
803  prev = subdir;
804  if ((slash = path.find('/', ++slash)) == std::string::npos)
805  slash = path.size();
806  }
807 }
808 
810 bool
812 { return dirs_.count(path) > 0; }
813 
817 template <class HISTO, class COLLATE>
820  const char *context, int kind,
821  HISTO *h, COLLATE collate)
822 {
823  assert(name.find('/') == std::string::npos);
824  if (verbose_ > 3)
825  print_trace(dir, name);
827  mergePath(path, dir, name);
828 
829  // Put us in charge of h.
830  h->SetDirectory(nullptr);
831 
832  // Check if the request monitor element already exists.
833  MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_);
834  if (me)
835  {
836  if (collateHistograms_)
837  {
838  collate(me, h, verbose_);
839  delete h;
840  return me;
841  }
842  else
843  {
844  if (verbose_ > 1)
845  std::cout << "DQMStore: "
846  << context << ": monitor element '"
847  << path << "' already exists, collating" << std::endl;
848  me->Reset();
849  collate(me, h, verbose_);
850  delete h;
851  return me;
852  }
853  }
854  else
855  {
856  // Create and initialise core object.
857  assert(dirs_.count(dir));
858  MonitorElement proto(&*dirs_.find(dir), name, run_, streamId_, moduleId_);
859  me = const_cast<MonitorElement &>(*data_.insert(std::move(proto)).first)
861 
862  // Initialise quality test information.
863  auto qi = qtestspecs_.begin();
864  auto qe = qtestspecs_.end();
865  for ( ; qi != qe; ++qi)
866  {
867  if ( qi->first->match(path) )
868  me->addQReport(qi->second);
869  }
870 
871  // If we just booked a (plain) MonitorElement, and there is a reference
872  // MonitorElement with the same name, link the two together.
873  // The other direction is handled by the extract method.
874  std::string refdir;
875  refdir.reserve(s_referenceDirName.size() + dir.size() + 1);
876  refdir += s_referenceDirName;
877  refdir += '/';
878  refdir += dir;
879  MonitorElement* referenceME = findObject(refdir, name);
880  if (referenceME) {
881  // We have booked a new MonitorElement with a specific dir and name.
882  // Then, if we can find the corresponding MonitorElement in the reference
883  // dir we assign the object_ of the reference MonitorElement to the
884  // reference_ property of our new MonitorElement.
885  me->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
886  me->reference_ = referenceME->object_;
887  }
888 
889  // Return the monitor element.
890  return me;
891  }
892 }
893 
896  const std::string &name,
897  const char *context)
898 {
899  assert(name.find('/') == std::string::npos);
900  if (verbose_ > 3)
901  print_trace(dir, name);
902 
903  // Check if the request monitor element already exists.
904  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
905  {
906  if (verbose_ > 1)
907  {
909  mergePath(path, dir, name);
910 
911  std::cout << "DQMStore: "
912  << context << ": monitor element '"
913  << path << "' already exists, resetting" << std::endl;
914  }
915  me->Reset();
916  return me;
917  }
918  else
919  {
920  // Create it and return for initialisation.
921  assert(dirs_.count(dir));
922  MonitorElement proto(&*dirs_.find(dir), name, run_, streamId_, moduleId_);
923  return &const_cast<MonitorElement &>(*data_.insert(std::move(proto)).first);
924  }
925 }
926 
927 // -------------------------------------------------------------------
931 {
932  if (collateHistograms_)
933  {
934  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
935  {
936  me->Fill(0);
937  return me;
938  }
939  }
940 
941  return book_(dir, name, "bookInt")
943 }
944 
948 { return bookInt_(pwd_, name); }
949 
953 {
954  return bookInt_(pwd_, name);
955 }
956 
957 // -------------------------------------------------------------------
961 {
962  if (collateHistograms_)
963  {
964  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
965  {
966  me->Fill(0.);
967  return me;
968  }
969  }
970 
971  return book_(dir, name, "bookFloat")
973 }
974 
978 { return bookFloat_(pwd_, name); }
979 
983 {
984  return bookFloat_(pwd_, name);
985 }
986 
987 // -------------------------------------------------------------------
991  const std::string &name,
992  const std::string &value)
993 {
994  if (collateHistograms_)
995  {
996  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
997  return me;
998  }
999 
1000  return book_(dir, name, "bookString")
1002 }
1003 
1006 DQMStore::bookString(const char *name, const char *value)
1007 { return bookString_(pwd_, name, value); }
1008 
1012 {
1013  return bookString_(pwd_, name, value);
1014 }
1015 
1016 // -------------------------------------------------------------------
1020 {
1021  return book_(dir, name, "book1D", MonitorElement::DQM_KIND_TH1F, h, collate1D);
1022 }
1023 
1027 {
1028  return book_(dir, name, "book1S", MonitorElement::DQM_KIND_TH1S, h, collate1S);
1029 }
1030 
1034 {
1035  return book_(dir, name, "book1DD", MonitorElement::DQM_KIND_TH1D, h, collate1DD);
1036 }
1037 
1040 DQMStore::book1D(const char *name, const char *title,
1041  int nchX, double lowX, double highX)
1042 {
1043  return book1D_(pwd_, name, new TH1F(name, title, nchX, lowX, highX));
1044 }
1045 
1049  int nchX, double lowX, double highX)
1050 {
1051  return book1D_(pwd_, name, new TH1F(name.c_str(), title.c_str(), nchX, lowX, highX));
1052 }
1053 
1056 DQMStore::book1S(const char *name, const char *title,
1057  int nchX, double lowX, double highX)
1058 {
1059  return book1S_(pwd_, name, new TH1S(name, title, nchX, lowX, highX));
1060 }
1061 
1065  int nchX, double lowX, double highX)
1066 {
1067  return book1S_(pwd_, name, new TH1S(name.c_str(), title.c_str(), nchX, lowX, highX));
1068 }
1069 
1072 DQMStore::book1DD(const char *name, const char *title,
1073  int nchX, double lowX, double highX)
1074 {
1075  return book1DD_(pwd_, name, new TH1D(name, title, nchX, lowX, highX));
1076 }
1077 
1081  int nchX, double lowX, double highX)
1082 {
1083  return book1DD_(pwd_, name, new TH1D(name.c_str(), title.c_str(), nchX, lowX, highX));
1084 }
1085 
1088 DQMStore::book1D(const char *name, const char *title,
1089  int nchX, const float *xbinsize)
1090 {
1091  return book1D_(pwd_, name, new TH1F(name, title, nchX, xbinsize));
1092 }
1093 
1097  int nchX, const float *xbinsize)
1098 {
1099  return book1D_(pwd_, name, new TH1F(name.c_str(), title.c_str(), nchX, xbinsize));
1100 }
1101 
1104 DQMStore::book1D(const char *name, TH1F *source)
1105 {
1106  return book1D_(pwd_, name, static_cast<TH1F *>(source->Clone(name)));
1107 }
1108 
1112 {
1113  return book1D_(pwd_, name, static_cast<TH1F *>(source->Clone(name.c_str())));
1114 }
1115 
1118 DQMStore::book1S(const char *name, TH1S *source)
1119 {
1120  return book1S_(pwd_, name, static_cast<TH1S *>(source->Clone(name)));
1121 }
1122 
1126 {
1127  return book1S_(pwd_, name, static_cast<TH1S *>(source->Clone(name.c_str())));
1128 }
1129 
1132 DQMStore::book1DD(const char *name, TH1D *source)
1133 {
1134  return book1DD_(pwd_, name, static_cast<TH1D *>(source->Clone(name)));
1135 }
1136 
1140 {
1141  return book1DD_(pwd_, name, static_cast<TH1D *>(source->Clone(name.c_str())));
1142 }
1143 
1144 // -------------------------------------------------------------------
1148 {
1149  return book_(dir, name, "book2D", MonitorElement::DQM_KIND_TH2F, h, collate2D);
1150 }
1151 
1155 {
1156  return book_(dir, name, "book2S", MonitorElement::DQM_KIND_TH2S, h, collate2S);
1157 }
1158 
1162 {
1163  return book_(dir, name, "book2DD", MonitorElement::DQM_KIND_TH2D, h, collate2DD);
1164 }
1165 
1168 DQMStore::book2D(const char *name, const char *title,
1169  int nchX, double lowX, double highX,
1170  int nchY, double lowY, double highY)
1171 {
1172  return book2D_(pwd_, name, new TH2F(name, title,
1173  nchX, lowX, highX,
1174  nchY, lowY, highY));
1175 }
1176 
1180  int nchX, double lowX, double highX,
1181  int nchY, double lowY, double highY)
1182 {
1183  return book2D_(pwd_, name, new TH2F(name.c_str(), title.c_str(),
1184  nchX, lowX, highX,
1185  nchY, lowY, highY));
1186 }
1187 
1190 DQMStore::book2S(const char *name, const char *title,
1191  int nchX, double lowX, double highX,
1192  int nchY, double lowY, double highY)
1193 {
1194  return book2S_(pwd_, name, new TH2S(name, title,
1195  nchX, lowX, highX,
1196  nchY, lowY, highY));
1197 }
1198 
1202  int nchX, double lowX, double highX,
1203  int nchY, double lowY, double highY)
1204 {
1205  return book2S_(pwd_, name, new TH2S(name.c_str(), title.c_str(),
1206  nchX, lowX, highX,
1207  nchY, lowY, highY));
1208 }
1209 
1212 DQMStore::book2DD(const char *name, const char *title,
1213  int nchX, double lowX, double highX,
1214  int nchY, double lowY, double highY)
1215 {
1216  return book2DD_(pwd_, name, new TH2D(name, title,
1217  nchX, lowX, highX,
1218  nchY, lowY, highY));
1219 }
1220 
1224  int nchX, double lowX, double highX,
1225  int nchY, double lowY, double highY)
1226 {
1227  return book2DD_(pwd_, name, new TH2D(name.c_str(), title.c_str(),
1228  nchX, lowX, highX,
1229  nchY, lowY, highY));
1230 }
1231 
1234 DQMStore::book2D(const char *name, const char *title,
1235  int nchX, const float *xbinsize, int nchY, const float *ybinsize)
1236 {
1237  return book2D_(pwd_, name, new TH2F(name, title,
1238  nchX, xbinsize, nchY, ybinsize));
1239 }
1240 
1244  int nchX, const float *xbinsize, int nchY, const float *ybinsize)
1245 {
1246  return book2D_(pwd_, name, new TH2F(name.c_str(), title.c_str(),
1247  nchX, xbinsize, nchY, ybinsize));
1248 }
1249 
1252 DQMStore::book2S(const char *name, const char *title,
1253  int nchX, const float *xbinsize, int nchY, const float *ybinsize)
1254 {
1255  return book2S_(pwd_, name, new TH2S(name, title,
1256  nchX, xbinsize, nchY, ybinsize));
1257 }
1258 
1262  int nchX, const float *xbinsize, int nchY, const float *ybinsize)
1263 {
1264  return book2S_(pwd_, name, new TH2S(name.c_str(), title.c_str(),
1265  nchX, xbinsize, nchY, ybinsize));
1266 }
1267 
1270 DQMStore::book2D(const char *name, TH2F *source)
1271 {
1272  return book2D_(pwd_, name, static_cast<TH2F *>(source->Clone(name)));
1273 }
1274 
1278 {
1279  return book2D_(pwd_, name, static_cast<TH2F *>(source->Clone(name.c_str())));
1280 }
1281 
1284 DQMStore::book2S(const char *name, TH2S *source)
1285 {
1286  return book2S_(pwd_, name, static_cast<TH2S *>(source->Clone(name)));
1287 }
1288 
1292 {
1293  return book2S_(pwd_, name, static_cast<TH2S *>(source->Clone(name.c_str())));
1294 }
1295 
1298 DQMStore::book2DD(const char *name, TH2D *source)
1299 {
1300  return book2DD_(pwd_, name, static_cast<TH2D *>(source->Clone(name)));
1301 }
1302 
1306 {
1307  return book2DD_(pwd_, name, static_cast<TH2D *>(source->Clone(name.c_str())));
1308 }
1309 
1310 // -------------------------------------------------------------------
1314 {
1315  return book_(dir, name, "book3D", MonitorElement::DQM_KIND_TH3F, h, collate3D);
1316 }
1317 
1320 DQMStore::book3D(const char *name, const char *title,
1321  int nchX, double lowX, double highX,
1322  int nchY, double lowY, double highY,
1323  int nchZ, double lowZ, double highZ)
1324 {
1325  return book3D_(pwd_, name, new TH3F(name, title,
1326  nchX, lowX, highX,
1327  nchY, lowY, highY,
1328  nchZ, lowZ, highZ));
1329 }
1330 
1334  int nchX, double lowX, double highX,
1335  int nchY, double lowY, double highY,
1336  int nchZ, double lowZ, double highZ)
1337 {
1338  return book3D_(pwd_, name, new TH3F(name.c_str(), title.c_str(),
1339  nchX, lowX, highX,
1340  nchY, lowY, highY,
1341  nchZ, lowZ, highZ));
1342 }
1343 
1346 DQMStore::book3D(const char *name, TH3F *source)
1347 {
1348  return book3D_(pwd_, name, static_cast<TH3F *>(source->Clone(name)));
1349 }
1350 
1354 {
1355  return book3D_(pwd_, name, static_cast<TH3F *>(source->Clone(name.c_str())));
1356 }
1357 
1358 // -------------------------------------------------------------------
1362 {
1363  return book_(dir, name, "bookProfile",
1365  h, collateProfile);
1366 }
1367 
1372 DQMStore::bookProfile(const char *name, const char *title,
1373  int nchX, double lowX, double highX,
1374  int /* nchY */, double lowY, double highY,
1375  const char *option /* = "s" */)
1376 {
1377  return bookProfile_(pwd_, name, new TProfile(name, title,
1378  nchX, lowX, highX,
1379  lowY, highY,
1380  option));
1381 }
1382 
1388  int nchX, double lowX, double highX,
1389  int /* nchY */, double lowY, double highY,
1390  const char *option /* = "s" */)
1391 {
1392  return bookProfile_(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1393  nchX, lowX, highX,
1394  lowY, highY,
1395  option));
1396 }
1397 
1402 DQMStore::bookProfile(const char *name, const char *title,
1403  int nchX, double lowX, double highX,
1404  double lowY, double highY,
1405  const char *option /* = "s" */)
1406 {
1407  return bookProfile_(pwd_, name, new TProfile(name, title,
1408  nchX, lowX, highX,
1409  lowY, highY,
1410  option));
1411 }
1412 
1418  int nchX, double lowX, double highX,
1419  double lowY, double highY,
1420  const char *option /* = "s" */)
1421 {
1422  return bookProfile_(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1423  nchX, lowX, highX,
1424  lowY, highY,
1425  option));
1426 }
1427 
1432 DQMStore::bookProfile(const char *name, const char *title,
1433  int nchX, const double *xbinsize,
1434  int /* nchY */, double lowY, double highY,
1435  const char *option /* = "s" */)
1436 {
1437  return bookProfile_(pwd_, name, new TProfile(name, title,
1438  nchX, xbinsize,
1439  lowY, highY,
1440  option));
1441 }
1442 
1448  int nchX, const double *xbinsize,
1449  int /* nchY */, double lowY, double highY,
1450  const char *option /* = "s" */)
1451 {
1452  return bookProfile_(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1453  nchX, xbinsize,
1454  lowY, highY,
1455  option));
1456 }
1457 
1462 DQMStore::bookProfile(const char *name, const char *title,
1463  int nchX, const double *xbinsize,
1464  double lowY, double highY,
1465  const char *option /* = "s" */)
1466 {
1467  return bookProfile_(pwd_, name, new TProfile(name, title,
1468  nchX, xbinsize,
1469  lowY, highY,
1470  option));
1471 }
1472 
1478  int nchX, const double *xbinsize,
1479  double lowY, double highY,
1480  const char *option /* = "s" */)
1481 {
1482  return bookProfile_(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1483  nchX, xbinsize,
1484  lowY, highY,
1485  option));
1486 }
1487 
1490 DQMStore::bookProfile(const char *name, TProfile *source)
1491 {
1492  return bookProfile_(pwd_, name, static_cast<TProfile *>(source->Clone(name)));
1493 }
1494 
1498 {
1499  return bookProfile_(pwd_, name, static_cast<TProfile *>(source->Clone(name.c_str())));
1500 }
1501 
1502 // -------------------------------------------------------------------
1506 {
1507  return book_(dir, name, "bookProfile2D",
1509  h, collateProfile2D);
1510 }
1511 
1516 DQMStore::bookProfile2D(const char *name, const char *title,
1517  int nchX, double lowX, double highX,
1518  int nchY, double lowY, double highY,
1519  int /* nchZ */, double lowZ, double highZ,
1520  const char *option /* = "s" */)
1521 {
1522  return bookProfile2D_(pwd_, name, new TProfile2D(name, title,
1523  nchX, lowX, highX,
1524  nchY, lowY, highY,
1525  lowZ, highZ,
1526  option));
1527 }
1528 
1534  int nchX, double lowX, double highX,
1535  int nchY, double lowY, double highY,
1536  int /* nchZ */, double lowZ, double highZ,
1537  const char *option /* = "s" */)
1538 {
1539  return bookProfile2D_(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
1540  nchX, lowX, highX,
1541  nchY, lowY, highY,
1542  lowZ, highZ,
1543  option));
1544 }
1545 
1550 DQMStore::bookProfile2D(const char *name, const char *title,
1551  int nchX, double lowX, double highX,
1552  int nchY, double lowY, double highY,
1553  double lowZ, double highZ,
1554  const char *option /* = "s" */)
1555 {
1556  return bookProfile2D_(pwd_, name, new TProfile2D(name, title,
1557  nchX, lowX, highX,
1558  nchY, lowY, highY,
1559  lowZ, highZ,
1560  option));
1561 }
1562 
1568  int nchX, double lowX, double highX,
1569  int nchY, double lowY, double highY,
1570  double lowZ, double highZ,
1571  const char *option /* = "s" */)
1572 {
1573  return bookProfile2D_(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
1574  nchX, lowX, highX,
1575  nchY, lowY, highY,
1576  lowZ, highZ,
1577  option));
1578 }
1579 
1582 DQMStore::bookProfile2D(const char *name, TProfile2D *source)
1583 {
1584  return bookProfile2D_(pwd_, name, static_cast<TProfile2D *>(source->Clone(name)));
1585 }
1586 
1590 {
1591  return bookProfile2D_(pwd_, name, static_cast<TProfile2D *>(source->Clone(name.c_str())));
1592 }
1593 
1597 bool
1599 {
1600  if (me->getTH1()->GetNbinsX() != h->GetNbinsX()
1601  || me->getTH1()->GetNbinsY() != h->GetNbinsY()
1602  || me->getTH1()->GetNbinsZ() != h->GetNbinsZ()
1603  || me->getTH1()->GetXaxis()->GetXmin() != h->GetXaxis()->GetXmin()
1604  || me->getTH1()->GetYaxis()->GetXmin() != h->GetYaxis()->GetXmin()
1605  || me->getTH1()->GetZaxis()->GetXmin() != h->GetZaxis()->GetXmin()
1606  || me->getTH1()->GetXaxis()->GetXmax() != h->GetXaxis()->GetXmax()
1607  || me->getTH1()->GetYaxis()->GetXmax() != h->GetYaxis()->GetXmax()
1608  || me->getTH1()->GetZaxis()->GetXmax() != h->GetZaxis()->GetXmax()
1609  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetXaxis(),(TAxis*)h->GetXaxis())
1610  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetYaxis(),(TAxis*)h->GetYaxis())
1611  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetZaxis(),(TAxis*)h->GetZaxis()) )
1612  {
1613  if(verbose > 0)
1614  std::cout << "*** DQMStore: WARNING:"
1615  << "checkBinningMatches: different binning - cannot add object '"
1616  << h->GetName() << "' of type "
1617  << h->IsA()->GetName() << " to existing ME: '"
1618  << me->getFullname() << "'\n";
1619  return false;
1620  }
1621  return true;
1622 }
1623 
1624 void
1626 {
1627  if (checkBinningMatches(me,h,verbose))
1628  me->getTH1F()->Add(h);
1629 }
1630 
1631 void
1633 {
1634  if (checkBinningMatches(me,h,verbose))
1635  me->getTH1S()->Add(h);
1636 }
1637 
1638 void
1640 {
1641  if (checkBinningMatches(me,h,verbose))
1642  me->getTH1D()->Add(h);
1643 }
1644 
1645 void
1647 {
1648  if (checkBinningMatches(me,h,verbose))
1649  me->getTH2F()->Add(h);
1650 }
1651 
1652 void
1654 {
1655  if (checkBinningMatches(me,h,verbose))
1656  me->getTH2S()->Add(h);
1657 }
1658 
1659 void
1661 {
1662  if (checkBinningMatches(me,h,verbose))
1663  me->getTH2D()->Add(h);
1664 }
1665 
1666 void
1668 {
1669  if (checkBinningMatches(me,h,verbose))
1670  me->getTH3F()->Add(h);
1671 }
1672 
1673 void
1675 {
1676  if (checkBinningMatches(me,h,verbose))
1677  {
1678  TProfile *meh = me->getTProfile();
1679  me->addProfiles(h, meh, meh, 1, 1);
1680  }
1681 }
1682 
1683 void
1685 {
1686  if (checkBinningMatches(me,h,verbose))
1687  {
1688  TProfile2D *meh = me->getTProfile2D();
1689  me->addProfiles(h, meh, meh, 1, 1);
1690  }
1691 }
1692 
1697 void
1698 DQMStore::tag(MonitorElement *me, unsigned int myTag)
1699 {
1700  if (! myTag)
1701  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1702  " with a zero tag", me->getFullname().c_str());
1703  if ((me->data_.flags & DQMNet::DQM_PROP_TAGGED) && myTag != me->data_.tag)
1704  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1705  " twice with multiple tags", me->getFullname().c_str());
1706 
1707  me->data_.tag = myTag;
1709 }
1710 
1712 void
1713 DQMStore::tag(const std::string &path, unsigned int myTag)
1714 {
1715  std::string dir;
1716  std::string name;
1717  splitPath(dir, name, path);
1718 
1719  if (MonitorElement *me = findObject(dir, name))
1720  tag(me, myTag);
1721  else
1722  raiseDQMError("DQMStore", "Attempt to tag non-existent monitor element"
1723  " '%s' with tag %u", path.c_str(), myTag);
1724 
1725 }
1726 
1728 void
1729 DQMStore::tagContents(const std::string &path, unsigned int myTag)
1730 {
1731  MonitorElement proto(&path, std::string());
1732  auto e = data_.end();
1733  auto i = data_.lower_bound(proto);
1734  for ( ; i != e && path == *i->data_.dirname; ++i)
1735  tag(const_cast<MonitorElement *>(&*i), myTag);
1736 }
1737 
1740 void
1741 DQMStore::tagAllContents(const std::string &path, unsigned int myTag)
1742 {
1744  const std::string *cleaned = nullptr;
1745  cleanTrailingSlashes(path, clean, cleaned);
1746  MonitorElement proto(cleaned, std::string());
1747 
1748  // FIXME: WILDCARDS? Old one supported them, but nobody seemed to use them.
1749  auto e = data_.end();
1750  auto i = data_.lower_bound(proto);
1751  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
1752  {
1753  tag(const_cast<MonitorElement *>(&*i), myTag);
1754  ++i;
1755  }
1756 }
1757 
1762 std::vector<std::string>
1764 {
1765  std::vector<std::string> result;
1766  auto e = dirs_.end();
1767  auto i = dirs_.find(pwd_);
1768 
1769  // If we didn't find current directory, the tree is empty, so quit.
1770  if (i == e)
1771  return result;
1772 
1773  // Skip the current directory and then start looking for immediate
1774  // subdirectories in the dirs_ list. Stop when we are no longer in
1775  // (direct or indirect) subdirectories of pwd_. Note that we don't
1776  // "know" which order the set will sort A/B, A/B/C and A/D.
1777  while (++i != e && isSubdirectory(pwd_, *i))
1778  if (i->find('/', pwd_.size()+1) == std::string::npos)
1779  result.push_back(*i);
1780 
1781  return result;
1782 }
1783 
1785 std::vector<std::string>
1787 {
1788  MonitorElement proto(&pwd_, std::string());
1789  std::vector<std::string> result;
1790  auto e = data_.end();
1791  auto i = data_.lower_bound(proto);
1792  for ( ; i != e && isSubdirectory(pwd_, *i->data_.dirname); ++i)
1793  if (pwd_ == *i->data_.dirname)
1794  result.push_back(i->getName());
1795 
1796  return result;
1797 }
1798 
1801 bool
1803 {
1804  MonitorElement proto(&path, std::string());
1805  auto e = data_.end();
1806  auto i = data_.lower_bound(proto);
1807  return (i != e && isSubdirectory(path, *i->data_.dirname));
1808 }
1809 
1813 {
1814  std::string dir;
1815  std::string name;
1816  splitPath(dir, name, path);
1817  MonitorElement proto(&dir, name);
1818  auto mepos = data_.find(proto);
1819  return (mepos == data_.end() ? nullptr
1820  : const_cast<MonitorElement *>(&*mepos));
1821 }
1822 
1824 std::vector<MonitorElement *>
1825 DQMStore::get(unsigned int tag) const
1826 {
1827  // FIXME: Use reverse map [tag -> path] / [tag -> dir]?
1828  std::vector<MonitorElement *> result;
1829  for (auto const & me : data_)
1830  {
1831  if ((me.data_.flags & DQMNet::DQM_PROP_TAGGED) && me.data_.tag == tag)
1832  result.push_back(const_cast<MonitorElement *>(&me));
1833  }
1834  return result;
1835 }
1836 
1839 std::vector<MonitorElement *>
1841 {
1843  const std::string *cleaned = nullptr;
1844  cleanTrailingSlashes(path, clean, cleaned);
1845  MonitorElement proto(cleaned, std::string());
1846 
1847  std::vector<MonitorElement *> result;
1848  auto e = data_.end();
1849  auto i = data_.lower_bound(proto);
1850  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1851  if (*cleaned == *i->data_.dirname)
1852  result.push_back(const_cast<MonitorElement *>(&*i));
1853 
1854  return result;
1855 }
1856 
1858 std::vector<MonitorElement *>
1859 DQMStore::getContents(const std::string &path, unsigned int tag) const
1860 {
1862  const std::string *cleaned = nullptr;
1863  cleanTrailingSlashes(path, clean, cleaned);
1864  MonitorElement proto(cleaned, std::string());
1865 
1866  std::vector<MonitorElement *> result;
1867  auto e = data_.end();
1868  auto i = data_.lower_bound(proto);
1869  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1870  if (*cleaned == *i->data_.dirname
1871  && (i->data_.flags & DQMNet::DQM_PROP_TAGGED)
1872  && i->data_.tag == tag)
1873  result.push_back(const_cast<MonitorElement *>(&*i));
1874 
1875  return result;
1876 }
1877 
1882 void
1883 DQMStore::getContents(std::vector<std::string> &into, bool showContents /* = true */) const
1884 {
1885  into.clear();
1886  into.reserve(dirs_.size());
1887 
1888  auto me = data_.end();
1889  auto di = dirs_.begin();
1890  auto de = dirs_.end();
1891  for ( ; di != de; ++di)
1892  {
1893  MonitorElement proto(&*di, std::string());
1894  auto mi = data_.lower_bound(proto);
1895  auto m = mi;
1896  size_t sz = di->size() + 2;
1897  size_t nfound = 0;
1898  for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
1899  if (*di == *m->data_.dirname)
1900  {
1901  sz += m->data_.objname.size() + 1;
1902  ++nfound;
1903  }
1904 
1905  if (! nfound)
1906  continue;
1907 
1908  auto istr
1909  = into.insert(into.end(), std::string());
1910 
1911  if (showContents)
1912  {
1913  istr->reserve(sz);
1914 
1915  *istr += *di;
1916  *istr += ':';
1917  for (sz = 0; mi != m; ++mi)
1918  {
1919  if (*di != *mi->data_.dirname)
1920  continue;
1921 
1922  if (sz > 0)
1923  *istr += ',';
1924 
1925  *istr += mi->data_.objname;
1926  ++sz;
1927  }
1928  }
1929  else
1930  {
1931  istr->reserve(di->size() + 2);
1932  *istr += *di;
1933  *istr += ':';
1934  }
1935  }
1936 }
1937 
1942  const std::string &name,
1943  const uint32_t run /* = 0 */,
1944  const uint32_t lumi /* = 0 */,
1945  const uint32_t streamId /* = 0 */,
1946  const uint32_t moduleId /* = 0 */) const
1947 {
1948  if (dir.find_first_not_of(s_safe) != std::string::npos)
1949  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1950  " unacceptable characters", dir.c_str());
1951  if (name.find_first_not_of(s_safe) != std::string::npos)
1952  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1953  " unacceptable characters", name.c_str());
1954 
1955  MonitorElement proto;
1956  proto.data_.dirname = &dir;
1957  proto.data_.objname = name;
1958  proto.data_.run = run;
1959  proto.data_.lumi = lumi;
1960  proto.data_.streamId = streamId;
1961  proto.data_.moduleId = moduleId;
1962 
1963  auto mepos = data_.find(proto);
1964  return (mepos == data_.end() ? nullptr
1965  : const_cast<MonitorElement *>(&*mepos));
1966 }
1967 
1970 void
1971 DQMStore::getAllTags(std::vector<std::string> &into) const
1972 {
1973  into.clear();
1974  into.reserve(dirs_.size());
1975 
1976  auto me = data_.end();
1977  auto di = dirs_.begin();
1978  auto de = dirs_.end();
1979  char tagbuf[32]; // more than enough for '/' and up to 10 digits
1980 
1981  for ( ; di != de; ++di)
1982  {
1983  MonitorElement proto(&*di, std::string());
1984  auto mi = data_.lower_bound(proto);
1985  auto m = mi;
1986  size_t sz = di->size() + 2;
1987  size_t nfound = 0;
1988  for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
1989  if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
1990  {
1991  // the tags count for '/' + up to 10 digits, otherwise ',' + ME name
1992  sz += 1 + m->data_.objname.size() + 11;
1993  ++nfound;
1994  }
1995 
1996  if (! nfound)
1997  continue;
1998 
1999  auto istr
2000  = into.insert(into.end(), std::string());
2001 
2002  istr->reserve(sz);
2003 
2004  *istr += *di;
2005  *istr += ':';
2006  for (sz = 0; mi != m; ++mi)
2007  {
2008  if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
2009  {
2010  sprintf(tagbuf, "/%u", mi->data_.tag);
2011  if (sz > 0)
2012  *istr += ',';
2013  *istr += m->data_.objname;
2014  *istr += tagbuf;
2015  ++sz;
2016  }
2017  }
2018  }
2019 }
2020 
2023 std::vector<MonitorElement*>
2025  uint32_t runNumber /* = 0 */,
2026  uint32_t lumi /* = 0 */) const
2027 {
2029  const std::string *cleaned = nullptr;
2030  cleanTrailingSlashes(path, clean, cleaned);
2031  MonitorElement proto(cleaned, std::string(), runNumber);
2032  proto.setLumi(lumi);
2033 
2034  std::vector<MonitorElement *> result;
2035  auto e = data_.end();
2036  auto i = data_.lower_bound(proto);
2037  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
2038  if (runNumber != 0) {
2039  if (i->data_.run > runNumber // TODO[rovere]: pleonastic? first we encounter local ME of the same run ...
2040  || i->data_.streamId != 0
2041  || i->data_.moduleId != 0)
2042  break;
2043  }
2044  if (lumi != 0) {
2045  if (i->data_.lumi > lumi
2046  || i->data_.streamId != 0
2047  || i->data_.moduleId != 0)
2048  break;
2049  }
2050  if (runNumber != 0 or lumi !=0) {
2051  assert(i->data_.streamId == 0);
2052  assert(i->data_.moduleId == 0);
2053  }
2054  result.push_back(const_cast<MonitorElement *>(&*i));
2055  }
2056 
2057  if (enableMultiThread_)
2058  {
2059  //save legacy modules when running MT
2060  i = data_.begin();
2061  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
2062  if (i->data_.run != 0 || i->data_.streamId != 0 || i->data_.moduleId != 0) break;
2063  result.push_back(const_cast<MonitorElement *>(&*i));
2064  }
2065  }
2066 
2067  return result;
2068 }
2069 
2072 std::vector<MonitorElement*>
2073 DQMStore::getMatchingContents(const std::string &pattern, lat::Regexp::Syntax syntaxType /* = Wildcard */) const
2074 {
2075  lat::Regexp rx;
2076  try
2077  {
2078  rx = lat::Regexp(pattern, 0, syntaxType);
2079  rx.study();
2080  }
2081  catch (lat::Error &e)
2082  {
2083  raiseDQMError("DQMStore", "Invalid regular expression '%s': %s",
2084  pattern.c_str(), e.explain().c_str());
2085  }
2086 
2087  std::string path;
2088  std::vector<MonitorElement *> result;
2089  auto i = data_.begin();
2090  auto e = data_.end();
2091  for ( ; i != e; ++i)
2092  {
2093  path.clear();
2094  mergePath(path, *i->data_.dirname, i->data_.objname);
2095  if (rx.match(path))
2096  result.push_back(const_cast<MonitorElement *>(&*i));
2097  }
2098 
2099  return result;
2100 }
2101 
2105 
2108 void
2110 {
2111  auto mi = data_.begin();
2112  auto me = data_.end();
2113  for ( ; mi != me; ++mi)
2114  {
2115  auto &me = const_cast<MonitorElement &>(*mi);
2116  if (mi->wasUpdated())
2117  {
2118  if (me.resetMe())
2119  me.Reset();
2120  me.resetUpdate();
2121  }
2122  }
2123 
2124  reset_ = true;
2125 }
2126 
2130 
2132 void
2134 {
2135  auto mi = data_.begin();
2136  auto me = data_.end();
2137  for ( ; mi != me; ++mi)
2138  {
2139  if (forceResetOnBeginLumi_ && ((*mi).getLumiFlag() == false))
2140  continue;
2141  auto &me = const_cast<MonitorElement &>(*mi);
2142  me.Reset();
2143  me.resetUpdate();
2144  }
2145 
2146  reset_ = true;
2147 }
2148 
2149 
2153 
2157 void
2159 {
2160  static const std::string null_str("");
2161 
2162  auto const& lumiblock = gc.luminosityBlockID();
2163  uint32_t run = lumiblock.run();
2164 
2165  // find the range of non-legacy global MEs for the current run:
2166  // run != 0, lumi == 0 (implicit), stream id == 0, module id == 0
2167  const MonitorElement begin(&null_str, null_str, run, 0, 0);
2168  const MonitorElement end(&null_str, null_str, run, 0, 1);
2169  auto i = data_.lower_bound(begin);
2170  const auto e = data_.lower_bound(end);
2171  while (i != e) {
2172  auto& me = const_cast<MonitorElement&>(*i++);
2173  // skip per-run MEs
2174  if (not LSbasedMode_ and not me.getLumiFlag())
2175  continue;
2176  me.Reset();
2177  me.resetUpdate();
2178  }
2179 }
2180 
2184 
2188 void
2190 {
2191  if (!enableMultiThread_)
2192  return;
2193 
2194  std::lock_guard<std::mutex> guard(book_mutex_);
2195 
2196  std::string null_str("");
2197  MonitorElement proto(&null_str, null_str, run, 0, 0);
2198  proto.setLumi(lumi);
2199 
2200  auto e = data_.end();
2201  auto i = data_.lower_bound(proto);
2202 
2203  while (i != e) {
2204  if (i->data_.streamId != 0 ||
2205  i->data_.moduleId != 0)
2206  break;
2207  if (i->data_.lumi != lumi)
2208  break;
2209  if (i->data_.run != run)
2210  break;
2211  if (not i->markedToDelete()) {
2212  ++i;
2213  continue;
2214  }
2215 
2216  if (verbose_ > 1) {
2217  std::cout << "DQMStore::deleteUnusedLumiHistograms: deleted monitor element '"
2218  << *i->data_.dirname << "/" << i->data_.objname << "'"
2219  << "flags " << i->data_.flags << "\n";
2220  }
2221 
2222  i = data_.erase(i);
2223  }
2224 }
2225 
2231 bool
2233  bool overwrite, bool collateHistograms)
2234 {
2235  // NB: Profile histograms inherit from TH*D, checking order matters.
2236  MonitorElement *refcheck = nullptr;
2237  if (auto *h = dynamic_cast<TProfile *>(obj))
2238  {
2239  MonitorElement *me = findObject(dir, h->GetName());
2240  if (! me)
2241  me = bookProfile_(dir, h->GetName(), (TProfile *) h->Clone());
2242  else if (overwrite)
2243  me->copyFrom(h);
2244  else if (isCollateME(me) || collateHistograms)
2245  collateProfile(me, h, verbose_);
2246  refcheck = me;
2247  }
2248  else if (auto *h = dynamic_cast<TProfile2D *>(obj))
2249  {
2250  MonitorElement *me = findObject(dir, h->GetName());
2251  if (! me)
2252  me = bookProfile2D_(dir, h->GetName(), (TProfile2D *) h->Clone());
2253  else if (overwrite)
2254  me->copyFrom(h);
2255  else if (isCollateME(me) || collateHistograms)
2256  collateProfile2D(me, h, verbose_);
2257  refcheck = me;
2258  }
2259  else if (auto *h = dynamic_cast<TH1F *>(obj))
2260  {
2261  MonitorElement *me = findObject(dir, h->GetName());
2262  if (! me)
2263  me = book1D_(dir, h->GetName(), (TH1F *) h->Clone());
2264  else if (overwrite)
2265  me->copyFrom(h);
2266  else if (isCollateME(me) || collateHistograms)
2267  collate1D(me, h, verbose_);
2268  refcheck = me;
2269  }
2270  else if (auto *h = dynamic_cast<TH1S *>(obj))
2271  {
2272  MonitorElement *me = findObject(dir, h->GetName());
2273  if (! me)
2274  me = book1S_(dir, h->GetName(), (TH1S *) h->Clone());
2275  else if (overwrite)
2276  me->copyFrom(h);
2277  else if (isCollateME(me) || collateHistograms)
2278  collate1S(me, h, verbose_);
2279  refcheck = me;
2280  }
2281  else if (auto *h = dynamic_cast<TH1D *>(obj))
2282  {
2283  MonitorElement *me = findObject(dir, h->GetName());
2284  if (! me)
2285  me = book1DD_(dir, h->GetName(), (TH1D *) h->Clone());
2286  else if (overwrite)
2287  me->copyFrom(h);
2288  else if (isCollateME(me) || collateHistograms)
2289  collate1DD(me, h, verbose_);
2290  refcheck = me;
2291  }
2292  else if (auto *h = dynamic_cast<TH2F *>(obj))
2293  {
2294  MonitorElement *me = findObject(dir, h->GetName());
2295  if (! me)
2296  me = book2D_(dir, h->GetName(), (TH2F *) h->Clone());
2297  else if (overwrite)
2298  me->copyFrom(h);
2299  else if (isCollateME(me) || collateHistograms)
2300  collate2D(me, h, verbose_);
2301  refcheck = me;
2302  }
2303  else if (auto *h = dynamic_cast<TH2S *>(obj))
2304  {
2305  MonitorElement *me = findObject(dir, h->GetName());
2306  if (! me)
2307  me = book2S_(dir, h->GetName(), (TH2S *) h->Clone());
2308  else if (overwrite)
2309  me->copyFrom(h);
2310  else if (isCollateME(me) || collateHistograms)
2311  collate2S(me, h, verbose_);
2312  refcheck = me;
2313  }
2314  else if (auto *h = dynamic_cast<TH2D *>(obj))
2315  {
2316  MonitorElement *me = findObject(dir, h->GetName());
2317  if (! me)
2318  me = book2DD_(dir, h->GetName(), (TH2D *) h->Clone());
2319  else if (overwrite)
2320  me->copyFrom(h);
2321  else if (isCollateME(me) || collateHistograms)
2322  collate2DD(me, h, verbose_);
2323  refcheck = me;
2324  }
2325  else if (auto *h = dynamic_cast<TH3F *>(obj))
2326  {
2327  MonitorElement *me = findObject(dir, h->GetName());
2328  if (! me)
2329  me = book3D_(dir, h->GetName(), (TH3F *) h->Clone());
2330  else if (overwrite)
2331  me->copyFrom(h);
2332  else if (isCollateME(me) || collateHistograms)
2333  collate3D(me, h, verbose_);
2334  refcheck = me;
2335  }
2336  else if (dynamic_cast<TObjString *>(obj))
2337  {
2338  lat::RegexpMatch m;
2339  if (! s_rxmeval.match(obj->GetName(), 0, 0, &m))
2340  {
2341  if (strstr(obj->GetName(), "CMSSW"))
2342  {
2343  if (verbose_)
2344  std::cout << "Input file version: " << obj->GetName() << std::endl;
2345  return true;
2346  }
2347  else if (strstr(obj->GetName(), "DQMPATCH"))
2348  {
2349  if (verbose_)
2350  std::cout << "DQM patch version: " << obj->GetName() << std::endl;
2351  return true;
2352  }
2353  else
2354  {
2355  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2356  << obj->GetName() << "' of type '"
2357  << obj->IsA()->GetName() << "'\n";
2358  return false;
2359  }
2360  }
2361 
2362  std::string label = m.matchString(obj->GetName(), 1);
2363  std::string kind = m.matchString(obj->GetName(), 2);
2364  std::string value = m.matchString(obj->GetName(), 3);
2365 
2366  if (kind == "i")
2367  {
2368  MonitorElement *me = findObject(dir, label);
2369  if (! me || overwrite)
2370  {
2371  if (! me) me = bookInt_(dir, label);
2372  me->Fill(atoll(value.c_str()));
2373  }
2374  }
2375  else if (kind == "f")
2376  {
2377  MonitorElement *me = findObject(dir, label);
2378  if (! me || overwrite)
2379  {
2380  if (! me) me = bookFloat_(dir, label);
2381  me->Fill(atof(value.c_str()));
2382  }
2383  }
2384  else if (kind == "s")
2385  {
2386  MonitorElement *me = findObject(dir, label);
2387  if (! me)
2388  me = bookString_(dir, label, value);
2389  else if (overwrite)
2390  me->Fill(value);
2391  }
2392  else if (kind == "e")
2393  {
2394  MonitorElement *me = findObject(dir, label);
2395  if (! me)
2396  {
2397  std::cout << "*** DQMStore: WARNING: no monitor element '"
2398  << label << "' in directory '"
2399  << dir << "' to be marked as efficiency plot.\n";
2400  return false;
2401  }
2402  me->setEfficiencyFlag();
2403  }
2404  else if (kind == "t")
2405  {
2406  MonitorElement *me = findObject(dir, label);
2407  if (! me)
2408  {
2409  std::cout << "*** DQMStore: WARNING: no monitor element '"
2410  << label << "' in directory '"
2411  << dir << "' for a tag\n";
2412  return false;
2413  }
2414  errno = 0;
2415  char *endp = nullptr;
2416  unsigned long val = strtoul(value.c_str(), &endp, 10);
2417  if ((val == 0 && errno) || *endp || val > ~uint32_t(0))
2418  {
2419  std::cout << "*** DQMStore: WARNING: cannot restore tag '"
2420  << value << "' for monitor element '"
2421  << label << "' in directory '"
2422  << dir << "' - invalid value\n";
2423  return false;
2424  }
2425  tag(me, val);
2426  }
2427  else if (kind == "qr")
2428  {
2429  // Handle qreports, but skip them while reading in references.
2430  if (! isSubdirectory(s_referenceDirName, dir))
2431  {
2432  size_t dot = label.find('.');
2433  if (dot == std::string::npos)
2434  {
2435  std::cout << "*** DQMStore: WARNING: quality report label in '" << label
2436  << "' is missing a '.' and cannot be extracted\n";
2437  return false;
2438  }
2439 
2440  std::string mename (label, 0, dot);
2441  std::string qrname (label, dot+1, std::string::npos);
2442 
2443  m.reset();
2444  DQMNet::QValue qv;
2445  if (s_rxmeqr1.match(value, 0, 0, &m))
2446  {
2447  qv.code = atoi(m.matchString(value, 1).c_str());
2448  qv.qtresult = strtod(m.matchString(value, 2).c_str(), nullptr);
2449  qv.message = m.matchString(value, 4);
2450  qv.qtname = qrname;
2451  qv.algorithm = m.matchString(value, 3);
2452  }
2453  else if (s_rxmeqr2.match(value, 0, 0, &m))
2454  {
2455  qv.code = atoi(m.matchString(value, 1).c_str());
2456  qv.qtresult = 0; // unavailable in old format
2457  qv.message = m.matchString(value, 2);
2458  qv.qtname = qrname;
2459  // qv.algorithm unavailable in old format
2460  }
2461  else
2462  {
2463  std::cout << "*** DQMStore: WARNING: quality test value '"
2464  << value << "' is incorrectly formatted\n";
2465  return false;
2466  }
2467 
2468  MonitorElement *me = findObject(dir, mename);
2469  if (! me)
2470  {
2471  std::cout << "*** DQMStore: WARNING: no monitor element '"
2472  << mename << "' in directory '"
2473  << dir << "' for quality test '"
2474  << label << "'\n";
2475  return false;
2476  }
2477 
2478  me->addQReport(qv, /* FIXME: getQTest(qv.qtname)? */ nullptr);
2479  }
2480  }
2481  else
2482  {
2483  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2484  << obj->GetName() << "' of type '"
2485  << obj->IsA()->GetName() << "'\n";
2486  return false;
2487  }
2488  }
2489  else if (auto *n = dynamic_cast<TNamed *>(obj))
2490  {
2491  // For old DQM data.
2492  std::string s;
2493  s.reserve(6 + strlen(n->GetTitle()) + 2*strlen(n->GetName()));
2494  s += '<'; s += n->GetName(); s += '>';
2495  s += n->GetTitle();
2496  s += '<'; s += '/'; s += n->GetName(); s += '>';
2497  TObjString os(s.c_str());
2498  return extract(&os, dir, overwrite, collateHistograms_);
2499  }
2500  else
2501  {
2502  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2503  << obj->GetName() << "' of type '" << obj->IsA()->GetName()
2504  << "' and with title '" << obj->GetTitle() << "'\n";
2505  return false;
2506  }
2507 
2508  // If we just read in a reference MonitorElement, and there is a
2509  // MonitorElement with the same name, link the two together.
2510  // The other direction is handled by the book() method.
2511  if (refcheck && isSubdirectory(s_referenceDirName, dir))
2512  {
2513  std::string mdir(dir, s_referenceDirName.size()+1, std::string::npos);
2514  if (MonitorElement *master = findObject(mdir, obj->GetName()))
2515  {
2516  // We have extracted a MonitorElement, and it's located in the reference
2517  // dir. Then we find the corresponding MonitorElement in the
2518  // non-reference dir and assign the object_ of the reference
2519  // MonitorElement to the reference_ property of the corresponding
2520  // non-reference MonitorElement.
2521  master->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
2522  master->reference_ = refcheck->object_;
2523  }
2524  }
2525 
2526  return true;
2527 }
2528 
2532 bool
2534 {
2535  assert(! path.empty());
2536 
2537  // Find the first path component.
2538  size_t start = 0;
2539  size_t end = path.find('/', start);
2540  if (end == std::string::npos)
2541  end = path.size();
2542 
2543  while (true)
2544  {
2545  // Check if this subdirectory component exists. If yes, make sure
2546  // it is actually a subdirectory. Otherwise create or cd into it.
2547  std::string part(path, start, end-start);
2548  TObject *o = gDirectory->Get(part.c_str());
2549  if (o && ! dynamic_cast<TDirectory *>(o))
2550  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2551  " fails because the part '%s' already exists and is not"
2552  " directory", path.c_str(), part.c_str());
2553  else if (! o)
2554  gDirectory->mkdir(part.c_str());
2555 
2556  if (! gDirectory->cd(part.c_str()))
2557  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2558  " fails because could not cd into subdirectory '%s'",
2559  path.c_str(), part.c_str());
2560 
2561  // Stop if we reached the end, ignoring any trailing '/'.
2562  if (end+1 >= path.size())
2563  break;
2564 
2565  // Find the next path component.
2566  start = end+1;
2567  end = path.find('/', start);
2568  if (end == std::string::npos)
2569  end = path.size();
2570  }
2571 
2572  return true;
2573 }
2574 
2575 void
2577  MonitorElement const& me,
2578  TFile & file)
2579 {
2580  // Save the object.
2581  if (me.kind() < MonitorElement::DQM_KIND_TH1F) {
2582  TObjString(me.tagString().c_str()).Write();
2583  } else {
2584  me.object_->Write();
2585  }
2586 
2587  // Save quality reports if this is not in reference section.
2589  {
2590  for (auto const& report: me.data_.qreports) {
2591  TObjString(me.qualityTagString(report).c_str()).Write();
2592  }
2593  }
2594 
2595  // Save efficiency tag, if any.
2597  TObjString(me.effLabelString().c_str()).Write();
2598  }
2599 
2600  // Save tag if any.
2601  if (me.data_.flags & DQMNet::DQM_PROP_TAGGED) {
2602  TObjString(me.tagLabelString().c_str()).Write();
2603  }
2604 }
2605 
2606 void
2608  std::string const& dir,
2609  std::string const& refpath,
2610  SaveReferenceTag ref,
2611  int minStatus,
2612  unsigned int run,
2613  MEMap::const_iterator begin,
2614  MEMap::const_iterator end,
2615  TFile & file,
2616  unsigned int & counter)
2617 {
2618  for (auto const& me: boost::make_iterator_range(begin, end))
2619  {
2620  if (not isSubdirectory(dir, *me.data_.dirname))
2621  break;
2622 
2623  if (verbose_ > 1)
2624  std::cout << "DQMStore::save:"
2625  << " run: " << me.run()
2626  << " lumi: " << me.lumi()
2627  << " lumiFlag: " << me.getLumiFlag()
2628  << " streamId: " << me.streamId()
2629  << " moduleId: " << me.moduleId()
2630  << " fullpathname: " << me.getFullname()
2631  << " flags: " << std::hex << me.data_.flags
2632  << std::endl;
2633 
2634  // Skip MonitorElements in a subdirectory of the current one.
2635  if (dir != *me.data_.dirname) {
2636  if (verbose_ > 1) {
2637  std::cout << "DQMStore::save: skipping monitor element in a subfolder of " << dir << "/" << std::endl;
2638  }
2639  continue;
2640  }
2641 
2642  // For MonitorElements booked with the thread-safe approach, identified
2643  // by having run != 0, ignore the per-stream ones.
2644  if (run != 0 and (me.data_.streamId != 0 or me.data_.moduleId != 0)) {
2645  if (verbose_ > 1) {
2646  std::cout << "DQMStore::save: skipping per-stream monitor element" << std::endl;
2647  }
2648  continue;
2649  }
2650 
2651  // Handle reference histograms, with three distinct cases:
2652  // 1) Skip all references entirely on saving.
2653  // 2) Blanket saving of all references.
2654  // 3) Save only references for monitor elements with qtests.
2655  // The latter two are affected by "path" sub-tree selection,
2656  // i.e. references are saved only in the selected tree part.
2657  if (isSubdirectory(refpath, *me.data_.dirname))
2658  {
2659  if (ref == SaveWithoutReference)
2660  // Skip the reference entirely.
2661  continue;
2662  else if (ref == SaveWithReference)
2663  // Save all references regardless of qtests.
2664  ;
2665  else if (ref == SaveWithReferenceForQTest)
2666  {
2667  // Save only references for monitor elements with qtests
2668  // with an optional cut on minimum quality test result.
2669  int status = -1;
2670  std::string mname(me.getFullname(), s_referenceDirName.size()+1, std::string::npos);
2671  MonitorElement *master = get(mname);
2672  if (master)
2673  for (size_t i = 0, e = master->data_.qreports.size(); i != e; ++i)
2674  status = std::max(status, master->data_.qreports[i].code);
2675 
2676  if (not master or status < minStatus)
2677  {
2678  if (verbose_ > 1)
2679  std::cout << "DQMStore::save: skipping monitor element '"
2680  << me.data_.objname << "' while saving, status is "
2681  << status << ", required minimum status is "
2682  << minStatus << std::endl;
2683  continue;
2684  }
2685  }
2686  }
2687 
2688  if (verbose_ > 1) {
2689  std::cout << "DQMStore::save: saving monitor element" << std::endl;
2690  }
2691 
2692  saveMonitorElementToROOT(me, file);
2693 
2694  // Count saved histograms
2695  ++counter;
2696  }
2697 }
2698 
2701 void
2703  const std::string &path /* = "" */,
2704  const std::string &pattern /* = "" */,
2705  const std::string &rewrite /* = "" */,
2706  const uint32_t run /* = 0 */,
2707  const uint32_t lumi /* = 0 */,
2708  SaveReferenceTag ref /* = SaveWithReference */,
2709  int minStatus /* = dqm::qstatus::STATUS_OK */,
2710  const std::string &fileupdate /* = RECREATE */)
2711 {
2712  // TFile flushes to disk with fsync() on every TDirectory written to
2713  // the file. This makes DQM file saving painfully slow, and
2714  // ironically makes it _more_ likely the file saving gets
2715  // interrupted and corrupts the file. The utility class below
2716  // simply ignores the flush synchronisation.
2717  class TFileNoSync : public TFile
2718  {
2719  public:
2720  TFileNoSync(const char *file, const char *opt) : TFile(file, opt) {}
2721  Int_t SysSync(Int_t) override { return 0; }
2722  };
2723 
2724  std::lock_guard<std::mutex> guard(book_mutex_);
2725 
2726  unsigned int nme = 0;
2727 
2728  // open output file, on 1st save recreate, later update
2729  if (verbose_) {
2730  std::cout << "DQMStore::save: Opening TFile '" << filename
2731  << "' with option '" << fileupdate << "'"
2732  << std::endl;
2733  }
2734 
2735  TFileNoSync f(filename.c_str(), fileupdate.c_str()); // open file
2736  if(f.IsZombie())
2737  raiseDQMError("DQMStore", "Failed to create/update file '%s'", filename.c_str());
2738  f.cd();
2739 
2740  // Construct a regular expression from the pattern string.
2741  std::unique_ptr<lat::Regexp> rxpat;
2742  if (not pattern.empty())
2743  rxpat = std::make_unique<lat::Regexp>(pattern);
2744 
2745  // Prepare a path for the reference object selection.
2746  std::string refpath;
2747  refpath.reserve(s_referenceDirName.size() + path.size() + 2);
2748  refpath += s_referenceDirName;
2749  if (not path.empty())
2750  {
2751  refpath += '/';
2752  refpath += path;
2753  }
2754 
2755  // Loop over the directory structure.
2756  for (auto const& dir: dirs_)
2757  {
2758  // Check if we should process this directory. We process the
2759  // requested part of the object tree, including references.
2760  if (not path.empty()
2761  and not isSubdirectory(refpath, dir)
2762  and not isSubdirectory(path, dir))
2763  continue;
2764 
2765  if (verbose_ > 1) {
2766  std::cout << "DQMStore::save: DQM folder " << dir << "/" << std::endl;
2767  }
2768 
2769  // Create the directory.
2770  gDirectory->cd("/");
2771  if (dir.empty())
2773  else if (rxpat.get())
2774  cdInto(s_monitorDirName + '/' + lat::StringOps::replace(dir, *rxpat, rewrite));
2775  else
2776  cdInto(s_monitorDirName + '/' + dir);
2777 
2778  // Loop over monitor elements in this directory.
2779  if (not enableMultiThread_) {
2780  MonitorElement proto(&dir, std::string(), run, 0, 0);
2781  auto begin = data_.lower_bound(proto);
2782  auto end = data_.end();
2783  saveMonitorElementRangeToROOT(dir, refpath, ref, minStatus, run, begin, end, f, nme);
2784  } else {
2785  // Restrict the loop to the monitor elements for the current lumisection
2786  MonitorElement proto(&dir, std::string(), run, 0, 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  saveMonitorElementRangeToROOT(dir, refpath, ref, minStatus, run, begin, end, f, nme);
2792  }
2793 
2794  // In LSbasedMode, loop also over the (run, 0, 0, 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, 0));
2800  auto end = data_.lower_bound(MonitorElement(&dir, std::string(), run, 0, 1));
2801  saveMonitorElementRangeToROOT(dir, refpath, ref, minStatus, run, begin, end, f, nme);
2802  }
2803  }
2804 
2805  f.Close();
2806 
2807  // Maybe make some noise.
2808  if (verbose_) {
2809  std::cout << "DQMStore::save: successfully wrote " << nme
2810  << " objects from path '" << path << "/"
2811  << "' into DQM file '" << filename << "'\n";
2812  }
2813 }
2814 
2815 void
2817  MonitorElement const& me,
2819 {
2820  // Save the object.
2821  TBufferFile buffer(TBufferFile::kWrite);
2822  if (me.kind() < MonitorElement::DQM_KIND_TH1F) {
2823  TObjString object(me.tagString().c_str());
2824  buffer.WriteObject(&object);
2825  } else {
2826  buffer.WriteObject(me.object_);
2827  }
2829  histo.set_full_pathname(*me.data_.dirname + '/' + me.data_.objname);
2830  histo.set_flags(me.data_.flags);
2831  histo.set_size(buffer.Length());
2832  histo.set_streamed_histo((const void*)buffer.Buffer(), buffer.Length());
2833 
2834  // Save quality reports if this is not in reference section.
2835  // XXX not supported by protobuf files.
2836 
2837  // Save efficiency tag, if any.
2838  // XXX not supported by protobuf files.
2839 
2840  // Save tag if any.
2841  // XXX not supported by protobuf files.
2842 }
2843 
2844 void
2846  std::string const& dir,
2847  unsigned int run,
2848  MEMap::const_iterator begin,
2849  MEMap::const_iterator end,
2851  unsigned int & counter)
2852 {
2853  for (auto const& me: boost::make_iterator_range(begin, end))
2854  {
2855  if (not isSubdirectory(dir, *me.data_.dirname))
2856  break;
2857 
2858  if (verbose_ > 1)
2859  std::cout << "DQMStore::savePB:"
2860  << " run: " << me.run()
2861  << " lumi: " << me.lumi()
2862  << " lumiFlag: " << me.getLumiFlag()
2863  << " streamId: " << me.streamId()
2864  << " moduleId: " << me.moduleId()
2865  << " fullpathname: " << me.getFullname()
2866  << " flags: " << std::hex << me.data_.flags
2867  << std::endl;
2868 
2869  // Skip MonitorElements in a subdirectory of the current one.
2870  if (dir != *me.data_.dirname) {
2871  if (verbose_ > 1) {
2872  std::cout << "DQMStore::savePB: skipping monitor element in a subfolder of " << dir << "/" << std::endl;
2873  }
2874  continue;
2875  }
2876 
2877  // For MonitorElements booked with the thread-safe approach, identified
2878  // by having run != 0, ignore the per-stream ones.
2879  if (run != 0 and (me.data_.streamId != 0 or me.data_.moduleId != 0)) {
2880  if (verbose_ > 1) {
2881  std::cout << "DQMStore::savePB: skipping per-stream monitor element" << std::endl;
2882  }
2883  continue;
2884  }
2885 
2886  // Handle reference histograms, with three distinct cases:
2887  // XXX not supported by protobuf files.
2888 
2889  if (verbose_ > 1) {
2890  std::cout << "DQMStore::savePB: saving monitor element" << std::endl;
2891  }
2892 
2893  saveMonitorElementToPB(me, file);
2894 
2895  // Count saved histograms
2896  ++counter;
2897  }
2898 }
2899 
2902 void
2904  const std::string &path /* = "" */,
2905  const uint32_t run /* = 0 */,
2906  const uint32_t lumi /* = 0 */)
2907 {
2908  using google::protobuf::io::FileOutputStream;
2909  using google::protobuf::io::GzipOutputStream;
2910  using google::protobuf::io::StringOutputStream;
2911 
2912  std::lock_guard<std::mutex> guard(book_mutex_);
2913 
2914  unsigned int nme = 0;
2915 
2916  if (verbose_) {
2917  std::cout << "DQMStore::savePB: Opening PBFile '" << filename << "'"
2918  << std::endl;
2919  }
2920  dqmstorepb::ROOTFilePB dqmstore_message;
2921 
2922  // Loop over the directory structure.
2923  for (auto const& dir: dirs_)
2924  {
2925  // Check if we should process this directory. We process the
2926  // requested part of the object tree, including references.
2927  if (not path.empty()
2928  and not isSubdirectory(path, dir))
2929  continue;
2930 
2931  if (verbose_ > 1) {
2932  std::cout << "DQMStore::savePB: DQM folder " << dir << "/" << std::endl;
2933  }
2934 
2935  // Loop over monitor elements in this directory.
2936  if (not enableMultiThread_) {
2937  MonitorElement proto(&dir, std::string(), run, 0, 0);
2938  auto begin = data_.lower_bound(proto);
2939  auto end = data_.end();
2940  saveMonitorElementRangeToPB(dir, run, begin, end, dqmstore_message, nme);
2941  } else {
2942  // Restrict the loop to the monitor elements for the current lumisection
2943  MonitorElement proto(&dir, std::string(), run, 0, 0);
2944  proto.setLumi(lumi);
2945  auto begin = data_.lower_bound(proto);
2946  proto.setLumi(lumi+1);
2947  auto end = data_.lower_bound(proto);
2948  saveMonitorElementRangeToPB(dir, run, begin, end, dqmstore_message, nme);
2949  }
2950 
2951  // In LSbasedMode, loop also over the (run, 0, 0, 0) global histograms;
2952  // these could be the merged global histrograms of their per-stream
2953  // counterparts after the streamEndRun transition - but they are not
2954  // produced in LSbasedMode.
2955  if (enableMultiThread_ and LSbasedMode_ and lumi != 0) {
2956  auto begin = data_.lower_bound(MonitorElement(&dir, std::string(), run, 0, 0));
2957  auto end = data_.lower_bound(MonitorElement(&dir, std::string(), run, 0, 1));
2958  saveMonitorElementRangeToPB(dir, run, begin, end, dqmstore_message, nme);
2959  }
2960  }
2961 
2962  int filedescriptor = ::open(filename.c_str(),
2963  O_WRONLY | O_CREAT | O_TRUNC,
2964  S_IRUSR | S_IWUSR |
2965  S_IRGRP | S_IWGRP |
2966  S_IROTH);
2967  FileOutputStream file_stream(filedescriptor);
2969  options.format = GzipOutputStream::GZIP;
2970  options.compression_level = 1;
2971  GzipOutputStream gzip_stream(&file_stream, options);
2972  dqmstore_message.SerializeToZeroCopyStream(&gzip_stream);
2973 
2974  // Flush the internal streams before closing the fd.
2975  gzip_stream.Close();
2976  file_stream.Close();
2977  ::close(filedescriptor);
2978 
2979  // Maybe make some noise.
2980  if (verbose_) {
2981  std::cout << "DQMStore::savePB: successfully wrote " << nme
2982  << " objects from path '" << path << "/"
2983  << "' into DQM file '" << filename << "'\n";
2984  }
2985 }
2986 
2987 
2990 unsigned int
2992  bool overwrite,
2993  const std::string &onlypath,
2994  const std::string &prepend,
2995  const std::string &curdir,
2996  OpenRunDirs stripdirs)
2997 {
2998  unsigned int ntot = 0;
2999  unsigned int count = 0;
3000 
3001  if (! file->cd(curdir.c_str()))
3002  raiseDQMError("DQMStore", "Failed to process directory '%s' while"
3003  " reading file '%s'", curdir.c_str(), file->GetName());
3004 
3005  // Figure out current directory name, but strip out the top
3006  // directory into which we dump everything.
3007  std::string dirpart = curdir;
3008  if (dirpart.compare(0, s_monitorDirName.size(), s_monitorDirName) == 0)
3009  {
3010  if (dirpart.size() == s_monitorDirName.size())
3011  dirpart.clear();
3012  else if (dirpart[s_monitorDirName.size()] == '/')
3013  dirpart.erase(0, s_monitorDirName.size()+1);
3014  }
3015 
3016  // See if we are going to skip this directory.
3017  bool skip = (! onlypath.empty() && ! isSubdirectory(onlypath, dirpart));
3018 
3019  if (prepend == s_collateDirName ||
3020  prepend == s_referenceDirName ||
3021  stripdirs == StripRunDirs )
3022  {
3023  // Remove Run # and RunSummary dirs
3024  // first look for Run summary,
3025  // if that is found and erased, also erase Run dir
3026  size_t slash = dirpart.find('/');
3027  size_t pos = dirpart.find("/Run summary");
3028  if (slash != std::string::npos && pos !=std::string::npos)
3029  {
3030  dirpart.erase(pos,12);
3031 
3032  pos = dirpart.find("Run ");
3033  size_t length = dirpart.find('/',pos+1)-pos+1;
3034  if (pos !=std::string::npos)
3035  dirpart.erase(pos,length);
3036  }
3037  }
3038 
3039  // If we are prepending, add it to the directory name,
3040  // and suppress reading of already existing reference histograms
3041  if (prepend == s_collateDirName ||
3042  prepend == s_referenceDirName)
3043  {
3044  size_t slash = dirpart.find('/');
3045  // If we are reading reference, skip previous reference.
3046  if (slash == std::string::npos // skip if Reference is toplevel folder, i.e. no slash
3047  && slash+1+s_referenceDirName.size() == dirpart.size()
3048  && dirpart.compare(slash+1, s_referenceDirName.size(), s_referenceDirName) == 0)
3049  return 0;
3050 
3051  slash = dirpart.find('/');
3052  // Skip reading of EventInfo subdirectory.
3053  if (slash != std::string::npos
3054  && slash + 10 == dirpart.size()
3055  && dirpart.compare( slash+1 , 9 , "EventInfo") == 0) {
3056  if (verbose_)
3057  std::cout << "DQMStore::readDirectory: skipping '" << dirpart << "'\n";
3058  return 0;
3059  }
3060 
3061  // Add prefix.
3062  if (dirpart.empty())
3063  dirpart = prepend;
3064  else
3065  dirpart = prepend + '/' + dirpart;
3066  }
3067  else if (! prepend.empty())
3068  {
3069  if (dirpart.empty())
3070  dirpart = prepend;
3071  else
3072  dirpart = prepend + '/' + dirpart;
3073  }
3074 
3075  // Loop over the contents of this directory in the file.
3076  // Post-pone string object handling to happen after other
3077  // objects have been read in so we are guaranteed to have
3078  // histograms by the time we read in quality tests and tags.
3079  TKey *key;
3080  TIter next (gDirectory->GetListOfKeys());
3081  std::list<TObject *> delayed;
3082  while ((key = (TKey *) next()))
3083  {
3084  std::unique_ptr<TObject> obj(key->ReadObj());
3085  if (dynamic_cast<TDirectory *>(obj.get()))
3086  {
3087  std::string subdir;
3088  subdir.reserve(curdir.size() + strlen(obj->GetName()) + 2);
3089  subdir += curdir;
3090  if (! curdir.empty())
3091  subdir += '/';
3092  subdir += obj->GetName();
3093 
3094  ntot += readDirectory(file, overwrite, onlypath, prepend, subdir, stripdirs);
3095  }
3096  else if (skip)
3097  ;
3098  else if (dynamic_cast<TObjString *>(obj.get()))
3099  {
3100  delayed.push_back(obj.release());
3101  }
3102  else
3103  {
3104  if (verbose_ > 2)
3105  std::cout << "DQMStore: reading object '" << obj->GetName()
3106  << "' of type '" << obj->IsA()->GetName()
3107  << "' from '" << file->GetName()
3108  << "' into '" << dirpart << "'\n";
3109 
3110  makeDirectory(dirpart);
3111  if (extract(obj.get(), dirpart, overwrite, collateHistograms_))
3112  ++count;
3113  }
3114  }
3115 
3116  while (! delayed.empty())
3117  {
3118  if (verbose_ > 2)
3119  std::cout << "DQMStore: reading object '" << delayed.front()->GetName()
3120  << "' of type '" << delayed.front()->IsA()->GetName()
3121  << "' from '" << file->GetName()
3122  << "' into '" << dirpart << "'\n";
3123 
3124  makeDirectory(dirpart);
3125  if (extract(delayed.front(), dirpart, overwrite, collateHistograms_))
3126  ++count;
3127 
3128  delete delayed.front();
3129  delayed.pop_front();
3130  }
3131 
3132  if (verbose_ > 1)
3133  std::cout << "DQMStore: read " << count << '/' << ntot
3134  << " objects from directory '" << dirpart << "'\n";
3135 
3136  return ntot + count;
3137 }
3138 
3145 bool
3147  bool overwrite /* = false */,
3148  const std::string &onlypath /* ="" */,
3149  const std::string &prepend /* ="" */,
3150  OpenRunDirs stripdirs /* =KeepRunDirs */,
3151  bool fileMustExist /* =true */)
3152 {
3153  return readFile(filename,overwrite,onlypath,prepend,stripdirs,fileMustExist);
3154 }
3155 
3160 bool
3162  OpenRunDirs stripdirs /* =StripRunDirs */,
3163  bool fileMustExist /* =true */)
3164 {
3165  bool overwrite = true;
3166  if (collateHistograms_) overwrite = false;
3167  if (verbose_)
3168  {
3169  std::cout << "DQMStore::load: reading from file '" << filename << "'\n";
3170  if (collateHistograms_)
3171  std::cout << "DQMStore::load: in collate mode " << "\n";
3172  else
3173  std::cout << "DQMStore::load: in overwrite mode " << "\n";
3174  }
3175 
3176  if (!s_rxpbfile.match(filename, 0, 0))
3177  return readFile(filename, overwrite, "", "", stripdirs, fileMustExist);
3178  else
3179  return readFilePB(filename, overwrite, "", "", stripdirs, fileMustExist);
3180 }
3181 
3187 bool
3189  bool overwrite /* = false */,
3190  const std::string &onlypath /* ="" */,
3191  const std::string &prepend /* ="" */,
3192  OpenRunDirs stripdirs /* =StripRunDirs */,
3193  bool fileMustExist /* =true */)
3194 {
3195 
3196  if (verbose_)
3197  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
3198 
3199  std::unique_ptr<TFile> f;
3200 
3201  try
3202  {
3203  f.reset(TFile::Open(filename.c_str()));
3204  if (! f.get() || f->IsZombie())
3205  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
3206  }
3207  catch (std::exception &)
3208  {
3209  if (fileMustExist)
3210  throw;
3211  else
3212  {
3213  if (verbose_)
3214  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
3215  return false;
3216  }
3217  }
3218 
3219  unsigned n = readDirectory(f.get(), overwrite, onlypath, prepend, "", stripdirs);
3220  f->Close();
3221 
3222  auto mi = data_.begin();
3223  auto me = data_.end();
3224  for ( ; mi != me; ++mi)
3225  const_cast<MonitorElement &>(*mi).updateQReportStats();
3226 
3227  if (verbose_)
3228  {
3229  std::cout << "DQMStore::open: successfully read " << n
3230  << " objects from file '" << filename << "'";
3231  if (! onlypath.empty())
3232  std::cout << " from directory '" << onlypath << "'";
3233  if (! prepend.empty())
3234  std::cout << " into directory '" << prepend << "'";
3235  std::cout << std::endl;
3236  }
3237  return true;
3238 }
3239 
3243 inline TObject * DQMStore::extractNextObject(TBufferFile &buf) const {
3244  if (buf.Length() == buf.BufferSize())
3245  return nullptr;
3246  buf.InitMap();
3247  void *ptr = buf.ReadObjectAny(nullptr);
3248  return reinterpret_cast<TObject *>(ptr);
3249 }
3250 
3253  std::string &objname,
3254  TObject ** obj) {
3255 
3256  size_t slash = h.full_pathname().rfind('/');
3257  size_t dirpos = (slash == std::string::npos ? 0 : slash);
3258  size_t namepos = (slash == std::string::npos ? 0 : slash+1);
3259  dirname.assign(h.full_pathname(), 0, dirpos);
3260  objname.assign(h.full_pathname(), namepos, std::string::npos);
3261  TBufferFile buf(TBufferFile::kRead, h.size(),
3262  (void*)h.streamed_histo().data(),
3263  kFALSE);
3264  buf.Reset();
3265  *obj = extractNextObject(buf);
3266  if (!*obj) {
3267  raiseDQMError("DQMStore", "Error reading element:'%s'" , h.full_pathname().c_str());
3268  }
3269 }
3270 
3271 bool
3273  bool overwrite /* = false */,
3274  const std::string &onlypath /* ="" */,
3275  const std::string &prepend /* ="" */,
3276  OpenRunDirs stripdirs /* =StripRunDirs */,
3277  bool fileMustExist /* =true */)
3278 {
3279  using google::protobuf::io::FileInputStream;
3280  using google::protobuf::io::FileOutputStream;
3281  using google::protobuf::io::GzipInputStream;
3282  using google::protobuf::io::GzipOutputStream;
3283  using google::protobuf::io::CodedInputStream;
3284  using google::protobuf::io::ArrayInputStream;
3285 
3286  if (verbose_)
3287  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
3288 
3289  int filedescriptor;
3290  if ((filedescriptor = ::open(filename.c_str(), O_RDONLY)) == -1) {
3291  if (fileMustExist)
3292  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
3293  else
3294  if (verbose_)
3295  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
3296  return false;
3297  }
3298 
3299  dqmstorepb::ROOTFilePB dqmstore_message;
3300  FileInputStream fin(filedescriptor);
3301  GzipInputStream input(&fin);
3302  CodedInputStream input_coded(&input);
3303  input_coded.SetTotalBytesLimit(1024*1024*1024, -1);
3304  if (!dqmstore_message.ParseFromCodedStream(&input_coded)) {
3305  raiseDQMError("DQMStore", "Fatal parsing file '%s'", filename.c_str());
3306  return false;
3307  }
3308  ::close(filedescriptor);
3309 
3310  for (int i = 0; i < dqmstore_message.histo_size(); i++) {
3311  std::string path;
3312  std::string objname;
3313 
3314  TObject *obj = nullptr;
3315  const dqmstorepb::ROOTFilePB::Histo &h = dqmstore_message.histo(i);
3316  get_info(h, path, objname, &obj);
3317 
3318  setCurrentFolder(path);
3319  if (obj)
3320  {
3321  /* Before calling the extract() check if histogram exists:
3322  * if it does - flags for the given monitor are already set (and merged)
3323  * else - set the flags after the histogram is created.
3324  */
3325  MonitorElement *me = findObject(path, objname);
3326 
3327  /* Run histograms should be collated and not overwritten,
3328  * Lumi histograms should be overwritten (and collate flag is not checked)
3329  */
3330  bool overwrite = h.flags() & DQMNet::DQM_PROP_LUMI;
3331  bool collate = !(h.flags() & DQMNet::DQM_PROP_LUMI);
3332  extract(static_cast<TObject *>(obj), path, overwrite, collate);
3333 
3334  if (me == nullptr) {
3335  me = findObject(path, objname);
3336  me->data_.flags = h.flags();
3337  }
3338 
3339  delete obj;
3340  }
3341  }
3342 
3343  cd();
3344  return true;
3345 }
3346 
3352 void
3354 {
3356  const std::string *cleaned = nullptr;
3357  cleanTrailingSlashes(path, clean, cleaned);
3358  MonitorElement proto(cleaned, std::string());
3359 
3360  auto e = data_.end();
3361  auto i = data_.lower_bound(proto);
3362  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
3363  data_.erase(i++);
3364 
3365  auto de = dirs_.end();
3366  auto di = dirs_.lower_bound(*cleaned);
3367  while (di != de && isSubdirectory(*cleaned, *di))
3368  dirs_.erase(di++);
3369 }
3370 
3372 void
3374 {
3375  MonitorElement proto(&dir, std::string());
3376  auto e = data_.end();
3377  auto i = data_.lower_bound(proto);
3378  while (i != e && isSubdirectory(dir, *i->data_.dirname))
3379  if (dir == *i->data_.dirname)
3380  data_.erase(i++);
3381  else
3382  ++i;
3383 }
3384 
3386 void
3388 {
3390 }
3391 
3394 void
3396 {
3397  removeElement(pwd_, name);
3398 }
3399 
3402 void
3403 DQMStore::removeElement(const std::string &dir, const std::string &name, bool warning /* = true */)
3404 {
3405  MonitorElement proto(&dir, name);
3406  auto pos = data_.find(proto);
3407  if (pos != data_.end())
3408  data_.erase(pos);
3409  else if (warning)
3410  std::cout << "DQMStore: WARNING: attempt to remove non-existent"
3411  << " monitor element '" << name << "' in '" << dir << "'\n";
3412 }
3413 
3419 QCriterion *
3421 {
3422  auto i = qtests_.find(qtname);
3423  auto e = qtests_.end();
3424  return (i == e ? nullptr : i->second);
3425 }
3426 
3430 QCriterion *
3432 {
3433  if (qtests_.count(qtname))
3434  raiseDQMError("DQMStore", "Attempt to create duplicate quality test '%s'",
3435  qtname.c_str());
3436 
3437  auto i = qalgos_.find(algoname);
3438  if (i == qalgos_.end())
3439  raiseDQMError("DQMStore", "Cannot create a quality test using unknown"
3440  " algorithm '%s'", algoname.c_str());
3441 
3442  QCriterion *qc = i->second(qtname);
3443  qc->setVerbose(verboseQT_);
3444 
3445  qtests_[qtname] = qc;
3446  return qc;
3447 }
3448 
3451 void
3453 {
3454  // Clean the path
3456  const std::string *cleaned = nullptr;
3457  cleanTrailingSlashes(dir, clean, cleaned);
3458 
3459  // Validate the path.
3460  if (cleaned->find_first_not_of(s_safe) != std::string::npos)
3461  raiseDQMError("DQMStore", "Monitor element path name '%s'"
3462  " uses unacceptable characters", cleaned->c_str());
3463 
3464  // Redirect to the pattern match version.
3465  useQTestByMatch(*cleaned + "/*", qtname);
3466 }
3467 
3469 int
3471 {
3472  QCriterion *qc = getQCriterion(qtname);
3473  if (! qc)
3474  raiseDQMError("DQMStore", "Cannot apply non-existent quality test '%s'",
3475  qtname.c_str());
3476 
3477  auto * fm = new fastmatch( pattern );
3478 
3479  // Record the test for future reference.
3480  QTestSpec qts(fm, qc);
3481  qtestspecs_.push_back(qts);
3482 
3483  // Apply the quality test.
3484  auto mi = data_.begin();
3485  auto me = data_.end();
3486  std::string path;
3487  int cases = 0;
3488  for ( ; mi != me; ++mi)
3489  {
3490  path.clear();
3491  mergePath(path, *mi->data_.dirname, mi->data_.objname);
3492  if (fm->match(path))
3493  {
3494  ++cases;
3495  const_cast<MonitorElement &>(*mi).addQReport(qts.second);
3496  }
3497  }
3498 
3499  //return the number of matched cases
3500  return cases;
3501 }
3504 void
3506 {
3507 
3508  if (verbose_ > 0)
3509  std::cout << "DQMStore: running runQTests() with reset = "
3510  << ( reset_ ? "true" : "false" ) << std::endl;
3511 
3512  // Apply quality tests to each monitor element, skipping references.
3513  auto mi = data_.begin();
3514  auto me = data_.end();
3515  for ( ; mi != me; ++mi)
3516  if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
3517  const_cast<MonitorElement &>(*mi).runQTests();
3518 
3519  reset_ = false;
3520 }
3521 
3525 int
3526 DQMStore::getStatus(const std::string &path /* = "" */) const
3527 {
3529  const std::string *cleaned = nullptr;
3530  cleanTrailingSlashes(path, clean, cleaned);
3531 
3533  auto mi = data_.begin();
3534  auto me = data_.end();
3535  for ( ; mi != me; ++mi)
3536  {
3537  if (! cleaned->empty() && ! isSubdirectory(*cleaned, *mi->data_.dirname))
3538  continue;
3539 
3540  if (mi->hasError())
3541  return dqm::qstatus::ERROR;
3542  else if (mi->hasWarning())
3543  status = dqm::qstatus::WARNING;
3544  else if (status < dqm::qstatus::WARNING
3545  && mi->hasOtherReport())
3546  status = dqm::qstatus::OTHER;
3547  }
3548  return status;
3549 }
3550 
3556 void
3558 {
3559  if (me)
3560  me->softReset();
3561 }
3562 
3563 // reverts action of softReset
3564 void
3566 {
3567  if (me)
3568  me->disableSoftReset();
3569 }
3570 
3573 void
3575 {
3576  if (me)
3577  me->setAccumulate(flag);
3578 }
3579 
3583 void
3585 {
3586  std::vector<std::string> contents;
3587  getContents(contents);
3588 
3589  std::cout << " ------------------------------------------------------------\n"
3590  << " Directory structure: \n"
3591  << " ------------------------------------------------------------\n";
3592 
3593  std::copy(contents.begin(), contents.end(),
3594  std::ostream_iterator<std::string>(std::cout, "\n"));
3595 
3596  std::cout << " ------------------------------------------------------------\n";
3597 }
3598 
3602 // check if the collate option is active on the DQMStore
3603 bool
3605 {
3606  return collateHistograms_;
3607 }
3611 // check if the monitor element is in auto-collation folder
3612 bool
3614 { return me && isSubdirectory(s_collateDirName, *me->data_.dirname); }
3618 
3620 void
3622 {
3623  if (scaleFlag_ == 0.0) return;
3624  if (verbose_ > 0)
3625  std::cout << " =========== " << " ScaleFlag " << scaleFlag_ << std::endl;
3626  double factor = scaleFlag_;
3627  int events = 1;
3628  if (dirExists("Info/EventInfo")) {
3629  if ( scaleFlag_ == -1.0) {
3630  MonitorElement * scale_me = get("Info/EventInfo/ScaleFactor");
3631  if (scale_me && scale_me->kind()==MonitorElement::DQM_KIND_REAL) factor = scale_me->getFloatValue();
3632  }
3633  MonitorElement * event_me = get("Info/EventInfo/processedEvents");
3634  if (event_me && event_me->kind()==MonitorElement::DQM_KIND_INT) events = event_me->getIntValue();
3635  }
3636  factor = factor/(events*1.0);
3637 
3638  auto mi = data_.begin();
3639  auto me = data_.end();
3640  for ( ; mi != me; ++mi)
3641  {
3642  auto &me = const_cast<MonitorElement &>(*mi);
3643  switch (me.kind())
3644  {
3646  {
3647  me.getTH1F()->Scale(factor);
3648  break;
3649  }
3651  {
3652  me.getTH1S()->Scale(factor);
3653  break;
3654  }
3656  {
3657  me.getTH1D()->Scale(factor);
3658  break;
3659  }
3661  {
3662  me.getTH2F()->Scale(factor);
3663  break;
3664  }
3666  {
3667  me.getTH2S()->Scale(factor);
3668  break;
3669  }
3671  {
3672  me.getTH2D()->Scale(factor);
3673  break;
3674  }
3676  {
3677  me.getTH3F()->Scale(factor);
3678  break;
3679  }
3681  {
3682  me.getTProfile()->Scale(factor);
3683  break;
3684  }
3686  {
3687  me.getTProfile2D()->Scale(factor);
3688  break;
3689  }
3690  default:
3691  if (verbose_ > 0)
3692  std::cout << " The DQM object '" << me.getFullname() << "' is not scalable object " << std::endl;
3693  continue;
3694  }
3695  }
3696 }
QCriterion * getQCriterion(const std::string &qtname) const
Definition: DQMStore.cc:3420
size
Write out results.
~DQMStore()
Definition: DQMStore.cc:570
MonitorElement * getElement(const std::string &path)
Definition: DQMStore.cc:311
IGetter * igetter_
Definition: DQMStore.h:883
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:1161
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:511
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:1190
bool containsAnyMonitorable(const std::string &path) const
Definition: DQMStore.cc:1802
uint32_t moduleId
Definition: DQMNet.h:105
::google::protobuf::uint32 size() const
int64_t getIntValue() const
bool isCollateME(MonitorElement *me) const
Definition: DQMStore.cc:3613
bool cdInto(const std::string &path) const
Definition: DQMStore.cc:2533
QReports qreports
Definition: DQMNet.h:108
const ::std::string & full_pathname() const
int getStatus(const std::string &path="") const
Definition: DQMStore.cc:3526
void copyFrom(TH1 *from)
const std::string & pwd() const
Definition: DQMStore.cc:718
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:1505
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:1040
void rmdir(const std::string &fullpath)
Definition: DQMStore.cc:3353
static void collate3D(MonitorElement *me, TH3F *h, unsigned verbose)
Definition: DQMStore.cc:1667
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:3188
MonitorElement * findObject(const std::string &dir, const std::string &name, const uint32_t run=0, const uint32_t lumi=0, const uint32_t streamId=0, const uint32_t moduleId=0) const
Definition: DQMStore.cc:1941
static void collateProfile(MonitorElement *me, TProfile *h, unsigned verbose)
Definition: DQMStore.cc:1674
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:1320
TH2S * getTH2S() const
void scaleElements()
Definition: DQMStore.cc:3621
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:2158
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:1212
uint32_t streamId_
Definition: DQMStore.h:869
std::pair< fastmatch *, QCriterion * > QTestSpec
Definition: DQMStore.h:827
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:52
TH1 * getTH1() const
static void collate2DD(MonitorElement *me, TH2D *h, unsigned verbose)
Definition: DQMStore.cc:1660
std::vector< MonitorElement * > getMatchingContents(const std::string &pattern, lat::Regexp::Syntax syntaxType=lat::Regexp::Wildcard) const
Definition: DQMStore.cc:2073
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:861
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:1072
void initializeFrom(const edm::ParameterSet &)
Definition: DQMStore.cc:584
#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:870
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:877
static const std::string s_collateDirName
Definition: DQMStore.cc:59
void forceReset()
Definition: DQMStore.cc:2133
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:881
MonitorElement * bookFloat(const char *name)
Book float.
Definition: DQMStore.cc:977
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:1698
MonitorElement * book2D_(const std::string &dir, const std::string &name, TH2F *h)
Book 2D histogram based on TH2F.
Definition: DQMStore.cc:1147
void disableSoftReset(MonitorElement *me)
Definition: DQMStore.cc:3565
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:2607
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:2576
std::vector< MonitorElement * > getAllContents(const std::string &path, uint32_t runNumber=0, uint32_t lumi=0) const
Definition: DQMStore.cc:2024
unsigned verboseQT_
Definition: DQMStore.h:860
void setEfficiencyFlag()
static const uint32_t DQM_PROP_HAS_REFERENCE
Definition: DQMNet.h:54
QTestSpecs qtestspecs_
Definition: DQMStore.h:879
double scaleFlag_
Definition: DQMStore.h:862
void deleteUnusedLumiHistograms(uint32_t run, uint32_t lumi)
Definition: DQMStore.cc:2189
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:3251
void watchPostSourceRun(PostSourceRun::slot_type const &iSlot)
MonitorElement * bookString(const char *name, const char *value)
Book string.
Definition: DQMStore.cc:1006
bool isCollate() const
Definition: DQMStore.cc:3604
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:990
void removeElement(const std::string &name)
Definition: DQMStore.cc:3395
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:1313
static void collateProfile2D(MonitorElement *me, TProfile2D *h, unsigned verbose)
Definition: DQMStore.cc:1684
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:2702
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:2845
MonitorElement * bookInt_(const std::string &dir, const std::string &name)
Book int.
Definition: DQMStore.cc:930
MonitorElement * bookProfile_(const std::string &dir, const std::string &name, TProfile *h)
Book profile histogram based on TProfile.
Definition: DQMStore.cc:1361
double f[11][100]
uint32_t run_
Definition: DQMStore.h:868
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:1372
QCriterion * makeQCriterion(const std::string &qtname)
Definition: DQMStore.cc:124
#define end
Definition: vmac.h:39
void setVerbose(unsigned level)
Definition: DQMStore.cc:710
Definition: value.py:1
void softReset(MonitorElement *me)
Definition: DQMStore.cc:3557
std::string pwd_
Definition: DQMStore.h:873
TObject * extractNextObject(TBufferFile &) const
Definition: DQMStore.cc:3243
lat::Regexp * regexp_
Definition: DQMStore.h:73
IBooker * ibooker_
Definition: DQMStore.h:882
MonitorElement * get(const std::string &path) const
get ME from full pathname (e.g. "my/long/dir/my_histo")
Definition: DQMStore.cc:1812
void Reset()
reset ME (ie. contents, errors, etc)
QAMap qalgos_
Definition: DQMStore.h:878
std::vector< MonitorElement * > getContents(const std::string &path) const
Definition: DQMStore.cc:1840
std::string readSelectedDirectory_
Definition: DQMStore.h:867
std::vector< std::string > getSubdirs() const
Definition: DQMStore.cc:1763
std::string objname
Definition: DQMNet.h:107
void mergeAndResetMEsRunSummaryCache(uint32_t run, uint32_t streamId, uint32_t moduleId)
Definition: DQMStore.cc:362
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:811
void runQTests()
run all quality tests
void getAllTags(std::vector< std::string > &into) const
Definition: DQMStore.cc:1971
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:3161
~fastmatch()
Definition: DQMStore.cc:204
void saveMonitorElementToPB(MonitorElement const &me, dqmstorepb::ROOTFilePB &file)
Definition: DQMStore.cc:2816
static void collate1DD(MonitorElement *me, TH1D *h, unsigned verbose)
Definition: DQMStore.cc:1639
void tagAllContents(const std::string &path, unsigned int myTag)
Definition: DQMStore.cc:1741
demangled
Definition: symbols.py:61
void showDirStructure() const
Definition: DQMStore.cc:3584
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:723
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:859
void set_size(::google::protobuf::uint32 value)
MonitorElement * book_(const std::string &dir, const std::string &name, const char *context)
Definition: DQMStore.cc:895
MonitorElement * book2S_(const std::string &dir, const std::string &name, TH2S *h)
Book 2D histogram based on TH2S.
Definition: DQMStore.cc:1154
TH3F * getTH3F() const
MEMap data_
Definition: DQMStore.h:874
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:645
MonitorElement * book1D_(const std::string &dir, const std::string &name, TH1F *h)
Book 1D histogram based on TH1F.
Definition: DQMStore.cc:1019
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:3470
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:1625
std::vector< std::string > getMEs() const
get list of (non-dir) MEs of current directory
Definition: DQMStore.cc:1786
tuple msg
Definition: mps_check.py:277
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:1033
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:2991
void setVerbose(int verbose)
probability limits for warnings, errors
Definition: QTest.h:118
void removeContents()
erase all monitoring elements in current directory (not including subfolders);
Definition: DQMStore.cc:3387
bool extract(TObject *obj, const std::string &dir, bool overwrite, bool collateHistograms)
Definition: DQMStore.cc:2232
bool forceResetOnBeginLumi_
Definition: DQMStore.h:866
#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:1729
::dqmstorepb::ROOTFilePB_Histo * add_histo()
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:3272
void useQTest(const std::string &dir, const std::string &qtname)
Definition: DQMStore.cc:3452
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:3146
::google::protobuf::uint32 flags() const
static const int STATUS_OK
TH1S * getTH1S() const
void setAccumulate(MonitorElement *me, bool flag)
Definition: DQMStore.cc:3574
static void collate1S(MonitorElement *me, TH1S *h, unsigned verbose)
Definition: DQMStore.cc:1632
void Reset(std::vector< TH2F > &depth)
std::ofstream * stream_
Definition: DQMStore.h:871
QCriterion * createQTest(const std::string &algoname, const std::string &qtname)
Definition: DQMStore.cc:3431
static bool checkBinningMatches(MonitorElement *me, TH1 *h, unsigned verbose)
Definition: DQMStore.cc:1598
dbl *** dir
Definition: mlp_gen.cc:35
void goUp()
equivalent to "cd .."
Definition: DQMStore.cc:757
void savePB(const std::string &filename, const std::string &path="", const uint32_t run=0, const uint32_t lumi=0)
Definition: DQMStore.cc:2903
MonitorElement * bookFloat_(const std::string &dir, const std::string &name)
Book float.
Definition: DQMStore.cc:960
static void collate2D(MonitorElement *me, TH2F *h, unsigned verbose)
Definition: DQMStore.cc:1646
MonitorElement * bookInt(const char *name)
Book int.
Definition: DQMStore.cc:947
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:1168
std::vector< std::string > getMEs()
Definition: DQMStore.cc:329
long double T
uint32_t streamId
Definition: DQMNet.h:104
void mergeAndResetMEsLuminositySummaryCache(uint32_t run, uint32_t lumi, uint32_t streamId, uint32_t moduleId)
Definition: DQMStore.cc:437
float qtresult
Definition: DQMNet.h:91
std::set< std::string > dirs_
Definition: DQMStore.h:875
bool collateHistograms_
Definition: DQMStore.h:863
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:865
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:1056
void runQTests()
Definition: DQMStore.cc:3505
static const lat::Regexp s_rxmeqr1("^st:(\\d+):([-+e.\\d]+):([^:]*):(.*)$")
void makeDirectory(const std::string &path)
Definition: DQMStore.cc:770
void connect(U iFunc)
Definition: Signal.h:63
Kind kind() const
Get the type of the monitor element.
void reset()
Definition: DQMStore.cc:2109
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:746
static void collate2S(MonitorElement *me, TH2S *h, unsigned verbose)
Definition: DQMStore.cc:1653
MonitorElement * book1S_(const std::string &dir, const std::string &name, TH1S *h)
Book 1D histogram based on TH1S.
Definition: DQMStore.cc:1026
static const int ERROR
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
bool enableMultiThread_
Definition: DQMStore.h:864
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:1516
void raiseDQMError(const char *context, const char *fmt,...)
Definition: DQMError.cc:11