CMS 3D CMS Logo

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