File indexing completed on 2026-05-30 08:18:21
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
0121
0122
0123
0124
0125
0126
0127 template <std::size_t Dim>
0128 class ProfileHistogram {
0129 public:
0130
0131
0132
0133
0134
0135
0136
0137 ProfileHistogram(std::string name, std::string title,
0138 const std::array<AxisVariant, Dim>& axes,
0139 std::string sampleAxisTitle,
0140 Range1D<double> sampleRange = {})
0141 : m_name(std::move(name)),
0142 m_title(std::move(title)),
0143 m_sampleAxisTitle(std::move(sampleAxisTitle)),
0144 m_sampleRange(sampleRange),
0145 m_hist(boost::histogram::make_profile(axes.begin(), axes.end())) {}
0146
0147
0148
0149
0150
0151 void fill(const std::array<double, Dim>& values, double sample) {
0152 if (!m_sampleRange.contains(sample)) {
0153 return;
0154 }
0155
0156 std::apply(
0157 [&](auto... v) { m_hist(v..., boost::histogram::sample(sample)); },
0158 std::tuple_cat(values));
0159 }
0160
0161
0162
0163 const std::string& name() const { return m_name; }
0164
0165
0166
0167 const std::string& title() const { return m_title; }
0168
0169
0170
0171 static constexpr std::size_t rank() { return Dim; }
0172
0173
0174
0175 const std::string& sampleAxisTitle() const { return m_sampleAxisTitle; }
0176
0177
0178
0179 const BoostProfileHist& histogram() const { return m_hist; }
0180
0181 private:
0182 std::string m_name;
0183 std::string m_title;
0184 std::string m_sampleAxisTitle;
0185 Range1D<double> m_sampleRange;
0186
0187 BoostProfileHist m_hist;
0188 };
0189
0190
0191 using ProfileHistogram1 = ProfileHistogram<1>;
0192
0193
0194
0195
0196
0197
0198
0199
0200 template <std::size_t Dim>
0201 class Efficiency {
0202 public:
0203
0204
0205
0206
0207
0208 Efficiency(std::string name, std::string title,
0209 const std::array<AxisVariant, Dim>& axes)
0210 : m_name(std::move(name)),
0211 m_title(std::move(title)),
0212 m_accepted(boost::histogram::make_histogram(axes.begin(), axes.end())),
0213 m_total(boost::histogram::make_histogram(axes.begin(), axes.end())) {}
0214
0215
0216
0217
0218
0219 void fill(const std::array<double, Dim>& values, bool accepted) {
0220 std::apply(
0221 [&](auto... v) {
0222 m_total(v...);
0223 if (accepted) {
0224 m_accepted(v...);
0225 }
0226 },
0227 std::tuple_cat(values));
0228 }
0229
0230
0231
0232 const std::string& name() const { return m_name; }
0233
0234
0235
0236 const std::string& title() const { return m_title; }
0237
0238
0239
0240 static constexpr std::size_t rank() { return Dim; }
0241
0242
0243
0244 const BoostHist& acceptedHistogram() const { return m_accepted; }
0245
0246
0247
0248 const BoostHist& totalHistogram() const { return m_total; }
0249
0250 private:
0251 std::string m_name;
0252 std::string m_title;
0253
0254 BoostHist m_accepted;
0255 BoostHist m_total;
0256 };
0257
0258
0259 using Efficiency1 = Efficiency<1>;
0260
0261 using Efficiency2 = Efficiency<2>;
0262
0263
0264
0265
0266
0267 Histogram1 projectionX(const Histogram2& hist2d);
0268
0269
0270
0271
0272
0273 Histogram1 projectionY(const Histogram2& hist2d);
0274
0275
0276
0277
0278
0279
0280
0281
0282 std::vector<double> extractBinEdges(const AxisVariant& axis);
0283
0284 }