CMS 3D CMS Logo

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