File indexing completed on 2026-03-28 07:45:31
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Utilities/RangeXD.hpp"
0012
0013 #include <array>
0014 #include <string>
0015 #include <tuple>
0016
0017 #include <boost/histogram.hpp>
0018
0019 namespace Acts::Experimental {
0020
0021
0022 using BoostVariableAxis = boost::histogram::axis::variable<double, std::string>;
0023
0024 using BoostRegularAxis =
0025 boost::histogram::axis::regular<double, boost::histogram::use_default,
0026 std::string>;
0027
0028 using BoostLogAxis = boost::histogram::axis::regular<
0029 double, boost::histogram::axis::transform::log, std::string>;
0030
0031
0032
0033
0034
0035 using AxisVariant =
0036 boost::histogram::axis::variant<BoostVariableAxis, BoostRegularAxis,
0037 BoostLogAxis>;
0038
0039
0040 using BoostHist = decltype(boost::histogram::make_histogram(
0041 std::declval<std::vector<AxisVariant>>()));
0042
0043
0044 using BoostProfileHist = decltype(boost::histogram::make_profile(
0045 std::declval<std::vector<AxisVariant>>()));
0046
0047
0048
0049
0050
0051
0052
0053 template <std::size_t Dim>
0054 class Histogram {
0055 public:
0056
0057
0058
0059
0060
0061 Histogram(std::string name, std::string title,
0062 const std::array<AxisVariant, Dim>& axes)
0063 : m_name(std::move(name)),
0064 m_title(std::move(title)),
0065 m_hist(boost::histogram::make_histogram(axes.begin(), axes.end())) {}
0066
0067
0068
0069 Histogram(const Histogram& other) = default;
0070
0071
0072
0073 Histogram(Histogram&& other) noexcept = default;
0074
0075
0076
0077
0078 Histogram& operator=(const Histogram& other) = default;
0079
0080
0081
0082
0083 Histogram& operator=(Histogram&& other) noexcept = default;
0084
0085
0086
0087
0088 void fill(const std::array<double, Dim>& values) {
0089 std::apply([this](auto... v) { m_hist(v...); }, std::tuple_cat(values));
0090 }
0091
0092
0093
0094 const std::string& name() const { return m_name; }
0095
0096
0097
0098 const std::string& title() const { return m_title; }
0099
0100
0101
0102 static constexpr std::size_t rank() { return Dim; }
0103
0104
0105
0106 const BoostHist& histogram() const { return m_hist; }
0107
0108 private:
0109 std::string m_name;
0110 std::string m_title;
0111
0112 BoostHist m_hist;
0113 };
0114
0115
0116 using Histogram1 = Histogram<1>;
0117
0118 using Histogram2 = Histogram<2>;
0119
0120 using Histogram3 = Histogram<3>;
0121
0122
0123
0124
0125
0126
0127
0128
0129 template <std::size_t Dim>
0130 class ProfileHistogram {
0131 public:
0132
0133
0134
0135
0136
0137
0138
0139 ProfileHistogram(std::string name, std::string title,
0140 const std::array<AxisVariant, Dim>& axes,
0141 std::string sampleAxisTitle,
0142 Range1D<double> sampleRange = {})
0143 : m_name(std::move(name)),
0144 m_title(std::move(title)),
0145 m_sampleAxisTitle(std::move(sampleAxisTitle)),
0146 m_sampleRange(sampleRange),
0147 m_hist(boost::histogram::make_profile(axes.begin(), axes.end())) {}
0148
0149
0150
0151
0152
0153 void fill(const std::array<double, Dim>& values, double sample) {
0154 if (!m_sampleRange.contains(sample)) {
0155 return;
0156 }
0157
0158 std::apply(
0159 [&](auto... v) { m_hist(v..., boost::histogram::sample(sample)); },
0160 std::tuple_cat(values));
0161 }
0162
0163
0164
0165 const std::string& name() const { return m_name; }
0166
0167
0168
0169 const std::string& title() const { return m_title; }
0170
0171
0172
0173 static constexpr std::size_t rank() { return Dim; }
0174
0175
0176
0177 const std::string& sampleAxisTitle() const { return m_sampleAxisTitle; }
0178
0179
0180
0181 const BoostProfileHist& histogram() const { return m_hist; }
0182
0183 private:
0184 std::string m_name;
0185 std::string m_title;
0186 std::string m_sampleAxisTitle;
0187 Range1D<double> m_sampleRange;
0188
0189 BoostProfileHist m_hist;
0190 };
0191
0192
0193 using ProfileHistogram1 = ProfileHistogram<1>;
0194
0195
0196
0197
0198
0199
0200
0201
0202 template <std::size_t Dim>
0203 class Efficiency {
0204 public:
0205
0206
0207
0208
0209
0210 Efficiency(std::string name, std::string title,
0211 const std::array<AxisVariant, Dim>& axes)
0212 : m_name(std::move(name)),
0213 m_title(std::move(title)),
0214 m_accepted(boost::histogram::make_histogram(axes.begin(), axes.end())),
0215 m_total(boost::histogram::make_histogram(axes.begin(), axes.end())) {}
0216
0217
0218
0219
0220
0221 void fill(const std::array<double, Dim>& values, bool accepted) {
0222 std::apply(
0223 [&](auto... v) {
0224 m_total(v...);
0225 if (accepted) {
0226 m_accepted(v...);
0227 }
0228 },
0229 std::tuple_cat(values));
0230 }
0231
0232
0233
0234 const std::string& name() const { return m_name; }
0235
0236
0237
0238 const std::string& title() const { return m_title; }
0239
0240
0241
0242 static constexpr std::size_t rank() { return Dim; }
0243
0244
0245
0246 const BoostHist& acceptedHistogram() const { return m_accepted; }
0247
0248
0249
0250 const BoostHist& totalHistogram() const { return m_total; }
0251
0252 private:
0253 std::string m_name;
0254 std::string m_title;
0255
0256 BoostHist m_accepted;
0257 BoostHist m_total;
0258 };
0259
0260
0261 using Efficiency1 = Efficiency<1>;
0262
0263 using Efficiency2 = Efficiency<2>;
0264
0265
0266
0267
0268
0269 Histogram1 projectionX(const Histogram2& hist2d);
0270
0271
0272
0273
0274
0275 Histogram1 projectionY(const Histogram2& hist2d);
0276
0277
0278
0279
0280
0281
0282
0283
0284 std::vector<double> extractBinEdges(const AxisVariant& axis);
0285
0286 }