Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:07:43

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include <array>
0012 #include <string>
0013 #include <tuple>
0014 
0015 #include <boost/histogram.hpp>
0016 
0017 namespace Acts::Experimental {
0018 
0019 using BoostVariableAxis = boost::histogram::axis::variable<double, std::string>;
0020 using BoostRegularAxis =
0021     boost::histogram::axis::regular<double, boost::histogram::use_default,
0022                                     std::string>;
0023 
0024 /// @brief Boost axis variant supporting both variable and regular axes with metadata
0025 /// NOTE: It seems not to be possible to combine compile-time fixed number of
0026 /// axes with boost::histogram::axis::variant. Therefore we use
0027 /// std::vector<AxisVariant> internally.
0028 using AxisVariant =
0029     boost::histogram::axis::variant<BoostVariableAxis, BoostRegularAxis>;
0030 
0031 /// @brief Underlying Boost type for histograms
0032 using BoostHist = decltype(boost::histogram::make_histogram(
0033     std::declval<std::vector<AxisVariant>>()));
0034 
0035 /// @brief Underlying Boost type for ProfileHistogram
0036 using BoostProfileHist = decltype(boost::histogram::make_profile(
0037     std::declval<std::vector<AxisVariant>>()));
0038 
0039 /// @brief Multi-dimensional histogram wrapper using boost::histogram for data collection
0040 ///
0041 /// This class wraps boost::histogram to provide a ROOT-independent histogram
0042 /// implementation with compile-time dimensionality.
0043 ///
0044 /// @tparam Dim Number of dimensions
0045 template <std::size_t Dim>
0046 class Histogram {
0047  public:
0048   /// Construct multi-dimensional histogram from axes
0049   ///
0050   /// @param name Histogram name (for identification and output)
0051   /// @param title Histogram title (for plotting)
0052   /// @param axes Array of axes with binning and metadata
0053   Histogram(std::string name, std::string title,
0054             const std::array<AxisVariant, Dim>& axes)
0055       : m_name(std::move(name)),
0056         m_title(std::move(title)),
0057         m_hist(boost::histogram::make_histogram(axes.begin(), axes.end())) {}
0058 
0059   /// Fill histogram with values
0060   ///
0061   /// @param values Values to fill (one per axis)
0062   void fill(const std::array<double, Dim>& values) {
0063     std::apply([this](auto... v) { m_hist(v...); }, std::tuple_cat(values));
0064   }
0065 
0066   /// Get histogram name
0067   const std::string& name() const { return m_name; }
0068 
0069   /// Get histogram title
0070   const std::string& title() const { return m_title; }
0071 
0072   /// Get number of dimensions (compile-time constant)
0073   static constexpr std::size_t rank() { return Dim; }
0074 
0075   /// Direct access to boost::histogram (for converters and tests)
0076   const BoostHist& histogram() const { return m_hist; }
0077 
0078  private:
0079   std::string m_name;
0080   std::string m_title;
0081 
0082   BoostHist m_hist;
0083 };
0084 
0085 /// Type aliases for common dimensions
0086 using Histogram1 = Histogram<1>;
0087 using Histogram2 = Histogram<2>;
0088 
0089 /// @brief Multi-dimensional profile histogram using boost::histogram
0090 ///
0091 /// This class wraps boost::histogram to provide a ROOT-independent profile
0092 /// histogram implementation with compile-time dimensionality. For each bin,
0093 /// it tracks the mean and variance of sample values.
0094 ///
0095 /// @tparam Dim Number of dimensions
0096 template <std::size_t Dim>
0097 class ProfileHistogram {
0098  public:
0099   /// Construct multi-dimensional profile histogram from axes
0100   ///
0101   /// @param name Histogram name (for identification and output)
0102   /// @param title Histogram title (for plotting)
0103   /// @param axes Array of axes with binning and metadata
0104   /// @param sampleAxisTitle Title for the sampled axis (profiled quantity)
0105   ProfileHistogram(std::string name, std::string title,
0106                    const std::array<AxisVariant, Dim>& axes,
0107                    std::string sampleAxisTitle)
0108       : m_name(std::move(name)),
0109         m_title(std::move(title)),
0110         m_sampleAxisTitle(std::move(sampleAxisTitle)),
0111         m_hist(boost::histogram::make_profile(axes.begin(), axes.end())) {}
0112 
0113   /// Fill profile with values and sample
0114   ///
0115   /// @param values Bin coordinate values (one per axis)
0116   /// @param sample Sample value (profiled quantity)
0117   void fill(const std::array<double, Dim>& values, double sample) {
0118     std::apply(
0119         [&](auto... v) { m_hist(v..., boost::histogram::sample(sample)); },
0120         std::tuple_cat(values));
0121   }
0122 
0123   /// Get histogram name
0124   const std::string& name() const { return m_name; }
0125 
0126   /// Get histogram title
0127   const std::string& title() const { return m_title; }
0128 
0129   /// Get number of dimensions (compile-time constant)
0130   static constexpr std::size_t rank() { return Dim; }
0131 
0132   /// Get title of the sample axis
0133   const std::string& sampleAxisTitle() const { return m_sampleAxisTitle; }
0134 
0135   /// Direct access to boost::histogram (for converters and tests)
0136   const BoostProfileHist& histogram() const { return m_hist; }
0137 
0138  private:
0139   std::string m_name;
0140   std::string m_title;
0141   std::string m_sampleAxisTitle;
0142 
0143   BoostProfileHist m_hist;
0144 };
0145 
0146 /// Type aliases for common dimensions
0147 using ProfileHistogram1 = ProfileHistogram<1>;
0148 
0149 /// @brief Multi-dimensional efficiency histogram using boost::histogram
0150 ///
0151 /// This class tracks pass/total counts for efficiency calculation.
0152 /// It internally uses two multi-dimensional histograms: one for accepted
0153 /// events, one for total events.
0154 ///
0155 /// @tparam Dim Number of dimensions
0156 template <std::size_t Dim>
0157 class Efficiency {
0158  public:
0159   /// Construct multi-dimensional efficiency histogram
0160   ///
0161   /// @param name Histogram name
0162   /// @param title Histogram title
0163   /// @param axes Array of axes with binning and metadata
0164   Efficiency(std::string name, std::string title,
0165              const std::array<AxisVariant, Dim>& axes)
0166       : m_name(std::move(name)),
0167         m_title(std::move(title)),
0168         m_accepted(boost::histogram::make_histogram(axes.begin(), axes.end())),
0169         m_total(boost::histogram::make_histogram(axes.begin(), axes.end())) {}
0170 
0171   /// Fill efficiency histogram
0172   ///
0173   /// @param values Values to fill (one per axis)
0174   /// @param accepted Whether the event passed selection
0175   void fill(const std::array<double, Dim>& values, bool accepted) {
0176     std::apply(
0177         [&](auto... v) {
0178           m_total(v...);
0179           if (accepted) {
0180             m_accepted(v...);
0181           }
0182         },
0183         std::tuple_cat(values));
0184   }
0185 
0186   /// Get histogram name
0187   const std::string& name() const { return m_name; }
0188 
0189   /// Get histogram title
0190   const std::string& title() const { return m_title; }
0191 
0192   /// Get number of dimensions (compile-time constant)
0193   static constexpr std::size_t rank() { return Dim; }
0194 
0195   /// Access to accepted histogram (for converters and tests)
0196   const BoostHist& acceptedHistogram() const { return m_accepted; }
0197 
0198   /// Access to total histogram (for converters and tests)
0199   const BoostHist& totalHistogram() const { return m_total; }
0200 
0201  private:
0202   std::string m_name;
0203   std::string m_title;
0204 
0205   BoostHist m_accepted;
0206   BoostHist m_total;
0207 };
0208 
0209 /// Type aliases for common dimensions
0210 using Efficiency1 = Efficiency<1>;
0211 using Efficiency2 = Efficiency<2>;
0212 
0213 /// Project a 2D histogram onto the X axis (axis 0)
0214 ///
0215 /// @param hist2d The 2D histogram to project
0216 /// @return A 1D histogram containing the projection
0217 Histogram1 projectionX(const Histogram2& hist2d);
0218 
0219 /// Project a 2D histogram onto the Y axis (axis 1)
0220 ///
0221 /// @param hist2d The 2D histogram to project
0222 /// @return A 1D histogram containing the projection
0223 Histogram1 projectionY(const Histogram2& hist2d);
0224 
0225 }  // namespace Acts::Experimental