1212// / \file Counter.h
1313// / \author Nicolo' Jacazio
1414// / \since 24/03/2020
15- // / \brief Utilities to count events and fill histograms at the end of the main processing loops
15+ // / \brief Utilities to count events and fill histograms at the end of the main processing loops.
16+ // / Can be used to count labelled and non labelled events and fill histograms only once.
1617// /
1718
1819#ifndef QC_MODULE_TOF_COUNTER_H
1920#define QC_MODULE_TOF_COUNTER_H
2021
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-
2422// ROOT includes
2523#include " TH1.h"
2624
@@ -35,7 +33,7 @@ namespace o2::quality_control_modules::tof
3533
3634// / \brief Class to count events
3735// / \author Nicolo' Jacazio
38- template <const unsigned size, const char * labels[size]>
36+ template <const unsigned int size, const char * labels[size]>
3937class Counter
4038{
4139 public:
@@ -47,119 +45,202 @@ class Counter
4745
4846 // / Function to increment a counter
4947 // / @param v Index in the counter array to increment
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- }
48+ void Count (const unsigned int & v);
6049
6150 // / Function to reset counters to zero
62- void Reset ()
63- {
64- LOG (INFO ) << " Resetting Counter" ;
65- for (unsigned int i = 0 ; i < size; i++) {
66- counter[i] = 0 ;
67- }
68- }
51+ void Reset ();
52+
53+ // / Function to print the counter content
54+ void Print ();
55+
56+ // / Function to get the total number of counts
57+ uint32_t Total ();
58+
59+ // / Function to get the total number of counts added since last call
60+ uint32_t TotalNew ();
61+
62+ // / Function to get the total number of counts and reset the counts
63+ uint32_t TotalAndReset ();
6964
7065 // / Function to get how many counts where observed
7166 // / @return Returns the number of counts observed for a particular index
7267 uint32_t HowMany (const unsigned int & pos) const { return counter[pos]; }
7368
7469 // / Function to make a histogram out of the counters
7570 // / @param h histogram to shape in order to have room for the counter size
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 << " )" ;
71+ void MakeHistogram (TH1 * h) const ;
72+
73+ // / Function to fill a histogram with the counters
74+ // / @param h The histogram to fill
75+ // / @param biny Y offset to fill to histogram, useful for TH2 and TH3
76+ // / @param binz Z offset to fill to histogram, useful for TH3
77+ void FillHistogram (TH1 * h, const unsigned int & biny = 0 , const unsigned int & binz = 0 ) const ;
78+
79+ // / Getter for the size
80+ // / @return Returns the size of the counter
81+ unsigned int Size () const { return size; }
82+
83+ private:
84+ // static_assert((sizeof(labels) / sizeof(const char*)) == size, "size of the counter and the one of the labels must coincide");
85+ // / Containers to fill
86+ std::array<uint32_t , size> counter = { 0 };
87+ uint32_t mTotal = 0 ;
88+ };
89+
90+ // //////////////////
91+ // Implementation //
92+ // //////////////////
93+
94+ // #define ENABLE_COUNTER_DEBUG_MODE // Flag used to enable more printing and more debug
95+ // #define ENABLE_PRINT_HISTOGRAMS_MODE // Flag used to enable more printing and more debug
96+
97+ template <const unsigned int size, const char * labels[size]>
98+ void Counter<size, labels>::Count(const unsigned int & v)
99+ {
100+ if (v > size) {
101+ LOG (FATAL ) << " Incrementing counter too far! " << v << " /" << size;
102+ }
103+ #ifdef ENABLE_COUNTER_DEBUG_MODE
104+ LOG (INFO ) << " Incrementing " << v << " /" << size << " to " << counter[v];
105+ #endif
106+ counter[v]++;
107+ }
108+
109+ template <const unsigned int size, const char * labels[size]>
110+ void Counter<size, labels>::Reset()
111+ {
112+ LOG (DEBUG ) << " Resetting Counter" ;
113+ for (unsigned int i = 0 ; i < size; i++) {
114+ counter[i] = 0 ;
115+ }
116+ }
117+
118+ template <const unsigned int size, const char * labels[size]>
119+ void Counter<size, labels>::Print()
120+ {
121+ for (unsigned int i = 0 ; i < size; i++) {
122+ if (labels) {
123+ LOG (DEBUG ) << " Bin " << i << " /" << size - 1 << " " << labels[i] << " = " << HowMany (i);
124+ } else {
125+ LOG (DEBUG ) << " Bin " << i << " /" << size - 1 << " = " << HowMany (i);
82126 }
83- h->Reset ();
84- unsigned int histo_size = size;
127+ }
128+ }
129+
130+ template <const unsigned int size, const char * labels[size]>
131+ uint32_t Counter<size, labels>::Total()
132+ {
133+ uint32_t sum = 0 ;
134+ for (unsigned int i = 0 ; i < size; i++) {
135+ sum += counter[i];
136+ }
137+ mTotal = sum;
138+ return sum;
139+ }
140+
141+ template <const unsigned int size, const char * labels[size]>
142+ uint32_t Counter<size, labels>::TotalNew()
143+ {
144+ uint32_t sum = mTotal ;
145+ return sum - Total ();
146+ }
147+
148+ template <const unsigned int size, const char * labels[size]>
149+ uint32_t Counter<size, labels>::TotalAndReset()
150+ {
151+ uint32_t sum = Total ();
152+ Reset ();
153+ return sum;
154+ }
155+
156+ template <const unsigned int size, const char * labels[size]>
157+ void Counter<size, labels>::MakeHistogram(TH1 * h) const
158+ {
159+ LOG (DEBUG ) << " Making Histogram " << h->GetName () << " to accomodate counter of size " << size;
160+ TAxis* axis = h->GetXaxis ();
161+ if (static_cast <unsigned int >(axis->GetNbins ()) < size) {
162+ LOG (FATAL ) << " The histogram size (" << axis->GetNbins () << " ) is not large enough to accomodate the counter size (" << size << " )" ;
163+ }
164+ h->Reset ();
165+ unsigned int histo_size = size;
166+ if (labels) { // Only if labels are defined
85167 for (unsigned int i = 0 ; i < size; i++) {
86- if (labels[i] && labels[i][0 ]) {
168+ if (labels[i] && !labels[i][0 ]) { // If label at position i is empty
169+ LOG (DEBUG ) << " Skipping label '" << labels[i] << " ' at position " << i << " /" << size - 1 ;
87170 histo_size--;
88171 }
89172 }
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);
173+ }
174+ if (histo_size == 0 ) {
175+ LOG (FATAL ) << " Asked to produce a histogram with size " << histo_size << " , check counter bin labels" ;
176+ } else {
177+ LOG (DEBUG ) << " Asked to produce a histogram with size " << histo_size << " out of the size " << size << " due to empty labels" ;
178+ }
179+
180+ axis->Set (histo_size, 0 , histo_size);
181+ if (labels) { // Only if labels are defined
94182 unsigned int binx = 1 ;
95183 for (unsigned int i = 0 ; i < size; i++) {
96- if (labels[i] && labels[i][0 ]) {
184+ if (labels[i] && ! labels[i][0 ]) { // If label at position i is empty
97185 continue ;
98186 }
99- LOG (INFO ) << " Setting bin " << binx << " /" << histo_size << " to contain counter for " << labels[i] << " (index " << i << " /" << size - 1 << " )" ;
187+ LOG (DEBUG ) << " Setting bin " << binx << " /" << histo_size << " to contain counter for ' " << labels[i] << " ' (index " << i << " /" << size - 1 << " )" ;
100188 if (histo_size < binx) {
101189 LOG (FATAL ) << " Making bin outside of histogram limits!" ;
102190 }
103191 axis->SetBinLabel (binx++, labels[i]);
104192 }
105- h->Reset ();
193+ }
194+ h->Reset ();
106195#ifdef ENABLE_PRINT_HISTOGRAMS_MODE
107- h->Print (" All" );
196+ h->Print (" All" );
108197#endif
109- }
198+ }
110199
111- // / Function to fill a histogram with the counters
112- // / @param h The histogram to fill
113- // / @param biny Y offset to fill to histogram, useful for TH2 and TH3
114- // / @param binz Z offset to fill to histogram, useful for TH3
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 ;
200+ template <const unsigned int size, const char * labels[size]>
201+ void Counter<size, labels>::FillHistogram(TH1 * h, const unsigned int & biny, const unsigned int & binz) const
202+ {
203+ LOG (DEBUG ) << " Filling Histogram " << h->GetName () << " with counter contents" ;
204+ unsigned int binx = 1 ;
205+ const unsigned int nbinsx = h->GetNbinsX ();
206+ for (unsigned int i = 0 ; i < size; i++) {
207+ if (labels && labels[i] && !labels[i][0 ]) { // Labels are defined and label is empty
208+ if (counter[i] > 0 ) {
209+ LOG (FATAL ) << " Counter at position " << i << " was non empty (" << counter[i] << " ) but was discarded because of empty labels" ;
126210 }
211+ continue ;
212+ }
127213#ifdef ENABLE_COUNTER_DEBUG_MODE
128- LOG (INFO ) << " Filling bin " << binx << " of position " << i << " of label " << labels[i] << " with " << counter[i];
214+ LOG (INFO ) << " Filling bin " << binx << " of position " << i << " of label " << labels[i] << " with " << counter[i];
129215#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 ) {
216+ if (binx > nbinsx) {
217+ LOG (FATAL ) << " Filling histogram " << h->GetName () << " at position " << binx << " i.e. past its size (" << nbinsx << " )!" ;
218+ }
219+ const char * bin_label = h->GetXaxis ()->GetBinLabel (binx);
220+ if (labels) {
221+ if (!labels[i]) {
222+ LOG (DEBUG ) << " Label at position " << i << " does not exist for axis label '" << bin_label << " '" ;
223+ } else if (strcmp (labels[i], bin_label) != 0 ) {
135224 LOG (FATAL ) << " Bin " << binx << " does not have the expected label '" << bin_label << " ' vs '" << labels[i] << " '" ;
136225 }
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- }
226+ }
227+ if (counter[i] > 0 ) {
228+ if (biny > 0 ) {
229+ if (binz > 0 ) {
230+ h->SetBinContent (binx, biny, binz, counter[i]);
144231 } else {
145- h->SetBinContent (binx, counter[i]);
232+ h->SetBinContent (binx, biny, counter[i]);
146233 }
234+ } else {
235+ h->SetBinContent (binx, counter[i]);
147236 }
148- binx++;
149237 }
238+ binx++;
239+ }
150240#ifdef ENABLE_PRINT_HISTOGRAMS_MODE
151- h->Print (" All" );
241+ h->Print (" All" );
152242#endif
153- }
154- // / Getter for the size
155- // / @return Returns the size of the counter
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");
160- // / Containers to fill
161- std::array<uint32_t , size> counter = { 0 };
162- };
243+ }
163244
164245} // namespace o2::quality_control_modules::tof
165246
0 commit comments