Project
Loading...
Searching...
No Matches
FastHisto.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
16
17#ifndef AliceO2_TPC_FastHisto_H
18#define AliceO2_TPC_FastHisto_H
19
20// o2 includes
21#include "MathUtils/fit.h"
22#include "Framework/Logger.h"
23#include <sstream>
24#include <vector>
25#include <iomanip>
26#include "Rtypes.h"
27
28namespace o2
29{
30namespace tpc
31{
32
49
50template <class T>
52{
53
54 public:
62 FastHisto(const unsigned int nBins = 20, const float xmin = 0.f, const float xmax = 2.f, const bool useUnderflow = true, const bool useOverflow = true)
63 : mNBins(nBins), mXmin(xmin), mXmax(xmax), mUseUnderflow(useUnderflow), mUseOverflow(useOverflow), mBinCont(nBins + useUnderflow + useOverflow), mBinWidth((mXmax - mXmin) / mNBins){};
64
66 ~FastHisto() = default;
67
71 void fill(const float val, T weight = 1);
72
76 int findBin(const float val) const;
77
79 void reset()
80 {
81 mBinCount = 0;
82 std::fill(mBinCont.begin(), mBinCont.end(), 0);
83 }
84
88 void fillBin(int index, T weight)
89 {
90 ++mBinCount;
91 mBinCont[index] += weight;
92 }
93
97 // TODO function prints only integers, add to print histgramm with 0.x values
98 void print(const int prec = 2) const;
99
103 math_utils::StatisticsData getStatisticsData(const float low = 0.05f, const float high = 0.6f) const;
104
107 T getBinContent(unsigned int index) const
108 {
109 if (checkBin(index)) {
110 return mBinCont[index];
111 } else {
112 return -1;
113 }
114 }
115
118 float getBinCenter(int bin) const
119 {
120 const float binWidth = getBinWidth();
121 const float val = (bin - mUseUnderflow) * binWidth + mXmin;
122 return val;
123 }
124
126 float getBinWidth() const { return mBinWidth; }
127
129 unsigned int getNBins() const { return mNBins; }
130
132 float getXmin() const { return mXmin; }
133
135 float getXmax() const { return mXmax; }
136
138 unsigned int getEntries() const { return mBinCount; }
139
141 bool isUnderflowSet() const { return mUseUnderflow; }
142
144 bool isOverflowSet() const { return mUseOverflow; }
145
147 bool checkBin(int bin) const
148 {
149 unsigned int vecsize = mBinCont.size();
150 if (bin >= vecsize) {
151 return 0;
152 } else {
153 return 1;
154 }
155 }
156
158 const FastHisto& operator+=(const FastHisto& other);
159
160 private:
161 unsigned int mNBins{};
162 float mXmin{};
163 float mXmax{};
164 bool mUseUnderflow = true;
165 bool mUseOverflow = true;
166 float mBinWidth{};
167 std::vector<T> mBinCont{};
168 unsigned int mBinCount{0};
169
170 ClassDefNV(FastHisto, 1)
171};
172
173//______________________________________________________________________________
174template <class T>
175inline void FastHisto<T>::fill(const float val, T weight)
176{
177 const int indexBin = findBin(val);
178 if ((indexBin < 0) || (indexBin > static_cast<int>(mBinCont.size()) - 1)) { // if no underflow/overflow bin is used, but the value should be in the underflow/overflow bin return
179 return;
180 }
181 fillBin(indexBin, weight); // fill the correct index with given weight
182}
183
184template <class T>
185inline void FastHisto<T>::print(const int prec) const
186{
187 const math_utils::StatisticsData data = getStatisticsData();
188 LOGP(info, "\n Entries: {}", mBinCount);
189 LOGP(info, "Truncated Mean: {}", data.mCOG);
190 LOGP(info, "Standard Deviation: {}", data.mStdDev);
191 LOGP(info, "sum of content: {}", data.mSum);
192
193 const int maxEle = *std::max_element(mBinCont.begin(), mBinCont.end()); // get the maximum element in the
194 // histogram needed for printing
195 // this loop prints the histogram
196 // starting from the largest value in the array and go backwards to 0
197 std::stringstream stream;
198 stream.width(10);
199
200 // getting the x axis label
201 stream << " 1";
202 for (int i = 2; i <= maxEle; ++i) {
203 stream.width(2);
204 stream << std::right << i;
205 }
206 LOGP(info, "{}", stream.str());
207 stream.str(std::string());
208 stream << "---------";
209 for (int i = 0; i <= maxEle; ++i) {
210 stream << "--";
211 }
212 LOGP(info, "{}", stream.str());
213
214 const float binWidth = getBinWidth();
215 const int totalBins = mBinCont.size();
216
217 for (int i = 0; i < totalBins; ++i) {
218 stream.str(std::string());
219 if (i == 0 && mUseUnderflow) {
220 stream.width(9);
221 stream << std::right << "U_Flow | ";
222 } else if (i == totalBins - 1 && mUseOverflow) {
223 stream.width(9);
224 stream << std::right << "O_Flow | ";
225 } else {
226 stream.width(6);
227 const float xPos = mXmin + binWidth * (i - mUseUnderflow);
228 stream << std::fixed << std::setprecision(prec) << xPos;
229 const std::string sIn = " | ";
230 stream << sIn;
231 }
232
233 for (int j = 1; j <= getBinContent(i); ++j) {
234 const std::string sIn = "x ";
235 stream << sIn;
236 }
237 std::string xPosString = stream.str();
238 LOGP(info, "{}", xPosString);
239 }
240 LOGP(info, "");
241}
242
243template <class T>
244inline math_utils::StatisticsData FastHisto<T>::getStatisticsData(const float low, const float high) const
245{
247 // in case something went wrong the COG is the histogram lower limit
248 data.mCOG = mXmin;
249 if (mBinCont.size() == 0) {
250 return data;
251 }
252 if (low > high) {
253 return data;
254 }
255
256 // total histogram content
257 const T integral = std::accumulate(mBinCont.begin(), mBinCont.end(), 0);
258 if (integral == 0) {
259 return data;
260 }
261 const float lowerBound = integral * low;
262 const float upperBound = integral * high;
263 const unsigned int lastBin = mBinCont.size() - 1;
264
265 float mean = 0;
266 float sum = 0;
267 float rms2 = 0;
268
269 // add fractional values
270 const float binWidth = getBinWidth();
271 const int shiftBin = mUseUnderflow ? -1 : 0; // shift the bin position in case of additional bin on the left
272
273 T countContent = 0;
274 bool isLowerFrac = false;
275 unsigned int bin = 0;
276 for (bin = 0; bin <= lastBin; ++bin) {
277 countContent += mBinCont[bin];
278
279 if (countContent - lowerBound <= 0) { // lower truncation cut
280 continue;
281 } else if (countContent >= upperBound) { // upper truncation cut
282 break;
283 }
284
285 const float xcenter = mXmin + (bin + 0.5f + shiftBin) * binWidth;
286 const float tmpBinCont = isLowerFrac ? mBinCont[bin] : countContent - lowerBound; // set bincontent to countcontent for first time only
287 const float tmpMean = tmpBinCont * xcenter;
288 mean += tmpMean;
289 sum += tmpBinCont;
290 rms2 += tmpMean * xcenter;
291 isLowerFrac = true;
292 }
293
294 if (!checkBin(bin)) {
295 return data;
296 }
297
298 // set last bin
299 // TODO move to upper loop
300 const float xcenter = mXmin + (bin + 0.5f + shiftBin) * binWidth;
301 const T upFrac = mBinCont[bin] - (static_cast<float>(countContent) - upperBound);
302 const float tmpMean = upFrac * xcenter;
303 mean += tmpMean;
304 sum += upFrac;
305 rms2 += tmpMean * xcenter;
306
307 if (sum == 0) {
308 return data;
309 }
310
311 mean /= sum;
312 data.mCOG = mean;
313 rms2 /= sum;
314 data.mStdDev = std::sqrt(std::abs(rms2 - mean * mean));
315 data.mSum = sum;
316 return data;
317}
318
319template <class T>
320inline int FastHisto<T>::findBin(const float val) const
321{
322 if (val < mXmin) {
323 if (!mUseUnderflow) {
324 LOGP(warning, "findBin: UNDERFLOW BIN: BIN IS NOT IN HISTOGRAM RANGE!");
325 return -1; // if undeflow bin is not used BUT value is in underflow bin return -1
326 } else {
327 return 0; // if underflow bin is used return 0 as index
328 }
329 }
330
331 if (val >= mXmax) {
332 if (!mUseOverflow) {
333 LOGP(warning, "findBin: OVERFLOW BIN: BIN IS NOT IN HISTOGRAM RANGE!");
334 return -1; // if overflow bin is not used BUT value is in overflow bin return -1
335 } else {
336 return mBinCont.size() - 1; // if overflow bin is used return the last index in the vector
337 }
338 }
339
340 const float binWidth = getBinWidth();
341 const int bin = (val - mXmin) / binWidth + mUseUnderflow;
342 return bin;
343};
344
345template <class T>
347{
348 if (other.mBinCount == 0) {
349 return *this;
350 }
351
352 // make sure the calibration objects have the same substructure
353 if (mNBins != other.mNBins || mXmin != other.mXmin || mXmax != other.mXmax || mUseUnderflow != other.mUseUnderflow || mUseOverflow != other.mUseOverflow) {
354 static int errCount = 0;
355 if (mBinCount && errCount < 10) {
356 errCount++;
357 LOGP(warning, "mBinCount {} other.mBinCount: {} mNBins {}, other.mNBins {}, mXmin {}, other.mXmin {}, mXmax {}, other.mXmax {}, mUseUnderflow {}, other.mUseUnderflow {}, mUseOverflow {}, other.mUseOverflow {}", mBinCount, other.mBinCount, mNBins, other.mNBins, mXmin, other.mXmin, mXmax, other.mXmax, mUseUnderflow, other.mUseUnderflow, mUseOverflow, other.mUseOverflow);
358 }
359 *this = other;
360 return *this;
361 }
362 mBinCount += other.mBinCount;
363 std::transform(mBinCont.begin(), mBinCont.end(), other.mBinCont.begin(), mBinCont.begin(), std::plus<T>());
364 return *this;
365}
366
367} // namespace tpc
368} // namespace o2
369
370#endif
void print() const
int32_t i
uint32_t j
Definition RawData.h:0
templated 1D-histogram class.
Definition FastHisto.h:52
float getBinWidth() const
Definition FastHisto.h:126
~FastHisto()=default
default destructor
unsigned int getEntries() const
Definition FastHisto.h:138
int findBin(const float val) const
Definition FastHisto.h:320
T getBinContent(unsigned int index) const
Definition FastHisto.h:107
float getXmax() const
Definition FastHisto.h:135
float getXmin() const
Definition FastHisto.h:132
unsigned int getNBins() const
Definition FastHisto.h:129
bool checkBin(int bin) const
Definition FastHisto.h:147
void fillBin(int index, T weight)
Definition FastHisto.h:88
FastHisto(const unsigned int nBins=20, const float xmin=0.f, const float xmax=2.f, const bool useUnderflow=true, const bool useOverflow=true)
Definition FastHisto.h:62
void fill(const float val, T weight=1)
Definition FastHisto.h:175
bool isUnderflowSet() const
Definition FastHisto.h:141
bool isOverflowSet() const
Definition FastHisto.h:144
const FastHisto & operator+=(const FastHisto &other)
overload of operator +
Definition FastHisto.h:346
math_utils::StatisticsData getStatisticsData(const float low=0.05f, const float high=0.6f) const
Definition FastHisto.h:244
void print(const int prec=2) const
Definition FastHisto.h:185
void reset()
this function resets the bin content in the histogram
Definition FastHisto.h:79
float getBinCenter(int bin) const
Definition FastHisto.h:118
GLuint index
Definition glcorearb.h:781
GLuint GLuint GLfloat weight
Definition glcorearb.h:5477
GLboolean * data
Definition glcorearb.h:298
GLuint GLfloat * val
Definition glcorearb.h:1582
GLuint GLuint stream
Definition glcorearb.h:1806
DataT sum(const Vector< DataT, N > &a)
Definition Vector.h:107
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
double mCOG
calculated centre of gravity
Definition fit.h:457
VectorOfTObjectPtrs other