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  // make the ME reusable for the next LS
435  const_cast<MonitorElement*>(&*i)->Reset();
436  ++i;
437 
438  // check and remove the global lumi based histo belonging to the previous LSs
439  // if properly flagged as DQMNet::DQM_PROP_MARKTODELETE
440  global_me.setLumi(1);
441  std::set<MonitorElement>::const_iterator i_lumi = data_.lower_bound(global_me);
442  while (i_lumi->data_.lumi != lumi) {
443  auto temp = i_lumi++;
444  if (i_lumi->getFullname() == i->getFullname() && i_lumi->markedToDelete())
445  {
446  data_.erase(temp);
447  }
448  }
449  }
450 }
451 
454  : verbose_ (1),
455  verboseQT_ (1),
456  reset_ (false),
461  run_(0),
462  streamId_(0),
463  moduleId_(0),
464  pwd_ (""),
465  ibooker_(0),
466  igetter_(0)
467 {
468  if (!ibooker_)
469  ibooker_ = new DQMStore::IBooker(this);
470  if (!igetter_)
471  igetter_ = new DQMStore::IGetter(this);
472  initializeFrom(pset);
473 
474  if(pset.getUntrackedParameter<bool>("forceResetOnBeginRun",false)) {
476  }
477  ar.preallocateSignal_.connect([this](edm::service::SystemBounds const& iBounds) {
478  if(iBounds.maxNumberOfStreams() > 1 ) {
479  enableMultiThread_ = true;
480  }
481  });
482  if(pset.getUntrackedParameter<bool>("forceResetOnBeginLumi",false) && enableMultiThread_ == false) {
483  forceResetOnBeginLumi_ = true;
485  }
486 }
487 
489  : verbose_ (1),
490  verboseQT_ (1),
491  reset_ (false),
492  collateHistograms_ (false),
493  enableMultiThread_(false),
494  readSelectedDirectory_ (""),
495  run_(0),
496  streamId_(0),
497  moduleId_(0),
498  pwd_ (""),
499  ibooker_(0),
500  igetter_(0)
501 {
502  if (!ibooker_)
503  ibooker_ = new DQMStore::IBooker(this);
504  if (!igetter_)
505  igetter_ = new DQMStore::IGetter(this);
506  initializeFrom(pset);
507 }
508 
510 {
511  for (QCMap::iterator i = qtests_.begin(), e = qtests_.end(); i != e; ++i)
512  delete i->second;
513 
514  for (QTestSpecs::iterator i = qtestspecs_.begin(), e = qtestspecs_.end(); i != e; ++i)
515  delete i->first;
516 
517 }
518 
519 void
521  makeDirectory("");
522  reset();
523 
524  // set steerable parameters
525  verbose_ = pset.getUntrackedParameter<int>("verbose", 0);
526  if (verbose_ > 0)
527  std::cout << "DQMStore: verbosity set to " << verbose_ << std::endl;
528 
529  verboseQT_ = pset.getUntrackedParameter<int>("verboseQT", 0);
530  if (verbose_ > 0)
531  std::cout << "DQMStore: QTest verbosity set to " << verboseQT_ << std::endl;
532 
533  collateHistograms_ = pset.getUntrackedParameter<bool>("collateHistograms", false);
534  if (collateHistograms_)
535  std::cout << "DQMStore: histogram collation is enabled\n";
536 
537  enableMultiThread_ = pset.getUntrackedParameter<bool>("enableMultiThread", false);
538  if (enableMultiThread_)
539  std::cout << "DQMStore: MultiThread option is enabled\n";
540 
541  LSbasedMode_ = pset.getUntrackedParameter<bool>("LSbasedMode", false);
542  if (LSbasedMode_)
543  std::cout << "DQMStore: LSbasedMode option is enabled\n";
544 
545  std::string ref = pset.getUntrackedParameter<std::string>("referenceFileName", "");
546  if (! ref.empty())
547  {
548  std::cout << "DQMStore: using reference file '" << ref << "'\n";
549  readFile(ref, true, "", s_referenceDirName, StripRunDirs, false);
550  }
551 
552  initQCriterion<Comp2RefChi2>(qalgos_);
553  initQCriterion<Comp2RefKolmogorov>(qalgos_);
554  initQCriterion<ContentsXRange>(qalgos_);
555  initQCriterion<ContentsYRange>(qalgos_);
556  initQCriterion<MeanWithinExpected>(qalgos_);
557  initQCriterion<Comp2RefEqualH>(qalgos_);
558  initQCriterion<DeadChannel>(qalgos_);
559  initQCriterion<NoisyChannel>(qalgos_);
560  initQCriterion<ContentsWithinExpected>(qalgos_);
561  initQCriterion<CompareToMedian>(qalgos_);
562  initQCriterion<CompareLastFilledBin>(qalgos_);
563  initQCriterion<CheckVariance>(qalgos_);
564 
565  scaleFlag_ = pset.getUntrackedParameter<double>("ScalingFlag", 0.0);
566  if (verbose_ > 0)
567  std::cout << "DQMStore: Scaling Flag set to " << scaleFlag_ << std::endl;
568 }
569 
570 /* Generic method to do a backtrace and print it to stdout. It is
571  customised to properly get the routine that called the booking of the
572  histograms, which, following the usual stack, is at position 4. The
573  name of the calling function is properly demangled and the original
574  shared library including this function is also printed. For a more
575  detailed explanation of the routines involved, see here:
576  http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
577  http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html.*/
578 
579 void
581 {
582  static std::ofstream stream("histogramBookingBT.log");
583  void *array[10];
584  size_t size;
585  char **strings;
586  int r=0;
587  lat::RegexpMatch m;
588  m.reset();
589 
590  size = backtrace (array, 10);
591  strings = backtrace_symbols (array, size);
592 
593  if ((size > 4)
594  &&s_rxtrace.match(strings[4], 0, 0, &m))
595  {
596  char * demangled = abi::__cxa_demangle(m.matchString(strings[4], 2).c_str(), 0, 0, &r);
597  stream << "\"" << dir << "/"
598  << name << "\" "
599  << (r ? m.matchString(strings[4], 2) : demangled) << " "
600  << m.matchString(strings[4], 1) << "\n";
601  free(demangled);
602  }
603  else
604  stream << "Skipping "<< dir << "/" << name
605  << " with stack size " << size << "\n";
606  /* In this case print the full stack trace, up to main or to the
607  * maximum stack size, i.e. 10. */
608  if (verbose_ > 4)
609  {
610  size_t i;
611  m.reset();
612 
613  for (i = 0; i < size; i++)
614  if (s_rxtrace.match(strings[i], 0, 0, &m))
615  {
616  char * demangled = abi::__cxa_demangle(m.matchString(strings[i], 2).c_str(), 0, 0, &r);
617  stream << "\t\t" << i << "/" << size << " "
618  << (r ? m.matchString(strings[i], 2) : demangled) << " "
619  << m.matchString(strings[i], 1) << std::endl;
620  free (demangled);
621  }
622  }
623  free (strings);
624 }
625 
630 void
631 DQMStore::setVerbose(unsigned /* level */)
632 { return; }
633 
638 const std::string &
639 DQMStore::pwd(void) const
640 { return pwd_; }
641 
643 void
645 { setCurrentFolder(""); }
646 
648 void
649 DQMStore::cd(const std::string &subdir)
650 {
652  const std::string *cleaned = 0;
653  cleanTrailingSlashes(subdir, clean, cleaned);
654 
655  if (! dirExists(*cleaned))
656  raiseDQMError("DQMStore", "Cannot 'cd' into non-existent directory '%s'",
657  cleaned->c_str());
658 
659  setCurrentFolder(*cleaned);
660 }
661 
666 void
668 {
670  const std::string *cleaned = 0;
671  cleanTrailingSlashes(fullpath, clean, cleaned);
672  makeDirectory(*cleaned);
673  pwd_ = *cleaned;
674 }
675 
677 void
679 {
680  size_t pos = pwd_.rfind('/');
681  if (pos == std::string::npos)
682  setCurrentFolder("");
683  else
684  setCurrentFolder(pwd_.substr(0, pos));
685 }
686 
687 // -------------------------------------------------------------------
690 void
692 {
693  std::string prev;
694  std::string subdir;
696  prev.reserve(path.size());
697  subdir.reserve(path.size());
698  name.reserve(path.size());
699  size_t prevname = 0;
700  size_t slash = 0;
701 
702  while (true)
703  {
704  // Create this subdirectory component.
705  subdir.clear();
706  subdir.append(path, 0, slash);
707  name.clear();
708  name.append(subdir, prevname, std::string::npos);
709  if (! prev.empty() && findObject(prev, name))
710  raiseDQMError("DQMStore", "Attempt to create subdirectory '%s'"
711  " which already exists as a monitor element",
712  subdir.c_str());
713 
714  if (! dirs_.count(subdir))
715  dirs_.insert(subdir);
716 
717  // Stop if we've reached the end (including possibly a trailing slash).
718  if (slash+1 >= path.size())
719  break;
720 
721  // Find the next slash, making sure we progress. If reach the end,
722  // process the last path component; the next loop round will terminate.
723  prevname = slash ? slash+1 : slash;
724  prev = subdir;
725  if ((slash = path.find('/', ++slash)) == std::string::npos)
726  slash = path.size();
727  }
728 }
729 
731 bool
733 { return dirs_.count(path) > 0; }
734 
738 template <class HISTO, class COLLATE>
741  const char *context, int kind,
742  HISTO *h, COLLATE collate)
743 {
744  assert(name.find('/') == std::string::npos);
745  if (verbose_ > 3)
746  print_trace(dir, name);
748  mergePath(path, dir, name);
749 
750  // Put us in charge of h.
751  h->SetDirectory(0);
752 
753  // Check if the request monitor element already exists.
754  MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_);
755  if (me)
756  {
757  if (collateHistograms_)
758  {
759  collate(me, h);
760  delete h;
761  return me;
762  }
763  else
764  {
765  if (verbose_ > 1)
766  std::cout << "DQMStore: "
767  << context << ": monitor element '"
768  << path << "' already exists, collating" << std::endl;
769  me->Reset();
770  collate(me, h);
771  delete h;
772  return me;
773  }
774  }
775  else
776  {
777  // Create and initialise core object.
778  assert(dirs_.count(dir));
779  MonitorElement proto(&*dirs_.find(dir), name, run_, streamId_, moduleId_);
780  me = const_cast<MonitorElement &>(*data_.insert(proto).first)
782 
783  // Initialise quality test information.
784  QTestSpecs::iterator qi = qtestspecs_.begin();
785  QTestSpecs::iterator qe = qtestspecs_.end();
786  for ( ; qi != qe; ++qi)
787  {
788  if ( qi->first->match(path) )
789  me->addQReport(qi->second);
790  }
791 
792  // Assign reference if we have one.
793  std::string refdir;
794  refdir.reserve(s_referenceDirName.size() + dir.size() + 2);
795  refdir += s_referenceDirName;
796  refdir += '/';
797  refdir += dir;
798 
799  if (MonitorElement *refme = findObject(refdir, name))
800  {
801  me->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
802  }
803  // Return the monitor element.
804  return me;
805  }
806 }
807 
810  const std::string &name,
811  const char *context)
812 {
813  assert(name.find('/') == std::string::npos);
814  if (verbose_ > 3)
815  print_trace(dir, name);
816 
817  // Check if the request monitor element already exists.
818  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
819  {
820  if (verbose_ > 1)
821  {
823  mergePath(path, dir, name);
824 
825  std::cout << "DQMStore: "
826  << context << ": monitor element '"
827  << path << "' already exists, resetting" << std::endl;
828  }
829  me->Reset();
830  return me;
831  }
832  else
833  {
834  // Create it and return for initialisation.
835  assert(dirs_.count(dir));
836  MonitorElement proto(&*dirs_.find(dir), name, run_, streamId_, moduleId_);
837  return &const_cast<MonitorElement &>(*data_.insert(proto).first);
838  }
839 }
840 
841 // -------------------------------------------------------------------
845 {
846  if (collateHistograms_)
847  {
848  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
849  {
850  me->Fill(0);
851  return me;
852  }
853  }
854 
855  return book(dir, name, "bookInt")
857 }
858 
862 { return bookInt(pwd_, name); }
863 
867 {
868  return bookInt(pwd_, name);
869 }
870 
871 // -------------------------------------------------------------------
875 {
876  if (collateHistograms_)
877  {
878  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
879  {
880  me->Fill(0.);
881  return me;
882  }
883  }
884 
885  return book(dir, name, "bookFloat")
887 }
888 
892 { return bookFloat(pwd_, name); }
893 
897 {
898  return bookFloat(pwd_, name);
899 }
900 
901 // -------------------------------------------------------------------
905  const std::string &name,
906  const std::string &value)
907 {
908  if (collateHistograms_)
909  {
910  if (MonitorElement *me = findObject(dir, name, run_, 0, streamId_, moduleId_))
911  return me;
912  }
913 
914  return book(dir, name, "bookString")
916 }
917 
920 DQMStore::bookString(const char *name, const char *value)
921 { return bookString(pwd_, name, value); }
922 
926 {
927  return bookString(pwd_, name, value);
928 }
929 
930 // -------------------------------------------------------------------
934 {
935  return book(dir, name, "book1D", MonitorElement::DQM_KIND_TH1F, h, collate1D);
936 }
937 
941 {
942  return book(dir, name, "book1S", MonitorElement::DQM_KIND_TH1S, h, collate1S);
943 }
944 
948 {
949  return book(dir, name, "book1DD", MonitorElement::DQM_KIND_TH1D, h, collate1DD);
950 }
951 
954 DQMStore::book1D(const char *name, const char *title,
955  int nchX, double lowX, double highX)
956 {
957  return book1D(pwd_, name, new TH1F(name, title, nchX, lowX, highX));
958 }
959 
963  int nchX, double lowX, double highX)
964 {
965  return book1D(pwd_, name, new TH1F(name.c_str(), title.c_str(), nchX, lowX, highX));
966 }
967 
970 DQMStore::book1S(const char *name, const char *title,
971  int nchX, double lowX, double highX)
972 {
973  return book1S(pwd_, name, new TH1S(name, title, nchX, lowX, highX));
974 }
975 
979  int nchX, double lowX, double highX)
980 {
981  return book1S(pwd_, name, new TH1S(name.c_str(), title.c_str(), nchX, lowX, highX));
982 }
983 
986 DQMStore::book1DD(const char *name, const char *title,
987  int nchX, double lowX, double highX)
988 {
989  return book1DD(pwd_, name, new TH1D(name, title, nchX, lowX, highX));
990 }
991 
995  int nchX, double lowX, double highX)
996 {
997  return book1DD(pwd_, name, new TH1D(name.c_str(), title.c_str(), nchX, lowX, highX));
998 }
999 
1002 DQMStore::book1D(const char *name, const char *title,
1003  int nchX, float *xbinsize)
1004 {
1005  return book1D(pwd_, name, new TH1F(name, title, nchX, xbinsize));
1006 }
1007 
1011  int nchX, float *xbinsize)
1012 {
1013  return book1D(pwd_, name, new TH1F(name.c_str(), title.c_str(), nchX, xbinsize));
1014 }
1015 
1018 DQMStore::book1D(const char *name, TH1F *source)
1019 {
1020  return book1D(pwd_, name, static_cast<TH1F *>(source->Clone(name)));
1021 }
1022 
1026 {
1027  return book1D(pwd_, name, static_cast<TH1F *>(source->Clone(name.c_str())));
1028 }
1029 
1032 DQMStore::book1S(const char *name, TH1S *source)
1033 {
1034  return book1S(pwd_, name, static_cast<TH1S *>(source->Clone(name)));
1035 }
1036 
1040 {
1041  return book1S(pwd_, name, static_cast<TH1S *>(source->Clone(name.c_str())));
1042 }
1043 
1046 DQMStore::book1DD(const char *name, TH1D *source)
1047 {
1048  return book1DD(pwd_, name, static_cast<TH1D *>(source->Clone(name)));
1049 }
1050 
1054 {
1055  return book1DD(pwd_, name, static_cast<TH1D *>(source->Clone(name.c_str())));
1056 }
1057 
1058 // -------------------------------------------------------------------
1062 {
1063  return book(dir, name, "book2D", MonitorElement::DQM_KIND_TH2F, h, collate2D);
1064 }
1065 
1069 {
1070  return book(dir, name, "book2S", MonitorElement::DQM_KIND_TH2S, h, collate2S);
1071 }
1072 
1076 {
1077  return book(dir, name, "book2DD", MonitorElement::DQM_KIND_TH2D, h, collate2DD);
1078 }
1079 
1082 DQMStore::book2D(const char *name, const char *title,
1083  int nchX, double lowX, double highX,
1084  int nchY, double lowY, double highY)
1085 {
1086  return book2D(pwd_, name, new TH2F(name, title,
1087  nchX, lowX, highX,
1088  nchY, lowY, highY));
1089 }
1090 
1094  int nchX, double lowX, double highX,
1095  int nchY, double lowY, double highY)
1096 {
1097  return book2D(pwd_, name, new TH2F(name.c_str(), title.c_str(),
1098  nchX, lowX, highX,
1099  nchY, lowY, highY));
1100 }
1101 
1104 DQMStore::book2S(const char *name, const char *title,
1105  int nchX, double lowX, double highX,
1106  int nchY, double lowY, double highY)
1107 {
1108  return book2S(pwd_, name, new TH2S(name, title,
1109  nchX, lowX, highX,
1110  nchY, lowY, highY));
1111 }
1112 
1116  int nchX, double lowX, double highX,
1117  int nchY, double lowY, double highY)
1118 {
1119  return book2S(pwd_, name, new TH2S(name.c_str(), title.c_str(),
1120  nchX, lowX, highX,
1121  nchY, lowY, highY));
1122 }
1123 
1126 DQMStore::book2DD(const char *name, const char *title,
1127  int nchX, double lowX, double highX,
1128  int nchY, double lowY, double highY)
1129 {
1130  return book2DD(pwd_, name, new TH2D(name, title,
1131  nchX, lowX, highX,
1132  nchY, lowY, highY));
1133 }
1134 
1138  int nchX, double lowX, double highX,
1139  int nchY, double lowY, double highY)
1140 {
1141  return book2DD(pwd_, name, new TH2D(name.c_str(), title.c_str(),
1142  nchX, lowX, highX,
1143  nchY, lowY, highY));
1144 }
1145 
1148 DQMStore::book2D(const char *name, const char *title,
1149  int nchX, float *xbinsize, int nchY, float *ybinsize)
1150 {
1151  return book2D(pwd_, name, new TH2F(name, title,
1152  nchX, xbinsize, nchY, ybinsize));
1153 }
1154 
1158  int nchX, float *xbinsize, int nchY, float *ybinsize)
1159 {
1160  return book2D(pwd_, name, new TH2F(name.c_str(), title.c_str(),
1161  nchX, xbinsize, nchY, ybinsize));
1162 }
1163 
1166 DQMStore::book2D(const char *name, TH2F *source)
1167 {
1168  return book2D(pwd_, name, static_cast<TH2F *>(source->Clone(name)));
1169 }
1170 
1174 {
1175  return book2D(pwd_, name, static_cast<TH2F *>(source->Clone(name.c_str())));
1176 }
1177 
1180 DQMStore::book2S(const char *name, TH2S *source)
1181 {
1182  return book2S(pwd_, name, static_cast<TH2S *>(source->Clone(name)));
1183 }
1184 
1188 {
1189  return book2S(pwd_, name, static_cast<TH2S *>(source->Clone(name.c_str())));
1190 }
1191 
1194 DQMStore::book2DD(const char *name, TH2D *source)
1195 {
1196  return book2DD(pwd_, name, static_cast<TH2D *>(source->Clone(name)));
1197 }
1198 
1202 {
1203  return book2DD(pwd_, name, static_cast<TH2D *>(source->Clone(name.c_str())));
1204 }
1205 
1206 // -------------------------------------------------------------------
1210 {
1211  return book(dir, name, "book3D", MonitorElement::DQM_KIND_TH3F, h, collate3D);
1212 }
1213 
1216 DQMStore::book3D(const char *name, const char *title,
1217  int nchX, double lowX, double highX,
1218  int nchY, double lowY, double highY,
1219  int nchZ, double lowZ, double highZ)
1220 {
1221  return book3D(pwd_, name, new TH3F(name, title,
1222  nchX, lowX, highX,
1223  nchY, lowY, highY,
1224  nchZ, lowZ, highZ));
1225 }
1226 
1230  int nchX, double lowX, double highX,
1231  int nchY, double lowY, double highY,
1232  int nchZ, double lowZ, double highZ)
1233 {
1234  return book3D(pwd_, name, new TH3F(name.c_str(), title.c_str(),
1235  nchX, lowX, highX,
1236  nchY, lowY, highY,
1237  nchZ, lowZ, highZ));
1238 }
1239 
1242 DQMStore::book3D(const char *name, TH3F *source)
1243 {
1244  return book3D(pwd_, name, static_cast<TH3F *>(source->Clone(name)));
1245 }
1246 
1250 {
1251  return book3D(pwd_, name, static_cast<TH3F *>(source->Clone(name.c_str())));
1252 }
1253 
1254 // -------------------------------------------------------------------
1258 {
1259  return book(dir, name, "bookProfile",
1261  h, collateProfile);
1262 }
1263 
1268 DQMStore::bookProfile(const char *name, const char *title,
1269  int nchX, double lowX, double highX,
1270  int /* nchY */, double lowY, double highY,
1271  const char *option /* = "s" */)
1272 {
1273  return bookProfile(pwd_, name, new TProfile(name, title,
1274  nchX, lowX, highX,
1275  lowY, highY,
1276  option));
1277 }
1278 
1284  int nchX, double lowX, double highX,
1285  int /* nchY */, double lowY, double highY,
1286  const char *option /* = "s" */)
1287 {
1288  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1289  nchX, lowX, highX,
1290  lowY, highY,
1291  option));
1292 }
1293 
1298 DQMStore::bookProfile(const char *name, const char *title,
1299  int nchX, double lowX, double highX,
1300  double lowY, double highY,
1301  const char *option /* = "s" */)
1302 {
1303  return bookProfile(pwd_, name, new TProfile(name, title,
1304  nchX, lowX, highX,
1305  lowY, highY,
1306  option));
1307 }
1308 
1314  int nchX, double lowX, double highX,
1315  double lowY, double highY,
1316  const char *option /* = "s" */)
1317 {
1318  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1319  nchX, lowX, highX,
1320  lowY, highY,
1321  option));
1322 }
1323 
1328 DQMStore::bookProfile(const char *name, const char *title,
1329  int nchX, double *xbinsize,
1330  int /* nchY */, double lowY, double highY,
1331  const char *option /* = "s" */)
1332 {
1333  return bookProfile(pwd_, name, new TProfile(name, title,
1334  nchX, xbinsize,
1335  lowY, highY,
1336  option));
1337 }
1338 
1344  int nchX, double *xbinsize,
1345  int /* nchY */, double lowY, double highY,
1346  const char *option /* = "s" */)
1347 {
1348  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1349  nchX, xbinsize,
1350  lowY, highY,
1351  option));
1352 }
1353 
1358 DQMStore::bookProfile(const char *name, const char *title,
1359  int nchX, double *xbinsize,
1360  double lowY, double highY,
1361  const char *option /* = "s" */)
1362 {
1363  return bookProfile(pwd_, name, new TProfile(name, title,
1364  nchX, xbinsize,
1365  lowY, highY,
1366  option));
1367 }
1368 
1374  int nchX, double *xbinsize,
1375  double lowY, double highY,
1376  const char *option /* = "s" */)
1377 {
1378  return bookProfile(pwd_, name, new TProfile(name.c_str(), title.c_str(),
1379  nchX, xbinsize,
1380  lowY, highY,
1381  option));
1382 }
1383 
1386 DQMStore::bookProfile(const char *name, TProfile *source)
1387 {
1388  return bookProfile(pwd_, name, static_cast<TProfile *>(source->Clone(name)));
1389 }
1390 
1394 {
1395  return bookProfile(pwd_, name, static_cast<TProfile *>(source->Clone(name.c_str())));
1396 }
1397 
1398 // -------------------------------------------------------------------
1402 {
1403  return book(dir, name, "bookProfile2D",
1405  h, collateProfile2D);
1406 }
1407 
1412 DQMStore::bookProfile2D(const char *name, const char *title,
1413  int nchX, double lowX, double highX,
1414  int nchY, double lowY, double highY,
1415  int /* nchZ */, double lowZ, double highZ,
1416  const char *option /* = "s" */)
1417 {
1418  return bookProfile2D(pwd_, name, new TProfile2D(name, title,
1419  nchX, lowX, highX,
1420  nchY, lowY, highY,
1421  lowZ, highZ,
1422  option));
1423 }
1424 
1430  int nchX, double lowX, double highX,
1431  int nchY, double lowY, double highY,
1432  int /* nchZ */, double lowZ, double highZ,
1433  const char *option /* = "s" */)
1434 {
1435  return bookProfile2D(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
1436  nchX, lowX, highX,
1437  nchY, lowY, highY,
1438  lowZ, highZ,
1439  option));
1440 }
1441 
1446 DQMStore::bookProfile2D(const char *name, const char *title,
1447  int nchX, double lowX, double highX,
1448  int nchY, double lowY, double highY,
1449  double lowZ, double highZ,
1450  const char *option /* = "s" */)
1451 {
1452  return bookProfile2D(pwd_, name, new TProfile2D(name, title,
1453  nchX, lowX, highX,
1454  nchY, lowY, highY,
1455  lowZ, highZ,
1456  option));
1457 }
1458 
1464  int nchX, double lowX, double highX,
1465  int nchY, double lowY, double highY,
1466  double lowZ, double highZ,
1467  const char *option /* = "s" */)
1468 {
1469  return bookProfile2D(pwd_, name, new TProfile2D(name.c_str(), title.c_str(),
1470  nchX, lowX, highX,
1471  nchY, lowY, highY,
1472  lowZ, highZ,
1473  option));
1474 }
1475 
1478 DQMStore::bookProfile2D(const char *name, TProfile2D *source)
1479 {
1480  return bookProfile2D(pwd_, name, static_cast<TProfile2D *>(source->Clone(name)));
1481 }
1482 
1486 {
1487  return bookProfile2D(pwd_, name, static_cast<TProfile2D *>(source->Clone(name.c_str())));
1488 }
1489 
1493 bool
1495 {
1496  if (me->getTH1()->GetNbinsX() != h->GetNbinsX()
1497  || me->getTH1()->GetNbinsY() != h->GetNbinsY()
1498  || me->getTH1()->GetNbinsZ() != h->GetNbinsZ()
1499  || me->getTH1()->GetXaxis()->GetXmin() != h->GetXaxis()->GetXmin()
1500  || me->getTH1()->GetYaxis()->GetXmin() != h->GetYaxis()->GetXmin()
1501  || me->getTH1()->GetZaxis()->GetXmin() != h->GetZaxis()->GetXmin()
1502  || me->getTH1()->GetXaxis()->GetXmax() != h->GetXaxis()->GetXmax()
1503  || me->getTH1()->GetYaxis()->GetXmax() != h->GetYaxis()->GetXmax()
1504  || me->getTH1()->GetZaxis()->GetXmax() != h->GetZaxis()->GetXmax()
1505  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetXaxis(),(TAxis*)h->GetXaxis())
1506  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetYaxis(),(TAxis*)h->GetYaxis())
1507  || !MonitorElement::CheckBinLabels((TAxis*)me->getTH1()->GetZaxis(),(TAxis*)h->GetZaxis()) )
1508  {
1509  // edm::LogWarning ("DQMStore")
1510  std::cout << "*** DQMStore: WARNING:"
1511  << "checkBinningMatches: different binning - cannot add object '"
1512  << h->GetName() << "' of type "
1513  << h->IsA()->GetName() << " to existing ME: '"
1514  << me->getFullname() << "'\n";
1515  return false;
1516  }
1517  return true;
1518 }
1519 
1520 void
1522 {
1523  if (checkBinningMatches(me,h))
1524  me->getTH1F()->Add(h);
1525 }
1526 
1527 void
1529 {
1530  if (checkBinningMatches(me,h))
1531  me->getTH1S()->Add(h);
1532 }
1533 
1534 void
1536 {
1537  if (checkBinningMatches(me,h))
1538  me->getTH1D()->Add(h);
1539 }
1540 
1541 void
1543 {
1544  if (checkBinningMatches(me,h))
1545  me->getTH2F()->Add(h);
1546 }
1547 
1548 void
1550 {
1551  if (checkBinningMatches(me,h))
1552  me->getTH2S()->Add(h);
1553 }
1554 
1555 void
1557 {
1558  if (checkBinningMatches(me,h))
1559  me->getTH2D()->Add(h);
1560 }
1561 
1562 void
1564 {
1565  if (checkBinningMatches(me,h))
1566  me->getTH3F()->Add(h);
1567 }
1568 
1569 void
1571 {
1572  if (checkBinningMatches(me,h))
1573  {
1574  TProfile *meh = me->getTProfile();
1575  me->addProfiles(h, meh, meh, 1, 1);
1576  }
1577 }
1578 
1579 void
1581 {
1582  if (checkBinningMatches(me,h))
1583  {
1584  TProfile2D *meh = me->getTProfile2D();
1585  me->addProfiles(h, meh, meh, 1, 1);
1586  }
1587 }
1588 
1593 void
1594 DQMStore::tag(MonitorElement *me, unsigned int myTag)
1595 {
1596  if (! myTag)
1597  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1598  " with a zero tag", me->getFullname().c_str());
1599  if ((me->data_.flags & DQMNet::DQM_PROP_TAGGED) && myTag != me->data_.tag)
1600  raiseDQMError("DQMStore", "Attempt to tag monitor element '%s'"
1601  " twice with multiple tags", me->getFullname().c_str());
1602 
1603  me->data_.tag = myTag;
1605 }
1606 
1608 void
1609 DQMStore::tag(const std::string &path, unsigned int myTag)
1610 {
1611  std::string dir;
1612  std::string name;
1613  splitPath(dir, name, path);
1614 
1615  if (MonitorElement *me = findObject(dir, name))
1616  tag(me, myTag);
1617  else
1618  raiseDQMError("DQMStore", "Attempt to tag non-existent monitor element"
1619  " '%s' with tag %u", path.c_str(), myTag);
1620 
1621 }
1622 
1624 void
1625 DQMStore::tagContents(const std::string &path, unsigned int myTag)
1626 {
1627  MonitorElement proto(&path, std::string());
1628  MEMap::iterator e = data_.end();
1629  MEMap::iterator i = data_.lower_bound(proto);
1630  for ( ; i != e && path == *i->data_.dirname; ++i)
1631  tag(const_cast<MonitorElement *>(&*i), myTag);
1632 }
1633 
1636 void
1637 DQMStore::tagAllContents(const std::string &path, unsigned int myTag)
1638 {
1640  const std::string *cleaned = 0;
1641  cleanTrailingSlashes(path, clean, cleaned);
1642  MonitorElement proto(cleaned, std::string());
1643 
1644  // FIXME: WILDCARDS? Old one supported them, but nobody seemed to use them.
1645  MEMap::iterator e = data_.end();
1646  MEMap::iterator i = data_.lower_bound(proto);
1647  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
1648  {
1649  tag(const_cast<MonitorElement *>(&*i), myTag);
1650  ++i;
1651  }
1652 }
1653 
1658 std::vector<std::string>
1660 {
1661  std::vector<std::string> result;
1662  std::set<std::string>::const_iterator e = dirs_.end();
1663  std::set<std::string>::const_iterator i = dirs_.find(pwd_);
1664 
1665  // If we didn't find current directory, the tree is empty, so quit.
1666  if (i == e)
1667  return result;
1668 
1669  // Skip the current directory and then start looking for immediate
1670  // subdirectories in the dirs_ list. Stop when we are no longer in
1671  // (direct or indirect) subdirectories of pwd_. Note that we don't
1672  // "know" which order the set will sort A/B, A/B/C and A/D.
1673  while (++i != e && isSubdirectory(pwd_, *i))
1674  if (i->find('/', pwd_.size()+1) == std::string::npos)
1675  result.push_back(*i);
1676 
1677  return result;
1678 }
1679 
1681 std::vector<std::string>
1682 DQMStore::getMEs(void) const
1683 {
1684  MonitorElement proto(&pwd_, std::string());
1685  std::vector<std::string> result;
1686  MEMap::const_iterator e = data_.end();
1687  MEMap::const_iterator i = data_.lower_bound(proto);
1688  for ( ; i != e && isSubdirectory(pwd_, *i->data_.dirname); ++i)
1689  if (pwd_ == *i->data_.dirname)
1690  result.push_back(i->getName());
1691 
1692  return result;
1693 }
1694 
1697 bool
1699 {
1700  MonitorElement proto(&path, std::string());
1701  MEMap::const_iterator e = data_.end();
1702  MEMap::const_iterator i = data_.lower_bound(proto);
1703  return (i != e && isSubdirectory(path, *i->data_.dirname));
1704 }
1705 
1709 {
1710  std::string dir;
1711  std::string name;
1712  splitPath(dir, name, path);
1713  MonitorElement proto(&dir, name);
1714  MEMap::const_iterator mepos = data_.find(proto);
1715  return (mepos == data_.end() ? 0
1716  : const_cast<MonitorElement *>(&*mepos));
1717 }
1718 
1720 std::vector<MonitorElement *>
1721 DQMStore::get(unsigned int tag) const
1722 {
1723  // FIXME: Use reverse map [tag -> path] / [tag -> dir]?
1724  std::vector<MonitorElement *> result;
1725  for (MEMap::const_iterator i = data_.begin(), e = data_.end(); i != e; ++i)
1726  {
1727  const MonitorElement &me = *i;
1728  if ((me.data_.flags & DQMNet::DQM_PROP_TAGGED) && me.data_.tag == tag)
1729  result.push_back(const_cast<MonitorElement *>(&me));
1730  }
1731  return result;
1732 }
1733 
1736 std::vector<MonitorElement *>
1738 {
1740  const std::string *cleaned = 0;
1741  cleanTrailingSlashes(path, clean, cleaned);
1742  MonitorElement proto(cleaned, std::string());
1743 
1744  std::vector<MonitorElement *> result;
1745  MEMap::const_iterator e = data_.end();
1746  MEMap::const_iterator i = data_.lower_bound(proto);
1747  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1748  if (*cleaned == *i->data_.dirname)
1749  result.push_back(const_cast<MonitorElement *>(&*i));
1750 
1751  return result;
1752 }
1753 
1755 std::vector<MonitorElement *>
1756 DQMStore::getContents(const std::string &path, unsigned int tag) const
1757 {
1759  const std::string *cleaned = 0;
1760  cleanTrailingSlashes(path, clean, cleaned);
1761  MonitorElement proto(cleaned, std::string());
1762 
1763  std::vector<MonitorElement *> result;
1764  MEMap::const_iterator e = data_.end();
1765  MEMap::const_iterator i = data_.lower_bound(proto);
1766  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i)
1767  if (*cleaned == *i->data_.dirname
1768  && (i->data_.flags & DQMNet::DQM_PROP_TAGGED)
1769  && i->data_.tag == tag)
1770  result.push_back(const_cast<MonitorElement *>(&*i));
1771 
1772  return result;
1773 }
1774 
1779 void
1780 DQMStore::getContents(std::vector<std::string> &into, bool showContents /* = true */) const
1781 {
1782  into.clear();
1783  into.reserve(dirs_.size());
1784 
1785  MEMap::const_iterator me = data_.end();
1786  std::set<std::string>::const_iterator di = dirs_.begin();
1787  std::set<std::string>::const_iterator de = dirs_.end();
1788  for ( ; di != de; ++di)
1789  {
1790  MonitorElement proto(&*di, std::string());
1791  MEMap::const_iterator mi = data_.lower_bound(proto);
1792  MEMap::const_iterator m = mi;
1793  size_t sz = di->size() + 2;
1794  size_t nfound = 0;
1795  for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
1796  if (*di == *m->data_.dirname)
1797  {
1798  sz += m->data_.objname.size() + 1;
1799  ++nfound;
1800  }
1801 
1802  if (! nfound)
1803  continue;
1804 
1805  std::vector<std::string>::iterator istr
1806  = into.insert(into.end(), std::string());
1807 
1808  if (showContents)
1809  {
1810  istr->reserve(sz);
1811 
1812  *istr += *di;
1813  *istr += ':';
1814  for (sz = 0; mi != m; ++mi)
1815  {
1816  if (*di != *mi->data_.dirname)
1817  continue;
1818 
1819  if (sz > 0)
1820  *istr += ',';
1821 
1822  *istr += mi->data_.objname;
1823  ++sz;
1824  }
1825  }
1826  else
1827  {
1828  istr->reserve(di->size() + 2);
1829  *istr += *di;
1830  *istr += ':';
1831  }
1832  }
1833 }
1834 
1839  const std::string &name,
1840  const uint32_t run /* = 0 */,
1841  const uint32_t lumi /* = 0 */,
1842  const uint32_t streamId /* = 0 */,
1843  const uint32_t moduleId /* = 0 */) const
1844 {
1845  if (dir.find_first_not_of(s_safe) != std::string::npos)
1846  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1847  " unacceptable characters", dir.c_str());
1848  if (name.find_first_not_of(s_safe) != std::string::npos)
1849  raiseDQMError("DQMStore", "Monitor element path name '%s' uses"
1850  " unacceptable characters", name.c_str());
1851 
1852  MonitorElement proto;
1853  proto.data_.dirname = &dir;
1854  proto.data_.objname = name;
1855  proto.data_.run = run;
1856  proto.data_.lumi = lumi;
1857  proto.data_.streamId = streamId;
1858  proto.data_.moduleId = moduleId;
1859 
1860  MEMap::const_iterator mepos = data_.find(proto);
1861  return (mepos == data_.end() ? 0
1862  : const_cast<MonitorElement *>(&*mepos));
1863 }
1864 
1867 void
1868 DQMStore::getAllTags(std::vector<std::string> &into) const
1869 {
1870  into.clear();
1871  into.reserve(dirs_.size());
1872 
1873  MEMap::const_iterator me = data_.end();
1874  std::set<std::string>::const_iterator di = dirs_.begin();
1875  std::set<std::string>::const_iterator de = dirs_.end();
1876  char tagbuf[32]; // more than enough for '/' and up to 10 digits
1877 
1878  for ( ; di != de; ++di)
1879  {
1880  MonitorElement proto(&*di, std::string());
1881  MEMap::const_iterator mi = data_.lower_bound(proto);
1882  MEMap::const_iterator m = mi;
1883  size_t sz = di->size() + 2;
1884  size_t nfound = 0;
1885  for ( ; m != me && isSubdirectory(*di, *m->data_.dirname); ++m)
1886  if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
1887  {
1888  // the tags count for '/' + up to 10 digits, otherwise ',' + ME name
1889  sz += 1 + m->data_.objname.size() + 11;
1890  ++nfound;
1891  }
1892 
1893  if (! nfound)
1894  continue;
1895 
1896  std::vector<std::string>::iterator istr
1897  = into.insert(into.end(), std::string());
1898 
1899  istr->reserve(sz);
1900 
1901  *istr += *di;
1902  *istr += ':';
1903  for (sz = 0; mi != m; ++mi)
1904  {
1905  if (*di == *m->data_.dirname && (m->data_.flags & DQMNet::DQM_PROP_TAGGED))
1906  {
1907  sprintf(tagbuf, "/%u", mi->data_.tag);
1908  if (sz > 0)
1909  *istr += ',';
1910  *istr += m->data_.objname;
1911  *istr += tagbuf;
1912  ++sz;
1913  }
1914  }
1915  }
1916 }
1917 
1920 std::vector<MonitorElement*>
1922  uint32_t runNumber /* = 0 */,
1923  uint32_t lumi /* = 0 */) const
1924 {
1926  const std::string *cleaned = 0;
1927  cleanTrailingSlashes(path, clean, cleaned);
1928  MonitorElement proto(cleaned, std::string(), runNumber);
1929  proto.setLumi(lumi);
1930 
1931  std::vector<MonitorElement *> result;
1932  MEMap::const_iterator e = data_.end();
1933  MEMap::const_iterator i = data_.lower_bound(proto);
1934  for ( ; i != e && isSubdirectory(*cleaned, *i->data_.dirname); ++i) {
1935  if (runNumber != 0) {
1936  if (i->data_.run > runNumber // TODO[rovere]: pleonastic? first we encounter local ME of the same run ...
1937  || i->data_.streamId != 0
1938  || i->data_.moduleId != 0)
1939  break;
1940  }
1941  if (lumi != 0) {
1942  if (i->data_.lumi > lumi
1943  || i->data_.streamId != 0
1944  || i->data_.moduleId != 0)
1945  break;
1946  }
1947  if (runNumber != 0 or lumi !=0) {
1948  assert(i->data_.streamId == 0);
1949  assert(i->data_.moduleId == 0);
1950  }
1951  result.push_back(const_cast<MonitorElement *>(&*i));
1952  }
1953  return result;
1954 }
1955 
1958 std::vector<MonitorElement*>
1959 DQMStore::getMatchingContents(const std::string &pattern, lat::Regexp::Syntax syntaxType /* = Wildcard */) const
1960 {
1961  lat::Regexp rx;
1962  try
1963  {
1964  rx = lat::Regexp(pattern, 0, syntaxType);
1965  rx.study();
1966  }
1967  catch (lat::Error &e)
1968  {
1969  raiseDQMError("DQMStore", "Invalid regular expression '%s': %s",
1970  pattern.c_str(), e.explain().c_str());
1971  }
1972 
1973  std::string path;
1974  std::vector<MonitorElement *> result;
1975  MEMap::const_iterator i = data_.begin();
1976  MEMap::const_iterator e = data_.end();
1977  for ( ; i != e; ++i)
1978  {
1979  path.clear();
1980  mergePath(path, *i->data_.dirname, i->data_.objname);
1981  if (rx.match(path))
1982  result.push_back(const_cast<MonitorElement *>(&*i));
1983  }
1984 
1985  return result;
1986 }
1987 
1991 
1994 void
1996 {
1997  MEMap::iterator mi = data_.begin();
1998  MEMap::iterator me = data_.end();
1999  for ( ; mi != me; ++mi)
2000  {
2001  MonitorElement &me = const_cast<MonitorElement &>(*mi);
2002  if (mi->wasUpdated())
2003  {
2004  if (me.resetMe())
2005  me.Reset();
2006  me.resetUpdate();
2007  }
2008  }
2009 
2010  reset_ = true;
2011 }
2012 
2016 
2018 void
2020 {
2021  MEMap::iterator mi = data_.begin();
2022  MEMap::iterator me = data_.end();
2023  for ( ; mi != me; ++mi)
2024  {
2025  if (forceResetOnBeginLumi_ && ((*mi).getLumiFlag() == false))
2026  continue;
2027  MonitorElement &me = const_cast<MonitorElement &>(*mi);
2028  me.Reset();
2029  me.resetUpdate();
2030  }
2031 
2032  reset_ = true;
2033 }
2034 
2038 
2039 void
2041  uint32_t lumi)
2042 {
2043 
2044  std::string null_str("");
2045  MonitorElement proto(&null_str, null_str, run, 0, 0);
2046  if (enableMultiThread_)
2047  proto.setLumi(lumi);
2048 
2049  std::set<MonitorElement>::const_iterator e = data_.end();
2050  std::set<MonitorElement>::const_iterator i = data_.lower_bound(proto);
2051 
2052  while (i != e) {
2053  if (i->data_.streamId != 0 ||
2054  i->data_.moduleId != 0)
2055  break;
2056  if ((i->data_.lumi != lumi) && enableMultiThread_)
2057  break;
2058  if (i->data_.run != run)
2059  break;
2060 
2061  const_cast<MonitorElement*>(&*i)->markToDelete();
2062 
2063  if (verbose_ > 1)
2064  std::cout << "DQMStore::markForDeletion: marked monitor element '"
2065  << *i->data_.dirname << "/" << i->data_.objname << "'"
2066  << "flags " << i->data_.flags << "\n";
2067 
2068  ++i;
2069  }
2070 }
2071 
2072 
2078 bool
2080  bool overwrite, bool collateHistograms)
2081 {
2082  // NB: Profile histograms inherit from TH*D, checking order matters.
2083  MonitorElement *refcheck = 0;
2084  if (TProfile *h = dynamic_cast<TProfile *>(obj))
2085  {
2086  MonitorElement *me = findObject(dir, h->GetName());
2087  if (! me)
2088  me = bookProfile(dir, h->GetName(), (TProfile *) h->Clone());
2089  else if (overwrite)
2090  me->copyFrom(h);
2091  else if (isCollateME(me) || collateHistograms)
2092  collateProfile(me, h);
2093  refcheck = me;
2094  }
2095  else if (TProfile2D *h = dynamic_cast<TProfile2D *>(obj))
2096  {
2097  MonitorElement *me = findObject(dir, h->GetName());
2098  if (! me)
2099  me = bookProfile2D(dir, h->GetName(), (TProfile2D *) h->Clone());
2100  else if (overwrite)
2101  me->copyFrom(h);
2102  else if (isCollateME(me) || collateHistograms)
2103  collateProfile2D(me, h);
2104  refcheck = me;
2105  }
2106  else if (TH1F *h = dynamic_cast<TH1F *>(obj))
2107  {
2108  MonitorElement *me = findObject(dir, h->GetName());
2109  if (! me)
2110  me = book1D(dir, h->GetName(), (TH1F *) h->Clone());
2111  else if (overwrite)
2112  me->copyFrom(h);
2113  else if (isCollateME(me) || collateHistograms)
2114  collate1D(me, h);
2115  refcheck = me;
2116  }
2117  else if (TH1S *h = dynamic_cast<TH1S *>(obj))
2118  {
2119  MonitorElement *me = findObject(dir, h->GetName());
2120  if (! me)
2121  me = book1S(dir, h->GetName(), (TH1S *) h->Clone());
2122  else if (overwrite)
2123  me->copyFrom(h);
2124  else if (isCollateME(me) || collateHistograms)
2125  collate1S(me, h);
2126  refcheck = me;
2127  }
2128  else if (TH1D *h = dynamic_cast<TH1D *>(obj))
2129  {
2130  MonitorElement *me = findObject(dir, h->GetName());
2131  if (! me)
2132  me = book1DD(dir, h->GetName(), (TH1D *) h->Clone());
2133  else if (overwrite)
2134  me->copyFrom(h);
2135  else if (isCollateME(me) || collateHistograms)
2136  collate1DD(me, h);
2137  refcheck = me;
2138  }
2139  else if (TH2F *h = dynamic_cast<TH2F *>(obj))
2140  {
2141  MonitorElement *me = findObject(dir, h->GetName());
2142  if (! me)
2143  me = book2D(dir, h->GetName(), (TH2F *) h->Clone());
2144  else if (overwrite)
2145  me->copyFrom(h);
2146  else if (isCollateME(me) || collateHistograms)
2147  collate2D(me, h);
2148  refcheck = me;
2149  }
2150  else if (TH2S *h = dynamic_cast<TH2S *>(obj))
2151  {
2152  MonitorElement *me = findObject(dir, h->GetName());
2153  if (! me)
2154  me = book2S(dir, h->GetName(), (TH2S *) h->Clone());
2155  else if (overwrite)
2156  me->copyFrom(h);
2157  else if (isCollateME(me) || collateHistograms)
2158  collate2S(me, h);
2159  refcheck = me;
2160  }
2161  else if (TH2D *h = dynamic_cast<TH2D *>(obj))
2162  {
2163  MonitorElement *me = findObject(dir, h->GetName());
2164  if (! me)
2165  me = book2DD(dir, h->GetName(), (TH2D *) h->Clone());
2166  else if (overwrite)
2167  me->copyFrom(h);
2168  else if (isCollateME(me) || collateHistograms)
2169  collate2DD(me, h);
2170  refcheck = me;
2171  }
2172  else if (TH3F *h = dynamic_cast<TH3F *>(obj))
2173  {
2174  MonitorElement *me = findObject(dir, h->GetName());
2175  if (! me)
2176  me = book3D(dir, h->GetName(), (TH3F *) h->Clone());
2177  else if (overwrite)
2178  me->copyFrom(h);
2179  else if (isCollateME(me) || collateHistograms)
2180  collate3D(me, h);
2181  refcheck = me;
2182  }
2183  else if (dynamic_cast<TObjString *>(obj))
2184  {
2185  lat::RegexpMatch m;
2186  if (! s_rxmeval.match(obj->GetName(), 0, 0, &m))
2187  {
2188  if (strstr(obj->GetName(), "CMSSW"))
2189  {
2190  if (verbose_)
2191  std::cout << "Input file version: " << obj->GetName() << std::endl;
2192  return true;
2193  }
2194  else if (strstr(obj->GetName(), "DQMPATCH"))
2195  {
2196  if (verbose_)
2197  std::cout << "DQM patch version: " << obj->GetName() << std::endl;
2198  return true;
2199  }
2200  else
2201  {
2202  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2203  << obj->GetName() << "' of type '"
2204  << obj->IsA()->GetName() << "'\n";
2205  return false;
2206  }
2207  }
2208 
2209  std::string label = m.matchString(obj->GetName(), 1);
2210  std::string kind = m.matchString(obj->GetName(), 2);
2211  std::string value = m.matchString(obj->GetName(), 3);
2212 
2213  if (kind == "i")
2214  {
2215  MonitorElement *me = findObject(dir, label);
2216  if (! me || overwrite)
2217  {
2218  if (! me) me = bookInt(dir, label);
2219  me->Fill(atoll(value.c_str()));
2220  }
2221  }
2222  else if (kind == "f")
2223  {
2224  MonitorElement *me = findObject(dir, label);
2225  if (! me || overwrite)
2226  {
2227  if (! me) me = bookFloat(dir, label);
2228  me->Fill(atof(value.c_str()));
2229  }
2230  }
2231  else if (kind == "s")
2232  {
2233  MonitorElement *me = findObject(dir, label);
2234  if (! me)
2235  me = bookString(dir, label, value);
2236  else if (overwrite)
2237  me->Fill(value);
2238  }
2239  else if (kind == "e")
2240  {
2241  MonitorElement *me = findObject(dir, label);
2242  if (! me)
2243  {
2244  std::cout << "*** DQMStore: WARNING: no monitor element '"
2245  << label << "' in directory '"
2246  << dir << "' to be marked as efficiency plot.\n";
2247  return false;
2248  }
2249  me->setEfficiencyFlag();
2250  }
2251  else if (kind == "t")
2252  {
2253  MonitorElement *me = findObject(dir, label);
2254  if (! me)
2255  {
2256  std::cout << "*** DQMStore: WARNING: no monitor element '"
2257  << label << "' in directory '"
2258  << dir << "' for a tag\n";
2259  return false;
2260  }
2261  errno = 0;
2262  char *endp = 0;
2263  unsigned long val = strtoul(value.c_str(), &endp, 10);
2264  if ((val == 0 && errno) || *endp || val > ~uint32_t(0))
2265  {
2266  std::cout << "*** DQMStore: WARNING: cannot restore tag '"
2267  << value << "' for monitor element '"
2268  << label << "' in directory '"
2269  << dir << "' - invalid value\n";
2270  return false;
2271  }
2272  tag(me, val);
2273  }
2274  else if (kind == "qr")
2275  {
2276  // Handle qreports, but skip them while reading in references.
2277  if (! isSubdirectory(s_referenceDirName, dir))
2278  {
2279  size_t dot = label.find('.');
2280  if (dot == std::string::npos)
2281  {
2282  std::cout << "*** DQMStore: WARNING: quality report label in '" << label
2283  << "' is missing a '.' and cannot be extracted\n";
2284  return false;
2285  }
2286 
2287  std::string mename (label, 0, dot);
2288  std::string qrname (label, dot+1, std::string::npos);
2289 
2290  m.reset();
2291  DQMNet::QValue qv;
2292  if (s_rxmeqr1.match(value, 0, 0, &m))
2293  {
2294  qv.code = atoi(m.matchString(value, 1).c_str());
2295  qv.qtresult = strtod(m.matchString(value, 2).c_str(), 0);
2296  qv.message = m.matchString(value, 4);
2297  qv.qtname = qrname;
2298  qv.algorithm = m.matchString(value, 3);
2299  }
2300  else if (s_rxmeqr2.match(value, 0, 0, &m))
2301  {
2302  qv.code = atoi(m.matchString(value, 1).c_str());
2303  qv.qtresult = 0; // unavailable in old format
2304  qv.message = m.matchString(value, 2);
2305  qv.qtname = qrname;
2306  // qv.algorithm unavailable in old format
2307  }
2308  else
2309  {
2310  std::cout << "*** DQMStore: WARNING: quality test value '"
2311  << value << "' is incorrectly formatted\n";
2312  return false;
2313  }
2314 
2315  MonitorElement *me = findObject(dir, mename);
2316  if (! me)
2317  {
2318  std::cout << "*** DQMStore: WARNING: no monitor element '"
2319  << mename << "' in directory '"
2320  << dir << "' for quality test '"
2321  << label << "'\n";
2322  return false;
2323  }
2324 
2325  me->addQReport(qv, /* FIXME: getQTest(qv.qtname)? */ 0);
2326  }
2327  }
2328  else
2329  {
2330  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2331  << obj->GetName() << "' of type '"
2332  << obj->IsA()->GetName() << "'\n";
2333  return false;
2334  }
2335  }
2336  else if (TNamed *n = dynamic_cast<TNamed *>(obj))
2337  {
2338  // For old DQM data.
2339  std::string s;
2340  s.reserve(6 + strlen(n->GetTitle()) + 2*strlen(n->GetName()));
2341  s += '<'; s += n->GetName(); s += '>';
2342  s += n->GetTitle();
2343  s += '<'; s += '/'; s += n->GetName(); s += '>';
2344  TObjString os(s.c_str());
2345  return extract(&os, dir, overwrite, collateHistograms_);
2346  }
2347  else
2348  {
2349  std::cout << "*** DQMStore: WARNING: cannot extract object '"
2350  << obj->GetName() << "' of type '" << obj->IsA()->GetName()
2351  << "' and with title '" << obj->GetTitle() << "'\n";
2352  return false;
2353  }
2354 
2355  // If we just read in a reference monitor element, and there is a
2356  // monitor element with the same name, link the two together. The
2357  // other direction is handled by the initialise() method.
2358  if (refcheck && isSubdirectory(s_referenceDirName, dir))
2359  {
2360  std::string mdir(dir, s_referenceDirName.size()+1, std::string::npos);
2361  if (MonitorElement *master = findObject(mdir, obj->GetName()))
2362  {
2363  master->data_.flags |= DQMNet::DQM_PROP_HAS_REFERENCE;
2364  master->reference_ = refcheck->object_;
2365  }
2366  }
2367 
2368  return true;
2369 }
2370 
2374 bool
2376 {
2377  assert(! path.empty());
2378 
2379  // Find the first path component.
2380  size_t start = 0;
2381  size_t end = path.find('/', start);
2382  if (end == std::string::npos)
2383  end = path.size();
2384 
2385  while (true)
2386  {
2387  // Check if this subdirectory component exists. If yes, make sure
2388  // it is actually a subdirectory. Otherwise create or cd into it.
2389  std::string part(path, start, end-start);
2390  TObject *o = gDirectory->Get(part.c_str());
2391  if (o && ! dynamic_cast<TDirectory *>(o))
2392  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2393  " fails because the part '%s' already exists and is not"
2394  " directory", path.c_str(), part.c_str());
2395  else if (! o)
2396  gDirectory->mkdir(part.c_str());
2397 
2398  if (! gDirectory->cd(part.c_str()))
2399  raiseDQMError("DQMStore", "Attempt to create directory '%s' in a file"
2400  " fails because could not cd into subdirectory '%s'",
2401  path.c_str(), part.c_str());
2402 
2403  // Stop if we reached the end, ignoring any trailing '/'.
2404  if (end+1 >= path.size())
2405  break;
2406 
2407  // Find the next path component.
2408  start = end+1;
2409  end = path.find('/', start);
2410  if (end == std::string::npos)
2411  end = path.size();
2412  }
2413 
2414  return true;
2415 }
2416 
2418  const std::string &path /* = "" */,
2419  const uint32_t run /* = 0 */,
2420  const uint32_t lumi /* = 0 */,
2421  const bool resetMEsAfterWriting /* = false */)
2422 {
2423  using google::protobuf::io::FileOutputStream;
2424  using google::protobuf::io::GzipOutputStream;
2425  using google::protobuf::io::StringOutputStream;
2426 
2427  std::set<std::string>::iterator di, de;
2428  MEMap::iterator mi, me = data_.end();
2429  dqmstorepb::ROOTFilePB dqmstore_message;
2430  int nme = 0;
2431 
2432  if (verbose_)
2433  std::cout << "\n DQMStore: Opening PBFile '"
2434  << filename << "'"<< std::endl;
2435 
2436  // Loop over the directory structure.
2437  for (di = dirs_.begin(), de = dirs_.end(); di != de; ++di)
2438  {
2439  // Check if we should process this directory. We process the
2440  // requested part of the object tree, including references.
2441  if (! path.empty()
2442  && ! isSubdirectory(path, *di))
2443  continue;
2444 
2445  // Loop over monitor elements in this directory.
2446  MonitorElement proto(&*di, std::string(), run, 0, 0);
2447  if (enableMultiThread_)
2448  proto.setLumi(lumi);
2449 
2450  mi = data_.lower_bound(proto);
2451  for ( ; mi != me && isSubdirectory(*di, *mi->data_.dirname); ++mi)
2452  {
2453  if (verbose_ > 1)
2454  std::cout << "Run: " << (*mi).run()
2455  << " Lumi: " << (*mi).lumi()
2456  << " LumiFlag: " << (*mi).getLumiFlag()
2457  << " streamId: " << (*mi).streamId()
2458  << " moduleId: " << (*mi).moduleId()
2459  << " fullpathname: " << (*mi).getFullname() << std::endl;
2460 
2461  // Upper bound in the loop over the MEs
2462  if (enableMultiThread_ && ((*mi).lumi() != lumi))
2463  break;
2464 
2465  // Skip if it isn't a direct child.
2466  if (*di != *mi->data_.dirname)
2467  continue;
2468 
2469  // Keep backward compatibility with the old way of
2470  // booking/handlind MonitorElements into the DQMStore. If run is
2471  // 0 it means that a booking happened w/ the old non-threadsafe
2472  // style, and we have to ignore the streamId and moduleId as a
2473  // consequence.
2474 
2475  if (run != 0 && (mi->data_.streamId !=0 || mi->data_.moduleId !=0))
2476  continue;
2477 
2478  if (verbose_ > 1)
2479  std::cout << "DQMStore::savePB: saving monitor element '"
2480  << *mi->data_.dirname << "/" << mi->data_.objname << "'"
2481  << "flags " << mi->data_.flags << "\n";
2482 
2483  nme++;
2484  dqmstorepb::ROOTFilePB::Histo* me = dqmstore_message.add_histo();
2485  me->set_full_pathname((*mi->data_.dirname) + '/' + mi->data_.objname);
2486  me->set_flags(mi->data_.flags);
2487 
2488  TObject *toWrite = nullptr;
2489  bool deleteObject = false;
2490 
2491  if (mi->kind() < MonitorElement::DQM_KIND_TH1F) {
2492  toWrite = new TObjString(mi->tagString().c_str());
2493  deleteObject = true;
2494  } else {
2495  toWrite = mi->object_;
2496  }
2497 
2498  TBufferFile buffer(TBufferFile::kWrite);
2499  buffer.WriteObject(toWrite);
2500  me->set_size(buffer.Length());
2501  me->set_streamed_histo((const void*)buffer.Buffer(),
2502  buffer.Length());
2503 
2504  if (deleteObject) {
2505  delete toWrite;
2506  }
2507 
2508  //reset the ME just written to make it available for the next LS (online)
2509  if (resetMEsAfterWriting)
2510  const_cast<MonitorElement*>(&*mi)->Reset();
2511  }
2512  }
2513 
2514  int filedescriptor = ::open(filename.c_str(),
2515  O_WRONLY | O_CREAT | O_TRUNC,
2516  S_IRUSR | S_IWUSR |
2517  S_IRGRP | S_IWGRP |
2518  S_IROTH);
2519  FileOutputStream file_stream(filedescriptor);
2521  options.format = GzipOutputStream::GZIP;
2522  options.compression_level = 6;
2523  GzipOutputStream gzip_stream(&file_stream,
2524  options);
2525  dqmstore_message.SerializeToZeroCopyStream(&gzip_stream);
2526 
2527  // Maybe make some noise.
2528  if (verbose_)
2529  std::cout << "DQMStore::savePB: successfully wrote " << nme
2530  << " objects from path '" << path
2531  << "' into DQM file '" << filename << "'\n";
2532 }
2533 
2534 
2539 void
2541  const std::string &path /* = "" */,
2542  const std::string &pattern /* = "" */,
2543  const std::string &rewrite /* = "" */,
2544  const uint32_t run /* = 0 */,
2545  const uint32_t lumi /* = 0 */,
2546  SaveReferenceTag ref /* = SaveWithReference */,
2547  int minStatus /* = dqm::qstatus::STATUS_OK */,
2548  const std::string &fileupdate /* = RECREATE */,
2549  const bool resetMEsAfterWriting /* = false */)
2550 {
2551  std::set<std::string>::iterator di, de;
2552  MEMap::iterator mi, me = data_.end();
2553  DQMNet::QReports::const_iterator qi, qe;
2554  int nme=0;
2555 
2556  // TFile flushes to disk with fsync() on every TDirectory written to
2557  // the file. This makes DQM file saving painfully slow, and
2558  // ironically makes it _more_ likely the file saving gets
2559  // interrupted and corrupts the file. The utility class below
2560  // simply ignores the flush synchronisation.
2561  class TFileNoSync : public TFile
2562  {
2563  public:
2564  TFileNoSync(const char *file, const char *opt) : TFile(file, opt) {}
2565  virtual Int_t SysSync(Int_t) override { return 0; }
2566  };
2567 
2568  // open output file, on 1st save recreate, later update
2569  if (verbose_)
2570  std::cout << "\n DQMStore: Opening TFile '" << filename
2571  << "' with option '" << fileupdate <<"'\n";
2572 
2573  TFileNoSync f(filename.c_str(), fileupdate.c_str()); // open file
2574  if(f.IsZombie())
2575  raiseDQMError("DQMStore", "Failed to create/update file '%s'", filename.c_str());
2576  f.cd();
2577 
2578  // Construct a regular expression from the pattern string.
2579  std::auto_ptr<lat::Regexp> rxpat;
2580  if (! pattern.empty())
2581  rxpat.reset(new lat::Regexp(pattern.c_str()));
2582 
2583  // Prepare a path for the reference object selection.
2584  std::string refpath;
2585  refpath.reserve(s_referenceDirName.size() + path.size() + 2);
2586  refpath += s_referenceDirName;
2587  if (! path.empty())
2588  {
2589  refpath += '/';
2590  refpath += path;
2591  }
2592 
2593  // Loop over the directory structure.
2594  for (di = dirs_.begin(), de = dirs_.end(); di != de; ++di)
2595  {
2596  // Check if we should process this directory. We process the
2597  // requested part of the object tree, including references.
2598  if (! path.empty()
2599  && ! isSubdirectory(path, *di)
2600  && ! isSubdirectory(refpath, *di))
2601  continue;
2602 
2603  // Loop over monitor elements in this directory.
2604  MonitorElement proto(&*di, std::string(), run, 0, 0);
2605  if (enableMultiThread_)
2606  proto.setLumi(lumi);
2607 
2608  mi = data_.lower_bound(proto);
2609  for ( ; mi != me && isSubdirectory(*di, *mi->data_.dirname); ++mi)
2610  {
2611  if (verbose_ > 1)
2612  std::cout << "DQMStore::save: Run: " << (*mi).run()
2613  << " Lumi: " << (*mi).lumi()
2614  << " LumiFlag: " << (*mi).getLumiFlag()
2615  << " streamId: " << (*mi).streamId()
2616  << " moduleId: " << (*mi).moduleId()
2617  << " fullpathname: " << (*mi).getFullname() << std::endl;
2618 
2619  // Upper bound in the loop over the MEs
2620  if (enableMultiThread_ && ((*mi).lumi() != lumi))
2621  break;
2622 
2623  // Skip if it isn't a direct child.
2624  if (*di != *mi->data_.dirname) {
2625  if (verbose_ > 1)
2626  std::cout << "DQMStore::save: isn't a direct child. Skipping" << std::endl;
2627  continue;
2628  }
2629 
2630  // Keep backward compatibility with the old way of
2631  // booking/handlind MonitorElements into the DQMStore. If run is
2632  // 0 it means that a booking happened w/ the old non-threadsafe
2633  // style, and we have to ignore the streamId and moduleId as a
2634  // consequence.
2635 
2636  if (run != 0 && (mi->data_.streamId !=0 || mi->data_.moduleId !=0)) {
2637  continue;
2638  }
2639 
2640  // Handle reference histograms, with three distinct cases:
2641  // 1) Skip all references entirely on saving.
2642  // 2) Blanket saving of all references.
2643  // 3) Save only references for monitor elements with qtests.
2644  // The latter two are affected by "path" sub-tree selection,
2645  // i.e. references are saved only in the selected tree part.
2646  if (isSubdirectory(refpath, *mi->data_.dirname))
2647  {
2648  if (ref == SaveWithoutReference)
2649  // Skip the reference entirely.
2650  continue;
2651  else if (ref == SaveWithReference)
2652  // Save all references regardless of qtests.
2653  ;
2654  else if (ref == SaveWithReferenceForQTest)
2655  {
2656  // Save only references for monitor elements with qtests
2657  // with an optional cut on minimum quality test result.
2658  int status = -1;
2659  std::string mname(mi->getFullname(), s_referenceDirName.size()+1, std::string::npos);
2660  MonitorElement *master = get(mname);
2661  if (master)
2662  for (size_t i = 0, e = master->data_.qreports.size(); i != e; ++i)
2663  status = std::max(status, master->data_.qreports[i].code);
2664 
2665  if (! master || status < minStatus)
2666  {
2667  if (verbose_ > 1)
2668  std::cout << "DQMStore::save: skipping monitor element '"
2669  << mi->data_.objname << "' while saving, status is "
2670  << status << ", required minimum status is "
2671  << minStatus << std::endl;
2672  continue;
2673  }
2674  }
2675  }
2676 
2677  if (verbose_ > 1)
2678  std::cout << "DQMStore::save: saving monitor element '"
2679  << mi->data_.objname << "'\n";
2680  nme++; // count saved histograms
2681 
2682  // Create the directory.
2683  gDirectory->cd("/");
2684  if (di->empty())
2686  else if (rxpat.get())
2687  cdInto(s_monitorDirName + '/' + lat::StringOps::replace(*di, *rxpat, rewrite));
2688  else
2689  cdInto(s_monitorDirName + '/' + *di);
2690 
2691  // Save the object.
2692  switch (mi->kind())
2693  {
2697  TObjString(mi->tagString().c_str()).Write();
2698  break;
2699 
2700  default:
2701  mi->object_->Write();
2702  break;
2703  }
2704 
2705  // Save quality reports if this is not in reference section.
2706  if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
2707  {
2708  qi = mi->data_.qreports.begin();
2709  qe = mi->data_.qreports.end();
2710  for ( ; qi != qe; ++qi)
2711  TObjString(mi->qualityTagString(*qi).c_str()).Write();
2712  }
2713 
2714  // Save efficiency tag, if any
2715  if (mi->data_.flags & DQMNet::DQM_PROP_EFFICIENCY_PLOT)
2716  TObjString(mi->effLabelString().c_str()).Write();
2717 
2718  // Save tag if any
2719  if (mi->data_.flags & DQMNet::DQM_PROP_TAGGED)
2720  TObjString(mi->tagLabelString().c_str()).Write();
2721 
2722  //reset the ME just written to make it available for the next LS (online)
2723  if (resetMEsAfterWriting)
2724  const_cast<MonitorElement*>(&*mi)->Reset();
2725  }
2726  }
2727 
2728  f.Close();
2729 
2730  // Maybe make some noise.
2731  if (verbose_)
2732  std::cout << "DQMStore::save: successfully wrote " << nme
2733  << " objects from path '" << path
2734  << "' into DQM file '" << filename << "'\n";
2735 }
2736 
2739 unsigned int
2741  bool overwrite,
2742  const std::string &onlypath,
2743  const std::string &prepend,
2744  const std::string &curdir,
2745  OpenRunDirs stripdirs)
2746 {
2747  unsigned int ntot = 0;
2748  unsigned int count = 0;
2749 
2750  if (! file->cd(curdir.c_str()))
2751  raiseDQMError("DQMStore", "Failed to process directory '%s' while"
2752  " reading file '%s'", curdir.c_str(), file->GetName());
2753 
2754  // Figure out current directory name, but strip out the top
2755  // directory into which we dump everything.
2756  std::string dirpart = curdir;
2757  if (dirpart.compare(0, s_monitorDirName.size(), s_monitorDirName) == 0)
2758  {
2759  if (dirpart.size() == s_monitorDirName.size())
2760  dirpart.clear();
2761  else if (dirpart[s_monitorDirName.size()] == '/')
2762  dirpart.erase(0, s_monitorDirName.size()+1);
2763  }
2764 
2765  // See if we are going to skip this directory.
2766  bool skip = (! onlypath.empty() && ! isSubdirectory(onlypath, dirpart));
2767 
2768  if (prepend == s_collateDirName ||
2769  prepend == s_referenceDirName ||
2770  stripdirs == StripRunDirs )
2771  {
2772  // Remove Run # and RunSummary dirs
2773  // first look for Run summary,
2774  // if that is found and erased, also erase Run dir
2775  size_t slash = dirpart.find('/');
2776  size_t pos = dirpart.find("/Run summary");
2777  if (slash != std::string::npos && pos !=std::string::npos)
2778  {
2779  dirpart.erase(pos,12);
2780 
2781  pos = dirpart.find("Run ");
2782  size_t length = dirpart.find('/',pos+1)-pos+1;
2783  if (pos !=std::string::npos)
2784  dirpart.erase(pos,length);
2785  }
2786  }
2787 
2788  // If we are prepending, add it to the directory name,
2789  // and suppress reading of already existing reference histograms
2790  if (prepend == s_collateDirName ||
2791  prepend == s_referenceDirName)
2792  {
2793  size_t slash = dirpart.find('/');
2794  // If we are reading reference, skip previous reference.
2795  if (slash == std::string::npos // skip if Reference is toplevel folder, i.e. no slash
2796  && slash+1+s_referenceDirName.size() == dirpart.size()
2797  && dirpart.compare(slash+1, s_referenceDirName.size(), s_referenceDirName) == 0)
2798  return 0;
2799 
2800  slash = dirpart.find('/');
2801  // Skip reading of EventInfo subdirectory.
2802  if (slash != std::string::npos
2803  && slash + 10 == dirpart.size()
2804  && dirpart.compare( slash+1 , 9 , "EventInfo") == 0) {
2805  if (verbose_)
2806  std::cout << "DQMStore::readDirectory: skipping '" << dirpart << "'\n";
2807  return 0;
2808  }
2809 
2810  // Add prefix.
2811  if (dirpart.empty())
2812  dirpart = prepend;
2813  else
2814  dirpart = prepend + '/' + dirpart;
2815  }
2816  else if (! prepend.empty())
2817  {
2818  if (dirpart.empty())
2819  dirpart = prepend;
2820  else
2821  dirpart = prepend + '/' + dirpart;
2822  }
2823 
2824  // Loop over the contents of this directory in the file.
2825  // Post-pone string object handling to happen after other
2826  // objects have been read in so we are guaranteed to have
2827  // histograms by the time we read in quality tests and tags.
2828  TKey *key;
2829  TIter next (gDirectory->GetListOfKeys());
2830  std::list<TObject *> delayed;
2831  while ((key = (TKey *) next()))
2832  {
2833  std::auto_ptr<TObject> obj(key->ReadObj());
2834  if (dynamic_cast<TDirectory *>(obj.get()))
2835  {
2836  std::string subdir;
2837  subdir.reserve(curdir.size() + strlen(obj->GetName()) + 2);
2838  subdir += curdir;
2839  if (! curdir.empty())
2840  subdir += '/';
2841  subdir += obj->GetName();
2842 
2843  ntot += readDirectory(file, overwrite, onlypath, prepend, subdir, stripdirs);
2844  }
2845  else if (skip)
2846  ;
2847  else if (dynamic_cast<TObjString *>(obj.get()))
2848  {
2849  delayed.push_back(obj.release());
2850  }
2851  else
2852  {
2853  if (verbose_ > 2)
2854  std::cout << "DQMStore: reading object '" << obj->GetName()
2855  << "' of type '" << obj->IsA()->GetName()
2856  << "' from '" << file->GetName()
2857  << "' into '" << dirpart << "'\n";
2858 
2859  makeDirectory(dirpart);
2860  if (extract(obj.get(), dirpart, overwrite, collateHistograms_))
2861  ++count;
2862  }
2863  }
2864 
2865  while (! delayed.empty())
2866  {
2867  if (verbose_ > 2)
2868  std::cout << "DQMStore: reading object '" << delayed.front()->GetName()
2869  << "' of type '" << delayed.front()->IsA()->GetName()
2870  << "' from '" << file->GetName()
2871  << "' into '" << dirpart << "'\n";
2872 
2873  makeDirectory(dirpart);
2874  if (extract(delayed.front(), dirpart, overwrite, collateHistograms_))
2875  ++count;
2876 
2877  delete delayed.front();
2878  delayed.pop_front();
2879  }
2880 
2881  if (verbose_ > 1)
2882  std::cout << "DQMStore: read " << count << '/' << ntot
2883  << " objects from directory '" << dirpart << "'\n";
2884 
2885  return ntot + count;
2886 }
2887 
2894 bool
2896  bool overwrite /* = false */,
2897  const std::string &onlypath /* ="" */,
2898  const std::string &prepend /* ="" */,
2899  OpenRunDirs stripdirs /* =KeepRunDirs */,
2900  bool fileMustExist /* =true */)
2901 {
2902  return readFile(filename,overwrite,onlypath,prepend,stripdirs,fileMustExist);
2903 }
2904 
2909 bool
2911  OpenRunDirs stripdirs /* =StripRunDirs */,
2912  bool fileMustExist /* =true */)
2913 {
2914  bool overwrite = true;
2915  if (collateHistograms_) overwrite = false;
2916  if (verbose_)
2917  {
2918  std::cout << "DQMStore::load: reading from file '" << filename << "'\n";
2919  if (collateHistograms_)
2920  std::cout << "DQMStore::load: in collate mode " << "\n";
2921  else
2922  std::cout << "DQMStore::load: in overwrite mode " << "\n";
2923  }
2924 
2925  if (!s_rxpbfile.match(filename, 0, 0))
2926  return readFile(filename, overwrite, "", "", stripdirs, fileMustExist);
2927  else
2928  return readFilePB(filename, overwrite, "", "", stripdirs, fileMustExist);
2929 }
2930 
2936 bool
2938  bool overwrite /* = false */,
2939  const std::string &onlypath /* ="" */,
2940  const std::string &prepend /* ="" */,
2941  OpenRunDirs stripdirs /* =StripRunDirs */,
2942  bool fileMustExist /* =true */)
2943 {
2944 
2945  if (verbose_)
2946  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
2947 
2948  std::auto_ptr<TFile> f;
2949 
2950  try
2951  {
2952  f.reset(TFile::Open(filename.c_str()));
2953  if (! f.get() || f->IsZombie())
2954  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
2955  }
2956  catch (std::exception &)
2957  {
2958  if (fileMustExist)
2959  throw;
2960  else
2961  {
2962  if (verbose_)
2963  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
2964  return false;
2965  }
2966  }
2967 
2968  unsigned n = readDirectory(f.get(), overwrite, onlypath, prepend, "", stripdirs);
2969  f->Close();
2970 
2971  MEMap::iterator mi = data_.begin();
2972  MEMap::iterator me = data_.end();
2973  for ( ; mi != me; ++mi)
2974  const_cast<MonitorElement &>(*mi).updateQReportStats();
2975 
2976  if (verbose_)
2977  {
2978  std::cout << "DQMStore::open: successfully read " << n
2979  << " objects from file '" << filename << "'";
2980  if (! onlypath.empty())
2981  std::cout << " from directory '" << onlypath << "'";
2982  if (! prepend.empty())
2983  std::cout << " into directory '" << prepend << "'";
2984  std::cout << std::endl;
2985  }
2986  return true;
2987 }
2988 
2992 inline TObject * DQMStore::extractNextObject(TBufferFile &buf) const {
2993  if (buf.Length() == buf.BufferSize())
2994  return 0;
2995  buf.InitMap();
2996  void *ptr = buf.ReadObjectAny(0);
2997  return reinterpret_cast<TObject *>(ptr);
2998 }
2999 
3001  std::string &dirname,
3002  std::string &objname,
3003  TObject ** obj) {
3004 
3005  size_t slash = h.full_pathname().rfind('/');
3006  size_t dirpos = (slash == std::string::npos ? 0 : slash);
3007  size_t namepos = (slash == std::string::npos ? 0 : slash+1);
3008  dirname.assign(h.full_pathname(), 0, dirpos);
3009  objname.assign(h.full_pathname(), namepos, std::string::npos);
3010  TBufferFile buf(TBufferFile::kRead, h.size(),
3011  (void*)h.streamed_histo().data(),
3012  kFALSE);
3013  buf.Reset();
3014  *obj = extractNextObject(buf);
3015  if (!*obj) {
3016  raiseDQMError("DQMStore", "Error reading element:'%s'" , h.full_pathname().c_str());
3017  }
3018 }
3019 
3020 bool
3022  bool overwrite /* = false */,
3023  const std::string &onlypath /* ="" */,
3024  const std::string &prepend /* ="" */,
3025  OpenRunDirs stripdirs /* =StripRunDirs */,
3026  bool fileMustExist /* =true */)
3027 {
3028  using google::protobuf::io::FileInputStream;
3029  using google::protobuf::io::FileOutputStream;
3030  using google::protobuf::io::GzipInputStream;
3031  using google::protobuf::io::GzipOutputStream;
3032  using google::protobuf::io::CodedInputStream;
3033  using google::protobuf::io::ArrayInputStream;
3034 
3035  if (verbose_)
3036  std::cout << "DQMStore::readFile: reading from file '" << filename << "'\n";
3037 
3038  int filedescriptor;
3039  if ((filedescriptor = ::open(filename.c_str(), O_RDONLY)) == -1) {
3040  if (fileMustExist)
3041  raiseDQMError("DQMStore", "Failed to open file '%s'", filename.c_str());
3042  else
3043  if (verbose_)
3044  std::cout << "DQMStore::readFile: file '" << filename << "' does not exist, continuing\n";
3045  return false;
3046  }
3047 
3048  dqmstorepb::ROOTFilePB dqmstore_message;
3049  FileInputStream fin(filedescriptor);
3050  GzipInputStream input(&fin);
3051  CodedInputStream input_coded(&input);
3052  input_coded.SetTotalBytesLimit(1024*1024*1024, -1);
3053  if (!dqmstore_message.ParseFromCodedStream(&input_coded)) {
3054  raiseDQMError("DQMStore", "Fatal parsing file '%s'", filename.c_str());
3055  return false;
3056  }
3057 
3058  for (int i = 0; i < dqmstore_message.histo_size(); i++) {
3059  std::string path;
3060  std::string objname;
3061 
3062  TObject *obj = NULL;
3063  const dqmstorepb::ROOTFilePB::Histo &h = dqmstore_message.histo(i);
3064  get_info(h, path, objname, &obj);
3065 
3066  setCurrentFolder(path);
3067  if (obj)
3068  {
3069  /* Before calling the extract() check if histogram exists:
3070  * if it does - flags for the given monitor are already set (and merged)
3071  * else - set the flags after the histogram is created.
3072  */
3073  MonitorElement *me = findObject(path, objname);
3074 
3075  /* Run histograms should be collated and not overwritten,
3076  * Lumi histograms should be overwritten (and collate flag is not checked)
3077  */
3078  bool overwrite = h.flags() & DQMNet::DQM_PROP_LUMI;
3079  bool collate = !(h.flags() & DQMNet::DQM_PROP_LUMI);
3080  extract(static_cast<TObject *>(obj), path, overwrite, collate);
3081 
3082  if (me == nullptr) {
3083  me = findObject(path, objname);
3084  me->data_.flags = h.flags();
3085  }
3086 
3087  delete obj;
3088  }
3089  }
3090 
3091  cd();
3092  return true;
3093 }
3094 
3100 void
3102 {
3104  const std::string *cleaned = 0;
3105  cleanTrailingSlashes(path, clean, cleaned);
3106  MonitorElement proto(cleaned, std::string());
3107 
3108  MEMap::iterator e = data_.end();
3109  MEMap::iterator i = data_.lower_bound(proto);
3110  while (i != e && isSubdirectory(*cleaned, *i->data_.dirname))
3111  data_.erase(i++);
3112 
3113  std::set<std::string>::iterator de = dirs_.end();
3114  std::set<std::string>::iterator di = dirs_.lower_bound(*cleaned);
3115  while (di != de && isSubdirectory(*cleaned, *di))
3116  dirs_.erase(di++);
3117 }
3118 
3120 void
3122 {
3123  MonitorElement proto(&dir, std::string());
3124  MEMap::iterator e = data_.end();
3125  MEMap::iterator i = data_.lower_bound(proto);
3126  while (i != e && isSubdirectory(dir, *i->data_.dirname))
3127  if (dir == *i->data_.dirname)
3128  data_.erase(i++);
3129  else
3130  ++i;
3131 }
3132 
3134 void
3136 {
3138 }
3139 
3142 void
3144 {
3145  removeElement(pwd_, name);
3146 }
3147 
3150 void
3151 DQMStore::removeElement(const std::string &dir, const std::string &name, bool warning /* = true */)
3152 {
3153  MonitorElement proto(&dir, name);
3154  MEMap::iterator pos = data_.find(proto);
3155  if (pos == data_.end() && warning)
3156  std::cout << "DQMStore: WARNING: attempt to remove non-existent"
3157  << " monitor element '" << name << "' in '" << dir << "'\n";
3158  else
3159  data_.erase(pos);
3160 }
3161 
3167 QCriterion *
3169 {
3170  QCMap::const_iterator i = qtests_.find(qtname);
3171  QCMap::const_iterator e = qtests_.end();
3172  return (i == e ? 0 : i->second);
3173 }
3174 
3178 QCriterion *
3179 DQMStore::createQTest(const std::string &algoname, const std::string &qtname)
3180 {
3181  if (qtests_.count(qtname))
3182  raiseDQMError("DQMStore", "Attempt to create duplicate quality test '%s'",
3183  qtname.c_str());
3184 
3185  QAMap::iterator i = qalgos_.find(algoname);
3186  if (i == qalgos_.end())
3187  raiseDQMError("DQMStore", "Cannot create a quality test using unknown"
3188  " algorithm '%s'", algoname.c_str());
3189 
3190  QCriterion *qc = i->second(qtname);
3191  qc->setVerbose(verboseQT_);
3192 
3193  qtests_[qtname] = qc;
3194  return qc;
3195 }
3196 
3199 void
3201 {
3202  // Clean the path
3204  const std::string *cleaned = 0;
3205  cleanTrailingSlashes(dir, clean, cleaned);
3206 
3207  // Validate the path.
3208  if (cleaned->find_first_not_of(s_safe) != std::string::npos)
3209  raiseDQMError("DQMStore", "Monitor element path name '%s'"
3210  " uses unacceptable characters", cleaned->c_str());
3211 
3212  // Redirect to the pattern match version.
3213  useQTestByMatch(*cleaned + "/*", qtname);
3214 }
3215 
3217 int
3219 {
3220  QCriterion *qc = getQCriterion(qtname);
3221  if (! qc)
3222  raiseDQMError("DQMStore", "Cannot apply non-existent quality test '%s'",
3223  qtname.c_str());
3224 
3225  fastmatch * fm = new fastmatch( pattern );
3226 
3227  // Record the test for future reference.
3228  QTestSpec qts(fm, qc);
3229  qtestspecs_.push_back(qts);
3230 
3231  // Apply the quality test.
3232  MEMap::iterator mi = data_.begin();
3233  MEMap::iterator me = data_.end();
3234  std::string path;
3235  int cases = 0;
3236  for ( ; mi != me; ++mi)
3237  {
3238  path.clear();
3239  mergePath(path, *mi->data_.dirname, mi->data_.objname);
3240  if (fm->match(path))
3241  {
3242  ++cases;
3243  const_cast<MonitorElement &>(*mi).addQReport(qts.second);
3244  }
3245  }
3246 
3247  //return the number of matched cases
3248  return cases;
3249 }
3252 void
3254 {
3255 
3256  if (verbose_ > 0)
3257  std::cout << "DQMStore: running runQTests() with reset = "
3258  << ( reset_ ? "true" : "false" ) << std::endl;
3259 
3260  // Apply quality tests to each monitor element, skipping references.
3261  MEMap::iterator mi = data_.begin();
3262  MEMap::iterator me = data_.end();
3263  for ( ; mi != me; ++mi)
3264  if (! isSubdirectory(s_referenceDirName, *mi->data_.dirname))
3265  const_cast<MonitorElement &>(*mi).runQTests();
3266 
3267  reset_ = false;
3268 }
3269 
3273 int
3274 DQMStore::getStatus(const std::string &path /* = "" */) const
3275 {
3277  const std::string *cleaned = 0;
3278  cleanTrailingSlashes(path, clean, cleaned);
3279 
3281  MEMap::const_iterator mi = data_.begin();
3282  MEMap::const_iterator me = data_.end();
3283  for ( ; mi != me; ++mi)
3284  {
3285  if (! cleaned->empty() && ! isSubdirectory(*cleaned, *mi->data_.dirname))
3286  continue;
3287 
3288  if (mi->hasError())
3289  return dqm::qstatus::ERROR;
3290  else if (mi->hasWarning())
3291  status = dqm::qstatus::WARNING;
3292  else if (status < dqm::qstatus::WARNING
3293  && mi->hasOtherReport())
3294  status = dqm::qstatus::OTHER;
3295  }
3296  return status;
3297 }
3298 
3304 void
3306 {
3307  if (me)
3308  me->softReset();
3309 }
3310 
3311 // reverts action of softReset
3312 void
3314 {
3315  if (me)
3316  me->disableSoftReset();
3317 }
3318 
3321 void
3323 {
3324  if (me)
3325  me->setAccumulate(flag);
3326 }
3327 
3331 void
3333 {
3334  std::vector<std::string> contents;
3335  getContents(contents);
3336 
3337  std::cout << " ------------------------------------------------------------\n"
3338  << " Directory structure: \n"
3339  << " ------------------------------------------------------------\n";
3340 
3341  std::copy(contents.begin(), contents.end(),
3342  std::ostream_iterator<std::string>(std::cout, "\n"));
3343 
3344  std::cout << " ------------------------------------------------------------\n";
3345 }
3346 
3350 // check if the collate option is active on the DQMStore
3351 bool
3353 {
3354  return collateHistograms_;
3355 }
3359 // check if the monitor element is in auto-collation folder
3360 bool
3362 { return me && isSubdirectory(s_collateDirName, *me->data_.dirname); }
3366 
3368 void
3370 {
3371  if (scaleFlag_ == 0.0) return;
3372  if (verbose_ > 0)
3373  std::cout << " =========== " << " ScaleFlag " << scaleFlag_ << std::endl;
3374  double factor = scaleFlag_;
3375  int events = 1;
3376  if (dirExists("Info/EventInfo")) {
3377  if ( scaleFlag_ == -1.0) {
3378  MonitorElement * scale_me = get("Info/EventInfo/ScaleFactor");
3379  if (scale_me && scale_me->kind()==MonitorElement::DQM_KIND_REAL) factor = scale_me->getFloatValue();
3380  }
3381  MonitorElement * event_me = get("Info/EventInfo/processedEvents");
3382  if (event_me && event_me->kind()==MonitorElement::DQM_KIND_INT) events = event_me->getIntValue();
3383  }
3384  factor = factor/(events*1.0);
3385 
3386  MEMap::iterator mi = data_.begin();
3387  MEMap::iterator me = data_.end();
3388  for ( ; mi != me; ++mi)
3389  {
3390  MonitorElement &me = const_cast<MonitorElement &>(*mi);
3391  switch (me.kind())
3392  {
3394  {
3395  me.getTH1F()->Scale(factor);
3396  break;
3397  }
3399  {
3400  me.getTH1S()->Scale(factor);
3401  break;
3402  }
3404  {
3405  me.getTH1D()->Scale(factor);
3406  break;
3407  }
3409  {
3410  me.getTH2F()->Scale(factor);
3411  break;
3412  }
3414  {
3415  me.getTH2S()->Scale(factor);
3416  break;
3417  }
3419  {
3420  me.getTH2D()->Scale(factor);
3421  break;
3422  }
3424  {
3425  me.getTH3F()->Scale(factor);
3426  break;
3427  }
3429  {
3430  me.getTProfile()->Scale(factor);
3431  break;
3432  }
3434  {
3435  me.getTProfile2D()->Scale(factor);
3436  break;
3437  }
3438  default:
3439  if (verbose_ > 0)
3440  std::cout << " The DQM object '" << me.getFullname() << "' is not scalable object " << std::endl;
3441  continue;
3442  }
3443  }
3444 }
static void collateProfile2D(MonitorElement *me, TProfile2D *h)
Definition: DQMStore.cc:1580
QCriterion * getQCriterion(const std::string &qtname) const
Definition: DQMStore.cc:3168
IGetter * igetter_
Definition: DQMStore.h:706
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:677
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:453
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:1104
bool containsAnyMonitorable(const std::string &path) const
Definition: DQMStore.cc:1698
uint32_t moduleId
Definition: DQMNet.h:104
inline::google::protobuf::uint32 size() const
bool isCollateME(MonitorElement *me) const
Definition: DQMStore.cc:3361
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:2375
const ::std::string & full_pathname() const
void cd(void)
Definition: DQMStore.cc:311
int getStatus(const std::string &path="") const
Definition: DQMStore.cc:3274
void copyFrom(TH1 *from)
MonitorElement * initialise(Kind kind)
static const int OTHER
static void mergePath(std::string &path, const std::string &dir, const std::string &name)
Definition: DQMStore.cc:108
std::string algorithm
Definition: DQMNet.h:93
std::vector< std::string > getSubdirs(void) const
Definition: DQMStore.cc:1659
TProfile2D * getTProfile2D(void) const
MonitorElement * book1D(const char *name, const char *title, int nchX, double lowX, double highX)
Book 1D histogram.
Definition: DQMStore.cc:954
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:3101
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:2937
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:1838
static void collate3D(MonitorElement *me, TH3F *h)
Definition: DQMStore.cc:1563
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:1216
static void collate1D(MonitorElement *me, TH1F *h)
Definition: DQMStore.cc:1521
void setLumi(uint32_t ls)
void cd(void)
Definition: DQMStore.cc:266
void cd(void)
go to top directory (ie. root)
Definition: DQMStore.cc:644
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:1126
uint32_t streamId_
Definition: DQMStore.h:693
tuple lumi
Definition: fjr2json.py:35
void markForDeletion(uint32_t run, uint32_t lumi)
Definition: DQMStore.cc:2040
static void collate1DD(MonitorElement *me, TH1D *h)
Definition: DQMStore.cc:1535
static const std::string s_safe
Definition: DQMStore.cc:56
static void splitPath(std::string &dir, std::string &name, const std::string &path)
Definition: DQMStore.cc:95
uint32_t flags
Definition: DQMNet.h:98
const std::string & pwd(void)
Definition: DQMStore.cc:282
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:1959
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:99
bool reset_
Definition: DQMStore.h:685
const std::string * dirname
Definition: DQMNet.h:105
MonitorElement * book1DD(const char *name, const char *title, int nchX, double lowX, double highX)
Book 1S histogram.
Definition: DQMStore.cc:986
void initializeFrom(const edm::ParameterSet &)
Definition: DQMStore.cc:520
OpenRunDirs
Definition: DQMStore.h:82
void set_flags(::google::protobuf::uint32 value)
uint32_t run
Definition: DQMNet.h:101
uint32_t moduleId_
Definition: DQMStore.h:694
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:700
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:809
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:704
MonitorElement * bookFloat(const char *name)
Book float.
Definition: DQMStore.cc:891
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:1594
~DQMStore(void)
Definition: DQMStore.cc:509
void disableSoftReset(MonitorElement *me)
Definition: DQMStore.cc:3313
static void collateProfile(MonitorElement *me, TProfile *h)
Definition: DQMStore.cc:1570
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:2019
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:1921
fastmatch(std::string const &_fastString)
Definition: DQMStore.cc:129
unsigned verboseQT_
Definition: DQMStore.h:684
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:3135
QTestSpecs qtestspecs_
Definition: DQMStore.h:702
tuple path
else: Piece not in the list, fine.
double scaleFlag_
Definition: DQMStore.h:686
void get_info(const dqmstorepb::ROOTFilePB_Histo &, std::string &dirname, std::string &objname, TObject **obj)
Definition: DQMStore.cc:3000
void watchPostSourceRun(PostSourceRun::slot_type const &iSlot)
MonitorElement * bookString(const char *name, const char *value)
Book string.
Definition: DQMStore.cc:920
static void collate1S(MonitorElement *me, TH1S *h)
Definition: DQMStore.cc:1528
void setAccumulate(bool)
uint32_t lumi
Definition: DQMNet.h:102
bool isCollate(void) const
Definition: DQMStore.cc:3352
tuple result
Definition: query.py:137
void removeElement(const std::string &name)
Definition: DQMStore.cc:3143
void addProfiles(TProfile *h1, TProfile *h2, TProfile *sum, float c1, float c2)
static bool checkBinningMatches(MonitorElement *me, TH1 *h)
Definition: DQMStore.cc:1494
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:692
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:1268
QCriterion * makeQCriterion(const std::string &qtname)
Definition: DQMStore.cc:119
#define end
Definition: vmac.h:37
void setVerbose(unsigned level)
Definition: DQMStore.cc:631
void softReset(MonitorElement *me)
Definition: DQMStore.cc:3305
std::string pwd_
Definition: DQMStore.h:696
Kind kind(void) const
Get the type of the monitor element.
void runQTests(void)
Definition: DQMStore.cc:3253
TObject * extractNextObject(TBufferFile &) const
Definition: DQMStore.cc:2992
lat::Regexp * regexp_
Definition: DQMStore.h:68
IBooker * ibooker_
Definition: DQMStore.h:705
MonitorElement * get(const std::string &path) const
get ME from full pathname (e.g. &quot;my/long/dir/my_histo&quot;)
Definition: DQMStore.cc:1708
QAMap qalgos_
Definition: DQMStore.h:701
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:1737
std::string readSelectedDirectory_
Definition: DQMStore.h:691
std::vector< std::string > getMEs(void)
Definition: DQMStore.cc:299
std::string objname
Definition: DQMNet.h:106
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:92
DQMNet::CoreObject data_
bool dirExists(const std::string &path) const
true if directory exists
Definition: DQMStore.cc:732
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:2417
void getAllTags(std::vector< std::string > &into) const
Definition: DQMStore.cc:1868
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:2910
void scaleElements(void)
Definition: DQMStore.cc:3369
~fastmatch()
Definition: DQMStore.cc:199
void tagAllContents(const std::string &path, unsigned int myTag)
Definition: DQMStore.cc:1637
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:683
void set_size(::google::protobuf::uint32 value)
static void collate2S(MonitorElement *me, TH2S *h)
Definition: DQMStore.cc:1549
MEMap data_
Definition: DQMStore.h:697
part
Definition: HCALResponse.h:20
int64_t getIntValue(void) const
static void collate2D(MonitorElement *me, TH2F *h)
Definition: DQMStore.cc:1542
static const std::string s_referenceDirName
Definition: DQMStore.cc:54
void print_trace(const std::string &dir, const std::string &name)
Definition: DQMStore.cc:580
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:3218
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:1682
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:2740
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:2079
bool forceResetOnBeginLumi_
Definition: DQMStore.h:690
static void collate2DD(MonitorElement *me, TH2D *h)
Definition: DQMStore.cc:1556
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:1625
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:2540
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:3021
TProfile * getTProfile(void) const
void useQTest(const std::string &dir, const std::string &qtname)
Definition: DQMStore.cc:3200
tuple filename
Definition: lut2db_cfg.py:20
std::string message
Definition: DQMNet.h:91
void goUp(void)
equivalent to &quot;cd ..&quot;
Definition: DQMStore.cc:678
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:2895
inline::google::protobuf::uint32 flags() const
static const int STATUS_OK
void setAccumulate(MonitorElement *me, bool flag)
Definition: DQMStore.cc:3322
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:3179
dbl *** dir
Definition: mlp_gen.cc:35
volatile std::atomic< bool > shutdown_flag false
void showDirStructure(void) const
Definition: DQMStore.cc:3332
void reset(void)
Definition: DQMStore.cc:1995
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:861
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:1082
tuple collateHistograms
for(const auto &isodef:isoDefs)
long double T
uint32_t streamId
Definition: DQMNet.h:103
void mergeAndResetMEsLuminositySummaryCache(uint32_t run, uint32_t lumi, uint32_t streamId, uint32_t moduleId)
Definition: DQMStore.cc:387
float qtresult
Definition: DQMNet.h:90
std::set< std::string > dirs_
Definition: DQMStore.h:698
bool collateHistograms_
Definition: DQMStore.h:687
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:689
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:970
tuple size
Write out results.
static const lat::Regexp s_rxmeqr1("^st:(\\d+):([-+e.\\d]+):([^:]*):(.*)$")
void makeDirectory(const std::string &path)
Definition: DQMStore.cc:691
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:667
static const int ERROR
const std::string & pwd(void) const
Definition: DQMStore.cc:639
bool enableMultiThread_
Definition: DQMStore.h:688
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:1412
void raiseDQMError(const char *context, const char *fmt,...)
Definition: DQMError.cc:11