Skip to content

Commit 588e8fb

Browse files
committed
[hist] Implement weighted filling in RHistAutoAxisFiller
1 parent f38920b commit 588e8fb

File tree

2 files changed

+89
-14
lines changed

2 files changed

+89
-14
lines changed

hist/histv7/inc/ROOT/RHistAutoAxisFiller.hxx

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#define ROOT_RHistAutoAxisFiller
77

88
#include "RHist.hxx"
9+
#include "RHistEngine.hxx"
10+
#include "RWeight.hxx"
911

1012
#include <cmath>
1113
#include <cstddef>
@@ -42,6 +44,10 @@ Feedback is welcome!
4244
*/
4345
template <typename BinContentType>
4446
class RHistAutoAxisFiller final {
47+
public:
48+
static constexpr bool SupportsWeightedFilling = RHistEngine<BinContentType>::SupportsWeightedFilling;
49+
50+
private:
4551
/// The filled histogram, after it has been constructed
4652
std::optional<RHist<BinContentType>> fHist;
4753

@@ -50,9 +56,10 @@ class RHistAutoAxisFiller final {
5056
/// The maximum buffer size until Flush() is automatically called
5157
std::size_t fMaxBufferSize;
5258

59+
using BufferElement = std::conditional_t<SupportsWeightedFilling, std::pair<double, RWeight>, double>;
60+
5361
/// The buffer of filled entries
54-
// FIXME: need to store weights!
55-
std::vector<double> fBuffer;
62+
std::vector<BufferElement> fBuffer;
5663
/// The minimum of the filled entries
5764
double fMinimum = std::numeric_limits<double>::infinity();
5865
/// The maximum of the filled entries
@@ -77,18 +84,17 @@ public:
7784
std::size_t GetNNormalBins() const { return fNNormalBins; }
7885
std::size_t GetMaxBufferSize() const { return fMaxBufferSize; }
7986

80-
/// Fill an entry into the histogram.
81-
///
82-
/// \param[in] x the argument
83-
void Fill(double x)
87+
private:
88+
void BufferImpl(double x, RWeight weight)
8489
{
85-
// If the histogram exists, forward the Fill call.
86-
if (fHist) {
87-
fHist->Fill(x);
88-
return;
90+
if constexpr (SupportsWeightedFilling) {
91+
fBuffer.emplace_back(x, weight);
92+
} else {
93+
assert(weight.fValue == 1.0);
94+
// Silence compiler warning about unused parameter
95+
(void)weight;
96+
fBuffer.push_back(x);
8997
}
90-
91-
fBuffer.push_back(x);
9298
if (x < fMinimum) {
9399
fMinimum = x;
94100
}
@@ -101,6 +107,41 @@ public:
101107
}
102108
}
103109

110+
public:
111+
/// Fill an entry into the histogram.
112+
///
113+
/// \param[in] x the argument
114+
/// \par See also
115+
/// the \ref Fill(double x, RWeight weight) "overload for weighted filling"
116+
void Fill(double x)
117+
{
118+
// If the histogram exists, forward the Fill call.
119+
if (fHist) {
120+
fHist->Fill(x);
121+
return;
122+
}
123+
BufferImpl(x, RWeight(1.0));
124+
}
125+
126+
/// Fill an entry into the histogram with a weight.
127+
///
128+
/// This overload is only available for floating-point bin content types (see
129+
/// \ref RHistEngine::SupportsWeightedFilling).
130+
///
131+
/// \param[in] x the argument
132+
/// \param[in] weight the weight for this entry
133+
/// \par See also
134+
/// the \ref Fill(double x) "overload for unweighted filling"
135+
void Fill(double x, RWeight weight)
136+
{
137+
// If the histogram exists, forward the Fill call.
138+
if (fHist) {
139+
fHist->Fill(x, weight);
140+
return;
141+
}
142+
BufferImpl(x, weight);
143+
}
144+
104145
/// Flush the buffer of entries and construct the histogram.
105146
///
106147
/// Throws an exception if the buffer is empty, the axis interval cannot be determined, or if it would be empty
@@ -127,8 +168,12 @@ public:
127168
assert(high > fMaximum);
128169
fHist.emplace(fNNormalBins, std::make_pair(fMinimum, high));
129170

130-
for (double x : fBuffer) {
131-
fHist->Fill(x);
171+
for (auto &&x : fBuffer) {
172+
if constexpr (SupportsWeightedFilling) {
173+
fHist->Fill(x.first, x.second);
174+
} else {
175+
fHist->Fill(x);
176+
}
132177
}
133178
fBuffer.clear();
134179
}

hist/histv7/test/hist_auto.cxx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,36 @@ TEST(RHistAutoAxisFiller, FillMax0)
8585
EXPECT_EQ(hist.GetBinContent(RBinIndex::Overflow()), 0);
8686
}
8787

88+
TEST(RHistAutoAxisFiller, FillFloat)
89+
{
90+
RHistAutoAxisFiller<float> filler(3);
91+
92+
filler.Fill(1);
93+
filler.Fill(2);
94+
95+
auto &hist = filler.GetHist();
96+
EXPECT_EQ(hist.GetBinContent(0), 1);
97+
EXPECT_EQ(hist.GetBinContent(2), 1);
98+
99+
filler.Fill(1.5);
100+
EXPECT_EQ(hist.GetBinContent(1), 1);
101+
}
102+
103+
TEST(RHistAutoAxisFiller, FillWeight)
104+
{
105+
RHistAutoAxisFiller<float> filler(3);
106+
107+
filler.Fill(1, RWeight(0.8));
108+
filler.Fill(2, RWeight(0.9));
109+
110+
auto &hist = filler.GetHist();
111+
EXPECT_FLOAT_EQ(hist.GetBinContent(0), 0.8);
112+
EXPECT_FLOAT_EQ(hist.GetBinContent(2), 0.9);
113+
114+
filler.Fill(1.5, RWeight(0.85));
115+
EXPECT_FLOAT_EQ(hist.GetBinContent(1), 0.85);
116+
}
117+
88118
TEST(RHistAutoAxisFiller, FlushError)
89119
{
90120
static constexpr std::size_t Bins = 20;

0 commit comments

Comments
 (0)