CMS 3D CMS Logo

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