Project
Loading...
Searching...
No Matches
fit.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
12#ifndef ALICEO2_MATHUTILS_MATHBASE_H_
13#define ALICEO2_MATHUTILS_MATHBASE_H_
14
17
18#include <cmath>
19#include <numeric>
20#include <algorithm>
21#include <vector>
22#include <array>
23
24#include "Rtypes.h"
25#include "TLinearFitter.h"
26#include "TVectorD.h"
27#include "TMath.h"
28#include "TF1.h"
29#include "Foption.h"
30#include "HFitInterface.h"
31#include "TFitResultPtr.h"
32#include "TFitResult.h"
33#include "Fit/Fitter.h"
34#include "Fit/BinData.h"
35#include "Math/WrappedMultiTF1.h"
36#include <Math/SMatrix.h>
37#include <Math/SVector.h>
38#include "Framework/Logger.h"
39
40namespace o2
41{
42namespace math_utils
43{
58template <typename T>
59TFitResultPtr fit(const size_t nBins, const T* arr, const T xMin, const T xMax, TF1& func, std::string_view option = "")
60{
61 Foption_t fitOption;
62 ROOT::Fit::FitOptionsMake(ROOT::Fit::EFitObjectType::kHistogram, option.data(), fitOption);
63
64 ROOT::Fit::DataRange range(xMin, xMax);
65 ROOT::Fit::DataOptions opt;
66 ROOT::Fit::BinData fitdata(opt, range);
67 fitdata.Initialize(nBins, 1);
68
69 // create an empty TFitResult
70 std::shared_ptr<TFitResult> tfr(new TFitResult());
71 // create the fitter from an empty fit result
72 //std::shared_ptr<ROOT::Fit::Fitter> fitter(new ROOT::Fit::Fitter(std::static_pointer_cast<ROOT::Fit::FitResult>(tfr) ) );
73 ROOT::Fit::Fitter fitter(tfr);
74 //ROOT::Fit::FitConfig & fitConfig = fitter->Config();
75
76 const double binWidth = double(xMax - xMin) / double(nBins);
77
78 for (Int_t ibin = 0; ibin < nBins; ibin++) {
79 const double x = double(xMin) + double(ibin + 0.5) * binWidth;
80 const double y = double(arr[ibin]);
81 const double ey = std::sqrt(y);
82 fitdata.Add(x, y, ey);
83 }
84
85 const int special = func.GetNumber();
86 const int npar = func.GetNpar();
87 bool linear = func.IsLinear();
88 if (special == 299 + npar) {
89 linear = kTRUE; // for polynomial functions
90 }
91 // do not use linear fitter in these case
92 if (fitOption.Bound || fitOption.Like || fitOption.Errors || fitOption.Gradient || fitOption.More || fitOption.User || fitOption.Integral || fitOption.Minuit) {
93 linear = kFALSE;
94 }
95
96 if (special != 0 && !fitOption.Bound && !linear) {
97 if (special == 100) {
98 ROOT::Fit::InitGaus(fitdata, &func); // gaussian
99 } else if (special == 400) {
100 ROOT::Fit::InitGaus(fitdata, &func); // landau (use the same)
101 } else if (special == 200) {
102 ROOT::Fit::InitExpo(fitdata, &func); // exponential
103 }
104 }
105
106 if ((linear || fitOption.Gradient)) {
107 fitter.SetFunction(ROOT::Math::WrappedMultiTF1(func));
108 } else {
109 fitter.SetFunction(static_cast<const ROOT::Math::IParamMultiFunction&>(ROOT::Math::WrappedMultiTF1(func)));
110 }
111
112 // standard least square fit
113 const bool fitok = fitter.Fit(fitdata, fitOption.ExecPolicy);
114 if (!fitok) {
115 LOGP(warning, "bad fit");
116 }
117
118 return TFitResultPtr(tfr);
119}
120
130
131template <typename T>
132bool medmadGaus(size_t nBins, const T* arr, const T xMin, const T xMax, std::array<double, 3>& param)
133{
134 int bStart = 0, bEnd = -1;
135 double sum = 0, binW = double(xMax - xMin) / nBins, medVal = xMin;
136 for (int i = 0; i < (int)nBins; i++) {
137 auto v = arr[i];
138 if (v) {
139 if (!sum) {
140 bStart = i;
141 }
142 sum += v;
143 bEnd = i;
144 }
145 }
146 if (bEnd < bStart) {
147 return false;
148 }
149 bEnd++;
150 double cum = 0, thresh = 0.5 * sum, frac0 = 0;
151 int bid = bStart, prevbid = bid;
152 while (bid < bEnd) {
153 if (arr[bid] > 0) {
154 cum += arr[bid];
155 if (cum > thresh) {
156 frac0 = 1. + (thresh - cum) / float(arr[bid]);
157 medVal = xMin + binW * (bid + frac0);
158 int bdiff = bid - prevbid - 1;
159 if (bdiff > 0) {
160 medVal -= bdiff * binW * 0.5; // account for the gap
161 bid -= bdiff / 2;
162 }
163 break;
164 }
165 prevbid = bid;
166 }
167 bid++;
168 }
169 cum = 0.;
170 double edgeL = frac0 + bid, edgeR = edgeL, dist = 0., wL = 0, wR = 0;
171 while (1) {
172 float amp = 0.;
173 int bL = edgeL, bR = edgeR; // left and right bins
174 if (edgeL > bStart) {
175 wL = edgeL - bL;
176 amp += arr[bL];
177 } else {
178 wL = 1.;
179 }
180 if (edgeR < bEnd) {
181 wR = 1. + bR - edgeR;
182 amp += arr[bR];
183 } else {
184 wR = 1.;
185 }
186 auto wdt = std::min(wL, wR);
187 if (wdt < 1e-5) {
188 wdt = std::max(wL, wR);
189 }
190 if (amp > 0) {
191 amp *= wdt;
192 cum += amp;
193 if (cum >= thresh) {
194 dist += wdt * (cum - thresh) / amp * 0.5;
195 break;
196 }
197 }
198 dist += wdt;
199 edgeL -= wdt;
200 edgeR += wdt;
201 }
202 constexpr double SQRT2PI = 2.5066283;
203 param[1] = medVal;
204 param[2] = dist * binW * 1.4826; // MAD -> sigma
205 param[0] = sum * binW / (param[2] * SQRT2PI);
206 return true;
207}
208
228//template <typename T>
229//Double_t fitGaus(const size_t nBins, const T *arr, const T xMin, const T xMax, std::vector<T>& param);
230template <typename T>
231Double_t fitGaus(const size_t nBins, const T* arr, const T xMin, const T xMax, std::vector<T>& param)
232{
233 static TLinearFitter fitter(3, "pol2");
234 static TMatrixD mat(3, 3);
235 static Double_t kTol = mat.GetTol();
236 fitter.StoreData(kFALSE);
237 fitter.ClearPoints();
238 TVectorD par(3);
239 TVectorD sigma(3);
240 TMatrixD A(3, 3);
241 TMatrixD b(3, 1);
242 T rms = TMath::RMS(nBins, arr);
243 T max = TMath::MaxElement(nBins, arr);
244 T binWidth = (xMax - xMin) / T(nBins);
245
246 Float_t meanCOG = 0;
247 Float_t rms2COG = 0;
248 Float_t sumCOG = 0;
249
250 Float_t entries = 0;
251 Int_t nfilled = 0;
252
253 param.resize(4);
254 param[0] = 0.;
255 param[1] = 0.;
256 param[2] = 0.;
257 param[3] = 0.;
258
259 for (size_t i = 0; i < nBins; i++) {
260 entries += arr[i];
261 if (arr[i] > 0) {
262 nfilled++;
263 }
264 }
265
266 // TODO: Check why this is needed
267 if (max < 4) {
268 return -4;
269 }
270 if (entries < 12) {
271 return -4;
272 }
273
274 if (rms < kTol) {
275 return -4;
276 }
277
278 param[3] = entries;
279
280 Int_t npoints = 0;
281 for (size_t ibin = 0; ibin < nBins; ibin++) {
282 Float_t entriesI = arr[ibin];
283 if (entriesI > 1) {
284 Double_t xcenter = xMin + (ibin + 0.5) * binWidth;
285 Double_t error = 1. / TMath::Sqrt(entriesI);
286 Double_t val = TMath::Log(Float_t(entriesI));
287 fitter.AddPoint(&xcenter, val, error);
288 if (npoints < 3) {
289 A(npoints, 0) = 1;
290 A(npoints, 1) = xcenter;
291 A(npoints, 2) = xcenter * xcenter;
292 b(npoints, 0) = val;
293 meanCOG += xcenter * entriesI;
294 rms2COG += xcenter * entriesI * xcenter;
295 sumCOG += entriesI;
296 }
297 npoints++;
298 }
299 }
300
301 Double_t chi2 = 0;
302 if (npoints >= 3) {
303 if (npoints == 3) {
304 //analytic calculation of the parameters for three points
305 A.Invert();
306 TMatrixD res(1, 3);
307 res.Mult(A, b);
308 par[0] = res(0, 0);
309 par[1] = res(0, 1);
310 par[2] = res(0, 2);
311 chi2 = -3.;
312 } else {
313 // use fitter for more than three points
314 fitter.Eval();
315 fitter.GetParameters(par);
316 fitter.GetCovarianceMatrix(mat);
317 chi2 = fitter.GetChisquare() / Double_t(npoints);
318 }
319 if (TMath::Abs(par[1]) < kTol) {
320 return -4;
321 }
322 if (TMath::Abs(par[2]) < kTol) {
323 return -4;
324 }
325 param[1] = T(par[1] / (-2. * par[2]));
326 param[2] = T(1. / TMath::Sqrt(TMath::Abs(-2. * par[2])));
327 Double_t lnparam0 = par[0] + par[1] * param[1] + par[2] * param[1] * param[1];
328 if (lnparam0 > 307) {
329 return -4;
330 }
331 param[0] = TMath::Exp(lnparam0);
332
333 return chi2;
334 }
335
336 if (npoints == 2) {
337 //use center of gravity for 2 points
338 meanCOG /= sumCOG;
339 rms2COG /= sumCOG;
340 param[0] = max;
341 param[1] = meanCOG;
342 param[2] = TMath::Sqrt(TMath::Abs(meanCOG * meanCOG - rms2COG));
343 chi2 = -2.;
344 }
345 if (npoints == 1) {
346 meanCOG /= sumCOG;
347 param[0] = max;
348 param[1] = meanCOG;
349 param[2] = binWidth / TMath::Sqrt(12);
350 chi2 = -1.;
351 }
352 return chi2;
353}
354
355// more optimal implementation of guassian fit via log-normal fit, appropriate for MT calls
356// Only bins with values above minVal will be accounted.
357// If applyMAD is true, the fit is done whithin the nSigmaMAD range of the preliminary estimate by MAD
358template <typename T>
359double fitGaus(size_t nBins, const T* arr, const T xMin, const T xMax, std::array<double, 3>& param,
360 ROOT::Math::SMatrix<double, 3, 3, ROOT::Math::MatRepSym<double, 3>>* covMat = nullptr,
361 int minVal = 2, bool applyMAD = true)
362{
363 double binW = double(xMax - xMin) / nBins, s0 = 0, s1 = 0, s2 = 0, s3 = 0, s4 = 0, sy0 = 0, sy1 = 0, sy2 = 0, syy = 0;
364 int np = 0;
365 int bStart = 0, bEnd = (int)nBins;
366 const float nSigmaMAD = 2.;
367 if (applyMAD) {
368 std::array<double, 3> madPar;
369 if (!medmadGaus(nBins, arr, xMin, xMax, madPar)) {
370 return -10;
371 }
372 bStart = std::max(bStart, int((madPar[1] - nSigmaMAD * madPar[2] - xMin) / binW));
373 bEnd = std::min(bEnd, 1 + int((madPar[1] + nSigmaMAD * madPar[2] - xMin) / binW));
374 }
375 float x = xMin + (bStart - 0.5) * binW;
376 for (int i = bStart; i < bEnd; i++) {
377 x += binW;
378 auto v = arr[i];
379 if (v < 0) {
380 throw std::runtime_error("Log-normal fit is possible only with non-negative data");
381 }
382 if (v < minVal) {
383 continue;
384 }
385 double y = std::log(v), err2i = v, err2iX = err2i, err2iY = err2i * y;
386 s0 += err2iX;
387 s1 += (err2iX *= x);
388 s2 += (err2iX *= x);
389 s3 += (err2iX *= x);
390 s4 += (err2iX *= x);
391 sy0 += err2iY;
392 syy += err2iY * y;
393 sy1 += (err2iY *= x);
394 sy2 += (err2iY *= x);
395 np++;
396 }
397 if (np < 1) {
398 return -10;
399 }
400 auto recover = [&param, binW, np, s0, s1, s2, sy0]() {
401 param[0] = std::exp(sy0 / s0); // recover center of gravity
402 param[1] = s1 / s0; // mean x;
403 param[2] = np == 1 ? binW / std::sqrt(12) : std::sqrt(std::abs(param[1] * param[1] - s2 / s0));
404 };
405 if (np < 3) {
406 recover();
407 return -np;
408 }
410 ROOT::Math::SVector<double, 3> v3{sy0, sy1, sy2};
411 m33(0, 0) = s0;
412 m33(1, 0) = s1;
413 m33(1, 1) = m33(2, 0) = s2;
414 m33(2, 1) = s3;
415 m33(2, 2) = s4;
416 int res = 0;
417 auto m33i = m33.Inverse(res);
418 if (res) {
419 recover();
420 LOG(error) << np << " points collected, matrix inversion failed " << m33;
421 return -10;
422 }
423 auto v = m33i * v3;
424 if (v(2) >= 0.) { // fit failed, use mean amd RMS
425 recover();
426 return -3;
427 }
428
429 double chi2 = v(0) * v(0) * s0 + v(1) * v(1) * s2 + v(2) * v(2) * s4 + syy +
430 2. * (v(0) * v(1) * s1 + v(0) * v(2) * s2 + v(1) * v(2) * s3 - v(0) * sy0 - v(1) * sy1 - v(2) * sy2);
431 param[1] = -0.5 * v(1) / v(2);
432 param[2] = 1. / std::sqrt(-2. * v(2));
433 param[0] = std::exp(v(0) - param[1] * param[1] * v(2));
434 if (std::isnan(param[0]) || std::isnan(param[1]) || std::isnan(param[2])) {
435 recover();
436 return -3;
437 }
438 if (covMat) {
439 // build jacobian of transformation from log-normal to normal params
441 j33(0, 0) = param[0];
442 j33(0, 1) = param[0] * param[1];
443 j33(0, 2) = j33(0, 1) * param[1];
444 j33(1, 1) = -0.5 / v(2);
445 j33(1, 2) = -param[1] / v(2);
446 j33(2, 2) = param[2] * j33(1, 1);
447 *covMat = ROOT::Math::Similarity(j33, m33i);
448 }
449 return np > 3 ? chi2 / (np - 3.) : 0.;
450}
451
457 double mCOG{0};
458 double mStdDev{0};
459 double mSum{0};
460};
461
469template <typename T>
470StatisticsData getStatisticsData(const T* arr, const size_t nBins, const double xMin, const double xMax)
471{
472 double mean = 0;
473 double rms2 = 0;
474 double sum = 0;
475 size_t npoints = 0;
476
477 double binWidth = (xMax - xMin) / (double)nBins;
478
480 // in case something went wrong the COG is the histogram lower limit
481 data.mCOG = xMin;
482
483 for (size_t ibin = 0; ibin < nBins; ++ibin) {
484 double entriesI = (double)arr[ibin];
485 double xcenter = xMin + (ibin + 0.5) * binWidth; // +0.5 to shift to bin centre
486 if (entriesI > 0) {
487 mean += xcenter * entriesI;
488 rms2 += xcenter * entriesI * xcenter;
489 sum += entriesI;
490 ++npoints;
491 }
492 }
493 if (sum == 0) {
494 return data;
495 }
496 mean /= sum;
497
498 data.mCOG = mean;
499 // exception in case of only one bin is filled
500 // set the standard deviation to bin width over sqrt(12)
501 rms2 /= sum;
502 if (npoints == 1) {
503 data.mStdDev = binWidth / std::sqrt(12.);
504 } else {
505 data.mStdDev = std::sqrt(std::abs(rms2 - mean * mean));
506 }
507
508 data.mSum = sum;
509
510 return data;
511}
512
518template <typename T, typename R = double>
519R median(std::vector<T> v)
520{
521 if (v.empty()) {
522 return R{};
523 }
524 auto n = v.size() / 2;
525 nth_element(v.begin(), v.begin() + n, v.end());
526 auto med = R{v[n]};
527 if (!(v.size() & 1)) { //If the set size is even
528 auto max_it = max_element(v.begin(), v.begin() + n);
529 med = R{(*max_it + med) / 2.0};
530 }
531 return med;
532}
533
538template <typename T>
539void SortData(std::vector<T> const& values, std::vector<size_t>& index)
540{
541 if (values.size() != index.size()) {
542 LOG(error) << "Vector with values must have same size as vector for indices";
543 return;
544 }
545 std::iota(index.begin(), index.end(), static_cast<size_t>(0));
546 std::sort(index.begin(), index.end(), [&](size_t a, size_t b) { return values[a] < values[b]; });
547}
548
568template <typename T>
569bool LTMUnbinned(const std::vector<T>& data, std::vector<size_t>& index, std::array<float, 7>& params, float fracKeep)
570{
571 int nPoints = data.size();
572 std::vector<float> w(2 * nPoints);
573 int nKeep = nPoints * fracKeep;
574 if (nKeep > nPoints) {
575 nKeep = nPoints;
576 }
577 if (nKeep < 2) {
578 return false;
579 }
580 // sort in increasing order
582 // build cumulants
583 double sum1 = 0.0;
584 double sum2 = 0.0;
585 for (int i = 0; i < nPoints; i++) {
586 double x = data[index[i]];
587 sum1 += x;
588 sum2 += x * x;
589 w[i] = sum1;
590 w[i + nPoints] = sum2;
591 }
592 double maxRMS = sum2 + 1e6;
593 params[0] = nKeep;
594 int limI = nPoints - nKeep + 1; // lowest possible bin to accept
595 for (int i = 0; i < limI; i++) {
596 const int limJ = i + nKeep - 1; // highest accepted bin
597 sum1 = static_cast<double>(w[limJ]) - static_cast<double>(i ? w[i - 1] : 0.);
598 sum2 = static_cast<double>(w[nPoints + limJ]) - static_cast<double>(i ? w[nPoints + i - 1] : 0.);
599 const double mean = sum1 / nKeep;
600 const double rms2 = sum2 / nKeep - mean * mean;
601 if (rms2 > maxRMS) {
602 continue;
603 }
604 maxRMS = rms2;
605 params[1] = mean;
606 params[2] = rms2;
607 params[5] = i;
608 params[6] = limJ;
609 }
610 //
611 if (params[2] < 0) {
612 LOG(error) << "Rounding error: RMS = " << params[2] << " < 0";
613 return false;
614 }
615 params[2] = std::sqrt(params[2]);
616 params[3] = params[2] / std::sqrt(params[0]); // error on mean
617 params[4] = params[3] / std::sqrt(2.0); // error on RMS
618 return true;
619}
620
624template <typename T>
625void Reorder(std::vector<T>& data, const std::vector<size_t>& index)
626{
627 // rearange data in order given by index
628 if (data.size() != index.size()) {
629 LOG(error) << "Reordering not possible if number of elements in index container different from the data container";
630 return;
631 }
632 std::vector<T> tmp(data);
633 for (size_t i = 0; i < data.size(); ++i) {
634 data[i] = tmp[index[i]];
635 }
636}
637
647template <typename T>
648bool LTMUnbinnedSig(const std::vector<T>& data, std::vector<size_t>& index, std::array<float, 7>& params, float fracKeepMin, float sigTgt, bool sorted = false)
649{
650 int nPoints = data.size();
651 std::vector<double> wx(nPoints);
652 std::vector<double> wx2(nPoints);
653
654 if (!sorted) {
655 // sort in increasing order
657 } else {
658 // array is already sorted
659 std::iota(index.begin(), index.end(), 0);
660 }
661 // build cumulants
662 double sum1 = 0.0;
663 double sum2 = 0.0;
664 for (int i = 0; i < nPoints; i++) {
665 double x = data[index[i]];
666 sum1 += x;
667 sum2 += x * x;
668 wx[i] = sum1;
669 wx2[i] = sum2;
670 }
671 int keepMax = nPoints;
672 int keepMin = fracKeepMin * nPoints;
673 if (keepMin > keepMax) {
674 keepMin = keepMax;
675 }
676 float sigTgt2 = sigTgt * sigTgt;
677 //
678 while (true) {
679 double maxRMS = wx2.back() + 1e6;
680 int keepN = (keepMax + keepMin) / 2;
681 if (keepN < 2) {
682 return false;
683 }
684 params[0] = keepN;
685 int limI = nPoints - keepN + 1;
686 for (int i = 0; i < limI; ++i) {
687 const int limJ = i + keepN - 1;
688 sum1 = wx[limJ] - (i ? wx[i - 1] : 0.);
689 sum2 = wx2[limJ] - (i ? wx2[i - 1] : 0.);
690 const double mean = sum1 / keepN;
691 const double rms2 = sum2 / keepN - mean * mean;
692 if (rms2 > maxRMS) {
693 continue;
694 }
695 maxRMS = rms2;
696 params[1] = mean;
697 params[2] = rms2;
698 params[5] = i;
699 params[6] = limJ;
700 }
701 if (maxRMS < sigTgt2) {
702 keepMin = keepN;
703 } else {
704 keepMax = keepN;
705 }
706 if (keepMin >= keepMax - 1) {
707 break;
708 }
709 }
710 params[2] = std::sqrt(params[2]);
711 params[3] = params[2] / std::sqrt(params[0]); // error on mean
712 params[4] = params[3] / std::sqrt(2.0); // error on RMS
713 return true;
714}
715
716//___________________________________________________________________
717template <typename T>
718T selKthMin(int k, int np, T* arr)
719{
720 // Returns the k th smallest value in the array. The input array will be rearranged
721 // to have this value in location arr[k] , with all smaller elements moved before it
722 // (in arbitrary order) and all larger elements after (also in arbitrary order).
723 // From Numerical Recipes in C++
724
725 int i, j, mid, ir = np - 1, l = 0;
726 T a;
727 for (;;) {
728 if (ir <= l + 1) {
729 if (ir == l + 1 && arr[ir] < arr[l]) {
730 std::swap(arr[l], arr[ir]);
731 }
732 return arr[k];
733 } else {
734 int mid = (l + ir) >> 1, i = l + 1;
735 std::swap(arr[mid], arr[i]);
736 if (arr[i] > arr[ir]) {
737 std::swap(arr[i], arr[ir]);
738 }
739 if (arr[l] > arr[ir]) {
740 std::swap(arr[l], arr[ir]);
741 }
742 if (arr[i] > arr[l]) {
743 std::swap(arr[i], arr[l]);
744 }
745 j = ir;
746 a = arr[l];
747 for (;;) {
748 do {
749 i++;
750 } while (arr[i] < a);
751 do {
752 j--;
753 } while (arr[j] > a);
754 if (j < i) {
755 break;
756 }
757 std::swap(arr[i], arr[j]);
758 }
759 arr[l] = arr[j];
760 arr[j] = a;
761 if (j >= k) {
762 ir = j - 1;
763 }
764 if (j <= k) {
765 l = i;
766 }
767 }
768 }
769}
770
771//___________________________________________________________________
772template <typename T>
773T MAD2Sigma(int np, T* y)
774{
775 // Sigma calculated from median absolute deviations, https://en.wikipedia.org/wiki/Median_absolute_deviation
776 // the input array is modified
777 if (np < 2) {
778 return 0;
779 }
780 int nph = np >> 1;
781 float median = (np & 0x1) ? selKthMin(nph, np, y) : 0.5 * (selKthMin(nph - 1, np, y) + selKthMin(nph, np, y));
782 // build abs differences to median
783 for (int i = np; i--;) {
784 y[i] = std::abs(y[i] - median);
785 }
786 // now get median of abs deviations
787 median = (np & 0x1) ? selKthMin(nph, np, y) : 0.5 * (selKthMin(nph - 1, np, y) + selKthMin(nph, np, y));
788 return median * 1.4826; // convert to Gaussian sigma
789}
790
791} // namespace math_utils
792} // namespace o2
793#endif
int32_t i
uint32_t j
Definition RawData.h:0
uint32_t res
Definition RawData.h:0
Definition A.h:16
float sum(float s, o2::dcs::DataPointValue v)
Definition dcs-ccdb.cxx:39
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum func
Definition glcorearb.h:778
const GLdouble * v
Definition glcorearb.h:832
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition glcorearb.h:5034
GLuint index
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLenum GLint * range
Definition glcorearb.h:1899
GLenum const GLfloat * params
Definition glcorearb.h:272
GLenum GLsizei GLsizei GLint * values
Definition glcorearb.h:1576
GLboolean * data
Definition glcorearb.h:298
GLuint GLfloat * val
Definition glcorearb.h:1582
GLfloat GLfloat GLfloat GLfloat v3
Definition glcorearb.h:814
GLenum GLfloat param
Definition glcorearb.h:271
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
Definition glcorearb.h:5034
bool medmadGaus(size_t nBins, const T *arr, const T xMin, const T xMax, std::array< double, 3 > &param)
Definition fit.h:132
void Reorder(std::vector< T > &data, const std::vector< size_t > &index)
Definition fit.h:625
TFitResultPtr fit(const size_t nBins, const T *arr, const T xMin, const T xMax, TF1 &func, std::string_view option="")
Definition fit.h:59
bool LTMUnbinnedSig(const std::vector< T > &data, std::vector< size_t > &index, std::array< float, 7 > &params, float fracKeepMin, float sigTgt, bool sorted=false)
Definition fit.h:648
void SortData(std::vector< T > const &values, std::vector< size_t > &index)
Definition fit.h:539
StatisticsData getStatisticsData(const T *arr, const size_t nBins, const double xMin, const double xMax)
Definition fit.h:470
T MAD2Sigma(int np, T *y)
Definition fit.h:773
const T y
Definition Utils.h:225
bool LTMUnbinned(const std::vector< T > &data, std::vector< size_t > &index, std::array< float, 7 > &params, float fracKeep)
Definition fit.h:569
T selKthMin(int k, int np, T *arr)
Definition fit.h:718
R median(std::vector< T > v)
Definition fit.h:519
Double_t fitGaus(const size_t nBins, const T *arr, const T xMin, const T xMax, std::vector< T > &param)
Definition fit.h:231
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
double mSum
sum of values
Definition fit.h:459
double mStdDev
standard deviation
Definition fit.h:458
constexpr size_t max
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)