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::book2D(const char *name, TH2F *source)
1248 {
1249  return book2D(pwd_, name, static_cast<TH2F *>(source->Clone(name)));
1250 }
1251 
1255 {
1256  return book2D(pwd_, name, static_cast<TH2F *>(source->Clone(name.c_str())));
1257 }
1258 
1261 DQMStore::book2S(const char *name, TH2S *source)
1262 {
1263  return book2S(pwd_, name, static_cast<TH2S *>(source->Clone(name)));
1264 }
1265 
1269 {
1270  return book2S(pwd_, name, static_cast<TH2S *>(source->Clone(name.c_str())));
1271 }
1272 
1275 DQMStore::book2DD(const char *name, TH2D *source)
1276 {
1277  return book2DD(pwd_, name, static_cast<TH2D *>(source->Clone(name)));
1278 }
1279 
1283 {
1284  return book2DD(pwd_, name, static_cast<TH2D *>(source->Clone(name.c_str())));
1285 }
1286 
1287 // -------------------------------------------------------------------
1291 {
1292  return book(dir, name, "book3D", MonitorElement::DQM_KIND_TH3F, h, collate3D);
1293 }
1294 
1297 DQMStore::book3D(const char *name, const char *title,
1298  int nchX, double lowX, double highX,
1299  int nchY, double lowY, double highY,
1300  int nchZ, double lowZ, double highZ)
1301 {
1302  return book3D(pwd_, name, new TH3F(name, title,
1303  nchX, lowX, highX,
1304  nchY, lowY, highY,
1305  nchZ, lowZ, highZ));
1306 }
1307 
1311  int nchX, double lowX, double highX,
1312  int nchY, double lowY, double highY,
1313  int nchZ, double lowZ, double highZ)
1314 {
1315  return book3D(pwd_, name, new TH3F(name.c_str(), title.c_str(),
1316  nchX, lowX, highX,
1317  nchY, lowY, highY,
1318  nchZ, lowZ, highZ));
1319 }
1320 
1323 DQMStore::book3D(const char *name, TH3F *source)
1324 {
1325  return book3D(pwd_, name, static_cast<TH3F *>(source->Clone(name)));
1326 }
1327 
1331 {
1332  return book3D(pwd_, name, static_cast<TH3F *>(source->Clone(name.c_str())));
1333 }
1334 
1335 // -------------------------------------------------------------------
1339 {
1340  return book(dir, name, "bookProfile",
1342  h, collateProfile);
1343 }
1344 
1349 DQMStore::bookProfile(const char *name, const char *title,
1350  int nchX, double lowX, double highX,
1351  int /* nchY */, double lowY, double highY,
1352  const char *option /* = "s" */)
1353 {
1354  return bookProfile(pwd_, name, new TProfile(name, title,
1355  nchX, lowX, highX,
1356  lowY, highY,
1357  option));
1358 }
1359 
1365  int nchX, double lowX, double highX,
1366  int /* nchY */, double lowY, double highY,
1367  const char *option /* = "s" */)
1368 {
1369  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1370  nchX, lowX, highX,
1371  lowY, highY,
1372  option));
1373 }
1374 
1379 DQMStore::bookProfile(const char *name, const char *title,
1380  int nchX, double lowX, double highX,
1381  double lowY, double highY,
1382  const char *option /* = "s" */)
1383 {
1384  return bookProfile(pwd_, name, new TProfile(name, title,
1385  nchX, lowX, highX,
1386  lowY, highY,
1387  option));
1388 }
1389 
1395  int nchX, double lowX, double highX,
1396  double lowY, double highY,
1397  const char *option /* = "s" */)
1398 {
1399  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1400  nchX, lowX, highX,
1401  lowY, highY,
1402  option));
1403 }
1404 
1409 DQMStore::bookProfile(const char *name, const char *title,
1410  int nchX, const double *xbinsize,
1411  int /* nchY */, double lowY, double highY,
1412  const char *option /* = "s" */)
1413 {
1414  return bookProfile(pwd_, name, new TProfile(name, title,
1415  nchX, xbinsize,
1416  lowY, highY,
1417  option));
1418 }
1419 
1425  int nchX, const double *xbinsize,
1426  int /* nchY */, double lowY, double highY,
1427  const char *option /* = "s" */)
1428 {
1429  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1430  nchX, xbinsize,
1431  lowY, highY,
1432  option));
1433 }
1434 
1439 DQMStore::bookProfile(const char *name, const char *title,
1440  int nchX, const double *xbinsize,
1441  double lowY, double highY,
1442  const char *option /* = "s" */)
1443 {
1444  return bookProfile(pwd_, name, new TProfile(name, title,
1445  nchX, xbinsize,
1446  lowY, highY,
1447  option));
1448 }
1449 
1455  int nchX, const double *xbinsize,
1456  double lowY, double highY,
1457  const char *option /* = "s" */)
1458 {
1459  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1460  nchX, xbinsize,
1461  lowY, highY,
1462  option));
1463 }
1464 
1467 DQMStore::bookProfile(const char *name, TProfile *source)
1468 {
1469  return bookProfile(pwd_, name, static_cast<TProfile *>(source->Clone(name)));
1470 }
1471 
1475 {
1476  return bookProfile(pwd_, name, static_cast<TProfile *>(source->Clone(name.c_str())));
1477 }
1478 
1479 // -------------------------------------------------------------------
1483 {
1484  return book(dir, name, "bookProfile2D",
1486  h, collateProfile2D);
1487 }
1488 
1493 DQMStore::bookProfile2D(const char *name, const char *title,
1494  int nchX, double lowX, double highX,
1495  int nchY, double lowY, double highY,
1496  int /* nchZ */, double lowZ, double highZ,
1497  const char *option /* = "s" */)
1498 {
1499  return bookProfile2D(pwd_, name, new TProfile2D(name, title,
1500  nchX, lowX, highX,
1501  nchY, lowY, highY,
1502  lowZ, highZ,
1503  option));
1504 }
1505 
1511  int nchX, double lowX, double highX,
1512  int nchY, double lowY, double highY,
1513  int /* nchZ */, double lowZ, double highZ,
1514  const char *option /* = "s" */)
1515 {
1516  return bookProfile2D(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
1517  nchX, lowX, highX,
1518  nchY, lowY, highY,
1519  lowZ, highZ,
1520  option));
1521 }
1522 
1527 DQMStore::bookProfile2D(const char *name, const char *title,
1528  int nchX, double lowX, double highX,
1529  int nchY, double lowY, double highY,
1530  double lowZ, double highZ,
1531  const char *option /* = "s" */)
1532 {
1533  return bookProfile2D(pwd_, name, new TProfile2D(name, title,
1534  nchX, lowX, highX,
1535  nchY, lowY, highY,
1536  lowZ, highZ,
1537  option));
1538 }
1539 
1545  int nchX, double lowX, double highX,
1546  int nchY, double lowY, double highY,
1547  double lowZ, double highZ,
1548  const char *option /* = "s" */)
1549 {
1550  return bookProfile2D(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
1551  nchX, lowX, highX,
1552  nchY, lowY, highY,
1553  lowZ, highZ,
1554  option));
1555 }
1556 
1559 DQMStore::bookProfile2D(const char *name, TProfile2D *source)
1560 {
1561  return bookProfile2D(pwd_, name, static_cast<TProfile2D *>(source->Clone(name)));
1562 }
1563 
1567 {
1568  return bookProfile2D(pwd_, name, static_cast<TProfile2D *>(source->Clone(name.c_str())));
1569 }
1570 
1574 bool
1576 {
1577  if (me->getTH1()->GetNbinsX() != h->GetNbinsX()
1578  || me->getTH1()->GetNbinsY() != h->GetNbinsY()
1579  || me->getTH1()->GetNbinsZ() != h->GetNbinsZ()
1580  || me->getTH1()->GetXaxis()->GetXmin() != h->GetXaxis()->GetXmin()
1581  || me->getTH1()->GetYaxis()->GetXmin() != h->GetYaxis()->GetXmin()
1582  || me->getTH1()->GetZaxis()->GetXmin() != h->GetZaxis()->GetXmin()
1583  || me->getTH1()->GetXaxis()->GetXmax() != h->GetXaxis()->GetXmax()
1584  || me->getTH1()->GetYaxis()->GetXmax() != h->GetYaxis()->GetXmax()
1585  || me->getTH1()->GetZaxis()->GetXmax() != h->GetZaxis()->GetXmax()
1586  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetXaxis(),(TAxis*)h->GetXaxis())
1587  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetYaxis(),(TAxis*)h->GetYaxis())
1588  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetZaxis(),(TAxis*)h->GetZaxis()) )
1589  {
1590  if(verbose > 0)
1591  std::cout << "*** DQMStore: WARNING:"
1592  << "checkBinningMatches: different binning - cannot add object '"
1593  << h->GetName() << "' of type "
1594  << h->IsA()->GetName() << " to existing ME: '"
1595  << me->getFullname() << "'\n";
1596  return false;
1597  }
1598  return true;
1599 }
1600 
1601 void
1603 {
1604  if (checkBinningMatches(me,h,verbose))
1605  me->getTH1F()->Add(h);
1606 }
1607 
1608 void
1610 {
1611  if (checkBinningMatches(me,h,verbose))
1612  me->getTH1S()->Add(h);
1613 }
1614 
1615 void
1617 {
1618  if (checkBinningMatches(me,h,verbose))
1619  me->getTH1D()->Add(h);
1620 }
1621 
1622 void
1624 {
1625  if (checkBinningMatches(me,h,verbose))
1626  me->getTH2F()->Add(h);
1627 }
1628 
1629 void
1631 {
1632  if (checkBinningMatches(me,h,verbose))
1633  me->getTH2S()->Add(h);
1634 }
1635 
1636 void
1638 {
1639  if (checkBinningMatches(me,h,verbose))
1640  me->getTH2D()->Add(h);
1641 }
1642 
1643 void
1645 {
1646  if (checkBinningMatches(me,h,verbose))
1647  me->getTH3F()->Add(h);
1648 }
1649 
1650 void
1652 {
1653  if (checkBinningMatches(me,h,verbose))
1654  {
1655  TProfile *meh = me->getTProfile();
1656  me->addProfiles(h, meh, meh, 1, 1);
1657  }
1658 }
1659 
1660 void
1662 {
1663  if (checkBinningMatches(me,h,verbose))
1664  {
1665  TProfile2D *meh = me->getTProfile2D();
1666  me->addProfiles(h, meh, meh, 1, 1);
1667  }
1668 }
1669 
1674 void
1675 DQMStore::tag(MonitorElement *me, unsigned int myTag)
1676 {
1677  if (! myTag)
1678  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1679  " with a zero tag", me->getFullname().c_str());
1680  if ((me->data_.flags & DQMNet::DQM_PROP_TAGGED) && myTag != me->data_.tag)
1681  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1682  " twice with multiple tags", me->getFullname().c_str());
1683 
1684  me->data_.tag = myTag;
1686 }
1687 
1689 void
1690 DQMStore::tag(const std::string &path, unsigned int myTag)
1691 {
1692  std::string dir;
1693  std::string name;
1694  splitPath(dir, name, path);
1695 
1696  if (MonitorElement *me = findObject(dir, name))
1697  tag(me, myTag);
1698  else
1699  raiseDQMError("DQMStore", "Attempt to tag non-existent monitor element"
1700  " '%s' with tag %u", path.c_str(), myTag);
1701 
1702 }
1703 
1705 void
1706 DQMStore::tagContents(const std::string &path, unsigned int myTag)
1707 {
1708  MonitorElement proto(&path, std::string());
1709  MEMap::iterator e = data_.end();
1710  MEMap::iterator i = data_.lower_bound(proto);
1711  for ( ; i != e && path == *i->data_.dirname; ++i)
1712  tag(const_cast<MonitorElement *>(&*i), myTag);
1713 }
1714 
1717 void
1718 DQMStore::tagAllContents(const std::string &path, unsigned int myTag)
1719 {
1721  const std::string *cleaned = 0;
1722  cleanTrailingSlashes(path, clean, cleaned);
1723  MonitorElement proto(cleaned, std::string());
1724 
1725  // FIXME: WILDCARDS? Old one supported them, but nobody seemed to use them.
1726  MEMap::iterator e = data_.end();
1727  MEMap::iterator i = data_.lower_bound(proto);
1728  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
1729  {
1730  tag(const_cast<MonitorElement *>(&*i), myTag);
1731  ++i;
1732  }
1733 }
1734 
1739 std::vector<std::string>
1741 {
1742  std::vector<std::string> result;
1743  std::set<std::string>::const_iterator e = dirs_.end();
1744  std::set<std::string>::const_iterator i = dirs_.find(pwd_);
1745 
1746  // If we didn't find current directory, the tree is empty, so quit.
1747  if (i == e)
1748  return result;
1749 
1750  // Skip the current directory and then start looking for immediate
1751  // subdirectories in the dirs_ list. Stop when we are no longer in
1752  // (direct or indirect) subdirectories of pwd_. Note that we don't
1753  // "know" which order the set will sort A/B, A/B/C and A/D.
1754  while (++i != e && isSubdirectory(pwd_, *i))
1755  if (i->find('/', pwd_.size()+1) == std::string::npos)
1756  result.push_back(*i);
1757 
1758  return result;
1759 }
1760 
1762 std::vector<std::string>
1763 DQMStore::getMEs(void) const
1764 {
1765  MonitorElement proto(&pwd_, std::string());
1766  std::vector<std::string> result;
1767  MEMap::const_iterator e = data_.end();
1768  MEMap::const_iterator i = data_.lower_bound(proto);
1769  for ( ; i != e && isSubdirectory(pwd_, *i->data_.dirname); ++i)
1770  if (pwd_ == *i->data_.dirname)
1771  result.push_back(i->getName());
1772 
1773  return result;
1774 }
1775 
1778 bool
1780 {
1781  MonitorElement proto(&path, std::string());
1782  MEMap::const_iterator e = data_.end();
1783  MEMap::const_iterator i = data_.lower_bound(proto);
1784  return (i != e && isSubdirectory(path, *i->data_.dirname));
1785 }
1786 
1790 {
1791  std::string dir;
1792  std::string name;
1793  splitPath(dir, name, path);
1794  MonitorElement proto(&dir, name);
1795  MEMap::const_iterator mepos = data_.find(proto);
1796  return (mepos == data_.end() ? 0
1797  : const_cast<MonitorElement *>(&*mepos));
1798 }
1799 
1801 std::vector<MonitorElement *>
1802 DQMStore::get(unsigned int tag) const
1803 {
1804  // FIXME: Use reverse map [tag -> path] / [tag -> dir]?
1805  std::vector<MonitorElement *> result;
1806  for (MEMap::const_iterator i = data_.begin(), e = data_.end(); i != e; ++i)
1807  {
1808  const MonitorElement &me = *i;
1809  if ((me.data_.flags & DQMNet::DQM_PROP_TAGGED) && me.data_.tag == tag)
1810  result.push_back(const_cast<MonitorElement *>(&me));
1811  }
1812  return result;
1813 }
1814 
1817 std::vector<MonitorElement *>
1819 {
1821  const std::string *cleaned = 0;
1822  cleanTrailingSlashes(path, clean, cleaned);
1823  MonitorElement proto(cleaned, std::string());
1824 
1825  std::vector<MonitorElement *> result;
1826  MEMap::const_iterator e = data_.end();
1827  MEMap::const_iterator i = data_.lower_bound(proto);
1828  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1829  if (*cleaned == *i->data_.dirname)
1830  result.push_back(const_cast<MonitorElement *>(&*i));
1831 
1832  return result;
1833 }
1834 
1836 std::vector<MonitorElement *>
1837 DQMStore::getContents(const std::string &path, unsigned int tag) const
1838 {
1840  const std::string *cleaned = 0;
1841  cleanTrailingSlashes(path, clean, cleaned);
1842  MonitorElement proto(cleaned, std::string());
1843 
1844  std::vector<MonitorElement *> result;
1845  MEMap::const_iterator e = data_.end();
1846  MEMap::const_iterator i = data_.lower_bound(proto);
1847  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1848  if (*cleaned == *i->data_.dirname
1849  && (i->data_.flags & DQMNet::DQM_PROP_TAGGED)
1850  && i->data_.tag == tag)
1851  result.push_back(const_cast<MonitorElement *>(&*i));
1852 
1853  return result;
1854 }
1855 
1860 void
1861 DQMStore::getContents(std::vector<std::string> &into, bool showContents /* = true */) const
1862 {
1863  into.clear();
1864  into.reserve(dirs_.size());
1865 
1866  MEMap::const_iterator me = data_.end();
1867  std::set<std::string>::const_iterator di = dirs_.begin();
1868  std::set<std::string>::const_iterator de = dirs_.end();
1869  for ( ; di != de; ++di)
1870  {
1871  MonitorElement proto(&*di, std::string());
1872  MEMap::const_iterator mi = data_.lower_bound(proto);
1873  MEMap::const_iterator m = mi;
1874  size_t sz = di->size() + 2;
1875  size_t nfound = 0;
1876  for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
1877  if (*di == *m->data_.dirname)
1878  {
1879  sz += m->data_.objname.size() + 1;
1880  ++nfound;
1881  }
1882 
1883  if (! nfound)
1884  continue;
1885 
1886  std::vector<std::string>::iterator istr
1887  = into.insert(into.end(), std::string());
1888 
1889  if (showContents)
1890  {
1891  istr->reserve(sz);
1892 
1893  *istr += *di;
1894  *istr += ':';
1895  for (sz = 0; mi != m; ++mi)
1896  {
1897  if (*di != *mi->data_.dirname)
1898  continue;
1899 
1900  if (sz > 0)
1901  *istr += ',';
1902 
1903  *istr += mi->data_.objname;
1904  ++sz;
1905  }
1906  }
1907  else
1908  {
1909  istr->reserve(di->size() + 2);
1910  *istr += *di;
1911  *istr += ':';
1912  }
1913  }
1914 }
1915 
1920  const std::string &name,
1921  const uint32_t run /* = 0 */,
1922  const uint32_t lumi /* = 0 */,
1923  const uint32_t streamId /* = 0 */,
1924  const uint32_t moduleId /* = 0 */) const
1925 {
1926  if (dir.find_first_not_of(s_safe) != std::string::npos)
1927  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1928  " unacceptable characters", dir.c_str());
1929  if (name.find_first_not_of(s_safe) != std::string::npos)
1930  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1931  " unacceptable characters", name.c_str());
1932 
1933  MonitorElement proto;
1934  proto.data_.dirname = &dir;
1935  proto.data_.objname = name;
1936  proto.data_.run = run;
1937  proto.data_.lumi = lumi;
1938  proto.data_.streamId = streamId;
1939  proto.data_.moduleId = moduleId;
1940 
1941  MEMap::const_iterator mepos = data_.find(proto);
1942  return (mepos == data_.end() ? 0
1943  : const_cast<MonitorElement *>(&*mepos));
1944 }
1945 
1948 void
1949 DQMStore::getAllTags(std::vector<std::string> &into) const
1950 {
1951  into.clear();
1952  into.reserve(dirs_.size());
1953 
1954  MEMap::const_iterator me = data_.end();
1955  std::set<std::string>::const_iterator di = dirs_.begin();
1956  std::set<std::string>::const_iterator de = dirs_.end();
1957  char tagbuf[32]; // more than enough for '/' and up to 10 digits
1958 
1959  for ( ; di != de; ++di)
1960  {
1961  MonitorElement proto(&*di, std::string());
1962  MEMap::const_iterator mi = data_.lower_bound(proto);
1963  MEMap::const_iterator m = mi;
1964  size_t sz = di->size() + 2;
1965  size_t nfound = 0;
1966  for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
1967  if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
1968  {
1969  // the tags count for '/' + up to 10 digits, otherwise ',' + ME name
1970  sz += 1 + m->data_.objname.size() + 11;
1971  ++nfound;
1972  }
1973 
1974  if (! nfound)
1975  continue;
1976 
1977  std::vector<std::string>::iterator istr
1978  = into.insert(into.end(), std::string());
1979 
1980  istr->reserve(sz);
1981 
1982  *istr += *di;
1983  *istr += ':';
1984  for (sz = 0; mi != m; ++mi)
1985  {
1986  if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
1987  {
1988  sprintf(tagbuf, "/%u", mi->data_.tag);
1989  if (sz > 0)
1990  *istr += ',';
1991  *istr += m->data_.objname;
1992  *istr += tagbuf;
1993  ++sz;
1994  }
1995  }
1996  }
1997 }
1998 
2001 std::vector<MonitorElement*>
2003  uint32_t runNumber /* = 0 */,
2004  uint32_t lumi /* = 0 */) const
2005 {
2007  const std::string *cleaned = 0;
2008  cleanTrailingSlashes(path, clean, cleaned);
2009  MonitorElement proto(cleaned, std::string(), runNumber);
2010  proto.setLumi(lumi);
2011 
2012  std::vector<MonitorElement *> result;
2013  MEMap::const_iterator e = data_.end();
2014  MEMap::const_iterator i = data_.lower_bound(proto);
2015  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
2016  if (runNumber != 0) {
2017  if (i->data_.run > runNumber // TODO[rovere]: pleonastic? first we encounter local ME of the same run ...
2018  || i->data_.streamId != 0
2019  || i->data_.moduleId != 0)
2020  break;
2021  }
2022  if (lumi != 0) {
2023  if (i->data_.lumi > lumi
2024  || i->data_.streamId != 0
2025  || i->data_.moduleId != 0)
2026  break;
2027  }
2028  if (runNumber != 0 or lumi !=0) {
2029  assert(i->data_.streamId == 0);
2030  assert(i->data_.moduleId == 0);
2031  }
2032  result.push_back(const_cast<MonitorElement *>(&*i));
2033  }
2034 
2035  if (enableMultiThread_)
2036  {
2037  //save legacy modules when running MT
2038  i = data_.begin();
2039  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
2040  if (i->data_.run != 0 || i->data_.streamId != 0 || i->data_.moduleId != 0) break;
2041  result.push_back(const_cast<MonitorElement *>(&*i));
2042  }
2043  }
2044 
2045  return result;
2046 }
2047 
2050 std::vector<MonitorElement*>
2051 DQMStore::getMatchingContents(const std::string &pattern, lat::Regexp::Syntax syntaxType /* = Wildcard */) const
2052 {
2053  lat::Regexp rx;
2054  try
2055  {
2056  rx = lat::Regexp(pattern, 0, syntaxType);
2057  rx.study();
2058  }
2059  catch (lat::Error &e)
2060  {
2061  raiseDQMError("DQMStore", "Invalid regular expression '%s': %s",
2062  pattern.c_str(), e.explain().c_str());
2063  }
2064 
2065  std::string path;
2066  std::vector<MonitorElement *> result;
2067  MEMap::const_iterator i = data_.begin();
2068  MEMap::const_iterator e = data_.end();
2069  for ( ; i != e; ++i)
2070  {
2071  path.clear();
2072  mergePath(path, *i->data_.dirname, i->data_.objname);
2073  if (rx.match(path))
2074  result.push_back(const_cast<MonitorElement *>(&*i));
2075  }
2076 
2077  return result;
2078 }
2079 
2083 
2086 void
2088 {
2089  MEMap::iterator mi = data_.begin();
2090  MEMap::iterator me = data_.end();
2091  for ( ; mi != me; ++mi)
2092  {
2093  MonitorElement &me = const_cast<MonitorElement &>(*mi);
2094  if (mi->wasUpdated())
2095  {
2096  if (me.resetMe())
2097  me.Reset();
2098  me.resetUpdate();
2099  }
2100  }
2101 
2102  reset_ = true;
2103 }
2104 
2108 
2110 void
2112 {
2113  MEMap::iterator mi = data_.begin();
2114  MEMap::iterator me = data_.end();
2115  for ( ; mi != me; ++mi)
2116  {
2117  if (forceResetOnBeginLumi_ && ((*mi).getLumiFlag() == false))
2118  continue;
2119  MonitorElement &me = const_cast<MonitorElement &>(*mi);
2120  me.Reset();
2121  me.resetUpdate();
2122  }
2123 
2124  reset_ = true;
2125 }
2126 
2130 
2134 void
2136 {
2137  if (!enableMultiThread_)
2138  return;
2139 
2140  std::lock_guard<std::mutex> guard(book_mutex_);
2141 
2142  std::string null_str("");
2143  MonitorElement proto(&null_str, null_str, run, 0, 0);
2144  proto.setLumi(lumi);
2145 
2146  std::set<MonitorElement>::const_iterator e = data_.end();
2147  std::set<MonitorElement>::const_iterator i = data_.lower_bound(proto);
2148 
2149  while (i != e) {
2150  if (i->data_.streamId != 0 ||
2151  i->data_.moduleId != 0)
2152  break;
2153  if (i->data_.lumi != lumi)
2154  break;
2155  if (i->data_.run != run)
2156  break;
2157 
2158  auto temp = i;
2159  ++i;
2160 
2161  if (verbose_ > 1) {
2162  std::cout << "DQMStore::deleteUnusedLumiHistograms: deleted monitor element '"
2163  << *i->data_.dirname << "/" << i->data_.objname << "'"
2164  << "flags " << i->data_.flags << "\n";
2165  }
2166 
2167  data_.erase(temp);
2168  }
2169 }
2170 
2176 bool
2178  bool overwrite, bool collateHistograms)
2179 {
2180  // NB: Profile histograms inherit from TH*D, checking order matters.
2181  MonitorElement *refcheck = 0;
2182  if (TProfile *h = dynamic_cast<TProfile *>(obj))
2183  {
2184  MonitorElement *me = findObject(dir, h->GetName());
2185  if (! me)
2186  me = bookProfile(dir, h->GetName(), (TProfile *) h->Clone());
2187  else if (overwrite)
2188  me->copyFrom(h);
2189  else if (isCollateME(me) || collateHistograms)
2190  collateProfile(me, h, verbose_);
2191  refcheck = me;
2192  }
2193  else if (TProfile2D *h = dynamic_cast<TProfile2D *>(obj))
2194  {
2195  MonitorElement *me = findObject(dir, h->GetName());
2196  if (! me)
2197  me = bookProfile2D(dir, h->GetName(), (TProfile2D *) h->Clone());
2198  else if (overwrite)
2199  me->copyFrom(h);
2200  else if (isCollateME(me) || collateHistograms)
2201  collateProfile2D(me, h, verbose_);
2202  refcheck = me;
2203  }
2204  else if (TH1F *h = dynamic_cast<TH1F *>(obj))
2205  {
2206  MonitorElement *me = findObject(dir, h->GetName());
2207  if (! me)
2208  me = book1D(dir, h->GetName(), (TH1F *) h->Clone());
2209  else if (overwrite)
2210  me->copyFrom(h);
2211  else if (isCollateME(me) || collateHistograms)
2212  collate1D(me, h, verbose_);
2213  refcheck = me;
2214  }
2215  else if (TH1S *h = dynamic_cast<TH1S *>(obj))
2216  {
2217  MonitorElement *me = findObject(dir, h->GetName());
2218  if (! me)
2219  me = book1S(dir, h->GetName(), (TH1S *) h->Clone());
2220  else if (overwrite)
2221  me->copyFrom(h);
2222  else if (isCollateME(me) || collateHistograms)
2223  collate1S(me, h, verbose_);
2224  refcheck = me;
2225  }
2226  else if (TH1D *h = dynamic_cast<TH1D *>(obj))
2227  {
2228  MonitorElement *me = findObject(dir, h->GetName());
2229  if (! me)
2230  me = book1DD(dir, h->GetName(), (TH1D *) h->Clone());
2231  else if (overwrite)
2232  me->copyFrom(h);
2233  else if (isCollateME(me) || collateHistograms)
2234  collate1DD(me, h, verbose_);
2235  refcheck = me;
2236  }
2237  else if (TH2F *h = dynamic_cast<TH2F *>(obj))
2238  {
2239  MonitorElement *me = findObject(dir, h->GetName());
2240  if (! me)
2241  me = book2D(dir, h->GetName(), (TH2F *) h->Clone());
2242  else if (overwrite)
2243  me->copyFrom(h);
2244  else if (isCollateME(me) || collateHistograms)
2245  collate2D(me, h, verbose_);
2246  refcheck = me;
2247  }
2248  else if (TH2S *h = dynamic_cast<TH2S *>(obj))
2249  {
2250  MonitorElement *me = findObject(dir, h->GetName());
2251  if (! me)
2252  me = book2S(dir, h->GetName(), (TH2S *) h->Clone());
2253  else if (overwrite)
2254  me->copyFrom(h);
2255  else if (isCollateME(me) || collateHistograms)
2256  collate2S(me, h, verbose_);
2257  refcheck = me;
2258  }
2259  else if (TH2D *h = dynamic_cast<TH2D *>(obj))
2260  {
2261  MonitorElement *me = findObject(dir, h->GetName());
2262  if (! me)
2263  me = book2DD(dir, h->GetName(), (TH2D *) h->Clone());
2264  else if (overwrite)
2265  me->copyFrom(h);
2266  else if (isCollateME(me) || collateHistograms)
2267  collate2DD(me, h, verbose_);
2268  refcheck = me;
2269  }
2270  else if (TH3F *h = dynamic_cast<TH3F *>(obj))
2271  {
2272  MonitorElement *me = findObject(dir, h->GetName());
2273  if (! me)
2274  me = book3D(dir, h->GetName(), (TH3F *) h->Clone());
2275  else if (overwrite)
2276  me->copyFrom(h);
2277  else if (isCollateME(me) || collateHistograms)
2278  collate3D(me, h, verbose_);
2279  refcheck = me;
2280  }
2281  else if (dynamic_cast<TObjString *>(obj))
2282  {
2283  lat::RegexpMatch m;
2284  if (! s_rxmeval.match(obj->GetName(), 0, 0, &m))
2285  {
2286  if (strstr(obj->GetName(), "CMSSW"))
2287  {
2288  if (verbose_)
2289  std::cout << "Input file version: " << obj->GetName() << std::endl;
2290  return true;
2291  }
2292  else if (strstr(obj->GetName(), "DQMPATCH"))
2293  {
2294  if (verbose_)
2295  std::cout << "DQM patch version: " << obj->GetName() << std::endl;
2296  return true;
2297  }
2298  else
2299  {
2300  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2301  << obj->GetName() << "' of type '"
2302  << obj->IsA()->GetName() << "'\n";
2303  return false;
2304  }
2305  }
2306 
2307  std::string label = m.matchString(obj->GetName(), 1);
2308  std::string kind = m.matchString(obj->GetName(), 2);
2309  std::string value = m.matchString(obj->GetName(), 3);
2310 
2311  if (kind == "i")
2312  {
2313  MonitorElement *me = findObject(dir, label);
2314  if (! me || overwrite)
2315  {
2316  if (! me) me = bookInt(dir, label);
2317  me->Fill(atoll(value.c_str()));
2318  }
2319  }
2320  else if (kind == "f")
2321  {
2322  MonitorElement *me = findObject(dir, label);
2323  if (! me || overwrite)
2324  {
2325  if (! me) me = bookFloat(dir, label);
2326  me->Fill(atof(value.c_str()));
2327  }
2328  }
2329  else if (kind == "s")
2330  {
2331  MonitorElement *me = findObject(dir, label);
2332  if (! me)
2333  me = bookString(dir, label, value);
2334  else if (overwrite)
2335  me->Fill(value);
2336  }
2337  else if (kind == "e")
2338  {
2339  MonitorElement *me = findObject(dir, label);
2340  if (! me)
2341  {
2342  std::cout << "*** DQMStore: WARNING: no monitor element '"
2343  << label << "' in directory '"
2344  << dir << "' to be marked as efficiency plot.\n";
2345  return false;
2346  }
2347  me->setEfficiencyFlag();
2348  }
2349  else if (kind == "t")
2350  {
2351  MonitorElement *me = findObject(dir, label);
2352  if (! me)
2353  {
2354  std::cout << "*** DQMStore: WARNING: no monitor element '"
2355  << label << "' in directory '"
2356  << dir << "' for a tag\n";
2357  return false;
2358  }
2359  errno = 0;
2360  char *endp = 0;
2361  unsigned long val = strtoul(value.c_str(), &endp, 10);
2362  if ((val == 0 && errno) || *endp || val > ~uint32_t(0))
2363  {
2364  std::cout << "*** DQMStore: WARNING: cannot restore tag '"
2365  << value << "' for monitor element '"
2366  << label << "' in directory '"
2367  << dir << "' - invalid value\n";
2368  return false;
2369  }
2370  tag(me, val);
2371  }
2372  else if (kind == "qr")
2373  {
2374  // Handle qreports, but skip them while reading in references.
2375  if (! isSubdirectory(s_referenceDirName, dir))
2376  {
2377  size_t dot = label.find('.');
2378  if (dot == std::string::npos)
2379  {
2380  std::cout << "*** DQMStore: WARNING: quality report label in '" << label
2381  << "' is missing a '.' and cannot be extracted\n";
2382  return false;
2383  }
2384 
2385  std::string mename (label, 0, dot);
2386  std::string qrname (label, dot+1, std::string::npos);
2387 
2388  m.reset();
2389  DQMNet::QValue qv;
2390  if (s_rxmeqr1.match(value, 0, 0, &m))
2391  {
2392  qv.code = atoi(m.matchString(value, 1).c_str());
2393  qv.qtresult = strtod(m.matchString(value, 2).c_str(), 0);
2394  qv.message = m.matchString(value, 4);
2395  qv.qtname = qrname;
2396  qv.algorithm = m.matchString(value, 3);
2397  }
2398  else if (s_rxmeqr2.match(value, 0, 0, &m))
2399  {
2400  qv.code = atoi(m.matchString(value, 1).c_str());
2401  qv.qtresult = 0; // unavailable in old format
2402  qv.message = m.matchString(value, 2);
2403  qv.qtname = qrname;
2404  // qv.algorithm unavailable in old format
2405  }
2406  else
2407  {
2408  std::cout << "*** DQMStore: WARNING: quality test value '"
2409  << value << "' is incorrectly formatted\n";
2410  return false;
2411  }
2412 
2413  MonitorElement *me = findObject(dir, mename);
2414  if (! me)
2415  {
2416  std::cout << "*** DQMStore: WARNING: no monitor element '"
2417  << mename << "' in directory '"
2418  << dir << "' for quality test '"
2419  << label << "'\n";
2420  return false;
2421  }
2422 
2423  me->addQReport(qv, /* FIXME: getQTest(qv.qtname)? */ 0);
2424  }
2425  }
2426  else
2427  {
2428  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2429  << obj->GetName() << "' of type '"
2430  << obj->IsA()->GetName() << "'\n";
2431  return false;
2432  }
2433  }
2434  else if (TNamed *n = dynamic_cast<TNamed *>(obj))
2435  {
2436  // For old DQM data.
2437  std::string s;
2438  s.reserve(6 + strlen(n->GetTitle()) + 2*strlen(n->GetName()));
2439  s += '<'; s += n->GetName(); s += '>';
2440  s += n->GetTitle();
2441  s += '<'; s += '/'; s += n->GetName(); s += '>';
2442  TObjString os(s.c_str());
2443  return extract(&os, dir, overwrite, collateHistograms_);
2444  }
2445  else
2446  {
2447  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2448  << obj->GetName() << "' of type '" << obj->IsA()->GetName()
2449  << "' and with title '" << obj->GetTitle() << "'\n";
2450  return false;
2451  }
2452 
2453  // If we just read in a reference MonitorElement, and there is a
2454  // MonitorElement with the same name, link the two together.
2455  // The other direction is handled by the book() method.
2456  if (refcheck && isSubdirectory(s_referenceDirName, dir))
2457  {
2458  std::string mdir(dir, s_referenceDirName.size()+1, std::string::npos);
2459  if (MonitorElement *master = findObject(mdir, obj->GetName()))
2460  {
2461  // We have extracted a MonitorElement, and it's located in the reference
2462  // dir. Then we find the corresponding MonitorElement in the
2463  // non-reference dir and assign the object_ of the reference
2464  // MonitorElement to the reference_ property of the corresponding
2465  // non-reference MonitorElement.
2466  master->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
2467  master->reference_ = refcheck->object_;
2468  }
2469  }
2470 
2471  return true;
2472 }
2473 
2477 bool
2479 {
2480  assert(! path.empty());
2481 
2482  // Find the first path component.
2483  size_t start = 0;
2484  size_t end = path.find('/', start);
2485  if (end == std::string::npos)
2486  end = path.size();
2487 
2488  while (true)
2489  {
2490  // Check if this subdirectory component exists. If yes, make sure
2491  // it is actually a subdirectory. Otherwise create or cd into it.
2492  std::string part(path, start, end-start);
2493  TObject *o = gDirectory->Get(part.c_str());
2494  if (o && ! dynamic_cast<TDirectory *>(o))
2495  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2496  " fails because the part '%s' already exists and is not"
2497  " directory", path.c_str(), part.c_str());
2498  else if (! o)
2499  gDirectory->mkdir(part.c_str());
2500 
2501  if (! gDirectory->cd(part.c_str()))
2502  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2503  " fails because could not cd into subdirectory '%s'",
2504  path.c_str(), part.c_str());
2505 
2506  // Stop if we reached the end, ignoring any trailing '/'.
2507  if (end+1 >= path.size())
2508  break;
2509 
2510  // Find the next path component.
2511  start = end+1;
2512  end = path.find('/', start);
2513  if (end == std::string::npos)
2514  end = path.size();
2515  }
2516 
2517  return true;
2518 }
2519 
2521  const std::string &path /* = "" */,
2522  const uint32_t run /* = 0 */,
2523  const uint32_t lumi /* = 0 */,
2524  const bool resetMEsAfterWriting /* = false */)
2525 {
2526  using google::protobuf::io::FileOutputStream;
2527  using google::protobuf::io::GzipOutputStream;
2528  using google::protobuf::io::StringOutputStream;
2529 
2530  std::lock_guard<std::mutex> guard(book_mutex_);
2531 
2532  std::set<std::string>::iterator di, de;
2533  MEMap::iterator mi, me = data_.end();
2534  dqmstorepb::ROOTFilePB dqmstore_message;
2535  int nme = 0;
2536 
2537  if (verbose_)
2538  std::cout << "\n DQMStore: Opening PBFile '"
2539  << filename << "'"<< std::endl;
2540 
2541  // Loop over the directory structure.
2542  for (di = dirs_.begin(), de = dirs_.end(); di != de; ++di)
2543  {
2544  // Check if we should process this directory. We process the
2545  // requested part of the object tree, including references.
2546  if (! path.empty()
2547  && ! isSubdirectory(path, *di))
2548  continue;
2549 
2550  // Loop over monitor elements in this directory.
2551  MonitorElement proto(&*di, std::string(), run, 0, 0);
2552  if (enableMultiThread_)
2553  proto.setLumi(lumi);
2554 
2555  mi = data_.lower_bound(proto);
2556  for ( ; mi != me && isSubdirectory(*di, *mi->data_.dirname); ++mi)
2557  {
2558  if (verbose_ > 1)
2559  std::cout << "Run: " << (*mi).run()
2560  << " Lumi: " << (*mi).lumi()
2561  << " LumiFlag: " << (*mi).getLumiFlag()
2562  << " streamId: " << (*mi).streamId()
2563  << " moduleId: " << (*mi).moduleId()
2564  << " fullpathname: " << (*mi).getFullname() << std::endl;
2565 
2566  // Upper bound in the loop over the MEs
2567  if (enableMultiThread_ && ((*mi).lumi() != lumi))
2568  break;
2569 
2570  // Skip if it isn't a direct child.
2571  if (*di != *mi->data_.dirname)
2572  continue;
2573 
2574  // Keep backward compatibility with the old way of
2575  // booking/handlind MonitorElements into the DQMStore. If run is
2576  // 0 it means that a booking happened w/ the old non-threadsafe
2577  // style, and we have to ignore the streamId and moduleId as a
2578  // consequence.
2579 
2580  if (run != 0 && (mi->data_.streamId !=0 || mi->data_.moduleId !=0))
2581  continue;
2582 
2583  if (verbose_ > 1)
2584  std::cout << "DQMStore::savePB: saving monitor element '"
2585  << *mi->data_.dirname << "/" << mi->data_.objname << "'"
2586  << "flags " << mi->data_.flags << "\n";
2587 
2588  nme++;
2589  dqmstorepb::ROOTFilePB::Histo* me = dqmstore_message.add_histo();
2590  me->set_full_pathname((*mi->data_.dirname) + '/' + mi->data_.objname);
2591  me->set_flags(mi->data_.flags);
2592 
2593  TObject *toWrite = nullptr;
2594  bool deleteObject = false;
2595 
2596  if (mi->kind() < MonitorElement::DQM_KIND_TH1F) {
2597  toWrite = new TObjString(mi->tagString().c_str());
2598  deleteObject = true;
2599  } else {
2600  toWrite = mi->object_;
2601  }
2602 
2603  TBufferFile buffer(TBufferFile::kWrite);
2604  buffer.WriteObject(toWrite);
2605  me->set_size(buffer.Length());
2606  me->set_streamed_histo((const void*)buffer.Buffer(),
2607  buffer.Length());
2608 
2609  if (deleteObject) {
2610  delete toWrite;
2611  }
2612 
2613  //reset the ME just written to make it available for the next LS (online)
2614  if (resetMEsAfterWriting)
2615  const_cast<MonitorElement*>(&*mi)->Reset();
2616  }
2617  }
2618 
2619  int filedescriptor = ::open(filename.c_str(),
2620  O_WRONLY | O_CREAT | O_TRUNC,
2621  S_IRUSR | S_IWUSR |
2622  S_IRGRP | S_IWGRP |
2623  S_IROTH);
2624  FileOutputStream file_stream(filedescriptor);
2626  options.format = GzipOutputStream::GZIP;
2627  options.compression_level = 1;
2628  GzipOutputStream gzip_stream(&file_stream,
2629  options);
2630  dqmstore_message.SerializeToZeroCopyStream(&gzip_stream);
2631 
2632  // we need to flush it before we close the fd
2633  gzip_stream.Close();
2634  file_stream.Close();
2635  ::close(filedescriptor);
2636 
2637  // Maybe make some noise.
2638  if (verbose_)
2639  std::cout << "DQMStore::savePB: successfully wrote " << nme
2640  << " objects from path '" << path
2641  << "' into DQM file '" << filename << "'\n";
2642 }
2643 
2644 
2649 void
2651  const std::string &path /* = "" */,
2652  const std::string &pattern /* = "" */,
2653  const std::string &rewrite /* = "" */,
2654  const uint32_t run /* = 0 */,
2655  const uint32_t lumi /* = 0 */,
2656  SaveReferenceTag ref /* = SaveWithReference */,
2657  int minStatus /* = dqm::qstatus::STATUS_OK */,
2658  const std::string &fileupdate /* = RECREATE */,
2659  const bool resetMEsAfterWriting /* = false */)
2660 {
2661  std::lock_guard<std::mutex> guard(book_mutex_);
2662 
2663  std::set<std::string>::iterator di, de;
2664  MEMap::iterator mi, me = data_.end();
2665  DQMNet::QReports::const_iterator qi, qe;
2666  int nme=0;
2667 
2668  // TFile flushes to disk with fsync() on every TDirectory written to
2669  // the file. This makes DQM file saving painfully slow, and
2670  // ironically makes it _more_ likely the file saving gets
2671  // interrupted and corrupts the file. The utility class below
2672  // simply ignores the flush synchronisation.
2673  class TFileNoSync : public TFile
2674  {
2675  public:
2676  TFileNoSync(const char *file, const char *opt) : TFile(file, opt) {}
2677  virtual Int_t SysSync(Int_t) override { return 0; }
2678  };
2679 
2680  // open output file, on 1st save recreate, later update
2681  if (verbose_)
2682  std::cout << "\n DQMStore: Opening TFile '" << filename
2683  << "' with option '" << fileupdate <<"'\n";
2684 
2685  TFileNoSync f(filename.c_str(), fileupdate.c_str()); // open file
2686  if(f.IsZombie())
2687  raiseDQMError("DQMStore", "Failed to create/update file '%s'", filename.c_str());
2688  f.cd();
2689 
2690  // Construct a regular expression from the pattern string.
2691  std::auto_ptr<lat::Regexp> rxpat;
2692  if (! pattern.empty())
2693  rxpat.reset(new lat::Regexp(pattern.c_str()));
2694 
2695  // Prepare a path for the reference object selection.
2696  std::string refpath;
2697  refpath.reserve(s_referenceDirName.size() + path.size() + 2);
2698  refpath += s_referenceDirName;
2699  if (! path.empty())
2700  {
2701  refpath += '/';
2702  refpath += path;
2703  }
2704 
2705  // Loop over the directory structure.
2706  for (di = dirs_.begin(), de = dirs_.end(); di != de; ++di)
2707  {
2708  // Check if we should process this directory. We process the
2709  // requested part of the object tree, including references.
2710  if (! path.empty()
2711  && ! isSubdirectory(path, *di)
2712  && ! isSubdirectory(refpath, *di))
2713  continue;
2714 
2715  // Loop over monitor elements in this directory.
2716  MonitorElement proto(&*di, std::string(), run, 0, 0);
2717  if (enableMultiThread_)
2718  proto.setLumi(lumi);
2719 
2720  mi = data_.lower_bound(proto);
2721  for ( ; mi != me && isSubdirectory(*di, *mi->data_.dirname); ++mi)
2722  {
2723  if (verbose_ > 1)
2724  std::cout << "DQMStore::save: Run: " << (*mi).run()
2725  << " Lumi: " << (*mi).lumi()
2726  << " LumiFlag: " << (*mi).getLumiFlag()
2727  << " streamId: " << (*mi).streamId()
2728  << " moduleId: " << (*mi).moduleId()
2729  << " fullpathname: " << (*mi).getFullname() << std::endl;
2730 
2731  // Upper bound in the loop over the MEs
2732  if (enableMultiThread_ && ((*mi).lumi() != lumi))
2733  break;
2734 
2735  // Skip if it isn't a direct child.
2736  if (*di != *mi->data_.dirname) {
2737  if (verbose_ > 1)
2738  std::cout << "DQMStore::save: isn't a direct child. Skipping" << std::endl;
2739  continue;
2740  }
2741 
2742  // Keep backward compatibility with the old way of
2743  // booking/handlind MonitorElements into the DQMStore. If run is
2744  // 0 it means that a booking happened w/ the old non-threadsafe
2745  // style, and we have to ignore the streamId and moduleId as a
2746  // consequence.
2747 
2748  if (run != 0 && (mi->data_.streamId !=0 || mi->data_.moduleId !=0)) {
2749  continue;
2750  }
2751 
2752  // Handle reference histograms, with three distinct cases:
2753  // 1) Skip all references entirely on saving.
2754  // 2) Blanket saving of all references.
2755  // 3) Save only references for monitor elements with qtests.
2756  // The latter two are affected by "path" sub-tree selection,
2757  // i.e. references are saved only in the selected tree part.
2758  if (isSubdirectory(refpath, *mi->data_.dirname))
2759  {
2760  if (ref == SaveWithoutReference)
2761  // Skip the reference entirely.
2762  continue;
2763  else if (ref == SaveWithReference)
2764  // Save all references regardless of qtests.
2765  ;
2766  else if (ref == SaveWithReferenceForQTest)
2767  {
2768  // Save only references for monitor elements with qtests
2769  // with an optional cut on minimum quality test result.
2770  int status = -1;
2771  std::string mname(mi->getFullname(), s_referenceDirName.size()+1, std::string::npos);
2772  MonitorElement *master = get(mname);
2773  if (master)
2774  for (size_t i = 0, e = master->data_.qreports.size(); i != e; ++i)
2775  status = std::max(status, master->data_.qreports[i].code);
2776 
2777  if (! master || status < minStatus)
2778  {
2779  if (verbose_ > 1)
2780  std::cout << "DQMStore::save: skipping monitor element '"
2781  << mi->data_.objname << "' while saving, status is "
2782  << status << ", required minimum status is "
2783  << minStatus << std::endl;
2784  continue;
2785  }
2786  }
2787  }
2788 
2789  if (verbose_ > 1)
2790  std::cout << "DQMStore::save: saving monitor element '"
2791  << mi->data_.objname << "'\n";
2792  nme++; // count saved histograms
2793 
2794  // Create the directory.
2795  gDirectory->cd("/");
2796  if (di->empty())
2798  else if (rxpat.get())
2799  cdInto(s_monitorDirName + '/' + lat::StringOps::replace(*di, *rxpat, rewrite));
2800  else
2801  cdInto(s_monitorDirName + '/' + *di);
2802 
2803  // Save the object.
2804  switch (mi->kind())
2805  {
2809  TObjString(mi->tagString().c_str()).Write();
2810  break;
2811 
2812  default:
2813  mi->object_->Write();
2814  break;
2815  }
2816 
2817  // Save quality reports if this is not in reference section.
2818  if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
2819  {
2820  qi = mi->data_.qreports.begin();
2821  qe = mi->data_.qreports.end();
2822  for ( ; qi != qe; ++qi)
2823  TObjString(mi->qualityTagString(*qi).c_str()).Write();
2824  }
2825 
2826  // Save efficiency tag, if any
2827  if (mi->data_.flags & DQMNet::DQM_PROP_EFFICIENCY_PLOT)
2828  TObjString(mi->effLabelString().c_str()).Write();
2829 
2830  // Save tag if any
2831  if (mi->data_.flags & DQMNet::DQM_PROP_TAGGED)
2832  TObjString(mi->tagLabelString().c_str()).Write();
2833 
2834  //reset the ME just written to make it available for the next LS (online)
2835  if (resetMEsAfterWriting)
2836  const_cast<MonitorElement*>(&*mi)->Reset();
2837  }
2838  }
2839 
2840  f.Close();
2841 
2842  // Maybe make some noise.
2843  if (verbose_)
2844  std::cout << "DQMStore::save: successfully wrote " << nme
2845  << " objects from path '" << path
2846  << "' into DQM file '" << filename << "'\n";
2847 }
2848 
2851 unsigned int
2853  bool overwrite,
2854  const std::string &onlypath,
2855  const std::string &prepend,
2856  const std::string &curdir,
2857  OpenRunDirs stripdirs)
2858 {
2859  unsigned int ntot = 0;
2860  unsigned int count = 0;
2861 
2862  if (! file->cd(curdir.c_str()))
2863  raiseDQMError("DQMStore", "Failed to process directory '%s' while"
2864  " reading file '%s'", curdir.c_str(), file->GetName());
2865 
2866  // Figure out current directory name, but strip out the top
2867  // directory into which we dump everything.
2868  std::string dirpart = curdir;
2869  if (dirpart.compare(0, s_monitorDirName.size(), s_monitorDirName) == 0)
2870  {
2871  if (dirpart.size() == s_monitorDirName.size())
2872  dirpart.clear();
2873  else if (dirpart[s_monitorDirName.size()] == '/')
2874  dirpart.erase(0, s_monitorDirName.size()+1);
2875  }
2876 
2877  // See if we are going to skip this directory.
2878  bool skip = (! onlypath.empty() && ! isSubdirectory(onlypath, dirpart));
2879 
2880  if (prepend == s_collateDirName ||
2881  prepend == s_referenceDirName ||
2882  stripdirs == StripRunDirs )
2883  {
2884  // Remove Run # and RunSummary dirs
2885  // first look for Run summary,
2886  // if that is found and erased, also erase Run dir
2887  size_t slash = dirpart.find('/');
2888  size_t pos = dirpart.find("/Run summary");
2889  if (slash != std::string::npos && pos !=std::string::npos)
2890  {
2891  dirpart.erase(pos,12);
2892 
2893  pos = dirpart.find("Run ");
2894  size_t length = dirpart.find('/',pos+1)-pos+1;
2895  if (pos !=std::string::npos)
2896  dirpart.erase(pos,length);
2897  }
2898  }
2899 
2900  // If we are prepending, add it to the directory name,
2901  // and suppress reading of already existing reference histograms
2902  if (prepend == s_collateDirName ||
2903  prepend == s_referenceDirName)
2904  {
2905  size_t slash = dirpart.find('/');
2906  // If we are reading reference, skip previous reference.
2907  if (slash == std::string::npos // skip if Reference is toplevel folder, i.e. no slash
2908  && slash+1+s_referenceDirName.size() == dirpart.size()
2909  && dirpart.compare(slash+1, s_referenceDirName.size(), s_referenceDirName) == 0)
2910  return 0;
2911 
2912  slash = dirpart.find('/');
2913  // Skip reading of EventInfo subdirectory.
2914  if (slash != std::string::npos
2915  && slash + 10 == dirpart.size()
2916  && dirpart.compare( slash+1 , 9 , "EventInfo") == 0) {
2917  if (verbose_)
2918  std::cout << "DQMStore::readDirectory: skipping '" << dirpart << "'\n";
2919  return 0;
2920  }
2921 
2922  // Add prefix.
2923  if (dirpart.empty())
2924  dirpart = prepend;
2925  else
2926  dirpart = prepend + '/' + dirpart;
2927  }
2928  else if (! prepend.empty())
2929  {
2930  if (dirpart.empty())
2931  dirpart = prepend;
2932  else
2933  dirpart = prepend + '/' + dirpart;
2934  }
2935 
2936  // Loop over the contents of this directory in the file.
2937  // Post-pone string object handling to happen after other
2938  // objects have been read in so we are guaranteed to have
2939  // histograms by the time we read in quality tests and tags.
2940  TKey *key;
2941  TIter next (gDirectory->GetListOfKeys());
2942  std::list<TObject *> delayed;
2943  while ((key = (TKey *) next()))
2944  {
2945  std::auto_ptr<TObject> obj(key->ReadObj());
2946  if (dynamic_cast<TDirectory *>(obj.get()))
2947  {
2948  std::string subdir;
2949  subdir.reserve(curdir.size() + strlen(obj->GetName()) + 2);
2950  subdir += curdir;
2951  if (! curdir.empty())
2952  subdir += '/';
2953  subdir += obj->GetName();
2954 
2955  ntot += readDirectory(file, overwrite, onlypath, prepend, subdir, stripdirs);
2956  }
2957  else if (skip)
2958  ;
2959  else if (dynamic_cast<TObjString *>(obj.get()))
2960  {
2961  delayed.push_back(obj.release());
2962  }
2963  else
2964  {
2965  if (verbose_ > 2)
2966  std::cout << "DQMStore: reading object '" << obj->GetName()
2967  << "' of type '" << obj->IsA()->GetName()
2968  << "' from '" << file->GetName()
2969  << "' into '" << dirpart << "'\n";
2970 
2971  makeDirectory(dirpart);
2972  if (extract(obj.get(), dirpart, overwrite, collateHistograms_))
2973  ++count;
2974  }
2975  }
2976 
2977  while (! delayed.empty())
2978  {
2979  if (verbose_ > 2)
2980  std::cout << "DQMStore: reading object '" << delayed.front()->GetName()
2981  << "' of type '" << delayed.front()->IsA()->GetName()
2982  << "' from '" << file->GetName()
2983  << "' into '" << dirpart << "'\n";
2984 
2985  makeDirectory(dirpart);
2986  if (extract(delayed.front(), dirpart, overwrite, collateHistograms_))
2987  ++count;
2988 
2989  delete delayed.front();
2990  delayed.pop_front();
2991  }
2992 
2993  if (verbose_ > 1)
2994  std::cout << "DQMStore: read " << count << '/' << ntot
2995  << " objects from directory '" << dirpart << "'\n";
2996 
2997  return ntot + count;
2998 }
2999 
3006 bool
3008  bool overwrite /* = false */,
3009  const std::string &onlypath /* ="" */,
3010  const std::string &prepend /* ="" */,
3011  OpenRunDirs stripdirs /* =KeepRunDirs */,
3012  bool fileMustExist /* =true */)
3013 {
3014  return readFile(filename,overwrite,onlypath,prepend,stripdirs,fileMustExist);
3015 }
3016 
3021 bool
3023  OpenRunDirs stripdirs /* =StripRunDirs */,
3024  bool fileMustExist /* =true */)
3025 {
3026  bool overwrite = true;
3027  if (collateHistograms_) overwrite = false;
3028  if (verbose_)
3029  {
3030  std::cout << "DQMStore::load: reading from file '" << filename << "'\n";
3031  if (collateHistograms_)
3032  std::cout << "DQMStore::load: in collate mode " << "\n";
3033  else
3034  std::cout << "DQMStore::load: in overwrite mode " << "\n";
3035  }
3036 
3037  if (!s_rxpbfile.match(filename, 0, 0))
3038  return readFile(filename, overwrite, "", "", stripdirs, fileMustExist);
3039  else
3040  return readFilePB(filename, overwrite, "", "", stripdirs, fileMustExist);
3041 }
3042 
3048 bool
3050  bool overwrite /* = false */,
3051  const std::string &onlypath /* ="" */,
3052  const std::string &prepend /* ="" */,
3053  OpenRunDirs stripdirs /* =StripRunDirs */,
3054  bool fileMustExist /* =true */)
3055 {
3056 
3057  if (verbose_)
3058  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
3059 
3060  std::auto_ptr<TFile> f;
3061 
3062  try
3063  {
3064  f.reset(TFile::Open(filename.c_str()));
3065  if (! f.get() || f->IsZombie())
3066  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
3067  }
3068  catch (std::exception &)
3069  {
3070  if (fileMustExist)
3071  throw;
3072  else
3073  {
3074  if (verbose_)
3075  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
3076  return false;
3077  }
3078  }
3079 
3080  unsigned n = readDirectory(f.get(), overwrite, onlypath, prepend, "", stripdirs);
3081  f->Close();
3082 
3083  MEMap::iterator mi = data_.begin();
3084  MEMap::iterator me = data_.end();
3085  for ( ; mi != me; ++mi)
3086  const_cast<MonitorElement &>(*mi).updateQReportStats();
3087 
3088  if (verbose_)
3089  {
3090  std::cout << "DQMStore::open: successfully read " << n
3091  << " objects from file '" << filename << "'";
3092  if (! onlypath.empty())
3093  std::cout << " from directory '" << onlypath << "'";
3094  if (! prepend.empty())
3095  std::cout << " into directory '" << prepend << "'";
3096  std::cout << std::endl;
3097  }
3098  return true;
3099 }
3100 
3104 inline TObject * DQMStore::extractNextObject(TBufferFile &buf) const {
3105  if (buf.Length() == buf.BufferSize())
3106  return 0;
3107  buf.InitMap();
3108  void *ptr = buf.ReadObjectAny(0);
3109  return reinterpret_cast<TObject *>(ptr);
3110 }
3111 
3114  std::string &objname,
3115  TObject ** obj) {
3116 
3117  size_t slash = h.full_pathname().rfind('/');
3118  size_t dirpos = (slash == std::string::npos ? 0 : slash);
3119  size_t namepos = (slash == std::string::npos ? 0 : slash+1);
3120  dirname.assign(h.full_pathname(), 0, dirpos);
3121  objname.assign(h.full_pathname(), namepos, std::string::npos);
3122  TBufferFile buf(TBufferFile::kRead, h.size(),
3123  (void*)h.streamed_histo().data(),
3124  kFALSE);
3125  buf.Reset();
3126  *obj = extractNextObject(buf);
3127  if (!*obj) {
3128  raiseDQMError("DQMStore", "Error reading element:'%s'" , h.full_pathname().c_str());
3129  }
3130 }
3131 
3132 bool
3134  bool overwrite /* = false */,
3135  const std::string &onlypath /* ="" */,
3136  const std::string &prepend /* ="" */,
3137  OpenRunDirs stripdirs /* =StripRunDirs */,
3138  bool fileMustExist /* =true */)
3139 {
3140  using google::protobuf::io::FileInputStream;
3141  using google::protobuf::io::FileOutputStream;
3142  using google::protobuf::io::GzipInputStream;
3143  using google::protobuf::io::GzipOutputStream;
3144  using google::protobuf::io::CodedInputStream;
3145  using google::protobuf::io::ArrayInputStream;
3146 
3147  if (verbose_)
3148  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
3149 
3150  int filedescriptor;
3151  if ((filedescriptor = ::open(filename.c_str(), O_RDONLY)) == -1) {
3152  if (fileMustExist)
3153  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
3154  else
3155  if (verbose_)
3156  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
3157  return false;
3158  }
3159 
3160  dqmstorepb::ROOTFilePB dqmstore_message;
3161  FileInputStream fin(filedescriptor);
3162  GzipInputStream input(&fin);
3163  CodedInputStream input_coded(&input);
3164  input_coded.SetTotalBytesLimit(1024*1024*1024, -1);
3165  if (!dqmstore_message.ParseFromCodedStream(&input_coded)) {
3166  raiseDQMError("DQMStore", "Fatal parsing file '%s'", filename.c_str());
3167  return false;
3168  }
3169  ::close(filedescriptor);
3170 
3171  for (int i = 0; i < dqmstore_message.histo_size(); i++) {
3172  std::string path;
3173  std::string objname;
3174 
3175  TObject *obj = NULL;
3176  const dqmstorepb::ROOTFilePB::Histo &h = dqmstore_message.histo(i);
3177  get_info(h, path, objname, &obj);
3178 
3179  setCurrentFolder(path);
3180  if (obj)
3181  {
3182  /* Before calling the extract() check if histogram exists:
3183  * if it does - flags for the given monitor are already set (and merged)
3184  * else - set the flags after the histogram is created.
3185  */
3186  MonitorElement *me = findObject(path, objname);
3187 
3188  /* Run histograms should be collated and not overwritten,
3189  * Lumi histograms should be overwritten (and collate flag is not checked)
3190  */
3191  bool overwrite = h.flags() & DQMNet::DQM_PROP_LUMI;
3192  bool collate = !(h.flags() & DQMNet::DQM_PROP_LUMI);
3193  extract(static_cast<TObject *>(obj), path, overwrite, collate);
3194 
3195  if (me == nullptr) {
3196  me = findObject(path, objname);
3197  me->data_.flags = h.flags();
3198  }
3199 
3200  delete obj;
3201  }
3202  }
3203 
3204  cd();
3205  return true;
3206 }
3207 
3213 void
3215 {
3217  const std::string *cleaned = 0;
3218  cleanTrailingSlashes(path, clean, cleaned);
3219  MonitorElement proto(cleaned, std::string());
3220 
3221  MEMap::iterator e = data_.end();
3222  MEMap::iterator i = data_.lower_bound(proto);
3223  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
3224  data_.erase(i++);
3225 
3226  std::set<std::string>::iterator de = dirs_.end();
3227  std::set<std::string>::iterator di = dirs_.lower_bound(*cleaned);
3228  while (di != de && isSubdirectory(*cleaned, *di))
3229  dirs_.erase(di++);
3230 }
3231 
3233 void
3235 {
3236  MonitorElement proto(&dir, std::string());
3237  MEMap::iterator e = data_.end();
3238  MEMap::iterator i = data_.lower_bound(proto);
3239  while (i != e && isSubdirectory(dir, *i->data_.dirname))
3240  if (dir == *i->data_.dirname)
3241  data_.erase(i++);
3242  else
3243  ++i;
3244 }
3245 
3247 void
3249 {
3251 }
3252 
3255 void
3257 {
3258  removeElement(pwd_, name);
3259 }
3260 
3263 void
3264 DQMStore::removeElement(const std::string &dir, const std::string &name, bool warning /* = true */)
3265 {
3266  MonitorElement proto(&dir, name);
3267  MEMap::iterator pos = data_.find(proto);
3268  if (pos != data_.end())
3269  data_.erase(pos);
3270  else if (warning)
3271  std::cout << "DQMStore: WARNING: attempt to remove non-existent"
3272  << " monitor element '" << name << "' in '" << dir << "'\n";
3273 }
3274 
3280 QCriterion *
3282 {
3283  QCMap::const_iterator i = qtests_.find(qtname);
3284  QCMap::const_iterator e = qtests_.end();
3285  return (i == e ? 0 : i->second);
3286 }
3287 
3291 QCriterion *
3293 {
3294  if (qtests_.count(qtname))
3295  raiseDQMError("DQMStore", "Attempt to create duplicate quality test '%s'",
3296  qtname.c_str());
3297 
3298  QAMap::iterator i = qalgos_.find(algoname);
3299  if (i == qalgos_.end())
3300  raiseDQMError("DQMStore", "Cannot create a quality test using unknown"
3301  " algorithm '%s'", algoname.c_str());
3302 
3303  QCriterion *qc = i->second(qtname);
3304  qc->setVerbose(verboseQT_);
3305 
3306  qtests_[qtname] = qc;
3307  return qc;
3308 }
3309 
3312 void
3314 {
3315  // Clean the path
3317  const std::string *cleaned = 0;
3318  cleanTrailingSlashes(dir, clean, cleaned);
3319 
3320  // Validate the path.
3321  if (cleaned->find_first_not_of(s_safe) != std::string::npos)
3322  raiseDQMError("DQMStore", "Monitor element path name '%s'"
3323  " uses unacceptable characters", cleaned->c_str());
3324 
3325  // Redirect to the pattern match version.
3326  useQTestByMatch(*cleaned + "/*", qtname);
3327 }
3328 
3330 int
3332 {
3333  QCriterion *qc = getQCriterion(qtname);
3334  if (! qc)
3335  raiseDQMError("DQMStore", "Cannot apply non-existent quality test '%s'",
3336  qtname.c_str());
3337 
3338  fastmatch * fm = new fastmatch( pattern );
3339 
3340  // Record the test for future reference.
3341  QTestSpec qts(fm, qc);
3342  qtestspecs_.push_back(qts);
3343 
3344  // Apply the quality test.
3345  MEMap::iterator mi = data_.begin();
3346  MEMap::iterator me = data_.end();
3347  std::string path;
3348  int cases = 0;
3349  for ( ; mi != me; ++mi)
3350  {
3351  path.clear();
3352  mergePath(path, *mi->data_.dirname, mi->data_.objname);
3353  if (fm->match(path))
3354  {
3355  ++cases;
3356  const_cast<MonitorElement &>(*mi).addQReport(qts.second);
3357  }
3358  }
3359 
3360  //return the number of matched cases
3361  return cases;
3362 }
3365 void
3367 {
3368 
3369  if (verbose_ > 0)
3370  std::cout << "DQMStore: running runQTests() with reset = "
3371  << ( reset_ ? "true" : "false" ) << std::endl;
3372 
3373  // Apply quality tests to each monitor element, skipping references.
3374  MEMap::iterator mi = data_.begin();
3375  MEMap::iterator me = data_.end();
3376  for ( ; mi != me; ++mi)
3377  if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
3378  const_cast<MonitorElement &>(*mi).runQTests();
3379 
3380  reset_ = false;
3381 }
3382 
3386 int
3387 DQMStore::getStatus(const std::string &path /* = "" */) const
3388 {
3390  const std::string *cleaned = 0;
3391  cleanTrailingSlashes(path, clean, cleaned);
3392 
3394  MEMap::const_iterator mi = data_.begin();
3395  MEMap::const_iterator me = data_.end();
3396  for ( ; mi != me; ++mi)
3397  {
3398  if (! cleaned->empty() && ! isSubdirectory(*cleaned, *mi->data_.dirname))
3399  continue;
3400 
3401  if (mi->hasError())
3402  return dqm::qstatus::ERROR;
3403  else if (mi->hasWarning())
3404  status = dqm::qstatus::WARNING;
3405  else if (status < dqm::qstatus::WARNING
3406  && mi->hasOtherReport())
3407  status = dqm::qstatus::OTHER;
3408  }
3409  return status;
3410 }
3411 
3417 void
3419 {
3420  if (me)
3421  me->softReset();
3422 }
3423 
3424 // reverts action of softReset
3425 void
3427 {
3428  if (me)
3429  me->disableSoftReset();
3430 }
3431 
3434 void
3436 {
3437  if (me)
3438  me->setAccumulate(flag);
3439 }
3440 
3444 void
3446 {
3447  std::vector<std::string> contents;
3448  getContents(contents);
3449 
3450  std::cout << " ------------------------------------------------------------\n"
3451  << " Directory structure: \n"
3452  << " ------------------------------------------------------------\n";
3453 
3454  std::copy(contents.begin(), contents.end(),
3455  std::ostream_iterator<std::string>(std::cout, "\n"));
3456 
3457  std::cout << " ------------------------------------------------------------\n";
3458 }
3459 
3463 // check if the collate option is active on the DQMStore
3464 bool
3466 {
3467  return collateHistograms_;
3468 }
3472 // check if the monitor element is in auto-collation folder
3473 bool
3475 { return me && isSubdirectory(s_collateDirName, *me->data_.dirname); }
3479 
3481 void
3483 {
3484  if (scaleFlag_ == 0.0) return;
3485  if (verbose_ > 0)
3486  std::cout << " =========== " << " ScaleFlag " << scaleFlag_ << std::endl;
3487  double factor = scaleFlag_;
3488  int events = 1;
3489  if (dirExists("Info/EventInfo")) {
3490  if ( scaleFlag_ == -1.0) {
3491  MonitorElement * scale_me = get("Info/EventInfo/ScaleFactor");
3492  if (scale_me && scale_me->kind()==MonitorElement::DQM_KIND_REAL) factor = scale_me->getFloatValue();
3493  }
3494  MonitorElement * event_me = get("Info/EventInfo/processedEvents");
3495  if (event_me && event_me->kind()==MonitorElement::DQM_KIND_INT) events = event_me->getIntValue();
3496  }
3497  factor = factor/(events*1.0);
3498 
3499  MEMap::iterator mi = data_.begin();
3500  MEMap::iterator me = data_.end();
3501  for ( ; mi != me; ++mi)
3502  {
3503  MonitorElement &me = const_cast<MonitorElement &>(*mi);
3504  switch (me.kind())
3505  {
3507  {
3508  me.getTH1F()->Scale(factor);
3509  break;
3510  }
3512  {
3513  me.getTH1S()->Scale(factor);
3514  break;
3515  }
3517  {
3518  me.getTH1D()->Scale(factor);
3519  break;
3520  }
3522  {
3523  me.getTH2F()->Scale(factor);
3524  break;
3525  }
3527  {
3528  me.getTH2S()->Scale(factor);
3529  break;
3530  }
3532  {
3533  me.getTH2D()->Scale(factor);
3534  break;
3535  }
3537  {
3538  me.getTH3F()->Scale(factor);
3539  break;
3540  }
3542  {
3543  me.getTProfile()->Scale(factor);
3544  break;
3545  }
3547  {
3548  me.getTProfile2D()->Scale(factor);
3549  break;
3550  }
3551  default:
3552  if (verbose_ > 0)
3553  std::cout << " The DQM object '" << me.getFullname() << "' is not scalable object " << std::endl;
3554  continue;
3555  }
3556  }
3557 }
QCriterion * getQCriterion(const std::string &qtname) const
Definition: DQMStore.cc:3281
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:1779
uint32_t moduleId
Definition: DQMNet.h:105
::google::protobuf::uint32 size() const
bool isCollateME(MonitorElement *me) const
Definition: DQMStore.cc:3474
void resetUpdate(void)
reset "was updated" flag
bool cdInto(const std::string &path) const
Definition: DQMStore.cc:2478
const ::std::string & full_pathname() const
void cd(void)
Definition: DQMStore.cc:339
int getStatus(const std::string &path="") const
Definition: DQMStore.cc:3387
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:1740
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:3214
static void collate3D(MonitorElement *me, TH3F *h, unsigned verbose)
Definition: DQMStore.cc:1644
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:3049
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:1919
static void collateProfile(MonitorElement *me, TProfile *h, unsigned verbose)
Definition: DQMStore.cc:1651
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:1297
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:1637
std::vector< MonitorElement * > getMatchingContents(const std::string &pattern, lat::Regexp::Syntax syntaxType=lat::Regexp::Wildcard) const
Definition: DQMStore.cc:2051
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:1675
~DQMStore(void)
Definition: DQMStore.cc:565
void disableSoftReset(MonitorElement *me)
Definition: DQMStore.cc:3426
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:2111
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:2002
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:3248
QTestSpecs qtestspecs_
Definition: DQMStore.h:719
double scaleFlag_
Definition: DQMStore.h:702
void deleteUnusedLumiHistograms(uint32_t run, uint32_t lumi)
Definition: DQMStore.cc:2135
void get_info(const dqmstorepb::ROOTFilePB_Histo &, std::string &dirname, std::string &objname, TObject **obj)
Definition: DQMStore.cc:3112
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:3465
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:3256
void addProfiles(TProfile *h1, TProfile *h2, TProfile *sum, float c1, float c2)
static void collateProfile2D(MonitorElement *me, TProfile2D *h, unsigned verbose)
Definition: DQMStore.cc:1661
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:1349
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:3418
std::string pwd_
Definition: DQMStore.h:713
Kind kind(void) const
Get the type of the monitor element.
void runQTests(void)
Definition: DQMStore.cc:3366
TObject * extractNextObject(TBufferFile &) const
Definition: DQMStore.cc:3104
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:1789
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:1818
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:2520
void getAllTags(std::vector< std::string > &into) const
Definition: DQMStore.cc:1949
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:3022
void scaleElements(void)
Definition: DQMStore.cc:3482
~fastmatch()
Definition: DQMStore.cc:202
static void collate1DD(MonitorElement *me, TH1D *h, unsigned verbose)
Definition: DQMStore.cc:1616
void tagAllContents(const std::string &path, unsigned int myTag)
Definition: DQMStore.cc:1718
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:3331
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:1602
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:1763
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:2852
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:2177
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:1706
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:2650
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:3133
TProfile * getTProfile(void) const
void useQTest(const std::string &dir, const std::string &qtname)
Definition: DQMStore.cc:3313
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:3007
::google::protobuf::uint32 flags() const
static const int STATUS_OK
void setAccumulate(MonitorElement *me, bool flag)
Definition: DQMStore.cc:3435
void setEfficiencyFlag(void)
static void collate1S(MonitorElement *me, TH1S *h, unsigned verbose)
Definition: DQMStore.cc:1609
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:3292
static bool checkBinningMatches(MonitorElement *me, TH1 *h, unsigned verbose)
Definition: DQMStore.cc:1575
dbl *** dir
Definition: mlp_gen.cc:35
void showDirStructure(void) const
Definition: DQMStore.cc:3445
void reset(void)
Definition: DQMStore.cc:2087
TH2F * getTH2F(void) const
static void collate2D(MonitorElement *me, TH2F *h, unsigned verbose)
Definition: DQMStore.cc:1623
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:1630
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:1493
void raiseDQMError(const char *context, const char *fmt,...)
Definition: DQMError.cc:11