CMS 3D CMS Logo

MonitorElement.h
Go to the documentation of this file.
1 #ifndef DQMSERVICES_CORE_MONITOR_ELEMENT_H
2 #define DQMSERVICES_CORE_MONITOR_ELEMENT_H
3 
4 #if __GNUC__ && !defined DQM_DEPRECATED
5 //#define DQM_DEPRECATED __attribute__((deprecated))
6 #define DQM_DEPRECATED
7 #endif
8 
10 
12 
14 
15 #include "TF1.h"
16 #include "TH1F.h"
17 #include "TH1S.h"
18 #include "TH1D.h"
19 #include "TH1I.h"
20 #include "TH2F.h"
21 #include "TH2S.h"
22 #include "TH2I.h"
23 #include "TH2D.h"
24 #include "TH3F.h"
25 #include "TProfile.h"
26 #include "TProfile2D.h"
27 #include "TObjString.h"
28 #include "TAxis.h"
29 
30 #include <mutex>
31 #include <memory>
32 #include <string>
33 #include <atomic>
34 #include <sstream>
35 #include <iomanip>
36 #include <cassert>
37 #include <cstdint>
38 #include <sys/time.h>
39 #include <oneapi/tbb/spin_mutex.h>
40 
41 // TODO: cleaup the usages and remove.
44 
45 // TODO: move to a better location (changing all usages)
46 namespace dqm {
49  namespace qstatus {
50  static const int OTHER = 30; //< Anything but 'ok','warning' or 'error'.
51  static const int DISABLED = 50; //< Test has been disabled.
52  static const int INVALID = 60; //< Problem preventing test from running.
53  static const int INSUF_STAT = 70; //< Insufficient statistics.
54  static const int DID_NOT_RUN = 90; //< Algorithm did not run.
55  static const int STATUS_OK = 100; //< Test was succesful.
56  static const int WARNING = 200; //< Test had some problems.
57  static const int ERROR = 300; //< Test has failed.
58  } // namespace qstatus
59 
60  namespace me_util {
62  }
63 } // namespace dqm
64 
65 // forward declarations for all our friends
66 namespace dqm::implementation {
67  class DQMStore;
68  class IBooker;
69 } // namespace dqm::implementation
70 struct DQMTTreeIO;
71 namespace dqm {
72  class DQMFileSaverPB;
73 }
74 class DQMService;
75 class QualityTester;
76 
77 namespace dqm::impl {
78 
79  using dqmmutex = tbb::spin_mutex;
80 
81  struct Access {
82  std::unique_lock<dqmmutex> guard_;
85  };
86  // TODO: can this be the same type, just const?
87  struct AccessMut {
88  std::unique_lock<dqmmutex> guard_;
91  };
92 
96  Access access() { return Access{std::unique_lock<dqmmutex>(lock_), data_.key_, data_.value_}; }
97  AccessMut accessMut() { return AccessMut{std::unique_lock<dqmmutex>(lock_), data_.key_, data_.value_}; }
98  };
99 
102  // these need to create and destroy MEs.
105  // these need to access some of the IO related methods.
106  friend ::DQMTTreeIO; // declared in DQMRootSource
107  friend ::dqm::DQMFileSaverPB;
108  friend ::DQMService;
109  // this one only needs syncCoreObject.
110  friend ::QualityTester;
111 
112  public:
115 
116  // Comparison helper used in DQMStore to insert into sets. This needs deep
117  // private access to the MEData, that is why it lives here.
118  struct MEComparison {
119  using is_transparent = int; // magic marker to allow C++14 heterogeneous set lookup.
120 
121  auto make_tuple(MonitorElement *me) const {
122  return std::make_tuple(std::reference_wrapper(me->getPathname()), std::reference_wrapper(me->getName()));
123  }
125  return std::make_tuple(std::reference_wrapper(path.getDirname()), std::reference_wrapper(path.getObjectname()));
126  }
127  bool operator()(MonitorElement *left, MonitorElement *right) const {
128  return make_tuple(left) < make_tuple(right);
129  }
130  bool operator()(MonitorElement *left, MonitorElementData::Path const &right) const {
131  return make_tuple(left) < make_tuple(right);
132  }
133  bool operator()(MonitorElementData::Path const &left, MonitorElement *right) const {
134  return make_tuple(left) < make_tuple(right);
135  }
136  bool operator()(MonitorElementData::Path const &left, MonitorElementData::Path const &right) const {
137  return make_tuple(left) < make_tuple(right);
138  }
139  };
140 
141  private:
142  std::shared_ptr<MutableMonitorElementData> mutable_; // only set if this is a mutable copy of this ME
143  // there are no immutable MEs at this time, but we might need them in the future.
153  const Access access() const {
154  // First, check if there is a mutable object
155  if (mutable_) {
156  // if there is a mutable object, that is the truth, and we take a lock.
157  return mutable_->access();
158  } // else
159  throw cms::Exception("LogicError") << "MonitorElement " << getName() << " not backed by any data!";
160  }
161 
163  // For completeness, set the legacy `updated` marker.
164  this->update();
165 
166  // First, check if there is a mutable object
167  if (mutable_) {
168  // if there is a mutable object, that is the truth, and we take a lock.
169  return mutable_->accessMut();
170  } // else
171  throw cms::Exception("LogicError") << "MonitorElement " << getName() << " not backed by any data!";
172  }
173 
174  private:
175  // but internal -- only for DQMStore etc.
176 
177  // Create ME using this data. A ROOT object pointer may be moved into the
178  // new ME. The new ME will own this data.
180  // Create new ME and take ownership of this data.
181  MonitorElement(std::shared_ptr<MutableMonitorElementData> data);
182  // Create a new ME sharing data with this existing ME.
184 
185  // return a new clone of the data of this ME. Calls ->Clone(), new object
186  // is owned by the returned value.
188 
189  // Remove access to the data.
190  std::shared_ptr<MutableMonitorElementData> release();
191 
192  // re-initialize this ME as a shared copy of the other.
194  // re-initialize taking ownership of this data.
195  void switchData(std::shared_ptr<MutableMonitorElementData> data);
196 
197  // Replace the ROOT object in this ME's data with the new object, taking
198  // ownership. The old object is deleted.
199  void switchObject(std::unique_ptr<TH1> &&newobject);
200 
201  // copy applicable fileds into the DQMNet core object for compatibility.
202  // In a few places these flags are also still used by the ME.
203  void syncCoreObject();
205 
206  // check if the ME is currently backed by MEData; if false (almost) any
207  // access will throw.
208  bool isValid() const { return mutable_ != nullptr; }
209 
210  // used to implement getQErrors et. al.
211  template <typename FILTER>
212  std::vector<MonitorElementData::QReport *> filterQReports(FILTER filter) const;
213 
214  // legacy interfaces, there are no alternatives but they should not be used
215 
217  bool operator<(const MonitorElement &x) const { return DQMNet::setOrder(data_, x.data_); }
219  static bool CheckBinLabels(const TAxis *a1, const TAxis *a2);
221  uint32_t flags() const { return data_.flags; }
224 
225  // mostly used for IO, should be private.
226  std::string valueString() const;
227  std::string tagString() const;
228  std::string tagLabelString() const;
229  std::string effLabelString() const;
231 
232  // kept for DQMService. data_ is also used for MEComparison, without it
233  // we'd need to keep a copy od the name somewhere else.
235  bool wasUpdated() const { return data_.flags & DQMNet::DQM_PROP_NEW; }
236  void packScalarData(std::string &into, const char *prefix) const;
237  void packQualityData(std::string &into) const;
238  DQMNet::CoreObject data_; //< Core object information.
239 
240  public:
241  MonitorElement &operator=(const MonitorElement &) = delete;
243  virtual ~MonitorElement();
244 
245  public:
246  // good to be used in subsystem code
247 
250 
252  const std::string &getName() const { return this->data_.objname; }
253 
255  const std::string &getPathname() const { return this->data_.dirname; }
256 
259 
261 
263 
265  bool getLumiFlag() const { return access().key.scope_ == MonitorElementData::Scope::LUMI; }
266 
270  auto access = this->accessMut();
271  if (access.value.object_)
272  access.value.object_->SetBit(TH1::kIsAverage);
273  }
275  auto access = this->access();
276  return access.value.object_ && access.value.object_->TestBit(TH1::kIsAverage);
277  }
278 
279  private:
280  // A static assert to check that T actually fits in
281  // int64_t.
282  template <typename T>
284  int checkArray[sizeof(int64_t) - sizeof(T) + 1];
285  };
286 
287  void doFill(int64_t x);
288 
289  public:
290  // filling API.
291 
292  void Fill(long long x) {
294  doFill(static_cast<int64_t>(x));
295  }
296  void Fill(unsigned long long x) {
298  doFill(static_cast<int64_t>(x));
299  }
300  void Fill(unsigned long x) {
302  doFill(static_cast<int64_t>(x));
303  }
304  void Fill(long x) {
306  doFill(static_cast<int64_t>(x));
307  }
308  void Fill(unsigned int x) {
310  doFill(static_cast<int64_t>(x));
311  }
312  void Fill(int x) {
314  doFill(static_cast<int64_t>(x));
315  }
316  void Fill(short x) {
318  doFill(static_cast<int64_t>(x));
319  }
320  void Fill(unsigned short x) {
322  doFill(static_cast<int64_t>(x));
323  }
324  void Fill(char x) {
326  doFill(static_cast<int64_t>(x));
327  }
328  void Fill(unsigned char x) {
330  doFill(static_cast<int64_t>(x));
331  }
332 
333  void Fill(float x) { Fill(static_cast<double>(x)); }
334  void Fill(double x);
335  void Fill(std::string &value);
336 
337  void Fill(double x, double yw);
338  void Fill(double x, double y, double zw);
339  void Fill(double x, double y, double z, double w);
341  void ShiftFillLast(double y, double ye = 0., int32_t xscale = 1);
342 
343  public:
344  // additional APIs, mainly for harvesting.
345 
347  virtual void Reset();
348 
351 
354 
357 
359  const MonitorElementData::QReport *getQReport(const std::string &qtname) const;
361  std::vector<MonitorElementData::QReport *> getQReports() const;
363  void getQReport(bool create, const std::string &qtname, MonitorElementData::QReport *&qr, DQMNet::QValue *&qv);
364 
366  std::vector<MonitorElementData::QReport *> getQWarnings() const;
368  std::vector<MonitorElementData::QReport *> getQErrors() const;
370  std::vector<MonitorElementData::QReport *> getQOthers() const;
371 
372  // const and data-independent -- safe
373  virtual int getNbinsX() const;
374  virtual int getNbinsY() const;
375  virtual int getNbinsZ() const;
376  virtual int getBin(int binx, int biny) const;
377  virtual std::string getAxisTitle(int axis = 1) const;
378  virtual std::string getTitle() const;
379 
380  // const but data-dependent -- semantically unsafe in RECO
381  virtual double getMean(int axis = 1) const;
382  virtual double getMeanError(int axis = 1) const;
383  virtual double getRMS(int axis = 1) const;
384  virtual double getRMSError(int axis = 1) const;
385  virtual double getBinContent(int binx) const;
386  virtual double getBinContent(int binx, int biny) const;
387  virtual double getBinContent(int binx, int biny, int binz) const;
388  virtual double getBinError(int binx) const;
389  virtual double getBinError(int binx, int biny) const;
390  virtual double getBinError(int binx, int biny, int binz) const;
391  virtual double getEntries() const;
392  virtual double getBinEntries(int bin) const;
393  virtual double getBinEntries(int binx, int biny) const;
394  virtual double integral() const;
395 
396  virtual int64_t getIntValue() const;
397  virtual double getFloatValue() const;
398  virtual const std::string &getStringValue() const;
399 
400  // non-const -- thread safety and semantical issues
401  virtual void setBinContent(int binx, double content);
402  virtual void setBinContent(int binx, int biny, double content);
403  virtual void setBinContent(int binx, int biny, int binz, double content);
404  virtual void setBinError(int binx, double error);
405  virtual void setBinError(int binx, int biny, double error);
406  virtual void setBinError(int binx, int biny, int binz, double error);
407  virtual void setBinEntries(int bin, double nentries);
408  virtual void setEntries(double nentries);
409  virtual void divide(const MonitorElement *, const MonitorElement *, double, double, const char *);
410  virtual void setBinLabel(int bin, const std::string &label, int axis = 1);
411  virtual void setAxisRange(double xmin, double xmax, int axis = 1);
412  virtual void setAxisTitle(const std::string &title, int axis = 1);
413  virtual void setAxisTimeDisplay(int value, int axis = 1);
414  virtual void setAxisTimeFormat(const char *format = "", int axis = 1);
415  virtual void setTitle(const std::string &title);
416 
417  // additional operations mainly for booking
418  virtual void setXTitle(std::string const &title);
419  virtual void setYTitle(std::string const &title);
420  virtual void enableSumw2();
421  virtual void disableAlphanumeric();
422  virtual void setOption(const char *option);
423  virtual double getAxisMin(int axis = 1) const;
424  virtual double getAxisMax(int axis = 1) const;
425  // We should avoid extending histograms in general, and if the behaviour
426  // is actually needed, provide a more specific interface rather than
427  // relying on the ROOT behaviour.
429  virtual void setCanExtend(unsigned int value);
430  // We should decide if we support this (or make it default)
432  virtual void setStatOverflows(bool value);
433  virtual bool getStatOverflows();
434 
435  // these should be non-const, since they are potentially not thread-safe
436  virtual TObject const *getRootObject() const;
437  virtual TH1 *getTH1();
438  virtual TH1F *getTH1F();
439  virtual TH1S *getTH1S();
440  virtual TH1D *getTH1D();
441  virtual TH1I *getTH1I();
442  virtual TH2F *getTH2F();
443  virtual TH2S *getTH2S();
444  virtual TH2I *getTH2I();
445  virtual TH2D *getTH2D();
446  virtual TH3F *getTH3F();
447  virtual TProfile *getTProfile();
448  virtual TProfile2D *getTProfile2D();
449 
450  private:
451  void incompatible(const char *func) const;
452  TH1 const *accessRootObject(Access const &access, const char *func, int reqdim) const;
453  TH1 *accessRootObject(AccessMut const &, const char *func, int reqdim) const;
454 
455  TAxis const *getAxis(Access const &access, const char *func, int axis) const;
456  TAxis *getAxis(AccessMut const &access, const char *func, int axis) const;
457  };
458 
459 } // namespace dqm::impl
460 
461 // These may become distinct classes in the future.
462 namespace dqm::reco {
464 }
465 namespace dqm::legacy {
467  public:
468  // import constructors
470 
471  // Add ROOT object accessors without cost here so that harvesting code can
472  // still freely use getTH1() and friends.
474  TObject *getRootObject() const override {
475  return const_cast<TObject *>(
477  };
479  virtual TH1 *getTH1() const {
481  };
483  virtual TH1F *getTH1F() const {
485  };
487  virtual TH1S *getTH1S() const {
489  };
491  virtual TH1D *getTH1D() const {
493  };
495  virtual TH1I *getTH1I() const {
497  };
499  virtual TH2F *getTH2F() const {
501  };
503  virtual TH2S *getTH2S() const {
505  };
507  virtual TH2I *getTH2I() const {
509  };
511  virtual TH2D *getTH2D() const {
513  };
515  virtual TH3F *getTH3F() const {
517  };
519  virtual TProfile *getTProfile() const {
521  };
523  virtual TProfile2D *getTProfile2D() const {
525  };
526  };
527 } // namespace dqm::legacy
528 namespace dqm::harvesting {
530 }
531 
532 #endif // DQMSERVICES_CORE_MONITOR_ELEMENT_H
static const uint32_t DQM_PROP_REPORT_WARN
Definition: DQMNet.h:51
virtual void setTitle(const std::string &title)
set (ie. change) histogram/profile title
std::shared_ptr< MutableMonitorElementData > mutable_
MonitorElement & operator=(const MonitorElement &)=delete
std::string tagLabelString() const
return label string for the monitor element tag (eg. <name>t=12345</name>)
virtual TH3F * getTH3F() const
virtual TProfile * getTProfile() const
virtual int getNbinsZ() const
get # of bins in Z-axis
virtual DQM_DEPRECATED void setCanExtend(unsigned int value)
virtual double getBinEntries(int bin) const
get # of bin entries (for profiles)
virtual void disableAlphanumeric()
static const int OTHER
std::shared_ptr< MutableMonitorElementData > release()
def create(alignables, pedeDump, additionalData, outputFile, config)
DQMNet::CoreObject data_
double Scalar
Definition: Definitions.h:25
virtual double integral() const
get integral of bins
virtual void setEntries(double nentries)
set # of entries
virtual void setAxisTimeDisplay(int value, int axis=1)
set x-, y-, or z-axis to display time values
T w() const
MonitorElementData::Key const & key
virtual void setOption(const char *option)
virtual void setAxisTimeFormat(const char *format="", int axis=1)
set the format of the time values that are displayed on an axis
std::vector< MonitorElementData::QReport * > getQReports() const
get map of QReports
virtual double getRMSError(int axis=1) const
get RMS uncertainty of histogram along x, y or z axis(axis=1,2,3 respectively)
virtual TH2I * getTH2I() const
uint32_t flags
Definition: DQMNet.h:90
edm::propagate_const< std::unique_ptr< TH1 > > object_
std::vector< MonitorElementData::QReport * > getQOthers() const
from last set of quality tests
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check the consistency of the axis labels.
std::vector< MonitorElementData::QReport * > filterQReports(FILTER filter) const
virtual std::string getAxisTitle(int axis=1) const
get x-, y- or z-axis title (axis=1, 2, 3 respectively)
Kind kind() const
Get the type of the monitor element.
static const int WARNING
std::string effLabelString() const
return label string for the monitor element tag (eg. <name>t=12345</name>)
virtual bool getStatOverflows()
tbb::spin_mutex dqmmutex
MonitorElement(MonitorElementData &&data)
const Access access() const
std::vector< MonitorElementData::QReport * > getQErrors() const
get errors from last set of quality tests
void switchData(MonitorElement *other)
std::string valueString() const
dqm::reco::DQMStore DQMStore
bool getLumiFlag() const
true if ME is meant to be stored for each luminosity section
void Fill(long long x)
virtual TH2F * getTH2F() const
virtual void Reset()
Remove all data from the ME, keept the empty histogram with all its settings.
DQM_DEPRECATED void ShiftFillLast(double y, double ye=0., int32_t xscale=1)
char const * label
MonitorElementData::QReport QReport
virtual double getRMS(int axis=1) const
get RMS of histogram along x, y or z axis (axis=1, 2, 3 respectively)
edm::LuminosityBlockID getRunLumi()
static const int INVALID
virtual void setXTitle(std::string const &title)
virtual TProfile2D * getTProfile2D()
bool hasOtherReport() const
true if at least of one of the tests returned some other (non-ok) status
bool operator<(const MonitorElement &x) const
Compare monitor elements, for ordering in sets.
MonitorElementData::Kind Kind
virtual void setAxisRange(double xmin, double xmax, int axis=1)
set x-, y- or z-axis range (axis=1, 2, 3 respectively)
const MonitorElementData::QReport * getQReport(const std::string &qtname) const
get QReport corresponding to <qtname> (null pointer if QReport does not exist)
virtual double getFloatValue() const
std::unique_lock< dqmmutex > guard_
static const int INSUF_STAT
void switchObject(std::unique_ptr< TH1 > &&newobject)
void Fill(unsigned int x)
void doFill(int64_t x)
"Fill" ME method for int64_t
MonitorElementData cloneMEData()
TH1 const * accessRootObject(Access const &access, const char *func, int reqdim) const
void packScalarData(std::string &into, const char *prefix) const
convert scalar data into a string.
static const int DID_NOT_RUN
static const uint32_t DQM_PROP_REPORT_ERROR
Definition: DQMNet.h:50
TAxis const * getAxis(Access const &access, const char *func, int axis) const
static const int DISABLED
virtual TH1D * getTH1D() const
std::string dirname
Definition: DQMNet.h:97
std::unique_lock< dqmmutex > guard_
virtual double getEntries() const
get # of entries
Definition: value.py:1
static const uint32_t DQM_PROP_REPORT_OTHER
Definition: DQMNet.h:52
void Fill(unsigned short x)
void Fill(unsigned long x)
bool operator()(MonitorElement *left, MonitorElementData::Path const &right) const
virtual void setBinLabel(int bin, const std::string &label, int axis=1)
set bin label for x, y or z axis (axis=1, 2, 3 respectively)
virtual TProfile * getTProfile()
std::string objname
Definition: DQMNet.h:98
virtual int getNbinsY() const
get # of bins in Y-axis
MonitorElementData::Value & value
MonitorElementData::Scope getScope()
virtual std::string getTitle() const
get MonitorElement title
void Fill(unsigned char x)
dqm::legacy::MonitorElement MonitorElement
MonitorElementData::Value const & value
virtual TObject const * getRootObject() const
void update()
Mark the object updated.
std::string getFullname() const
get full name of ME including Pathname
std::vector< MonitorElementData::QReport * > getQWarnings() const
get warnings from last set of quality tests
virtual void setYTitle(std::string const &title)
virtual void setBinEntries(int bin, double nentries)
set # of bin entries (to be used for profiles)
const std::string & getPathname() const
get pathname of parent folder
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
uint32_t flags() const
Get the object flags.
bool operator()(MonitorElementData::Path const &left, MonitorElement *right) const
bool operator()(MonitorElementData::Path const &left, MonitorElementData::Path const &right) const
MonitorElementData::Key const & key
virtual TH1F * getTH1F() const
std::string qualityTagString(const DQMNet::QValue &qv) const
bool wasUpdated() const
true if ME was updated in last monitoring cycle
virtual DQM_DEPRECATED void setStatOverflows(bool value)
std::string tagString() const
virtual TH1I * getTH1I() const
virtual double getAxisMin(int axis=1) const
virtual TH1S * getTH1S() const
virtual TH1 * getTH1() const
virtual const std::string & getStringValue() const
const std::string & getName() const
get name of ME
virtual double getMean(int axis=1) const
get mean value of histogram along x, y or z axis (axis=1, 2, 3 respectively)
void packQualityData(std::string &into) const
serialise quality report information into a string.
MonitorElementData::QReport::DQMChannel DQMChannel
auto make_tuple(MonitorElement *me) const
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
void Fill(unsigned long long x)
static bool setOrder(const CoreObject &a, const CoreObject &b)
Definition: DQMNet.h:166
virtual double getAxisMax(int axis=1) const
virtual TProfile2D * getTProfile2D() const
float x
static const int STATUS_OK
virtual int getBin(int binx, int biny) const
get global bin number (for 2-D profiles)
dqm::reco::DQMStore::IBooker IBooker
virtual int getNbinsX() const
get # of bins in X-axis
virtual double getBinError(int binx) const
get uncertainty on content of bin (1-D) - See TH1::GetBinError for details
auto zw(V v) -> Vec2< typename std::remove_reference< decltype(v[0])>::type >
Definition: ExtVec.h:71
TObject * getRootObject() const override
virtual void setBinError(int binx, double error)
set uncertainty on content of bin (1-D)
static const uint32_t DQM_PROP_NEW
Definition: DQMNet.h:60
static const uint32_t DQM_PROP_TYPE_MASK
Definition: DQMNet.h:27
bool hasError() const
true if at least of one of the quality tests returned an error
auto make_tuple(MonitorElementData::Path const &path) const
long double T
Definition: DQMStore.h:18
int checkArray[sizeof(int64_t) - sizeof(T)+1]
void incompatible(const char *func) const
virtual double getMeanError(int axis=1) const
bool hasWarning() const
true if at least of one of the quality tests returned a warning
virtual TH2S * getTH2S() const
virtual void divide(const MonitorElement *, const MonitorElement *, double, double, const char *)
Replace entries with results of dividing num by denom.
#define DQM_DEPRECATED
Definition: DQMStore.cc:2
static const int ERROR
bool operator()(MonitorElement *left, MonitorElement *right) const
virtual double getBinContent(int binx) const
get content of bin (1-D)
virtual void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)
virtual int64_t getIntValue() const
virtual TH2D * getTH2D() const