CMS 3D CMS Logo

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