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 }
481 
484  : verbose_ (1),
485  verboseQT_ (1),
486  reset_ (false),
491  run_(0),
492  streamId_(0),
493  moduleId_(0),
494  stream_(nullptr),
495  pwd_ (""),
496  ibooker_(0),
497  igetter_(0)
498 {
499  if (!ibooker_)
500  ibooker_ = new DQMStore::IBooker(this);
501  if (!igetter_)
502  igetter_ = new DQMStore::IGetter(this);
503  initializeFrom(pset);
504 
505  if(pset.getUntrackedParameter<bool>("forceResetOnBeginRun",false)) {
507  }
508  ar.preallocateSignal_.connect([this](edm::service::SystemBounds const& iBounds) {
509  if(iBounds.maxNumberOfStreams() > 1 ) {
510  enableMultiThread_ = true;
511  }
512  });
513  if(pset.getUntrackedParameter<bool>("forceResetOnBeginLumi",false) && enableMultiThread_ == false) {
514  forceResetOnBeginLumi_ = true;
516  }
517 }
518 
520  : verbose_ (1),
521  verboseQT_ (1),
522  reset_ (false),
523  collateHistograms_ (false),
524  enableMultiThread_(false),
525  readSelectedDirectory_ (""),
526  run_(0),
527  streamId_(0),
528  moduleId_(0),
529  stream_(nullptr),
530  pwd_ (""),
531  ibooker_(0),
532  igetter_(0)
533 {
534  if (!ibooker_)
535  ibooker_ = new DQMStore::IBooker(this);
536  if (!igetter_)
537  igetter_ = new DQMStore::IGetter(this);
538  initializeFrom(pset);
539 }
540 
542 {
543  for (QCMap::iterator i = qtests_.begin(), e = qtests_.end(); i != e; ++i)
544  delete i->second;
545 
546  for (QTestSpecs::iterator i = qtestspecs_.begin(), e = qtestspecs_.end(); i != e; ++i)
547  delete i->first;
548 
549  if (stream_)
550  stream_->close();
551  delete stream_;
552 }
553 
554 void
556  makeDirectory("");
557  reset();
558 
559  // set steerable parameters
560  verbose_ = pset.getUntrackedParameter<int>("verbose", 0);
561  if (verbose_ > 0)
562  std::cout << "DQMStore: verbosity set to " << verbose_ << std::endl;
563 
564  verboseQT_ = pset.getUntrackedParameter<int>("verboseQT", 0);
565  if (verbose_ > 0)
566  std::cout << "DQMStore: QTest verbosity set to " << verboseQT_ << std::endl;
567 
568  collateHistograms_ = pset.getUntrackedParameter<bool>("collateHistograms", false);
569  if (collateHistograms_)
570  std::cout << "DQMStore: histogram collation is enabled\n";
571 
572  enableMultiThread_ = pset.getUntrackedParameter<bool>("enableMultiThread", false);
573  if (enableMultiThread_)
574  std::cout << "DQMStore: MultiThread option is enabled\n";
575 
576  LSbasedMode_ = pset.getUntrackedParameter<bool>("LSbasedMode", false);
577  if (LSbasedMode_)
578  std::cout << "DQMStore: LSbasedMode option is enabled\n";
579 
580  std::string ref = pset.getUntrackedParameter<std::string>("referenceFileName", "");
581  if (! ref.empty())
582  {
583  std::cout << "DQMStore: using reference file '" << ref << "'\n";
584  readFile(ref, true, "", s_referenceDirName, StripRunDirs, false);
585  }
586 
587  initQCriterion<Comp2RefChi2>(qalgos_);
588  initQCriterion<Comp2RefKolmogorov>(qalgos_);
589  initQCriterion<ContentsXRange>(qalgos_);
590  initQCriterion<ContentsYRange>(qalgos_);
591  initQCriterion<MeanWithinExpected>(qalgos_);
592  initQCriterion<Comp2RefEqualH>(qalgos_);
593  initQCriterion<DeadChannel>(qalgos_);
594  initQCriterion<NoisyChannel>(qalgos_);
595  initQCriterion<ContentsWithinExpected>(qalgos_);
596  initQCriterion<CompareToMedian>(qalgos_);
597  initQCriterion<CompareLastFilledBin>(qalgos_);
598  initQCriterion<CheckVariance>(qalgos_);
599 
600  scaleFlag_ = pset.getUntrackedParameter<double>("ScalingFlag", 0.0);
601  if (verbose_ > 0)
602  std::cout << "DQMStore: Scaling Flag set to " << scaleFlag_ << std::endl;
603 }
604 
605 /* Generic method to do a backtrace and print it to stdout. It is
606  customised to properly get the routine that called the booking of the
607  histograms, which, following the usual stack, is at position 4. The
608  name of the calling function is properly demangled and the original
609  shared library including this function is also printed. For a more
610  detailed explanation of the routines involved, see here:
611  http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
612  http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html.*/
613 
614 void
616 {
617  // the access to the member stream_ is implicitely protected against
618  // concurrency problems because the print_trace method is always called behind
619  // a lock (see bookTransaction).
620  if (!stream_)
621  stream_ = new std::ofstream("histogramBookingBT.log");
622 
623  void *array[10];
624  size_t size;
625  char **strings;
626  int r=0;
627  lat::RegexpMatch m;
628  m.reset();
629 
630  size = backtrace (array, 10);
631  strings = backtrace_symbols (array, size);
632 
633  if ((size > 4)
634  &&s_rxtrace.match(strings[4], 0, 0, &m))
635  {
636  char * demangled = abi::__cxa_demangle(m.matchString(strings[4], 2).c_str(), 0, 0, &r);
637  *stream_ << "\"" << dir << "/"
638  << name << "\" "
639  << (r ? m.matchString(strings[4], 2) : demangled) << " "
640  << m.matchString(strings[4], 1) << "\n";
641  free(demangled);
642  }
643  else
644  *stream_ << "Skipping "<< dir << "/" << name
645  << " with stack size " << size << "\n";
646  /* In this case print the full stack trace, up to main or to the
647  * maximum stack size, i.e. 10. */
648  if (verbose_ > 4)
649  {
650  size_t i;
651  m.reset();
652 
653  for (i = 0; i < size; i++)
654  if (s_rxtrace.match(strings[i], 0, 0, &m))
655  {
656  char * demangled = abi::__cxa_demangle(m.matchString(strings[i], 2).c_str(), 0, 0, &r);
657  *stream_ << "\t\t" << i << "/" << size << " "
658  << (r ? m.matchString(strings[i], 2) : demangled) << " "
659  << m.matchString(strings[i], 1) << std::endl;
660  free (demangled);
661  }
662  }
663  free (strings);
664 }
665 
670 void
671 DQMStore::setVerbose(unsigned /* level */)
672 { return; }
673 
678 const std::string &
679 DQMStore::pwd(void) const
680 { return pwd_; }
681 
683 void
685 { setCurrentFolder(""); }
686 
688 void
689 DQMStore::cd(const std::string &subdir)
690 {
692  const std::string *cleaned = 0;
693  cleanTrailingSlashes(subdir, clean, cleaned);
694 
695  if (! dirExists(*cleaned))
696  raiseDQMError("DQMStore", "Cannot 'cd' into non-existent directory '%s'",
697  cleaned->c_str());
698 
699  setCurrentFolder(*cleaned);
700 }
701 
706 void
708 {
710  const std::string *cleaned = 0;
711  cleanTrailingSlashes(fullpath, clean, cleaned);
712  makeDirectory(*cleaned);
713  pwd_ = *cleaned;
714 }
715 
717 void
719 {
720  size_t pos = pwd_.rfind('/');
721  if (pos == std::string::npos)
722  setCurrentFolder("");
723  else
724  setCurrentFolder(pwd_.substr(0, pos));
725 }
726 
727 // -------------------------------------------------------------------
730 void
732 {
733  std::string prev;
734  std::string subdir;
736  prev.reserve(path.size());
737  subdir.reserve(path.size());
738  name.reserve(path.size());
739  size_t prevname = 0;
740  size_t slash = 0;
741 
742  while (true)
743  {
744  // Create this subdirectory component.
745  subdir.clear();
746  subdir.append(path, 0, slash);
747  name.clear();
748  name.append(subdir, prevname, std::string::npos);
749  if (! prev.empty() && findObject(prev, name))
750  raiseDQMError("DQMStore", "Attempt to create subdirectory '%s'"
751  " which already exists as a monitor element",
752  subdir.c_str());
753 
754  if (! dirs_.count(subdir))
755  dirs_.insert(subdir);
756 
757  // Stop if we've reached the end (including possibly a trailing slash).
758  if (slash+1 >= path.size())
759  break;
760 
761  // Find the next slash, making sure we progress. If reach the end,
762  // process the last path component; the next loop round will terminate.
763  prevname = slash ? slash+1 : slash;
764  prev = subdir;
765  if ((slash = path.find('/', ++slash)) == std::string::npos)
766  slash = path.size();
767  }
768 }
769 
771 bool
773 { return dirs_.count(path) > 0; }
774 
778 template <class HISTO, class COLLATE>
781  const char *context, int kind,
782  HISTO *h, COLLATE collate)
783 {
784  assert(name.find('/') == std::string::npos);
785  if (verbose_ > 3)
786  print_trace(dir, name);
788  mergePath(path, dir, name);
789 
790  // Put us in charge of h.
791  h->SetDirectory(0);
792 
793  // Check if the request monitor element already exists.
794  MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_);
795  if (me)
796  {
797  if (collateHistograms_)
798  {
799  collate(me, h, verbose_);
800  delete h;
801  return me;
802  }
803  else
804  {
805  if (verbose_ > 1)
806  std::cout << "DQMStore: "
807  << context << ": monitor element '"
808  << path << "' already exists, collating" << std::endl;
809  me->Reset();
810  collate(me, h, verbose_);
811  delete h;
812  return me;
813  }
814  }
815  else
816  {
817  // Create and initialise core object.
818  assert(dirs_.count(dir));
819  MonitorElement proto(&*dirs_.find(dir), name, run_, streamId_, moduleId_);
820  me = const_cast<MonitorElement &>(*data_.insert(std::move(proto)).first)
822 
823  // Initialise quality test information.
824  QTestSpecs::iterator qi = qtestspecs_.begin();
825  QTestSpecs::iterator qe = qtestspecs_.end();
826  for ( ; qi != qe; ++qi)
827  {
828  if ( qi->first->match(path) )
829  me->addQReport(qi->second);
830  }
831 
832  // Assign reference if we have one.
833  std::string refdir;
834  refdir.reserve(s_referenceDirName.size() + dir.size() + 2);
835  refdir += s_referenceDirName;
836  refdir += '/';
837  refdir += dir;
838 
839  if (findObject(refdir, name))
840  {
841  me->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
842  }
843  // Return the monitor element.
844  return me;
845  }
846 }
847 
850  const std::string &name,
851  const char *context)
852 {
853  assert(name.find('/') == std::string::npos);
854  if (verbose_ > 3)
855  print_trace(dir, name);
856 
857  // Check if the request monitor element already exists.
858  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
859  {
860  if (verbose_ > 1)
861  {
863  mergePath(path, dir, name);
864 
865  std::cout << "DQMStore: "
866  << context << ": monitor element '"
867  << path << "' already exists, resetting" << std::endl;
868  }
869  me->Reset();
870  return me;
871  }
872  else
873  {
874  // Create it and return for initialisation.
875  assert(dirs_.count(dir));
876  MonitorElement proto(&*dirs_.find(dir), name, run_, streamId_, moduleId_);
877  return &const_cast<MonitorElement &>(*data_.insert(std::move(proto)).first);
878  }
879 }
880 
881 // -------------------------------------------------------------------
885 {
886  if (collateHistograms_)
887  {
888  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
889  {
890  me->Fill(0);
891  return me;
892  }
893  }
894 
895  return book(dir, name, "bookInt")
897 }
898 
902 { return bookInt(pwd_, name); }
903 
907 {
908  return bookInt(pwd_, name);
909 }
910 
911 // -------------------------------------------------------------------
915 {
916  if (collateHistograms_)
917  {
918  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
919  {
920  me->Fill(0.);
921  return me;
922  }
923  }
924 
925  return book(dir, name, "bookFloat")
927 }
928 
932 { return bookFloat(pwd_, name); }
933 
937 {
938  return bookFloat(pwd_, name);
939 }
940 
941 // -------------------------------------------------------------------
945  const std::string &name,
946  const std::string &value)
947 {
948  if (collateHistograms_)
949  {
950  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
951  return me;
952  }
953 
954  return book(dir, name, "bookString")
956 }
957 
960 DQMStore::bookString(const char *name, const char *value)
961 { return bookString(pwd_, name, value); }
962 
966 {
967  return bookString(pwd_, name, value);
968 }
969 
970 // -------------------------------------------------------------------
974 {
975  return book(dir, name, "book1D", MonitorElement::DQM_KIND_TH1F, h, collate1D);
976 }
977 
981 {
982  return book(dir, name, "book1S", MonitorElement::DQM_KIND_TH1S, h, collate1S);
983 }
984 
988 {
989  return book(dir, name, "book1DD", MonitorElement::DQM_KIND_TH1D, h, collate1DD);
990 }
991 
994 DQMStore::book1D(const char *name, const char *title,
995  int nchX, double lowX, double highX)
996 {
997  return book1D(pwd_, name, new TH1F(name, title, nchX, lowX, highX));
998 }
999 
1003  int nchX, double lowX, double highX)
1004 {
1005  return book1D(pwd_, name, new TH1F(name.c_str(), title.c_str(), nchX, lowX, highX));
1006 }
1007 
1010 DQMStore::book1S(const char *name, const char *title,
1011  int nchX, double lowX, double highX)
1012 {
1013  return book1S(pwd_, name, new TH1S(name, title, nchX, lowX, highX));
1014 }
1015 
1019  int nchX, double lowX, double highX)
1020 {
1021  return book1S(pwd_, name, new TH1S(name.c_str(), title.c_str(), nchX, lowX, highX));
1022 }
1023 
1026 DQMStore::book1DD(const char *name, const char *title,
1027  int nchX, double lowX, double highX)
1028 {
1029  return book1DD(pwd_, name, new TH1D(name, title, nchX, lowX, highX));
1030 }
1031 
1035  int nchX, double lowX, double highX)
1036 {
1037  return book1DD(pwd_, name, new TH1D(name.c_str(), title.c_str(), nchX, lowX, highX));
1038 }
1039 
1042 DQMStore::book1D(const char *name, const char *title,
1043  int nchX, const float *xbinsize)
1044 {
1045  return book1D(pwd_, name, new TH1F(name, title, nchX, xbinsize));
1046 }
1047 
1051  int nchX, const float *xbinsize)
1052 {
1053  return book1D(pwd_, name, new TH1F(name.c_str(), title.c_str(), nchX, xbinsize));
1054 }
1055 
1058 DQMStore::book1D(const char *name, TH1F *source)
1059 {
1060  return book1D(pwd_, name, static_cast<TH1F *>(source->Clone(name)));
1061 }
1062 
1066 {
1067  return book1D(pwd_, name, static_cast<TH1F *>(source->Clone(name.c_str())));
1068 }
1069 
1072 DQMStore::book1S(const char *name, TH1S *source)
1073 {
1074  return book1S(pwd_, name, static_cast<TH1S *>(source->Clone(name)));
1075 }
1076 
1080 {
1081  return book1S(pwd_, name, static_cast<TH1S *>(source->Clone(name.c_str())));
1082 }
1083 
1086 DQMStore::book1DD(const char *name, TH1D *source)
1087 {
1088  return book1DD(pwd_, name, static_cast<TH1D *>(source->Clone(name)));
1089 }
1090 
1094 {
1095  return book1DD(pwd_, name, static_cast<TH1D *>(source->Clone(name.c_str())));
1096 }
1097 
1098 // -------------------------------------------------------------------
1102 {
1103  return book(dir, name, "book2D", MonitorElement::DQM_KIND_TH2F, h, collate2D);
1104 }
1105 
1109 {
1110  return book(dir, name, "book2S", MonitorElement::DQM_KIND_TH2S, h, collate2S);
1111 }
1112 
1116 {
1117  return book(dir, name, "book2DD", MonitorElement::DQM_KIND_TH2D, h, collate2DD);
1118 }
1119 
1122 DQMStore::book2D(const char *name, const char *title,
1123  int nchX, double lowX, double highX,
1124  int nchY, double lowY, double highY)
1125 {
1126  return book2D(pwd_, name, new TH2F(name, title,
1127  nchX, lowX, highX,
1128  nchY, lowY, highY));
1129 }
1130 
1134  int nchX, double lowX, double highX,
1135  int nchY, double lowY, double highY)
1136 {
1137  return book2D(pwd_, name, new TH2F(name.c_str(), title.c_str(),
1138  nchX, lowX, highX,
1139  nchY, lowY, highY));
1140 }
1141 
1144 DQMStore::book2S(const char *name, const char *title,
1145  int nchX, double lowX, double highX,
1146  int nchY, double lowY, double highY)
1147 {
1148  return book2S(pwd_, name, new TH2S(name, title,
1149  nchX, lowX, highX,
1150  nchY, lowY, highY));
1151 }
1152 
1156  int nchX, double lowX, double highX,
1157  int nchY, double lowY, double highY)
1158 {
1159  return book2S(pwd_, name, new TH2S(name.c_str(), title.c_str(),
1160  nchX, lowX, highX,
1161  nchY, lowY, highY));
1162 }
1163 
1166 DQMStore::book2DD(const char *name, const char *title,
1167  int nchX, double lowX, double highX,
1168  int nchY, double lowY, double highY)
1169 {
1170  return book2DD(pwd_, name, new TH2D(name, title,
1171  nchX, lowX, highX,
1172  nchY, lowY, highY));
1173 }
1174 
1178  int nchX, double lowX, double highX,
1179  int nchY, double lowY, double highY)
1180 {
1181  return book2DD(pwd_, name, new TH2D(name.c_str(), title.c_str(),
1182  nchX, lowX, highX,
1183  nchY, lowY, highY));
1184 }
1185 
1188 DQMStore::book2D(const char *name, const char *title,
1189  int nchX, const float *xbinsize, int nchY, const float *ybinsize)
1190 {
1191  return book2D(pwd_, name, new TH2F(name, title,
1192  nchX, xbinsize, nchY, ybinsize));
1193 }
1194 
1198  int nchX, const float *xbinsize, int nchY, const float *ybinsize)
1199 {
1200  return book2D(pwd_, name, new TH2F(name.c_str(), title.c_str(),
1201  nchX, xbinsize, nchY, ybinsize));
1202 }
1203 
1206 DQMStore::book2D(const char *name, TH2F *source)
1207 {
1208  return book2D(pwd_, name, static_cast<TH2F *>(source->Clone(name)));
1209 }
1210 
1214 {
1215  return book2D(pwd_, name, static_cast<TH2F *>(source->Clone(name.c_str())));
1216 }
1217 
1220 DQMStore::book2S(const char *name, TH2S *source)
1221 {
1222  return book2S(pwd_, name, static_cast<TH2S *>(source->Clone(name)));
1223 }
1224 
1228 {
1229  return book2S(pwd_, name, static_cast<TH2S *>(source->Clone(name.c_str())));
1230 }
1231 
1234 DQMStore::book2DD(const char *name, TH2D *source)
1235 {
1236  return book2DD(pwd_, name, static_cast<TH2D *>(source->Clone(name)));
1237 }
1238 
1242 {
1243  return book2DD(pwd_, name, static_cast<TH2D *>(source->Clone(name.c_str())));
1244 }
1245 
1246 // -------------------------------------------------------------------
1250 {
1251  return book(dir, name, "book3D", MonitorElement::DQM_KIND_TH3F, h, collate3D);
1252 }
1253 
1256 DQMStore::book3D(const char *name, const char *title,
1257  int nchX, double lowX, double highX,
1258  int nchY, double lowY, double highY,
1259  int nchZ, double lowZ, double highZ)
1260 {
1261  return book3D(pwd_, name, new TH3F(name, title,
1262  nchX, lowX, highX,
1263  nchY, lowY, highY,
1264  nchZ, lowZ, highZ));
1265 }
1266 
1270  int nchX, double lowX, double highX,
1271  int nchY, double lowY, double highY,
1272  int nchZ, double lowZ, double highZ)
1273 {
1274  return book3D(pwd_, name, new TH3F(name.c_str(), title.c_str(),
1275  nchX, lowX, highX,
1276  nchY, lowY, highY,
1277  nchZ, lowZ, highZ));
1278 }
1279 
1282 DQMStore::book3D(const char *name, TH3F *source)
1283 {
1284  return book3D(pwd_, name, static_cast<TH3F *>(source->Clone(name)));
1285 }
1286 
1290 {
1291  return book3D(pwd_, name, static_cast<TH3F *>(source->Clone(name.c_str())));
1292 }
1293 
1294 // -------------------------------------------------------------------
1298 {
1299  return book(dir, name, "bookProfile",
1301  h, collateProfile);
1302 }
1303 
1308 DQMStore::bookProfile(const char *name, const char *title,
1309  int nchX, double lowX, double highX,
1310  int /* nchY */, double lowY, double highY,
1311  const char *option /* = "s" */)
1312 {
1313  return bookProfile(pwd_, name, new TProfile(name, title,
1314  nchX, lowX, highX,
1315  lowY, highY,
1316  option));
1317 }
1318 
1324  int nchX, double lowX, double highX,
1325  int /* nchY */, double lowY, double highY,
1326  const char *option /* = "s" */)
1327 {
1328  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1329  nchX, lowX, highX,
1330  lowY, highY,
1331  option));
1332 }
1333 
1338 DQMStore::bookProfile(const char *name, const char *title,
1339  int nchX, double lowX, double highX,
1340  double lowY, double highY,
1341  const char *option /* = "s" */)
1342 {
1343  return bookProfile(pwd_, name, new TProfile(name, title,
1344  nchX, lowX, highX,
1345  lowY, highY,
1346  option));
1347 }
1348 
1354  int nchX, double lowX, double highX,
1355  double lowY, double highY,
1356  const char *option /* = "s" */)
1357 {
1358  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1359  nchX, lowX, highX,
1360  lowY, highY,
1361  option));
1362 }
1363 
1368 DQMStore::bookProfile(const char *name, const char *title,
1369  int nchX, const double *xbinsize,
1370  int /* nchY */, double lowY, double highY,
1371  const char *option /* = "s" */)
1372 {
1373  return bookProfile(pwd_, name, new TProfile(name, title,
1374  nchX, xbinsize,
1375  lowY, highY,
1376  option));
1377 }
1378 
1384  int nchX, const double *xbinsize,
1385  int /* nchY */, double lowY, double highY,
1386  const char *option /* = "s" */)
1387 {
1388  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1389  nchX, xbinsize,
1390  lowY, highY,
1391  option));
1392 }
1393 
1398 DQMStore::bookProfile(const char *name, const char *title,
1399  int nchX, const double *xbinsize,
1400  double lowY, double highY,
1401  const char *option /* = "s" */)
1402 {
1403  return bookProfile(pwd_, name, new TProfile(name, title,
1404  nchX, xbinsize,
1405  lowY, highY,
1406  option));
1407 }
1408 
1414  int nchX, const double *xbinsize,
1415  double lowY, double highY,
1416  const char *option /* = "s" */)
1417 {
1418  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1419  nchX, xbinsize,
1420  lowY, highY,
1421  option));
1422 }
1423 
1426 DQMStore::bookProfile(const char *name, TProfile *source)
1427 {
1428  return bookProfile(pwd_, name, static_cast<TProfile *>(source->Clone(name)));
1429 }
1430 
1434 {
1435  return bookProfile(pwd_, name, static_cast<TProfile *>(source->Clone(name.c_str())));
1436 }
1437 
1438 // -------------------------------------------------------------------
1442 {
1443  return book(dir, name, "bookProfile2D",
1445  h, collateProfile2D);
1446 }
1447 
1452 DQMStore::bookProfile2D(const char *name, const char *title,
1453  int nchX, double lowX, double highX,
1454  int nchY, double lowY, double highY,
1455  int /* nchZ */, double lowZ, double highZ,
1456  const char *option /* = "s" */)
1457 {
1458  return bookProfile2D(pwd_, name, new TProfile2D(name, title,
1459  nchX, lowX, highX,
1460  nchY, lowY, highY,
1461  lowZ, highZ,
1462  option));
1463 }
1464 
1470  int nchX, double lowX, double highX,
1471  int nchY, double lowY, double highY,
1472  int /* nchZ */, double lowZ, double highZ,
1473  const char *option /* = "s" */)
1474 {
1475  return bookProfile2D(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
1476  nchX, lowX, highX,
1477  nchY, lowY, highY,
1478  lowZ, highZ,
1479  option));
1480 }
1481 
1486 DQMStore::bookProfile2D(const char *name, const char *title,
1487  int nchX, double lowX, double highX,
1488  int nchY, double lowY, double highY,
1489  double lowZ, double highZ,
1490  const char *option /* = "s" */)
1491 {
1492  return bookProfile2D(pwd_, name, new TProfile2D(name, title,
1493  nchX, lowX, highX,
1494  nchY, lowY, highY,
1495  lowZ, highZ,
1496  option));
1497 }
1498 
1504  int nchX, double lowX, double highX,
1505  int nchY, double lowY, double highY,
1506  double lowZ, double highZ,
1507  const char *option /* = "s" */)
1508 {
1509  return bookProfile2D(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
1510  nchX, lowX, highX,
1511  nchY, lowY, highY,
1512  lowZ, highZ,
1513  option));
1514 }
1515 
1518 DQMStore::bookProfile2D(const char *name, TProfile2D *source)
1519 {
1520  return bookProfile2D(pwd_, name, static_cast<TProfile2D *>(source->Clone(name)));
1521 }
1522 
1526 {
1527  return bookProfile2D(pwd_, name, static_cast<TProfile2D *>(source->Clone(name.c_str())));
1528 }
1529 
1533 bool
1535 {
1536  if (me->getTH1()->GetNbinsX() != h->GetNbinsX()
1537  || me->getTH1()->GetNbinsY() != h->GetNbinsY()
1538  || me->getTH1()->GetNbinsZ() != h->GetNbinsZ()
1539  || me->getTH1()->GetXaxis()->GetXmin() != h->GetXaxis()->GetXmin()
1540  || me->getTH1()->GetYaxis()->GetXmin() != h->GetYaxis()->GetXmin()
1541  || me->getTH1()->GetZaxis()->GetXmin() != h->GetZaxis()->GetXmin()
1542  || me->getTH1()->GetXaxis()->GetXmax() != h->GetXaxis()->GetXmax()
1543  || me->getTH1()->GetYaxis()->GetXmax() != h->GetYaxis()->GetXmax()
1544  || me->getTH1()->GetZaxis()->GetXmax() != h->GetZaxis()->GetXmax()
1545  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetXaxis(),(TAxis*)h->GetXaxis())
1546  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetYaxis(),(TAxis*)h->GetYaxis())
1547  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetZaxis(),(TAxis*)h->GetZaxis()) )
1548  {
1549  if(verbose > 0)
1550  std::cout << "*** DQMStore: WARNING:"
1551  << "checkBinningMatches: different binning - cannot add object '"
1552  << h->GetName() << "' of type "
1553  << h->IsA()->GetName() << " to existing ME: '"
1554  << me->getFullname() << "'\n";
1555  return false;
1556  }
1557  return true;
1558 }
1559 
1560 void
1562 {
1563  if (checkBinningMatches(me,h,verbose))
1564  me->getTH1F()->Add(h);
1565 }
1566 
1567 void
1569 {
1570  if (checkBinningMatches(me,h,verbose))
1571  me->getTH1S()->Add(h);
1572 }
1573 
1574 void
1576 {
1577  if (checkBinningMatches(me,h,verbose))
1578  me->getTH1D()->Add(h);
1579 }
1580 
1581 void
1583 {
1584  if (checkBinningMatches(me,h,verbose))
1585  me->getTH2F()->Add(h);
1586 }
1587 
1588 void
1590 {
1591  if (checkBinningMatches(me,h,verbose))
1592  me->getTH2S()->Add(h);
1593 }
1594 
1595 void
1597 {
1598  if (checkBinningMatches(me,h,verbose))
1599  me->getTH2D()->Add(h);
1600 }
1601 
1602 void
1604 {
1605  if (checkBinningMatches(me,h,verbose))
1606  me->getTH3F()->Add(h);
1607 }
1608 
1609 void
1611 {
1612  if (checkBinningMatches(me,h,verbose))
1613  {
1614  TProfile *meh = me->getTProfile();
1615  me->addProfiles(h, meh, meh, 1, 1);
1616  }
1617 }
1618 
1619 void
1621 {
1622  if (checkBinningMatches(me,h,verbose))
1623  {
1624  TProfile2D *meh = me->getTProfile2D();
1625  me->addProfiles(h, meh, meh, 1, 1);
1626  }
1627 }
1628 
1633 void
1634 DQMStore::tag(MonitorElement *me, unsigned int myTag)
1635 {
1636  if (! myTag)
1637  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1638  " with a zero tag", me->getFullname().c_str());
1639  if ((me->data_.flags & DQMNet::DQM_PROP_TAGGED) && myTag != me->data_.tag)
1640  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1641  " twice with multiple tags", me->getFullname().c_str());
1642 
1643  me->data_.tag = myTag;
1645 }
1646 
1648 void
1649 DQMStore::tag(const std::string &path, unsigned int myTag)
1650 {
1651  std::string dir;
1652  std::string name;
1653  splitPath(dir, name, path);
1654 
1655  if (MonitorElement *me = findObject(dir, name))
1656  tag(me, myTag);
1657  else
1658  raiseDQMError("DQMStore", "Attempt to tag non-existent monitor element"
1659  " '%s' with tag %u", path.c_str(), myTag);
1660 
1661 }
1662 
1664 void
1665 DQMStore::tagContents(const std::string &path, unsigned int myTag)
1666 {
1667  MonitorElement proto(&path, std::string());
1668  MEMap::iterator e = data_.end();
1669  MEMap::iterator i = data_.lower_bound(proto);
1670  for ( ; i != e && path == *i->data_.dirname; ++i)
1671  tag(const_cast<MonitorElement *>(&*i), myTag);
1672 }
1673 
1676 void
1677 DQMStore::tagAllContents(const std::string &path, unsigned int myTag)
1678 {
1680  const std::string *cleaned = 0;
1681  cleanTrailingSlashes(path, clean, cleaned);
1682  MonitorElement proto(cleaned, std::string());
1683 
1684  // FIXME: WILDCARDS? Old one supported them, but nobody seemed to use them.
1685  MEMap::iterator e = data_.end();
1686  MEMap::iterator i = data_.lower_bound(proto);
1687  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
1688  {
1689  tag(const_cast<MonitorElement *>(&*i), myTag);
1690  ++i;
1691  }
1692 }
1693 
1698 std::vector<std::string>
1700 {
1701  std::vector<std::string> result;
1702  std::set<std::string>::const_iterator e = dirs_.end();
1703  std::set<std::string>::const_iterator i = dirs_.find(pwd_);
1704 
1705  // If we didn't find current directory, the tree is empty, so quit.
1706  if (i == e)
1707  return result;
1708 
1709  // Skip the current directory and then start looking for immediate
1710  // subdirectories in the dirs_ list. Stop when we are no longer in
1711  // (direct or indirect) subdirectories of pwd_. Note that we don't
1712  // "know" which order the set will sort A/B, A/B/C and A/D.
1713  while (++i != e && isSubdirectory(pwd_, *i))
1714  if (i->find('/', pwd_.size()+1) == std::string::npos)
1715  result.push_back(*i);
1716 
1717  return result;
1718 }
1719 
1721 std::vector<std::string>
1722 DQMStore::getMEs(void) const
1723 {
1724  MonitorElement proto(&pwd_, std::string());
1725  std::vector<std::string> result;
1726  MEMap::const_iterator e = data_.end();
1727  MEMap::const_iterator i = data_.lower_bound(proto);
1728  for ( ; i != e && isSubdirectory(pwd_, *i->data_.dirname); ++i)
1729  if (pwd_ == *i->data_.dirname)
1730  result.push_back(i->getName());
1731 
1732  return result;
1733 }
1734 
1737 bool
1739 {
1740  MonitorElement proto(&path, std::string());
1741  MEMap::const_iterator e = data_.end();
1742  MEMap::const_iterator i = data_.lower_bound(proto);
1743  return (i != e && isSubdirectory(path, *i->data_.dirname));
1744 }
1745 
1749 {
1750  std::string dir;
1751  std::string name;
1752  splitPath(dir, name, path);
1753  MonitorElement proto(&dir, name);
1754  MEMap::const_iterator mepos = data_.find(proto);
1755  return (mepos == data_.end() ? 0
1756  : const_cast<MonitorElement *>(&*mepos));
1757 }
1758 
1760 std::vector<MonitorElement *>
1761 DQMStore::get(unsigned int tag) const
1762 {
1763  // FIXME: Use reverse map [tag -> path] / [tag -> dir]?
1764  std::vector<MonitorElement *> result;
1765  for (MEMap::const_iterator i = data_.begin(), e = data_.end(); i != e; ++i)
1766  {
1767  const MonitorElement &me = *i;
1768  if ((me.data_.flags & DQMNet::DQM_PROP_TAGGED) && me.data_.tag == tag)
1769  result.push_back(const_cast<MonitorElement *>(&me));
1770  }
1771  return result;
1772 }
1773 
1776 std::vector<MonitorElement *>
1778 {
1780  const std::string *cleaned = 0;
1781  cleanTrailingSlashes(path, clean, cleaned);
1782  MonitorElement proto(cleaned, std::string());
1783 
1784  std::vector<MonitorElement *> result;
1785  MEMap::const_iterator e = data_.end();
1786  MEMap::const_iterator i = data_.lower_bound(proto);
1787  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1788  if (*cleaned == *i->data_.dirname)
1789  result.push_back(const_cast<MonitorElement *>(&*i));
1790 
1791  return result;
1792 }
1793 
1795 std::vector<MonitorElement *>
1796 DQMStore::getContents(const std::string &path, unsigned int tag) const
1797 {
1799  const std::string *cleaned = 0;
1800  cleanTrailingSlashes(path, clean, cleaned);
1801  MonitorElement proto(cleaned, std::string());
1802 
1803  std::vector<MonitorElement *> result;
1804  MEMap::const_iterator e = data_.end();
1805  MEMap::const_iterator i = data_.lower_bound(proto);
1806  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1807  if (*cleaned == *i->data_.dirname
1808  && (i->data_.flags & DQMNet::DQM_PROP_TAGGED)
1809  && i->data_.tag == tag)
1810  result.push_back(const_cast<MonitorElement *>(&*i));
1811 
1812  return result;
1813 }
1814 
1819 void
1820 DQMStore::getContents(std::vector<std::string> &into, bool showContents /* = true */) const
1821 {
1822  into.clear();
1823  into.reserve(dirs_.size());
1824 
1825  MEMap::const_iterator me = data_.end();
1826  std::set<std::string>::const_iterator di = dirs_.begin();
1827  std::set<std::string>::const_iterator de = dirs_.end();
1828  for ( ; di != de; ++di)
1829  {
1830  MonitorElement proto(&*di, std::string());
1831  MEMap::const_iterator mi = data_.lower_bound(proto);
1832  MEMap::const_iterator m = mi;
1833  size_t sz = di->size() + 2;
1834  size_t nfound = 0;
1835  for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
1836  if (*di == *m->data_.dirname)
1837  {
1838  sz += m->data_.objname.size() + 1;
1839  ++nfound;
1840  }
1841 
1842  if (! nfound)
1843  continue;
1844 
1845  std::vector<std::string>::iterator istr
1846  = into.insert(into.end(), std::string());
1847 
1848  if (showContents)
1849  {
1850  istr->reserve(sz);
1851 
1852  *istr += *di;
1853  *istr += ':';
1854  for (sz = 0; mi != m; ++mi)
1855  {
1856  if (*di != *mi->data_.dirname)
1857  continue;
1858 
1859  if (sz > 0)
1860  *istr += ',';
1861 
1862  *istr += mi->data_.objname;
1863  ++sz;
1864  }
1865  }
1866  else
1867  {
1868  istr->reserve(di->size() + 2);
1869  *istr += *di;
1870  *istr += ':';
1871  }
1872  }
1873 }
1874 
1879  const std::string &name,
1880  const uint32_t run /* = 0 */,
1881  const uint32_t lumi /* = 0 */,
1882  const uint32_t streamId /* = 0 */,
1883  const uint32_t moduleId /* = 0 */) const
1884 {
1885  if (dir.find_first_not_of(s_safe) != std::string::npos)
1886  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1887  " unacceptable characters", dir.c_str());
1888  if (name.find_first_not_of(s_safe) != std::string::npos)
1889  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1890  " unacceptable characters", name.c_str());
1891 
1892  MonitorElement proto;
1893  proto.data_.dirname = &dir;
1894  proto.data_.objname = name;
1895  proto.data_.run = run;
1896  proto.data_.lumi = lumi;
1897  proto.data_.streamId = streamId;
1898  proto.data_.moduleId = moduleId;
1899 
1900  MEMap::const_iterator mepos = data_.find(proto);
1901  return (mepos == data_.end() ? 0
1902  : const_cast<MonitorElement *>(&*mepos));
1903 }
1904 
1907 void
1908 DQMStore::getAllTags(std::vector<std::string> &into) const
1909 {
1910  into.clear();
1911  into.reserve(dirs_.size());
1912 
1913  MEMap::const_iterator me = data_.end();
1914  std::set<std::string>::const_iterator di = dirs_.begin();
1915  std::set<std::string>::const_iterator de = dirs_.end();
1916  char tagbuf[32]; // more than enough for '/' and up to 10 digits
1917 
1918  for ( ; di != de; ++di)
1919  {
1920  MonitorElement proto(&*di, std::string());
1921  MEMap::const_iterator mi = data_.lower_bound(proto);
1922  MEMap::const_iterator m = mi;
1923  size_t sz = di->size() + 2;
1924  size_t nfound = 0;
1925  for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
1926  if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
1927  {
1928  // the tags count for '/' + up to 10 digits, otherwise ',' + ME name
1929  sz += 1 + m->data_.objname.size() + 11;
1930  ++nfound;
1931  }
1932 
1933  if (! nfound)
1934  continue;
1935 
1936  std::vector<std::string>::iterator istr
1937  = into.insert(into.end(), std::string());
1938 
1939  istr->reserve(sz);
1940 
1941  *istr += *di;
1942  *istr += ':';
1943  for (sz = 0; mi != m; ++mi)
1944  {
1945  if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
1946  {
1947  sprintf(tagbuf, "/%u", mi->data_.tag);
1948  if (sz > 0)
1949  *istr += ',';
1950  *istr += m->data_.objname;
1951  *istr += tagbuf;
1952  ++sz;
1953  }
1954  }
1955  }
1956 }
1957 
1960 std::vector<MonitorElement*>
1962  uint32_t runNumber /* = 0 */,
1963  uint32_t lumi /* = 0 */) const
1964 {
1966  const std::string *cleaned = 0;
1967  cleanTrailingSlashes(path, clean, cleaned);
1968  MonitorElement proto(cleaned, std::string(), runNumber);
1969  proto.setLumi(lumi);
1970 
1971  std::vector<MonitorElement *> result;
1972  MEMap::const_iterator e = data_.end();
1973  MEMap::const_iterator i = data_.lower_bound(proto);
1974  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
1975  if (runNumber != 0) {
1976  if (i->data_.run > runNumber // TODO[rovere]: pleonastic? first we encounter local ME of the same run ...
1977  || i->data_.streamId != 0
1978  || i->data_.moduleId != 0)
1979  break;
1980  }
1981  if (lumi != 0) {
1982  if (i->data_.lumi > lumi
1983  || i->data_.streamId != 0
1984  || i->data_.moduleId != 0)
1985  break;
1986  }
1987  if (runNumber != 0 or lumi !=0) {
1988  assert(i->data_.streamId == 0);
1989  assert(i->data_.moduleId == 0);
1990  }
1991  result.push_back(const_cast<MonitorElement *>(&*i));
1992  }
1993 
1994  if (enableMultiThread_)
1995  {
1996  //save legacy modules when running MT
1997  i = data_.begin();
1998  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
1999  if (i->data_.run != 0 || i->data_.streamId != 0 || i->data_.moduleId != 0) break;
2000  result.push_back(const_cast<MonitorElement *>(&*i));
2001  }
2002  }
2003 
2004  return result;
2005 }
2006 
2009 std::vector<MonitorElement*>
2010 DQMStore::getMatchingContents(const std::string &pattern, lat::Regexp::Syntax syntaxType /* = Wildcard */) const
2011 {
2012  lat::Regexp rx;
2013  try
2014  {
2015  rx = lat::Regexp(pattern, 0, syntaxType);
2016  rx.study();
2017  }
2018  catch (lat::Error &e)
2019  {
2020  raiseDQMError("DQMStore", "Invalid regular expression '%s': %s",
2021  pattern.c_str(), e.explain().c_str());
2022  }
2023 
2024  std::string path;
2025  std::vector<MonitorElement *> result;
2026  MEMap::const_iterator i = data_.begin();
2027  MEMap::const_iterator e = data_.end();
2028  for ( ; i != e; ++i)
2029  {
2030  path.clear();
2031  mergePath(path, *i->data_.dirname, i->data_.objname);
2032  if (rx.match(path))
2033  result.push_back(const_cast<MonitorElement *>(&*i));
2034  }
2035 
2036  return result;
2037 }
2038 
2042 
2045 void
2047 {
2048  MEMap::iterator mi = data_.begin();
2049  MEMap::iterator me = data_.end();
2050  for ( ; mi != me; ++mi)
2051  {
2052  MonitorElement &me = const_cast<MonitorElement &>(*mi);
2053  if (mi->wasUpdated())
2054  {
2055  if (me.resetMe())
2056  me.Reset();
2057  me.resetUpdate();
2058  }
2059  }
2060 
2061  reset_ = true;
2062 }
2063 
2067 
2069 void
2071 {
2072  MEMap::iterator mi = data_.begin();
2073  MEMap::iterator me = data_.end();
2074  for ( ; mi != me; ++mi)
2075  {
2076  if (forceResetOnBeginLumi_ && ((*mi).getLumiFlag() == false))
2077  continue;
2078  MonitorElement &me = const_cast<MonitorElement &>(*mi);
2079  me.Reset();
2080  me.resetUpdate();
2081  }
2082 
2083  reset_ = true;
2084 }
2085 
2089 
2093 void
2095 {
2096  std::lock_guard<std::mutex> guard(book_mutex_);
2097 
2098  std::string null_str("");
2099  MonitorElement proto(&null_str, null_str, run, 0, 0);
2100  if (enableMultiThread_)
2101  proto.setLumi(lumi);
2102 
2103  std::set<MonitorElement>::const_iterator e = data_.end();
2104  std::set<MonitorElement>::const_iterator i = data_.lower_bound(proto);
2105 
2106  while (i != e) {
2107  if (i->data_.streamId != 0 ||
2108  i->data_.moduleId != 0)
2109  break;
2110  if ((i->data_.lumi != lumi) && enableMultiThread_)
2111  break;
2112  if (i->data_.run != run)
2113  break;
2114 
2115  auto temp = i;
2116  ++i;
2117 
2118  if (verbose_ > 1) {
2119  std::cout << "DQMStore::deleteUnusedLumiHistograms: deleted monitor element '"
2120  << *i->data_.dirname << "/" << i->data_.objname << "'"
2121  << "flags " << i->data_.flags << "\n";
2122  }
2123 
2124  data_.erase(temp);
2125  }
2126 }
2127 
2133 bool
2135  bool overwrite, bool collateHistograms)
2136 {
2137  // NB: Profile histograms inherit from TH*D, checking order matters.
2138  MonitorElement *refcheck = 0;
2139  if (TProfile *h = dynamic_cast<TProfile *>(obj))
2140  {
2141  MonitorElement *me = findObject(dir, h->GetName());
2142  if (! me)
2143  me = bookProfile(dir, h->GetName(), (TProfile *) h->Clone());
2144  else if (overwrite)
2145  me->copyFrom(h);
2146  else if (isCollateME(me) || collateHistograms)
2147  collateProfile(me, h, verbose_);
2148  refcheck = me;
2149  }
2150  else if (TProfile2D *h = dynamic_cast<TProfile2D *>(obj))
2151  {
2152  MonitorElement *me = findObject(dir, h->GetName());
2153  if (! me)
2154  me = bookProfile2D(dir, h->GetName(), (TProfile2D *) h->Clone());
2155  else if (overwrite)
2156  me->copyFrom(h);
2157  else if (isCollateME(me) || collateHistograms)
2158  collateProfile2D(me, h, verbose_);
2159  refcheck = me;
2160  }
2161  else if (TH1F *h = dynamic_cast<TH1F *>(obj))
2162  {
2163  MonitorElement *me = findObject(dir, h->GetName());
2164  if (! me)
2165  me = book1D(dir, h->GetName(), (TH1F *) h->Clone());
2166  else if (overwrite)
2167  me->copyFrom(h);
2168  else if (isCollateME(me) || collateHistograms)
2169  collate1D(me, h, verbose_);
2170  refcheck = me;
2171  }
2172  else if (TH1S *h = dynamic_cast<TH1S *>(obj))
2173  {
2174  MonitorElement *me = findObject(dir, h->GetName());
2175  if (! me)
2176  me = book1S(dir, h->GetName(), (TH1S *) h->Clone());
2177  else if (overwrite)
2178  me->copyFrom(h);
2179  else if (isCollateME(me) || collateHistograms)
2180  collate1S(me, h, verbose_);
2181  refcheck = me;
2182  }
2183  else if (TH1D *h = dynamic_cast<TH1D *>(obj))
2184  {
2185  MonitorElement *me = findObject(dir, h->GetName());
2186  if (! me)
2187  me = book1DD(dir, h->GetName(), (TH1D *) h->Clone());
2188  else if (overwrite)
2189  me->copyFrom(h);
2190  else if (isCollateME(me) || collateHistograms)
2191  collate1DD(me, h, verbose_);
2192  refcheck = me;
2193  }
2194  else if (TH2F *h = dynamic_cast<TH2F *>(obj))
2195  {
2196  MonitorElement *me = findObject(dir, h->GetName());
2197  if (! me)
2198  me = book2D(dir, h->GetName(), (TH2F *) h->Clone());
2199  else if (overwrite)
2200  me->copyFrom(h);
2201  else if (isCollateME(me) || collateHistograms)
2202  collate2D(me, h, verbose_);
2203  refcheck = me;
2204  }
2205  else if (TH2S *h = dynamic_cast<TH2S *>(obj))
2206  {
2207  MonitorElement *me = findObject(dir, h->GetName());
2208  if (! me)
2209  me = book2S(dir, h->GetName(), (TH2S *) h->Clone());
2210  else if (overwrite)
2211  me->copyFrom(h);
2212  else if (isCollateME(me) || collateHistograms)
2213  collate2S(me, h, verbose_);
2214  refcheck = me;
2215  }
2216  else if (TH2D *h = dynamic_cast<TH2D *>(obj))
2217  {
2218  MonitorElement *me = findObject(dir, h->GetName());
2219  if (! me)
2220  me = book2DD(dir, h->GetName(), (TH2D *) h->Clone());
2221  else if (overwrite)
2222  me->copyFrom(h);
2223  else if (isCollateME(me) || collateHistograms)
2224  collate2DD(me, h, verbose_);
2225  refcheck = me;
2226  }
2227  else if (TH3F *h = dynamic_cast<TH3F *>(obj))
2228  {
2229  MonitorElement *me = findObject(dir, h->GetName());
2230  if (! me)
2231  me = book3D(dir, h->GetName(), (TH3F *) h->Clone());
2232  else if (overwrite)
2233  me->copyFrom(h);
2234  else if (isCollateME(me) || collateHistograms)
2235  collate3D(me, h, verbose_);
2236  refcheck = me;
2237  }
2238  else if (dynamic_cast<TObjString *>(obj))
2239  {
2240  lat::RegexpMatch m;
2241  if (! s_rxmeval.match(obj->GetName(), 0, 0, &m))
2242  {
2243  if (strstr(obj->GetName(), "CMSSW"))
2244  {
2245  if (verbose_)
2246  std::cout << "Input file version: " << obj->GetName() << std::endl;
2247  return true;
2248  }
2249  else if (strstr(obj->GetName(), "DQMPATCH"))
2250  {
2251  if (verbose_)
2252  std::cout << "DQM patch version: " << obj->GetName() << std::endl;
2253  return true;
2254  }
2255  else
2256  {
2257  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2258  << obj->GetName() << "' of type '"
2259  << obj->IsA()->GetName() << "'\n";
2260  return false;
2261  }
2262  }
2263 
2264  std::string label = m.matchString(obj->GetName(), 1);
2265  std::string kind = m.matchString(obj->GetName(), 2);
2266  std::string value = m.matchString(obj->GetName(), 3);
2267 
2268  if (kind == "i")
2269  {
2270  MonitorElement *me = findObject(dir, label);
2271  if (! me || overwrite)
2272  {
2273  if (! me) me = bookInt(dir, label);
2274  me->Fill(atoll(value.c_str()));
2275  }
2276  }
2277  else if (kind == "f")
2278  {
2279  MonitorElement *me = findObject(dir, label);
2280  if (! me || overwrite)
2281  {
2282  if (! me) me = bookFloat(dir, label);
2283  me->Fill(atof(value.c_str()));
2284  }
2285  }
2286  else if (kind == "s")
2287  {
2288  MonitorElement *me = findObject(dir, label);
2289  if (! me)
2290  me = bookString(dir, label, value);
2291  else if (overwrite)
2292  me->Fill(value);
2293  }
2294  else if (kind == "e")
2295  {
2296  MonitorElement *me = findObject(dir, label);
2297  if (! me)
2298  {
2299  std::cout << "*** DQMStore: WARNING: no monitor element '"
2300  << label << "' in directory '"
2301  << dir << "' to be marked as efficiency plot.\n";
2302  return false;
2303  }
2304  me->setEfficiencyFlag();
2305  }
2306  else if (kind == "t")
2307  {
2308  MonitorElement *me = findObject(dir, label);
2309  if (! me)
2310  {
2311  std::cout << "*** DQMStore: WARNING: no monitor element '"
2312  << label << "' in directory '"
2313  << dir << "' for a tag\n";
2314  return false;
2315  }
2316  errno = 0;
2317  char *endp = 0;
2318  unsigned long val = strtoul(value.c_str(), &endp, 10);
2319  if ((val == 0 && errno) || *endp || val > ~uint32_t(0))
2320  {
2321  std::cout << "*** DQMStore: WARNING: cannot restore tag '"
2322  << value << "' for monitor element '"
2323  << label << "' in directory '"
2324  << dir << "' - invalid value\n";
2325  return false;
2326  }
2327  tag(me, val);
2328  }
2329  else if (kind == "qr")
2330  {
2331  // Handle qreports, but skip them while reading in references.
2332  if (! isSubdirectory(s_referenceDirName, dir))
2333  {
2334  size_t dot = label.find('.');
2335  if (dot == std::string::npos)
2336  {
2337  std::cout << "*** DQMStore: WARNING: quality report label in '" << label
2338  << "' is missing a '.' and cannot be extracted\n";
2339  return false;
2340  }
2341 
2342  std::string mename (label, 0, dot);
2343  std::string qrname (label, dot+1, std::string::npos);
2344 
2345  m.reset();
2346  DQMNet::QValue qv;
2347  if (s_rxmeqr1.match(value, 0, 0, &m))
2348  {
2349  qv.code = atoi(m.matchString(value, 1).c_str());
2350  qv.qtresult = strtod(m.matchString(value, 2).c_str(), 0);
2351  qv.message = m.matchString(value, 4);
2352  qv.qtname = qrname;
2353  qv.algorithm = m.matchString(value, 3);
2354  }
2355  else if (s_rxmeqr2.match(value, 0, 0, &m))
2356  {
2357  qv.code = atoi(m.matchString(value, 1).c_str());
2358  qv.qtresult = 0; // unavailable in old format
2359  qv.message = m.matchString(value, 2);
2360  qv.qtname = qrname;
2361  // qv.algorithm unavailable in old format
2362  }
2363  else
2364  {
2365  std::cout << "*** DQMStore: WARNING: quality test value '"
2366  << value << "' is incorrectly formatted\n";
2367  return false;
2368  }
2369 
2370  MonitorElement *me = findObject(dir, mename);
2371  if (! me)
2372  {
2373  std::cout << "*** DQMStore: WARNING: no monitor element '"
2374  << mename << "' in directory '"
2375  << dir << "' for quality test '"
2376  << label << "'\n";
2377  return false;
2378  }
2379 
2380  me->addQReport(qv, /* FIXME: getQTest(qv.qtname)? */ 0);
2381  }
2382  }
2383  else
2384  {
2385  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2386  << obj->GetName() << "' of type '"
2387  << obj->IsA()->GetName() << "'\n";
2388  return false;
2389  }
2390  }
2391  else if (TNamed *n = dynamic_cast<TNamed *>(obj))
2392  {
2393  // For old DQM data.
2394  std::string s;
2395  s.reserve(6 + strlen(n->GetTitle()) + 2*strlen(n->GetName()));
2396  s += '<'; s += n->GetName(); s += '>';
2397  s += n->GetTitle();
2398  s += '<'; s += '/'; s += n->GetName(); s += '>';
2399  TObjString os(s.c_str());
2400  return extract(&os, dir, overwrite, collateHistograms_);
2401  }
2402  else
2403  {
2404  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2405  << obj->GetName() << "' of type '" << obj->IsA()->GetName()
2406  << "' and with title '" << obj->GetTitle() << "'\n";
2407  return false;
2408  }
2409 
2410  // If we just read in a reference monitor element, and there is a
2411  // monitor element with the same name, link the two together. The
2412  // other direction is handled by the initialise() method.
2413  if (refcheck && isSubdirectory(s_referenceDirName, dir))
2414  {
2415  std::string mdir(dir, s_referenceDirName.size()+1, std::string::npos);
2416  if (MonitorElement *master = findObject(mdir, obj->GetName()))
2417  {
2418  master->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
2419  master->reference_ = refcheck->object_;
2420  }
2421  }
2422 
2423  return true;
2424 }
2425 
2429 bool
2431 {
2432  assert(! path.empty());
2433 
2434  // Find the first path component.
2435  size_t start = 0;
2436  size_t end = path.find('/', start);
2437  if (end == std::string::npos)
2438  end = path.size();
2439 
2440  while (true)
2441  {
2442  // Check if this subdirectory component exists. If yes, make sure
2443  // it is actually a subdirectory. Otherwise create or cd into it.
2444  std::string part(path, start, end-start);
2445  TObject *o = gDirectory->Get(part.c_str());
2446  if (o && ! dynamic_cast<TDirectory *>(o))
2447  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2448  " fails because the part '%s' already exists and is not"
2449  " directory", path.c_str(), part.c_str());
2450  else if (! o)
2451  gDirectory->mkdir(part.c_str());
2452 
2453  if (! gDirectory->cd(part.c_str()))
2454  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2455  " fails because could not cd into subdirectory '%s'",
2456  path.c_str(), part.c_str());
2457 
2458  // Stop if we reached the end, ignoring any trailing '/'.
2459  if (end+1 >= path.size())
2460  break;
2461 
2462  // Find the next path component.
2463  start = end+1;
2464  end = path.find('/', start);
2465  if (end == std::string::npos)
2466  end = path.size();
2467  }
2468 
2469  return true;
2470 }
2471 
2473  const std::string &path /* = "" */,
2474  const uint32_t run /* = 0 */,
2475  const uint32_t lumi /* = 0 */,
2476  const bool resetMEsAfterWriting /* = false */)
2477 {
2478  using google::protobuf::io::FileOutputStream;
2479  using google::protobuf::io::GzipOutputStream;
2480  using google::protobuf::io::StringOutputStream;
2481 
2482  std::lock_guard<std::mutex> guard(book_mutex_);
2483 
2484  std::set<std::string>::iterator di, de;
2485  MEMap::iterator mi, me = data_.end();
2486  dqmstorepb::ROOTFilePB dqmstore_message;
2487  int nme = 0;
2488 
2489  if (verbose_)
2490  std::cout << "\n DQMStore: Opening PBFile '"
2491  << filename << "'"<< std::endl;
2492 
2493  // Loop over the directory structure.
2494  for (di = dirs_.begin(), de = dirs_.end(); di != de; ++di)
2495  {
2496  // Check if we should process this directory. We process the
2497  // requested part of the object tree, including references.
2498  if (! path.empty()
2499  && ! isSubdirectory(path, *di))
2500  continue;
2501 
2502  // Loop over monitor elements in this directory.
2503  MonitorElement proto(&*di, std::string(), run, 0, 0);
2504  if (enableMultiThread_)
2505  proto.setLumi(lumi);
2506 
2507  mi = data_.lower_bound(proto);
2508  for ( ; mi != me && isSubdirectory(*di, *mi->data_.dirname); ++mi)
2509  {
2510  if (verbose_ > 1)
2511  std::cout << "Run: " << (*mi).run()
2512  << " Lumi: " << (*mi).lumi()
2513  << " LumiFlag: " << (*mi).getLumiFlag()
2514  << " streamId: " << (*mi).streamId()
2515  << " moduleId: " << (*mi).moduleId()
2516  << " fullpathname: " << (*mi).getFullname() << std::endl;
2517 
2518  // Upper bound in the loop over the MEs
2519  if (enableMultiThread_ && ((*mi).lumi() != lumi))
2520  break;
2521 
2522  // Skip if it isn't a direct child.
2523  if (*di != *mi->data_.dirname)
2524  continue;
2525 
2526  // Keep backward compatibility with the old way of
2527  // booking/handlind MonitorElements into the DQMStore. If run is
2528  // 0 it means that a booking happened w/ the old non-threadsafe
2529  // style, and we have to ignore the streamId and moduleId as a
2530  // consequence.
2531 
2532  if (run != 0 && (mi->data_.streamId !=0 || mi->data_.moduleId !=0))
2533  continue;
2534 
2535  if (verbose_ > 1)
2536  std::cout << "DQMStore::savePB: saving monitor element '"
2537  << *mi->data_.dirname << "/" << mi->data_.objname << "'"
2538  << "flags " << mi->data_.flags << "\n";
2539 
2540  nme++;
2541  dqmstorepb::ROOTFilePB::Histo* me = dqmstore_message.add_histo();
2542  me->set_full_pathname((*mi->data_.dirname) + '/' + mi->data_.objname);
2543  me->set_flags(mi->data_.flags);
2544 
2545  TObject *toWrite = nullptr;
2546  bool deleteObject = false;
2547 
2548  if (mi->kind() < MonitorElement::DQM_KIND_TH1F) {
2549  toWrite = new TObjString(mi->tagString().c_str());
2550  deleteObject = true;
2551  } else {
2552  toWrite = mi->object_;
2553  }
2554 
2555  TBufferFile buffer(TBufferFile::kWrite);
2556  buffer.WriteObject(toWrite);
2557  me->set_size(buffer.Length());
2558  me->set_streamed_histo((const void*)buffer.Buffer(),
2559  buffer.Length());
2560 
2561  if (deleteObject) {
2562  delete toWrite;
2563  }
2564 
2565  //reset the ME just written to make it available for the next LS (online)
2566  if (resetMEsAfterWriting)
2567  const_cast<MonitorElement*>(&*mi)->Reset();
2568  }
2569  }
2570 
2571  int filedescriptor = ::open(filename.c_str(),
2572  O_WRONLY | O_CREAT | O_TRUNC,
2573  S_IRUSR | S_IWUSR |
2574  S_IRGRP | S_IWGRP |
2575  S_IROTH);
2576  FileOutputStream file_stream(filedescriptor);
2578  options.format = GzipOutputStream::GZIP;
2579  options.compression_level = 6;
2580  GzipOutputStream gzip_stream(&file_stream,
2581  options);
2582  dqmstore_message.SerializeToZeroCopyStream(&gzip_stream);
2583 
2584  // we need to flush it before we close the fd
2585  gzip_stream.Close();
2586  file_stream.Close();
2587  ::close(filedescriptor);
2588 
2589  // Maybe make some noise.
2590  if (verbose_)
2591  std::cout << "DQMStore::savePB: successfully wrote " << nme
2592  << " objects from path '" << path
2593  << "' into DQM file '" << filename << "'\n";
2594 }
2595 
2596 
2601 void
2603  const std::string &path /* = "" */,
2604  const std::string &pattern /* = "" */,
2605  const std::string &rewrite /* = "" */,
2606  const uint32_t run /* = 0 */,
2607  const uint32_t lumi /* = 0 */,
2608  SaveReferenceTag ref /* = SaveWithReference */,
2609  int minStatus /* = dqm::qstatus::STATUS_OK */,
2610  const std::string &fileupdate /* = RECREATE */,
2611  const bool resetMEsAfterWriting /* = false */)
2612 {
2613  std::lock_guard<std::mutex> guard(book_mutex_);
2614 
2615  std::set<std::string>::iterator di, de;
2616  MEMap::iterator mi, me = data_.end();
2617  DQMNet::QReports::const_iterator qi, qe;
2618  int nme=0;
2619 
2620  // TFile flushes to disk with fsync() on every TDirectory written to
2621  // the file. This makes DQM file saving painfully slow, and
2622  // ironically makes it _more_ likely the file saving gets
2623  // interrupted and corrupts the file. The utility class below
2624  // simply ignores the flush synchronisation.
2625  class TFileNoSync : public TFile
2626  {
2627  public:
2628  TFileNoSync(const char *file, const char *opt) : TFile(file, opt) {}
2629  virtual Int_t SysSync(Int_t) override { return 0; }
2630  };
2631 
2632  // open output file, on 1st save recreate, later update
2633  if (verbose_)
2634  std::cout << "\n DQMStore: Opening TFile '" << filename
2635  << "' with option '" << fileupdate <<"'\n";
2636 
2637  TFileNoSync f(filename.c_str(), fileupdate.c_str()); // open file
2638  if(f.IsZombie())
2639  raiseDQMError("DQMStore", "Failed to create/update file '%s'", filename.c_str());
2640  f.cd();
2641 
2642  // Construct a regular expression from the pattern string.
2643  std::auto_ptr<lat::Regexp> rxpat;
2644  if (! pattern.empty())
2645  rxpat.reset(new lat::Regexp(pattern.c_str()));
2646 
2647  // Prepare a path for the reference object selection.
2648  std::string refpath;
2649  refpath.reserve(s_referenceDirName.size() + path.size() + 2);
2650  refpath += s_referenceDirName;
2651  if (! path.empty())
2652  {
2653  refpath += '/';
2654  refpath += path;
2655  }
2656 
2657  // Loop over the directory structure.
2658  for (di = dirs_.begin(), de = dirs_.end(); di != de; ++di)
2659  {
2660  // Check if we should process this directory. We process the
2661  // requested part of the object tree, including references.
2662  if (! path.empty()
2663  && ! isSubdirectory(path, *di)
2664  && ! isSubdirectory(refpath, *di))
2665  continue;
2666 
2667  // Loop over monitor elements in this directory.
2668  MonitorElement proto(&*di, std::string(), run, 0, 0);
2669  if (enableMultiThread_)
2670  proto.setLumi(lumi);
2671 
2672  mi = data_.lower_bound(proto);
2673  for ( ; mi != me && isSubdirectory(*di, *mi->data_.dirname); ++mi)
2674  {
2675  if (verbose_ > 1)
2676  std::cout << "DQMStore::save: Run: " << (*mi).run()
2677  << " Lumi: " << (*mi).lumi()
2678  << " LumiFlag: " << (*mi).getLumiFlag()
2679  << " streamId: " << (*mi).streamId()
2680  << " moduleId: " << (*mi).moduleId()
2681  << " fullpathname: " << (*mi).getFullname() << std::endl;
2682 
2683  // Upper bound in the loop over the MEs
2684  if (enableMultiThread_ && ((*mi).lumi() != lumi))
2685  break;
2686 
2687  // Skip if it isn't a direct child.
2688  if (*di != *mi->data_.dirname) {
2689  if (verbose_ > 1)
2690  std::cout << "DQMStore::save: isn't a direct child. Skipping" << std::endl;
2691  continue;
2692  }
2693 
2694  // Keep backward compatibility with the old way of
2695  // booking/handlind MonitorElements into the DQMStore. If run is
2696  // 0 it means that a booking happened w/ the old non-threadsafe
2697  // style, and we have to ignore the streamId and moduleId as a
2698  // consequence.
2699 
2700  if (run != 0 && (mi->data_.streamId !=0 || mi->data_.moduleId !=0)) {
2701  continue;
2702  }
2703 
2704  // Handle reference histograms, with three distinct cases:
2705  // 1) Skip all references entirely on saving.
2706  // 2) Blanket saving of all references.
2707  // 3) Save only references for monitor elements with qtests.
2708  // The latter two are affected by "path" sub-tree selection,
2709  // i.e. references are saved only in the selected tree part.
2710  if (isSubdirectory(refpath, *mi->data_.dirname))
2711  {
2712  if (ref == SaveWithoutReference)
2713  // Skip the reference entirely.
2714  continue;
2715  else if (ref == SaveWithReference)
2716  // Save all references regardless of qtests.
2717  ;
2718  else if (ref == SaveWithReferenceForQTest)
2719  {
2720  // Save only references for monitor elements with qtests
2721  // with an optional cut on minimum quality test result.
2722  int status = -1;
2723  std::string mname(mi->getFullname(), s_referenceDirName.size()+1, std::string::npos);
2724  MonitorElement *master = get(mname);
2725  if (master)
2726  for (size_t i = 0, e = master->data_.qreports.size(); i != e; ++i)
2727  status = std::max(status, master->data_.qreports[i].code);
2728 
2729  if (! master || status < minStatus)
2730  {
2731  if (verbose_ > 1)
2732  std::cout << "DQMStore::save: skipping monitor element '"
2733  << mi->data_.objname << "' while saving, status is "
2734  << status << ", required minimum status is "
2735  << minStatus << std::endl;
2736  continue;
2737  }
2738  }
2739  }
2740 
2741  if (verbose_ > 1)
2742  std::cout << "DQMStore::save: saving monitor element '"
2743  << mi->data_.objname << "'\n";
2744  nme++; // count saved histograms
2745 
2746  // Create the directory.
2747  gDirectory->cd("/");
2748  if (di->empty())
2750  else if (rxpat.get())
2751  cdInto(s_monitorDirName + '/' + lat::StringOps::replace(*di, *rxpat, rewrite));
2752  else
2753  cdInto(s_monitorDirName + '/' + *di);
2754 
2755  // Save the object.
2756  switch (mi->kind())
2757  {
2761  TObjString(mi->tagString().c_str()).Write();
2762  break;
2763 
2764  default:
2765  mi->object_->Write();
2766  break;
2767  }
2768 
2769  // Save quality reports if this is not in reference section.
2770  if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
2771  {
2772  qi = mi->data_.qreports.begin();
2773  qe = mi->data_.qreports.end();
2774  for ( ; qi != qe; ++qi)
2775  TObjString(mi->qualityTagString(*qi).c_str()).Write();
2776  }
2777 
2778  // Save efficiency tag, if any
2779  if (mi->data_.flags & DQMNet::DQM_PROP_EFFICIENCY_PLOT)
2780  TObjString(mi->effLabelString().c_str()).Write();
2781 
2782  // Save tag if any
2783  if (mi->data_.flags & DQMNet::DQM_PROP_TAGGED)
2784  TObjString(mi->tagLabelString().c_str()).Write();
2785 
2786  //reset the ME just written to make it available for the next LS (online)
2787  if (resetMEsAfterWriting)
2788  const_cast<MonitorElement*>(&*mi)->Reset();
2789  }
2790  }
2791 
2792  f.Close();
2793 
2794  // Maybe make some noise.
2795  if (verbose_)
2796  std::cout << "DQMStore::save: successfully wrote " << nme
2797  << " objects from path '" << path
2798  << "' into DQM file '" << filename << "'\n";
2799 }
2800 
2803 unsigned int
2805  bool overwrite,
2806  const std::string &onlypath,
2807  const std::string &prepend,
2808  const std::string &curdir,
2809  OpenRunDirs stripdirs)
2810 {
2811  unsigned int ntot = 0;
2812  unsigned int count = 0;
2813 
2814  if (! file->cd(curdir.c_str()))
2815  raiseDQMError("DQMStore", "Failed to process directory '%s' while"
2816  " reading file '%s'", curdir.c_str(), file->GetName());
2817 
2818  // Figure out current directory name, but strip out the top
2819  // directory into which we dump everything.
2820  std::string dirpart = curdir;
2821  if (dirpart.compare(0, s_monitorDirName.size(), s_monitorDirName) == 0)
2822  {
2823  if (dirpart.size() == s_monitorDirName.size())
2824  dirpart.clear();
2825  else if (dirpart[s_monitorDirName.size()] == '/')
2826  dirpart.erase(0, s_monitorDirName.size()+1);
2827  }
2828 
2829  // See if we are going to skip this directory.
2830  bool skip = (! onlypath.empty() && ! isSubdirectory(onlypath, dirpart));
2831 
2832  if (prepend == s_collateDirName ||
2833  prepend == s_referenceDirName ||
2834  stripdirs == StripRunDirs )
2835  {
2836  // Remove Run # and RunSummary dirs
2837  // first look for Run summary,
2838  // if that is found and erased, also erase Run dir
2839  size_t slash = dirpart.find('/');
2840  size_t pos = dirpart.find("/Run summary");
2841  if (slash != std::string::npos && pos !=std::string::npos)
2842  {
2843  dirpart.erase(pos,12);
2844 
2845  pos = dirpart.find("Run ");
2846  size_t length = dirpart.find('/',pos+1)-pos+1;
2847  if (pos !=std::string::npos)
2848  dirpart.erase(pos,length);
2849  }
2850  }
2851 
2852  // If we are prepending, add it to the directory name,
2853  // and suppress reading of already existing reference histograms
2854  if (prepend == s_collateDirName ||
2855  prepend == s_referenceDirName)
2856  {
2857  size_t slash = dirpart.find('/');
2858  // If we are reading reference, skip previous reference.
2859  if (slash == std::string::npos // skip if Reference is toplevel folder, i.e. no slash
2860  && slash+1+s_referenceDirName.size() == dirpart.size()
2861  && dirpart.compare(slash+1, s_referenceDirName.size(), s_referenceDirName) == 0)
2862  return 0;
2863 
2864  slash = dirpart.find('/');
2865  // Skip reading of EventInfo subdirectory.
2866  if (slash != std::string::npos
2867  && slash + 10 == dirpart.size()
2868  && dirpart.compare( slash+1 , 9 , "EventInfo") == 0) {
2869  if (verbose_)
2870  std::cout << "DQMStore::readDirectory: skipping '" << dirpart << "'\n";
2871  return 0;
2872  }
2873 
2874  // Add prefix.
2875  if (dirpart.empty())
2876  dirpart = prepend;
2877  else
2878  dirpart = prepend + '/' + dirpart;
2879  }
2880  else if (! prepend.empty())
2881  {
2882  if (dirpart.empty())
2883  dirpart = prepend;
2884  else
2885  dirpart = prepend + '/' + dirpart;
2886  }
2887 
2888  // Loop over the contents of this directory in the file.
2889  // Post-pone string object handling to happen after other
2890  // objects have been read in so we are guaranteed to have
2891  // histograms by the time we read in quality tests and tags.
2892  TKey *key;
2893  TIter next (gDirectory->GetListOfKeys());
2894  std::list<TObject *> delayed;
2895  while ((key = (TKey *) next()))
2896  {
2897  std::auto_ptr<TObject> obj(key->ReadObj());
2898  if (dynamic_cast<TDirectory *>(obj.get()))
2899  {
2900  std::string subdir;
2901  subdir.reserve(curdir.size() + strlen(obj->GetName()) + 2);
2902  subdir += curdir;
2903  if (! curdir.empty())
2904  subdir += '/';
2905  subdir += obj->GetName();
2906 
2907  ntot += readDirectory(file, overwrite, onlypath, prepend, subdir, stripdirs);
2908  }
2909  else if (skip)
2910  ;
2911  else if (dynamic_cast<TObjString *>(obj.get()))
2912  {
2913  delayed.push_back(obj.release());
2914  }
2915  else
2916  {
2917  if (verbose_ > 2)
2918  std::cout << "DQMStore: reading object '" << obj->GetName()
2919  << "' of type '" << obj->IsA()->GetName()
2920  << "' from '" << file->GetName()
2921  << "' into '" << dirpart << "'\n";
2922 
2923  makeDirectory(dirpart);
2924  if (extract(obj.get(), dirpart, overwrite, collateHistograms_))
2925  ++count;
2926  }
2927  }
2928 
2929  while (! delayed.empty())
2930  {
2931  if (verbose_ > 2)
2932  std::cout << "DQMStore: reading object '" << delayed.front()->GetName()
2933  << "' of type '" << delayed.front()->IsA()->GetName()
2934  << "' from '" << file->GetName()
2935  << "' into '" << dirpart << "'\n";
2936 
2937  makeDirectory(dirpart);
2938  if (extract(delayed.front(), dirpart, overwrite, collateHistograms_))
2939  ++count;
2940 
2941  delete delayed.front();
2942  delayed.pop_front();
2943  }
2944 
2945  if (verbose_ > 1)
2946  std::cout << "DQMStore: read " << count << '/' << ntot
2947  << " objects from directory '" << dirpart << "'\n";
2948 
2949  return ntot + count;
2950 }
2951 
2958 bool
2960  bool overwrite /* = false */,
2961  const std::string &onlypath /* ="" */,
2962  const std::string &prepend /* ="" */,
2963  OpenRunDirs stripdirs /* =KeepRunDirs */,
2964  bool fileMustExist /* =true */)
2965 {
2966  return readFile(filename,overwrite,onlypath,prepend,stripdirs,fileMustExist);
2967 }
2968 
2973 bool
2975  OpenRunDirs stripdirs /* =StripRunDirs */,
2976  bool fileMustExist /* =true */)
2977 {
2978  bool overwrite = true;
2979  if (collateHistograms_) overwrite = false;
2980  if (verbose_)
2981  {
2982  std::cout << "DQMStore::load: reading from file '" << filename << "'\n";
2983  if (collateHistograms_)
2984  std::cout << "DQMStore::load: in collate mode " << "\n";
2985  else
2986  std::cout << "DQMStore::load: in overwrite mode " << "\n";
2987  }
2988 
2989  if (!s_rxpbfile.match(filename, 0, 0))
2990  return readFile(filename, overwrite, "", "", stripdirs, fileMustExist);
2991  else
2992  return readFilePB(filename, overwrite, "", "", stripdirs, fileMustExist);
2993 }
2994 
3000 bool
3002  bool overwrite /* = false */,
3003  const std::string &onlypath /* ="" */,
3004  const std::string &prepend /* ="" */,
3005  OpenRunDirs stripdirs /* =StripRunDirs */,
3006  bool fileMustExist /* =true */)
3007 {
3008 
3009  if (verbose_)
3010  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
3011 
3012  std::auto_ptr<TFile> f;
3013 
3014  try
3015  {
3016  f.reset(TFile::Open(filename.c_str()));
3017  if (! f.get() || f->IsZombie())
3018  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
3019  }
3020  catch (std::exception &)
3021  {
3022  if (fileMustExist)
3023  throw;
3024  else
3025  {
3026  if (verbose_)
3027  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
3028  return false;
3029  }
3030  }
3031 
3032  unsigned n = readDirectory(f.get(), overwrite, onlypath, prepend, "", stripdirs);
3033  f->Close();
3034 
3035  MEMap::iterator mi = data_.begin();
3036  MEMap::iterator me = data_.end();
3037  for ( ; mi != me; ++mi)
3038  const_cast<MonitorElement &>(*mi).updateQReportStats();
3039 
3040  if (verbose_)
3041  {
3042  std::cout << "DQMStore::open: successfully read " << n
3043  << " objects from file '" << filename << "'";
3044  if (! onlypath.empty())
3045  std::cout << " from directory '" << onlypath << "'";
3046  if (! prepend.empty())
3047  std::cout << " into directory '" << prepend << "'";
3048  std::cout << std::endl;
3049  }
3050  return true;
3051 }
3052 
3056 inline TObject * DQMStore::extractNextObject(TBufferFile &buf) const {
3057  if (buf.Length() == buf.BufferSize())
3058  return 0;
3059  buf.InitMap();
3060  void *ptr = buf.ReadObjectAny(0);
3061  return reinterpret_cast<TObject *>(ptr);
3062 }
3063 
3066  std::string &objname,
3067  TObject ** obj) {
3068 
3069  size_t slash = h.full_pathname().rfind('/');
3070  size_t dirpos = (slash == std::string::npos ? 0 : slash);
3071  size_t namepos = (slash == std::string::npos ? 0 : slash+1);
3072  dirname.assign(h.full_pathname(), 0, dirpos);
3073  objname.assign(h.full_pathname(), namepos, std::string::npos);
3074  TBufferFile buf(TBufferFile::kRead, h.size(),
3075  (void*)h.streamed_histo().data(),
3076  kFALSE);
3077  buf.Reset();
3078  *obj = extractNextObject(buf);
3079  if (!*obj) {
3080  raiseDQMError("DQMStore", "Error reading element:'%s'" , h.full_pathname().c_str());
3081  }
3082 }
3083 
3084 bool
3086  bool overwrite /* = false */,
3087  const std::string &onlypath /* ="" */,
3088  const std::string &prepend /* ="" */,
3089  OpenRunDirs stripdirs /* =StripRunDirs */,
3090  bool fileMustExist /* =true */)
3091 {
3092  using google::protobuf::io::FileInputStream;
3093  using google::protobuf::io::FileOutputStream;
3094  using google::protobuf::io::GzipInputStream;
3095  using google::protobuf::io::GzipOutputStream;
3096  using google::protobuf::io::CodedInputStream;
3097  using google::protobuf::io::ArrayInputStream;
3098 
3099  if (verbose_)
3100  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
3101 
3102  int filedescriptor;
3103  if ((filedescriptor = ::open(filename.c_str(), O_RDONLY)) == -1) {
3104  if (fileMustExist)
3105  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
3106  else
3107  if (verbose_)
3108  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
3109  return false;
3110  }
3111 
3112  dqmstorepb::ROOTFilePB dqmstore_message;
3113  FileInputStream fin(filedescriptor);
3114  GzipInputStream input(&fin);
3115  CodedInputStream input_coded(&input);
3116  input_coded.SetTotalBytesLimit(1024*1024*1024, -1);
3117  if (!dqmstore_message.ParseFromCodedStream(&input_coded)) {
3118  raiseDQMError("DQMStore", "Fatal parsing file '%s'", filename.c_str());
3119  return false;
3120  }
3121  ::close(filedescriptor);
3122 
3123  for (int i = 0; i < dqmstore_message.histo_size(); i++) {
3124  std::string path;
3125  std::string objname;
3126 
3127  TObject *obj = NULL;
3128  const dqmstorepb::ROOTFilePB::Histo &h = dqmstore_message.histo(i);
3129  get_info(h, path, objname, &obj);
3130 
3131  setCurrentFolder(path);
3132  if (obj)
3133  {
3134  /* Before calling the extract() check if histogram exists:
3135  * if it does - flags for the given monitor are already set (and merged)
3136  * else - set the flags after the histogram is created.
3137  */
3138  MonitorElement *me = findObject(path, objname);
3139 
3140  /* Run histograms should be collated and not overwritten,
3141  * Lumi histograms should be overwritten (and collate flag is not checked)
3142  */
3143  bool overwrite = h.flags() & DQMNet::DQM_PROP_LUMI;
3144  bool collate = !(h.flags() & DQMNet::DQM_PROP_LUMI);
3145  extract(static_cast<TObject *>(obj), path, overwrite, collate);
3146 
3147  if (me == nullptr) {
3148  me = findObject(path, objname);
3149  me->data_.flags = h.flags();
3150  }
3151 
3152  delete obj;
3153  }
3154  }
3155 
3156  cd();
3157  return true;
3158 }
3159 
3165 void
3167 {
3169  const std::string *cleaned = 0;
3170  cleanTrailingSlashes(path, clean, cleaned);
3171  MonitorElement proto(cleaned, std::string());
3172 
3173  MEMap::iterator e = data_.end();
3174  MEMap::iterator i = data_.lower_bound(proto);
3175  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
3176  data_.erase(i++);
3177 
3178  std::set<std::string>::iterator de = dirs_.end();
3179  std::set<std::string>::iterator di = dirs_.lower_bound(*cleaned);
3180  while (di != de && isSubdirectory(*cleaned, *di))
3181  dirs_.erase(di++);
3182 }
3183 
3185 void
3187 {
3188  MonitorElement proto(&dir, std::string());
3189  MEMap::iterator e = data_.end();
3190  MEMap::iterator i = data_.lower_bound(proto);
3191  while (i != e && isSubdirectory(dir, *i->data_.dirname))
3192  if (dir == *i->data_.dirname)
3193  data_.erase(i++);
3194  else
3195  ++i;
3196 }
3197 
3199 void
3201 {
3203 }
3204 
3207 void
3209 {
3210  removeElement(pwd_, name);
3211 }
3212 
3215 void
3216 DQMStore::removeElement(const std::string &dir, const std::string &name, bool warning /* = true */)
3217 {
3218  MonitorElement proto(&dir, name);
3219  MEMap::iterator pos = data_.find(proto);
3220  if (pos != data_.end())
3221  data_.erase(pos);
3222  else if (warning)
3223  std::cout << "DQMStore: WARNING: attempt to remove non-existent"
3224  << " monitor element '" << name << "' in '" << dir << "'\n";
3225 }
3226 
3232 QCriterion *
3234 {
3235  QCMap::const_iterator i = qtests_.find(qtname);
3236  QCMap::const_iterator e = qtests_.end();
3237  return (i == e ? 0 : i->second);
3238 }
3239 
3243 QCriterion *
3244 DQMStore::createQTest(const std::string &algoname, const std::string &qtname)
3245 {
3246  if (qtests_.count(qtname))
3247  raiseDQMError("DQMStore", "Attempt to create duplicate quality test '%s'",
3248  qtname.c_str());
3249 
3250  QAMap::iterator i = qalgos_.find(algoname);
3251  if (i == qalgos_.end())
3252  raiseDQMError("DQMStore", "Cannot create a quality test using unknown"
3253  " algorithm '%s'", algoname.c_str());
3254 
3255  QCriterion *qc = i->second(qtname);
3256  qc->setVerbose(verboseQT_);
3257 
3258  qtests_[qtname] = qc;
3259  return qc;
3260 }
3261 
3264 void
3266 {
3267  // Clean the path
3269  const std::string *cleaned = 0;
3270  cleanTrailingSlashes(dir, clean, cleaned);
3271 
3272  // Validate the path.
3273  if (cleaned->find_first_not_of(s_safe) != std::string::npos)
3274  raiseDQMError("DQMStore", "Monitor element path name '%s'"
3275  " uses unacceptable characters", cleaned->c_str());
3276 
3277  // Redirect to the pattern match version.
3278  useQTestByMatch(*cleaned + "/*", qtname);
3279 }
3280 
3282 int
3284 {
3285  QCriterion *qc = getQCriterion(qtname);
3286  if (! qc)
3287  raiseDQMError("DQMStore", "Cannot apply non-existent quality test '%s'",
3288  qtname.c_str());
3289 
3290  fastmatch * fm = new fastmatch( pattern );
3291 
3292  // Record the test for future reference.
3293  QTestSpec qts(fm, qc);
3294  qtestspecs_.push_back(qts);
3295 
3296  // Apply the quality test.
3297  MEMap::iterator mi = data_.begin();
3298  MEMap::iterator me = data_.end();
3299  std::string path;
3300  int cases = 0;
3301  for ( ; mi != me; ++mi)
3302  {
3303  path.clear();
3304  mergePath(path, *mi->data_.dirname, mi->data_.objname);
3305  if (fm->match(path))
3306  {
3307  ++cases;
3308  const_cast<MonitorElement &>(*mi).addQReport(qts.second);
3309  }
3310  }
3311 
3312  //return the number of matched cases
3313  return cases;
3314 }
3317 void
3319 {
3320 
3321  if (verbose_ > 0)
3322  std::cout << "DQMStore: running runQTests() with reset = "
3323  << ( reset_ ? "true" : "false" ) << std::endl;
3324 
3325  // Apply quality tests to each monitor element, skipping references.
3326  MEMap::iterator mi = data_.begin();
3327  MEMap::iterator me = data_.end();
3328  for ( ; mi != me; ++mi)
3329  if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
3330  const_cast<MonitorElement &>(*mi).runQTests();
3331 
3332  reset_ = false;
3333 }
3334 
3338 int
3339 DQMStore::getStatus(const std::string &path /* = "" */) const
3340 {
3342  const std::string *cleaned = 0;
3343  cleanTrailingSlashes(path, clean, cleaned);
3344 
3346  MEMap::const_iterator mi = data_.begin();
3347  MEMap::const_iterator me = data_.end();
3348  for ( ; mi != me; ++mi)
3349  {
3350  if (! cleaned->empty() && ! isSubdirectory(*cleaned, *mi->data_.dirname))
3351  continue;
3352 
3353  if (mi->hasError())
3354  return dqm::qstatus::ERROR;
3355  else if (mi->hasWarning())
3356  status = dqm::qstatus::WARNING;
3357  else if (status < dqm::qstatus::WARNING
3358  && mi->hasOtherReport())
3359  status = dqm::qstatus::OTHER;
3360  }
3361  return status;
3362 }
3363 
3369 void
3371 {
3372  if (me)
3373  me->softReset();
3374 }
3375 
3376 // reverts action of softReset
3377 void
3379 {
3380  if (me)
3381  me->disableSoftReset();
3382 }
3383 
3386 void
3388 {
3389  if (me)
3390  me->setAccumulate(flag);
3391 }
3392 
3396 void
3398 {
3399  std::vector<std::string> contents;
3400  getContents(contents);
3401 
3402  std::cout << " ------------------------------------------------------------\n"
3403  << " Directory structure: \n"
3404  << " ------------------------------------------------------------\n";
3405 
3406  std::copy(contents.begin(), contents.end(),
3407  std::ostream_iterator<std::string>(std::cout, "\n"));
3408 
3409  std::cout << " ------------------------------------------------------------\n";
3410 }
3411 
3415 // check if the collate option is active on the DQMStore
3416 bool
3418 {
3419  return collateHistograms_;
3420 }
3424 // check if the monitor element is in auto-collation folder
3425 bool
3427 { return me && isSubdirectory(s_collateDirName, *me->data_.dirname); }
3431 
3433 void
3435 {
3436  if (scaleFlag_ == 0.0) return;
3437  if (verbose_ > 0)
3438  std::cout << " =========== " << " ScaleFlag " << scaleFlag_ << std::endl;
3439  double factor = scaleFlag_;
3440  int events = 1;
3441  if (dirExists("Info/EventInfo")) {
3442  if ( scaleFlag_ == -1.0) {
3443  MonitorElement * scale_me = get("Info/EventInfo/ScaleFactor");
3444  if (scale_me && scale_me->kind()==MonitorElement::DQM_KIND_REAL) factor = scale_me->getFloatValue();
3445  }
3446  MonitorElement * event_me = get("Info/EventInfo/processedEvents");
3447  if (event_me && event_me->kind()==MonitorElement::DQM_KIND_INT) events = event_me->getIntValue();
3448  }
3449  factor = factor/(events*1.0);
3450 
3451  MEMap::iterator mi = data_.begin();
3452  MEMap::iterator me = data_.end();
3453  for ( ; mi != me; ++mi)
3454  {
3455  MonitorElement &me = const_cast<MonitorElement &>(*mi);
3456  switch (me.kind())
3457  {
3459  {
3460  me.getTH1F()->Scale(factor);
3461  break;
3462  }
3464  {
3465  me.getTH1S()->Scale(factor);
3466  break;
3467  }
3469  {
3470  me.getTH1D()->Scale(factor);
3471  break;
3472  }
3474  {
3475  me.getTH2F()->Scale(factor);
3476  break;
3477  }
3479  {
3480  me.getTH2S()->Scale(factor);
3481  break;
3482  }
3484  {
3485  me.getTH2D()->Scale(factor);
3486  break;
3487  }
3489  {
3490  me.getTH3F()->Scale(factor);
3491  break;
3492  }
3494  {
3495  me.getTProfile()->Scale(factor);
3496  break;
3497  }
3499  {
3500  me.getTProfile2D()->Scale(factor);
3501  break;
3502  }
3503  default:
3504  if (verbose_ > 0)
3505  std::cout << " The DQM object '" << me.getFullname() << "' is not scalable object " << std::endl;
3506  continue;
3507  }
3508  }
3509 }
QCriterion * getQCriterion(const std::string &qtname) const
Definition: DQMStore.cc:3233
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:483
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:1144
bool containsAnyMonitorable(const std::string &path) const
Definition: DQMStore.cc:1738
uint32_t moduleId
Definition: DQMNet.h:104
inline::google::protobuf::uint32 size() const
bool isCollateME(MonitorElement *me) const
Definition: DQMStore.cc:3426
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:2430
const ::std::string & full_pathname() const
void cd(void)
Definition: DQMStore.cc:322
int getStatus(const std::string &path="") const
Definition: DQMStore.cc:3339
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:1699
TProfile2D * getTProfile2D(void) const
MonitorElement * book1D(const char *name, const char *title, int nchX, double lowX, double highX)
Book 1D histogram.
Definition: DQMStore.cc:994
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:3166
static void collate3D(MonitorElement *me, TH3F *h, unsigned verbose)
Definition: DQMStore.cc:1603
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:3001
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:1878
static void collateProfile(MonitorElement *me, TProfile *h, unsigned verbose)
Definition: DQMStore.cc:1610
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:1256
void setLumi(uint32_t ls)
void cd(void)
Definition: DQMStore.cc:266
void cd(void)
go to top directory (ie. root)
Definition: DQMStore.cc:684
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:1166
uint32_t streamId_
Definition: DQMStore.h:705
tuple lumi
Definition: fjr2json.py:35
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:1596
std::vector< MonitorElement * > getMatchingContents(const std::string &pattern, lat::Regexp::Syntax syntaxType=lat::Regexp::Wildcard) const
Definition: DQMStore.cc:2010
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:1026
void initializeFrom(const edm::ParameterSet &)
Definition: DQMStore.cc:555
#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:849
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:931
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:1634
~DQMStore(void)
Definition: DQMStore.cc:541
void disableSoftReset(MonitorElement *me)
Definition: DQMStore.cc:3378
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:2070
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:1961
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:3200
QTestSpecs qtestspecs_
Definition: DQMStore.h:715
tuple path
else: Piece not in the list, fine.
double scaleFlag_
Definition: DQMStore.h:698
void deleteUnusedLumiHistograms(uint32_t run, uint32_t lumi)
Definition: DQMStore.cc:2094
void get_info(const dqmstorepb::ROOTFilePB_Histo &, std::string &dirname, std::string &objname, TObject **obj)
Definition: DQMStore.cc:3064
void watchPostSourceRun(PostSourceRun::slot_type const &iSlot)
MonitorElement * bookString(const char *name, const char *value)
Book string.
Definition: DQMStore.cc:960
void setAccumulate(bool)
uint32_t lumi
Definition: DQMNet.h:102
bool isCollate(void) const
Definition: DQMStore.cc:3417
tuple result
Definition: query.py:137
void removeElement(const std::string &name)
Definition: DQMStore.cc:3208
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:1620
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:1308
QCriterion * makeQCriterion(const std::string &qtname)
Definition: DQMStore.cc:119
#define end
Definition: vmac.h:37
void setVerbose(unsigned level)
Definition: DQMStore.cc:671
void softReset(MonitorElement *me)
Definition: DQMStore.cc:3370
std::string pwd_
Definition: DQMStore.h:709
Kind kind(void) const
Get the type of the monitor element.
void runQTests(void)
Definition: DQMStore.cc:3318
TObject * extractNextObject(TBufferFile &) const
Definition: DQMStore.cc:3056
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:1748
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:1777
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:772
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:2472
void getAllTags(std::vector< std::string > &into) const
Definition: DQMStore.cc:1908
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:2974
void scaleElements(void)
Definition: DQMStore.cc:3434
~fastmatch()
Definition: DQMStore.cc:199
static void collate1DD(MonitorElement *me, TH1D *h, unsigned verbose)
Definition: DQMStore.cc:1575
void tagAllContents(const std::string &path, unsigned int myTag)
Definition: DQMStore.cc:1677
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:615
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:3283
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:1561
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:1722
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:2804
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:2134
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:1665
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:2602
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:3085
TProfile * getTProfile(void) const
void useQTest(const std::string &dir, const std::string &qtname)
Definition: DQMStore.cc:3265
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:718
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:2959
inline::google::protobuf::uint32 flags() const
static const int STATUS_OK
void setAccumulate(MonitorElement *me, bool flag)
Definition: DQMStore.cc:3387
tuple cout
Definition: gather_cfg.py:121
void setEfficiencyFlag(void)
static void collate1S(MonitorElement *me, TH1S *h, unsigned verbose)
Definition: DQMStore.cc:1568
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:3244
static bool checkBinningMatches(MonitorElement *me, TH1 *h, unsigned verbose)
Definition: DQMStore.cc:1534
dbl *** dir
Definition: mlp_gen.cc:35
volatile std::atomic< bool > shutdown_flag false
void showDirStructure(void) const
Definition: DQMStore.cc:3397
void reset(void)
Definition: DQMStore.cc:2046
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:1582
MonitorElement * bookInt(const char *name)
Book int.
Definition: DQMStore.cc:901
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:1122
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:1010
tuple size
Write out results.
static const lat::Regexp s_rxmeqr1("^st:(\\d+):([-+e.\\d]+):([^:]*):(.*)$")
void makeDirectory(const std::string &path)
Definition: DQMStore.cc:731
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:707
static void collate2S(MonitorElement *me, TH2S *h, unsigned verbose)
Definition: DQMStore.cc:1589
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:679
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:1452
void raiseDQMError(const char *context, const char *fmt,...)
Definition: DQMError.cc:11