CMS 3D CMS Logo

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