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