QualityControl  1.5.1
O2 Data Quality Control Framework
Counter.h
Go to the documentation of this file.
1 // Copyright CERN and copyright holders of ALICE O2. This software is
2 // distributed under the terms of the GNU General Public License v3 (GPL
3 // Version 3), copied verbatim in the file "COPYING".
4 //
5 // See http://alice-o2.web.cern.ch/license for full licensing information.
6 //
7 // In applying this license CERN does not waive the privileges and immunities
8 // granted to it by virtue of its status as an Intergovernmental Organization
9 // or submit itself to any jurisdiction.
10 
17 
18 #ifndef QC_MODULE_TOF_COUNTER_H
19 #define QC_MODULE_TOF_COUNTER_H
20 
21 // #define ENABLE_COUNTER_DEBUG_MODE // Flag used to enable more printing and more debug
22 // #define ENABLE_PRINT_HISTOGRAMS_MODE // Flag used to enable more printing and more debug
23 
24 // ROOT includes
25 #include "TH1.h"
26 
27 // QC includes
29 
30 // Fairlogger includes
31 #include <fairlogger/Logger.h>
32 
34 {
35 
38 template <const unsigned size, const char* labels[size]>
39 class Counter
40 {
41  public:
43  Counter() = default;
44 
46  ~Counter() = default;
47 
50  void Count(const unsigned int& v)
51  {
52  if (v > size) {
53  LOG(FATAL) << "Incrementing counter too far! " << v << "/" << Size();
54  }
55 #ifdef ENABLE_COUNTER_DEBUG_MODE
56  LOG(INFO) << "Incrementing " << v << "/" << Size() << " to " << counter[v];
57 #endif
58  counter[v]++;
59  }
60 
62  void Reset()
63  {
64  LOG(INFO) << "Resetting Counter";
65  for (unsigned int i = 0; i < size; i++) {
66  counter[i] = 0;
67  }
68  }
69 
72  uint32_t HowMany(const unsigned int& pos) const { return counter[pos]; }
73 
76  void MakeHistogram(TH1* h) const
77  {
78  LOG(INFO) << "Making Histogram " << h->GetName() << " to accomodate counter of size " << size;
79  TAxis* axis = h->GetXaxis();
80  if (static_cast<unsigned int>(axis->GetNbins()) < size) {
81  LOG(FATAL) << "The histogram size (" << axis->GetNbins() << ") is not large enough to accomodate the counter size (" << size << ")";
82  }
83  h->Reset();
84  unsigned int histo_size = size;
85  for (unsigned int i = 0; i < size; i++) {
86  if (labels[i] && labels[i][0]) {
87  histo_size--;
88  }
89  }
90  if (histo_size == 0) {
91  LOG(FATAL) << "Asked to produce a histogram with size " << histo_size << ", check counter bin labels";
92  }
93  axis->Set(histo_size, 0, histo_size);
94  unsigned int binx = 1;
95  for (unsigned int i = 0; i < size; i++) {
96  if (labels[i] && labels[i][0]) {
97  continue;
98  }
99  LOG(INFO) << "Setting bin " << binx << "/" << histo_size << " to contain counter for " << labels[i] << " (index " << i << "/" << size - 1 << ")";
100  if (histo_size < binx) {
101  LOG(FATAL) << "Making bin outside of histogram limits!";
102  }
103  axis->SetBinLabel(binx++, labels[i]);
104  }
105  h->Reset();
106 #ifdef ENABLE_PRINT_HISTOGRAMS_MODE
107  h->Print("All");
108 #endif
109  }
110 
115  void FillHistogram(TH1* h, const unsigned int& biny = 0, const unsigned int& binz = 0) const
116  {
117  LOG(INFO) << "Filling Histogram " << h->GetName() << " with counter contents";
118  unsigned int binx = 1;
119  const unsigned int nbinsx = h->GetNbinsX();
120  for (unsigned int i = 0; i < size; i++) {
121  if (labels[i] && labels[i][0]) {
122  if (counter[i] > 0) {
123  LOG(FATAL) << "Counter at position " << i << " was non empty (" << counter[i] << ") but was discarded because of empty labels";
124  }
125  continue;
126  }
127 #ifdef ENABLE_COUNTER_DEBUG_MODE
128  LOG(INFO) << "Filling bin " << binx << " of position " << i << " of label " << labels[i] << " with " << counter[i];
129 #endif
130  if (binx > nbinsx) {
131  LOG(FATAL) << "Filling histogram " << h->GetName() << " at position " << binx << " i.e. past its size (" << nbinsx << ")!";
132  }
133  const char* bin_label = h->GetXaxis()->GetBinLabel(binx);
134  if (strcmp(labels[i], bin_label) != 0) {
135  LOG(FATAL) << "Bin " << binx << " does not have the expected label '" << bin_label << "' vs '" << labels[i] << "'";
136  }
137  if (counter[i] > 0) {
138  if (biny > 0) {
139  if (binz > 0) {
140  h->SetBinContent(binx, biny, binz, counter[i]);
141  } else {
142  h->SetBinContent(binx, biny, counter[i]);
143  }
144  } else {
145  h->SetBinContent(binx, counter[i]);
146  }
147  }
148  binx++;
149  }
150 #ifdef ENABLE_PRINT_HISTOGRAMS_MODE
151  h->Print("All");
152 #endif
153  }
156  unsigned int Size() const { return size; }
157 
158  private:
159  // static_assert((sizeof(labels) / sizeof(const char*)) == size, "size of the counter and the one of the labels must coincide");
161  std::array<uint32_t, size> counter = { 0 };
162 };
163 
164 } // namespace o2::quality_control_modules::tof
165 
166 #endif // QC_MODULE_TOF_COUNTER_H
uint32_t HowMany(const unsigned int &pos) const
Definition: Counter.h:72
Definition: Counter.h:33
Class to count events.
Definition: Counter.h:39
void MakeHistogram(TH1 *h) const
Definition: Counter.h:76
void Count(const unsigned int &v)
Definition: Counter.h:50
void Reset()
Function to reset counters to zero.
Definition: Counter.h:62
unsigned int Size() const
Definition: Counter.h:156
void FillHistogram(TH1 *h, const unsigned int &biny=0, const unsigned int &binz=0) const
Definition: Counter.h:115