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 
11 
13 
15 
16 #include "TF1.h"
17 #include "TH1F.h"
18 #include "TH1S.h"
19 #include "TH1D.h"
20 #include "TH2F.h"
21 #include "TH2S.h"
22 #include "TH2D.h"
23 #include "TH3F.h"
24 #include "TProfile.h"
25 #include "TProfile2D.h"
26 #include "TObjString.h"
27 #include "TAxis.h"
28 
29 #include <mutex>
30 #include <string>
31 #include <atomic>
32 #include <sstream>
33 #include <iomanip>
34 #include <cassert>
35 #include <cstdint>
36 #include <sys/time.h>
37 #include <tbb/spin_mutex.h>
38 
39 class QCriterion;
40 class DQMService;
41 namespace dqm::dqmstoreimpl {
42  class DQMStore;
43 }
44 
45 // tag for a special constructor, see below
47 
48 namespace dqm::impl {
49 
50  using dqmmutex = tbb::spin_mutex;
51 
52  struct Access {
53  std::unique_lock<dqmmutex> guard_;
56  };
57  // TODO: can this be the same type, just const?
58  struct AccessMut {
59  std::unique_lock<dqmmutex> guard_;
62  };
63 
67  Access access() { return Access{std::unique_lock<dqmmutex>(lock_), data_.key_, data_.value_}; }
68  AccessMut accessMut() { return AccessMut{std::unique_lock<dqmmutex>(lock_), data_.key_, data_.value_}; }
69  };
70 
74  friend DQMService;
75 
76  public:
79 
80  protected:
81  DQMNet::CoreObject data_; //< Core object information.
82  // TODO: we only use the ::Value part so far.
83  // Still using the full thing to remain compatible with the new ME implementation.
84 
85  std::atomic<MonitorElementData const *> frozen_; // only set if this ME is in a product already
86  std::atomic<MutableMonitorElementData *> mutable_; // only set if there is a mutable copy of this ME
102  const Access access() const {
103  // First, check if there is a mutable object
104  auto mut = mutable_.load();
105  if (mut) {
106  // if there is a mutable object, that is the truth, and we take a lock.
107  return mut->access();
108  } // else
109  auto frozen = frozen_.load();
110  if (frozen) {
111  // in case of an immutable object read from edm products, create an
112  // access object without lock.
113  return Access{std::unique_lock<dqmmutex>(), frozen->key_, frozen->value_};
114  }
115  // else
116  throw cms::Exception("LogicError") << "MonitorElement not backed by any data!";
117  }
118 
120  // For completeness, set the legacy `updated` marker.
121  this->update();
122 
123  // First, check if there is a mutable object
124  auto mut = mutable_.load();
125  if (mut) {
126  // if there is a mutable object, that is the truth, and we take a lock.
127  return mut->accessMut();
128  } // else
129  auto frozen = frozen_.load();
130  if (!frozen) {
131  throw cms::Exception("LogicError") << "MonitorElement not backed by any data!";
132  }
133  // in case of an immutable object read from edm products, attempt to
134  // make a clone.
136  clone->data_.key_ = frozen->key_;
137  clone->data_.value_.scalar_ = frozen->value_.scalar_;
138  if (frozen->value_.object_) {
139  // Clone() the TH1
140  clone->data_.value_.object_ = std::unique_ptr<TH1>(static_cast<TH1 *>(frozen->value_.object_->Clone()));
141  }
142 
143  // now try to set our clone, and see if it was still needed (sb. else
144  // might have made a clone already!)
146  bool ok = mutable_.compare_exchange_strong(existing, clone);
147  if (!ok) {
148  // somebody else made a clone already, it is now in existing
149  delete clone;
150  return existing->accessMut();
151  } else {
152  // we won the race, and our clone is the real one now.
153  return clone->accessMut();
154  }
155  // in either case, if somebody destroyed the mutable object between us
156  // getting the pointer and us locking it, we are screwed. We have to rely
157  // on edm and the DQM code to make sure we only turn mutable objects into
158  // products once all processing is done (logically, this is safe).
159  }
160 
161  //TODO: to be dropped.
162  TH1 *reference_; //< Current ROOT reference object.
163  TH1 *refvalue_; //< Soft reference if any.
164  std::vector<QReport> qreports_; //< QReports associated to this object.
165 
166  MonitorElement *initialise(Kind kind);
167  MonitorElement *initialise(Kind kind, TH1 *rootobj);
168  MonitorElement *initialise(Kind kind, const std::string &value);
169  void globalize() { data_.moduleId = 0; }
170  void setLumi(uint32_t ls) { data_.lumi = ls; }
171 
172  public:
173  MonitorElement();
175  MonitorElement(const std::string *path, const std::string &name, uint32_t run, uint32_t moduleId);
178  MonitorElement &operator=(const MonitorElement &) = delete;
179  MonitorElement &operator=(MonitorElement &&) = delete;
180  virtual ~MonitorElement();
181 
183  bool operator<(const MonitorElement &x) const { return DQMNet::setOrder(data_, x.data_); }
184 
186  static bool CheckBinLabels(const TAxis *a1, const TAxis *a2);
187 
189  Kind kind() const { return Kind(data_.flags & DQMNet::DQM_PROP_TYPE_MASK); }
190 
192  uint32_t flags() const { return data_.flags; }
193 
195  const std::string &getName() const { return data_.objname; }
196 
198  const std::string &getPathname() const { return *data_.dirname; }
199 
201  const std::string getFullname() const {
203  path.reserve(data_.dirname->size() + data_.objname.size() + 2);
204  path += *data_.dirname;
205  if (!data_.dirname->empty())
206  path += '/';
207  path += data_.objname;
208  return path;
209  }
210 
212  bool wasUpdated() const { return data_.flags & DQMNet::DQM_PROP_NEW; }
213 
215  void update() { data_.flags |= DQMNet::DQM_PROP_NEW; }
216 
219  void setResetMe(bool /* flag */) { data_.flags |= DQMNet::DQM_PROP_RESET; }
220 
222  bool getLumiFlag() const { return data_.flags & DQMNet::DQM_PROP_LUMI; }
223 
226 
230 
231  // A static assert to check that T actually fits in
232  // int64_t.
233  template <typename T>
235  int checkArray[sizeof(int64_t) - sizeof(T) + 1];
236  };
237 
238  protected:
239  void doFill(int64_t x);
240 
241  public:
242  void Fill(long long x) {
244  doFill(static_cast<int64_t>(x));
245  }
246  void Fill(unsigned long long x) {
248  doFill(static_cast<int64_t>(x));
249  }
250  void Fill(unsigned long x) {
252  doFill(static_cast<int64_t>(x));
253  }
254  void Fill(long x) {
256  doFill(static_cast<int64_t>(x));
257  }
258  void Fill(unsigned int x) {
260  doFill(static_cast<int64_t>(x));
261  }
262  void Fill(int x) {
264  doFill(static_cast<int64_t>(x));
265  }
266  void Fill(short x) {
268  doFill(static_cast<int64_t>(x));
269  }
270  void Fill(unsigned short x) {
272  doFill(static_cast<int64_t>(x));
273  }
274  void Fill(char x) {
276  doFill(static_cast<int64_t>(x));
277  }
278  void Fill(unsigned char x) {
280  doFill(static_cast<int64_t>(x));
281  }
282 
283  void Fill(float x) { Fill(static_cast<double>(x)); }
284  void Fill(double x);
285  void Fill(std::string &value);
286 
287  void Fill(double x, double yw);
288  void Fill(double x, double y, double zw);
289  void Fill(double x, double y, double z, double w);
291  void ShiftFillLast(double y, double ye = 0., int32_t xscale = 1);
292 
293  virtual void Reset();
294 
295  // mostly used for IO, should be private.
296  std::string valueString() const;
297  std::string tagString() const;
298  std::string tagLabelString() const;
299  std::string effLabelString() const;
300  std::string qualityTagString(const DQMNet::QValue &qv) const;
301 
303  bool hasError() const { return data_.flags & DQMNet::DQM_PROP_REPORT_ERROR; }
304 
306  bool hasWarning() const { return data_.flags & DQMNet::DQM_PROP_REPORT_WARN; }
307 
309  bool hasOtherReport() const { return data_.flags & DQMNet::DQM_PROP_REPORT_OTHER; }
310 
313  bool isEfficiency() const { return data_.flags & DQMNet::DQM_PROP_EFFICIENCY_PLOT; }
314 
316  const QReport *getQReport(const std::string &qtname) const;
318  std::vector<QReport *> getQReports() const;
320  std::vector<QReport *> getQWarnings() const;
322  std::vector<QReport *> getQErrors() const;
324  std::vector<QReport *> getQOthers() const;
325 
327  void runQTests();
328 
329  // const and data-independent -- safe
330  virtual int getNbinsX() const;
331  virtual int getNbinsY() const;
332  virtual int getNbinsZ() const;
333  virtual std::string getAxisTitle(int axis = 1) const;
334  virtual std::string getTitle() const;
335 
336  // const but data-dependent -- semantically unsafe in RECO
337  virtual double getMean(int axis = 1) const;
338  virtual double getMeanError(int axis = 1) const;
339  virtual double getRMS(int axis = 1) const;
340  virtual double getRMSError(int axis = 1) const;
341  virtual double getBinContent(int binx) const;
342  virtual double getBinContent(int binx, int biny) const;
343  virtual double getBinContent(int binx, int biny, int binz) const;
344  virtual double getBinError(int binx) const;
345  virtual double getBinError(int binx, int biny) const;
346  virtual double getBinError(int binx, int biny, int binz) const;
347  virtual double getEntries() const;
348  virtual double getBinEntries(int bin) const;
349 
350  // non-const -- thread safety and semantical issues
351  virtual void setBinContent(int binx, double content);
352  virtual void setBinContent(int binx, int biny, double content);
353  virtual void setBinContent(int binx, int biny, int binz, double content);
354  virtual void setBinError(int binx, double error);
355  virtual void setBinError(int binx, int biny, double error);
356  virtual void setBinError(int binx, int biny, int binz, double error);
357  virtual void setBinEntries(int bin, double nentries);
358  virtual void setEntries(double nentries);
359  virtual void setBinLabel(int bin, const std::string &label, int axis = 1);
360  virtual void setAxisRange(double xmin, double xmax, int axis = 1);
361  virtual void setAxisTitle(const std::string &title, int axis = 1);
362  virtual void setAxisTimeDisplay(int value, int axis = 1);
363  virtual void setAxisTimeFormat(const char *format = "", int axis = 1);
364  virtual void setTitle(const std::string &title);
365  // --- Operations that origianted in ConcurrentME ---
366  virtual void setXTitle(std::string const &title);
367  virtual void setYTitle(std::string const &title);
368  virtual void enableSumw2();
369  virtual void disableAlphanumeric();
370  virtual void setOption(const char *option);
371 
372  // new operations to reduce usage of getTH*
373  virtual double getAxisMin(int axis = 1) const;
374  virtual double getAxisMax(int axis = 1) const;
375  // We should avoid extending histograms in general, and if the behaviour
376  // is actually needed, provide a more specific interface rather than
377  // relying on the ROOT behaviour.
379  virtual void setCanExtend(unsigned int value);
380  // We should decide if we support this (or make it default)
382  virtual void setStatOverflows(unsigned int value);
383 
384  // these should be non-const, since they are potentially not thread-safe
385  virtual TObject const *getRootObject() const;
386  virtual TH1 *getTH1();
387  virtual TH1F *getTH1F();
388  virtual TH1S *getTH1S();
389  virtual TH1D *getTH1D();
390  virtual TH2F *getTH2F();
391  virtual TH2S *getTH2S();
392  virtual TH2D *getTH2D();
393  virtual TH3F *getTH3F();
394  virtual TProfile *getTProfile();
395  virtual TProfile2D *getTProfile2D();
396 
397  public:
398  virtual int64_t getIntValue() const;
399  virtual double getFloatValue() const;
400  virtual const std::string &getStringValue() const;
401  void packScalarData(std::string &into, const char *prefix) const;
402  void packQualityData(std::string &into) const;
403 
404  protected:
405  void incompatible(const char *func) const;
406  TH1 const *accessRootObject(Access const &access, const char *func, int reqdim) const;
407  TH1 *accessRootObject(AccessMut const &, const char *func, int reqdim) const;
408 
409  void setAxisTimeOffset(double toffset, const char *option = "local", int axis = 1);
410 
412  bool markedToDelete() const { return data_.flags & DQMNet::DQM_PROP_MARKTODELETE; }
413 
417 
419  void resetUpdate() { data_.flags &= ~DQMNet::DQM_PROP_NEW; }
420 
422  bool resetMe() const { return data_.flags & DQMNet::DQM_PROP_RESET; }
423 
424  TAxis const *getAxis(Access const &access, const char *func, int axis) const;
425  TAxis *getAxis(AccessMut const &access, const char *func, int axis) const;
426 
427  void addProfiles(TProfile *h1, TProfile *h2, TProfile *sum, float c1, float c2);
428  void addProfiles(TProfile2D *h1, TProfile2D *h2, TProfile2D *sum, float c1, float c2);
429  void copyFunctions(TH1 *from, TH1 *to);
430  void copyFrom(TH1 *from);
431 
432  // --- Operations on MEs that are normally reset at end of monitoring cycle ---
433  void getQReport(bool create, const std::string &qtname, QReport *&qr, DQMNet::QValue *&qv);
434  void addQReport(const DQMNet::QValue &desc, QCriterion *qc);
435  void addQReport(QCriterion *qc);
436  void updateQReportStats();
437 
438  public:
439  const uint32_t run() const { return data_.run; }
440  const uint32_t lumi() const { return data_.lumi; }
441  const uint32_t moduleId() const { return data_.moduleId; }
442  };
443 
444 } // namespace dqm::impl
445 
446 // These will become distinct classes in the future.
447 namespace dqm::reco {
449 }
450 namespace dqm::legacy {
452  public:
453  // import constructors
455 
457  TObject *getRootObject() const override {
458  return const_cast<TObject *>(
460  };
462  virtual TH1 *getTH1() const {
464  };
466  virtual TH1F *getTH1F() const {
468  };
470  virtual TH1S *getTH1S() const {
472  };
474  virtual TH1D *getTH1D() const {
476  };
478  virtual TH2F *getTH2F() const {
480  };
482  virtual TH2S *getTH2S() const {
484  };
486  virtual TH2D *getTH2D() const {
488  };
490  virtual TH3F *getTH3F() const {
492  };
494  virtual TProfile *getTProfile() const {
496  };
498  virtual TProfile2D *getTProfile2D() const {
500  };
501  void runQTests();
502  };
503 } // namespace dqm::legacy
504 namespace dqm::harvesting {
506 }
507 
508 #endif // DQMSERVICES_CORE_MONITOR_ELEMENT_H
virtual TH2D * getTH2D() const
static const uint32_t DQM_PROP_REPORT_WARN
Definition: DQMNet.h:47
std::vector< QReport > qreports_
uint32_t moduleId
Definition: DQMNet.h:100
virtual TH2F * getTH2F() const
std::atomic< MonitorElementData const * > frozen_
const double w
Definition: UKUtility.cc:23
def create(alignables, pedeDump, additionalData, outputFile, config)
DQMNet::CoreObject data_
double Scalar
Definition: Definitions.h:25
MonitorElementData::Key const & key
Definition: DQMNet.h:23
dqm::legacy::MonitorElement MonitorElement
Definition: DQMStore.h:73
std::atomic< MutableMonitorElementData * > mutable_
virtual TH1F * getTH1F() const
const std::string & getPathname() const
get pathname of parent folder
uint32_t flags
Definition: DQMNet.h:94
edm::propagate_const< std::unique_ptr< TH1 > > object_
void setLumiFlag()
this ME is meant to be stored for each luminosity section
Kind kind() const
Get the type of the monitor element.
const std::string & getName() const
get name of ME
static const uint32_t DQM_PROP_EFFICIENCY_PLOT
Definition: DQMNet.h:61
static const uint32_t DQM_PROP_RESET
Definition: DQMNet.h:54
const std::string * dirname
Definition: DQMNet.h:101
bool hasOtherReport() const
true if at least of one of the tests returned some other (non-ok) status
tbb::spin_mutex dqmmutex
static const uint32_t DQM_PROP_MARKTODELETE
Definition: DQMNet.h:62
uint32_t run
Definition: DQMNet.h:97
virtual TH1S * getTH1S() const
const std::string getFullname() const
get full name of ME including Pathname
dqm::dqmstoreimpl::DQMStore DQMStore
Definition: DQMStore.h:706
class DQMOldReceiver DQM_DEPRECATED
void setLumi(uint32_t ls)
void Fill(long long x)
char const * label
bool hasWarning() const
true if at least of one of the quality tests returned a warning
virtual TProfile2D * getTProfile2D()
bool operator<(const MonitorElement &x) const
Compare monitor elements, for ordering in sets.
const uint32_t run() const
bool markedToDelete() const
true if ME is marked for deletion
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
std::unique_lock< dqmmutex > guard_
uint32_t lumi
Definition: DQMNet.h:98
const uint32_t lumi() const
void Fill(unsigned int x)
static const uint32_t DQM_PROP_REPORT_ERROR
Definition: DQMNet.h:46
const uint32_t moduleId() const
std::unique_lock< dqmmutex > guard_
Definition: value.py:1
static const uint32_t DQM_PROP_REPORT_OTHER
Definition: DQMNet.h:48
void Fill(unsigned short x)
void Fill(unsigned long x)
virtual TProfile2D * getTProfile2D() const
virtual TProfile * getTProfile()
std::string objname
Definition: DQMNet.h:102
MonitorElementData::Value & value
virtual TH2S * getTH2S() const
void Fill(unsigned char x)
doFill
Definition: cuy.py:576
MonitorElementData::Value const & value
void update()
Mark the object updated.
def ls(path, rec=False)
Definition: eostools.py:349
bool hasError() const
true if at least of one of the quality tests returned an error
virtual TProfile * getTProfile() const
virtual TH1D * getTH1D() const
MonitorElementData::Key const & key
uint32_t flags() const
Get the object flags.
bool getLumiFlag() const
true if ME is meant to be stored for each luminosity section
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
bool resetMe() const
true if ME should be reset at end of monitoring cycle
bool wasUpdated() const
true if ME was updated in last monitoring cycle
#define update(a, b)
void Fill(unsigned long long x)
static bool setOrder(const CoreObject &a, const CoreObject &b)
Definition: DQMNet.h:170
const Access access() const
auto zw(V v) -> Vec2< typename std::remove_reference< decltype(v[0])>::type >
Definition: ExtVec.h:75
TObject * getRootObject() const override
void Reset(std::vector< TH2F > &depth)
static const uint32_t DQM_PROP_NEW
Definition: DQMNet.h:56
static const uint32_t DQM_PROP_TYPE_MASK
Definition: DQMNet.h:25
long double T
void resetUpdate()
reset "was updated" flag
virtual TObject const * getRootObject() const
static const uint32_t DQM_PROP_LUMI
Definition: DQMNet.h:58
virtual TH1 * getTH1() const
virtual TH3F * getTH3F() const