29 throw std::runtime_error(
30 "A systematic variation was requested for a custom Fill action, but the type of the object to be filled does "
31 "not implement a Reset method, so we cannot safely re-initialize variations of the result. Aborting.");
36 h->SetDirectory(
nullptr);
40CountHelper::CountHelper(
const std::shared_ptr<ULong64_t> &resultCount,
const unsigned int nSlots)
41 : fResultCount(resultCount), fCounts(nSlots, 0)
45void CountHelper::Exec(
unsigned int slot)
50void CountHelper::Finalize()
53 for (
auto &
c : fCounts) {
58ULong64_t &CountHelper::PartialUpdate(
unsigned int slot)
63void BufferedFillHelper::UpdateMinMax(
unsigned int slot,
double v)
65 auto &thisMin = fMin[slot * CacheLineStep<BufEl_t>()];
66 auto &thisMax = fMax[slot * CacheLineStep<BufEl_t>()];
67 thisMin = std::min(thisMin,
v);
68 thisMax = std::max(thisMax,
v);
71BufferedFillHelper::BufferedFillHelper(
const std::shared_ptr<Hist_t> &
h,
const unsigned int nSlots)
72 : fResultHist(
h), fNSlots(nSlots), fBufSize(fgTotalBufSize / nSlots), fPartialHists(fNSlots),
73 fMin(nSlots *
CacheLineStep<BufEl_t>(), std::numeric_limits<BufEl_t>::
max()),
74 fMax(nSlots *
CacheLineStep<BufEl_t>(), std::numeric_limits<BufEl_t>::lowest())
76 fBuffers.reserve(fNSlots);
77 fWBuffers.reserve(fNSlots);
78 for (
unsigned int i = 0; i < fNSlots; ++i) {
81 fBuffers.emplace_back(
v);
82 fWBuffers.emplace_back(
v);
86void BufferedFillHelper::Exec(
unsigned int slot,
double v)
88 UpdateMinMax(slot,
v);
89 fBuffers[slot].emplace_back(
v);
92void BufferedFillHelper::Exec(
unsigned int slot,
double v,
double w)
94 UpdateMinMax(slot,
v);
95 fBuffers[slot].emplace_back(
v);
96 fWBuffers[slot].emplace_back(w);
99Hist_t &BufferedFillHelper::PartialUpdate(
unsigned int slot)
101 auto &partialHist = fPartialHists[slot];
104 partialHist = std::make_unique<Hist_t>(*fResultHist);
105 auto weights = fWBuffers[slot].empty() ? nullptr : fWBuffers[slot].data();
106 partialHist->FillN(fBuffers[slot].
size(), fBuffers[slot].data(), weights);
110void BufferedFillHelper::Finalize()
112 for (
unsigned int i = 0; i < fNSlots; ++i) {
113 if (!fWBuffers[i].empty() && fBuffers[i].
size() != fWBuffers[i].
size()) {
114 throw std::runtime_error(
"Cannot fill weighted histogram with values in containers of different sizes.");
118 BufEl_t globalMin = *std::min_element(fMin.begin(), fMin.end());
119 BufEl_t globalMax = *std::max_element(fMax.begin(), fMax.end());
121 if (fResultHist->CanExtendAllAxes() && globalMin != std::numeric_limits<BufEl_t>::max() &&
122 globalMax != std::numeric_limits<BufEl_t>::lowest()) {
123 fResultHist->SetBins(fResultHist->GetNbinsX(), globalMin, globalMax);
126 for (
unsigned int i = 0; i < fNSlots; ++i) {
127 auto weights = fWBuffers[i].empty() ? nullptr : fWBuffers[i].data();
128 fResultHist->FillN(fBuffers[i].
size(), fBuffers[i].data(), weights);
132MeanHelper::MeanHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots)
133 : fResultMean(meanVPtr), fCounts(nSlots, 0), fSums(nSlots, 0), fPartialMeans(nSlots), fCompensations(nSlots)
137void MeanHelper::Exec(
unsigned int slot,
double v)
141 double y =
v - fCompensations[slot];
142 double t = fSums[slot] +
y;
143 fCompensations[slot] = (t - fSums[slot]) -
y;
147void MeanHelper::Finalize()
149 double sumOfSums = 0;
151 double compensation(0);
154 for (
auto &
m : fSums) {
155 y =
m - compensation;
157 compensation = (t - sumOfSums) -
y;
161 for (
auto &
c : fCounts)
163 *fResultMean = sumOfSums / (sumOfCounts > 0 ? sumOfCounts : 1);
166double &MeanHelper::PartialUpdate(
unsigned int slot)
168 fPartialMeans[slot] = fSums[slot] / fCounts[slot];
169 return fPartialMeans[slot];
172StdDevHelper::StdDevHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots)
173 : fNSlots(nSlots), fResultStdDev(meanVPtr), fCounts(nSlots, 0), fMeans(nSlots, 0), fDistancesfromMean(nSlots, 0)
177void StdDevHelper::Exec(
unsigned int slot,
double v)
180 auto count = ++fCounts[slot];
181 auto delta =
v - fMeans[slot];
182 auto mean = fMeans[slot] + delta / count;
183 auto delta2 =
v - mean;
184 auto distance = fDistancesfromMean[slot] + delta * delta2;
186 fCounts[slot] = count;
188 fDistancesfromMean[slot] = distance;
191void StdDevHelper::Finalize()
194 double totalElements = 0;
195 for (
auto c : fCounts) {
198 if (totalElements == 0 || totalElements == 1) {
204 double overallMean = 0;
205 for (
unsigned int i = 0; i < fNSlots; ++i) {
206 overallMean += fCounts[i] * fMeans[i];
208 overallMean = overallMean / totalElements;
211 for (
unsigned int i = 0; i < fNSlots; ++i) {
212 if (fCounts[i] == 0) {
215 auto setVariance = fDistancesfromMean[i] / (fCounts[i]);
216 variance += (fCounts[i]) * (setVariance + std::pow((fMeans[i] - overallMean), 2));
219 variance = variance / (totalElements - 1);
220 *fResultStdDev = std::sqrt(variance);
225template class TakeHelper<bool, bool, std::vector<bool>>;
226template class TakeHelper<unsigned int, unsigned int, std::vector<unsigned int>>;
227template class TakeHelper<unsigned long, unsigned long, std::vector<unsigned long>>;
228template class TakeHelper<unsigned long long, unsigned long long, std::vector<unsigned long long>>;
229template class TakeHelper<int, int, std::vector<int>>;
230template class TakeHelper<long, long, std::vector<long>>;
231template class TakeHelper<long long, long long, std::vector<long long>>;
232template class TakeHelper<float, float, std::vector<float>>;
233template class TakeHelper<double, double, std::vector<double>>;
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Basic types used by ROOT and required by TInterpreter.
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
TH1 is the base class of all histogram classes in ROOT.
Statistical variable, defined by its mean and variance (RMS).
void ResetIfPossible(TStatistic *h)
constexpr std::size_t CacheLineStep()
Stepping through CacheLineStep<T> values in a vector<T> brings you to a new cache line.
void UnsetDirectoryIfPossible(TH1 *h)
__device__ AFloat max(AFloat x, AFloat y)