CMS 3D CMS Logo

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