Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-05 08:44:20

0001 // -*- C++ -*-
0002 //
0003 // This file is part of YODA -- Yet more Objects for Data Analysis
0004 // Copyright (C) 2008-2025 The YODA collaboration (see AUTHORS for details)
0005 //
0006 #ifndef YODA_BinnedUtils_h
0007 #define YODA_BinnedUtils_h
0008 
0009 #include "YODA/Utils/BinningUtils.h"
0010 
0011 namespace YODA {
0012 
0013 
0014   /// @name Mixin of convenience methods using CRTP
0015   /// @{
0016 
0017   /// @brief CRTP mixin introducing convenience aliases along X axis.
0018   template <class Derived, typename EdgeT = double>
0019   struct XAxisMixin {
0020 
0021     /// @name Bin accessors
0022     /// @{
0023 
0024     /// @brief Number of bins along the X axis
0025     size_t numBinsX(const bool includeOverflows=false) const {
0026       return static_cast<const Derived*>(this)->numBinsAt(0, includeOverflows);
0027     }
0028 
0029     /// @brief Low edge of first histo's axis
0030     template <class T = EdgeT>
0031     enable_if_CAxisT<T> xMin() const { return static_cast<const Derived*>(this)->template min<0>(); }
0032 
0033     /// @brief High edge of first histo's axis
0034     template <class T = EdgeT>
0035     enable_if_CAxisT<T> xMax() const { return static_cast<const Derived*>(this)->template max<0>(); }
0036 
0037     /// @brief All bin edges on X axis. +-inf edges are included.
0038     std::vector<EdgeT> xEdges(const bool includeOverflows = false) const {
0039       return static_cast<const Derived*>(this)->template edges<0>(includeOverflows);
0040     }
0041 
0042     /// @brief All widths on X axis
0043     ///
0044     /// @note Only supported for continuous axes
0045     template <class T = EdgeT>
0046     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0047     xWidths(const bool includeOverflows = false) const {
0048       return static_cast<const Derived*>(this)->template widths<0>(includeOverflows);
0049     }
0050 
0051     /// @brief All mins on X axis
0052     ///
0053     /// @note Only supported for continuous axes
0054     template <class T = EdgeT>
0055     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0056     xMins(const bool includeOverflows = false) const {
0057       return static_cast<const Derived*>(this)->template mins<0>(includeOverflows);
0058     }
0059 
0060     /// @brief All maxs on X axis
0061     ///
0062     /// @note Only supported for continuous axes
0063     template <class T = EdgeT>
0064     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0065     xMaxs(const bool includeOverflows = false) const {
0066       return static_cast<const Derived*>(this)->template maxs<0>(includeOverflows);
0067     }
0068 
0069     /// @brief All mids on X axis
0070     ///
0071     /// @note Only supported for continuous axes
0072     template <class T = EdgeT>
0073     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0074     xMids(const bool includeOverflows = false) const {
0075       return static_cast<const Derived*>(this)->template mids<0>(includeOverflows);
0076     }
0077 
0078     /// @brief Merge every group of @a n bins, from start to end inclusive
0079     ///
0080     /// @note Only supported for continuous axes
0081     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0082     void rebinXBy(unsigned int n, size_t begin=1, size_t end=UINT_MAX) {
0083       static_cast<Derived*>(this)->template rebinBy<0>(n, begin, end);
0084     }
0085 
0086     /// @brief Rebin to the given list of bin edges
0087     ///
0088     /// @note Only supported for continuous axes
0089     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0090     void rebinXTo(const std::vector<double>& newedges) {
0091       static_cast<Derived*>(this)->template rebinTo<0>(newedges);
0092     }
0093 
0094     /// @brief Overloaded alias for rebinXBy
0095     ///
0096     /// @note Only supported for continuous axes
0097     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0098     void rebinX(unsigned int n, size_t begin=1, size_t end=UINT_MAX) {
0099       static_cast<Derived*>(this)->template rebinBy<0>(n, begin, end);
0100     }
0101 
0102     /// @brief Overloaded alias for rebinXTo
0103     ///
0104     /// @note Only supported for continuous axes
0105     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0106     void rebinX(const std::vector<double>& newedges) {
0107       static_cast<Derived*>(this)->template rebinTo<0>(newedges);
0108     }
0109 
0110     /// @}
0111 
0112   };
0113 
0114 
0115   /// @brief CRTP mixin introducing convenience aliases to access statistics along X axis.
0116   template <class Derived>
0117   struct XStatsMixin {
0118 
0119     /// @name Whole histo data
0120     /// @{
0121 
0122     /// @brief List of mean values on X axis
0123     std::vector<double> xMeans(const bool includeOverflows=true) const noexcept {
0124       return static_cast<const Derived*>(this)->means(0, includeOverflows);
0125     }
0126 
0127     /// @brief Calculate the mean on X axis
0128     double xMean(const bool includeOverflows=true) const noexcept {
0129       return static_cast<const Derived*>(this)->mean(0, includeOverflows);
0130     }
0131 
0132     /// @brief Calculate the variance on X axis
0133     double xVariance(const bool includeOverflows=true) const noexcept {
0134       return static_cast<const Derived*>(this)->variance(0, includeOverflows);
0135     }
0136 
0137     /// @brief Calculate the standard deviation on X axis
0138     double xStdDev(const bool includeOverflows=true) const noexcept {
0139       return static_cast<const Derived*>(this)->stdDev(0, includeOverflows);
0140     }
0141 
0142     /// @brief Calculate the standard error on X axis
0143     double xStdErr(const bool includeOverflows=true) const noexcept {
0144       return static_cast<const Derived*>(this)->stdErr(0, includeOverflows);
0145     }
0146 
0147     /// @brief Calculate the RMS on X axis
0148     double xRMS(const bool includeOverflows=true) const noexcept {
0149       return static_cast<const Derived*>(this)->rms(0, includeOverflows);
0150     }
0151 
0152     /// @}
0153   };
0154 
0155 
0156   /// @brief CRTP mixin introducing convenience aliases along Y axis.
0157   template <class Derived, typename EdgeT = double>
0158   struct YAxisMixin {
0159 
0160     /// @name Bin accessors
0161     /// @{
0162 
0163     /// @brief Number of bins along the Y axis
0164     size_t numBinsY(const bool includeOverflows=false) const {
0165       return static_cast<const Derived*>(this)->numBinsAt(1, includeOverflows);
0166     }
0167 
0168     /// @brief Low edge of second histo's axis
0169     template <class T = EdgeT>
0170     enable_if_CAxisT<T> yMin() const { return static_cast<const Derived*>(this)->template min<1>(); }
0171 
0172     /// @brief High edge of second histo's axis
0173     template <class T = EdgeT>
0174     enable_if_CAxisT<T> yMax() const { return static_cast<const Derived*>(this)->template max<1>(); }
0175 
0176     /// @brief All bin edges on Y axis. +-inf edges are included.
0177     std::vector<EdgeT> yEdges(const bool includeOverflows = false) const {
0178       return static_cast<const Derived*>(this)->template edges<1>(includeOverflows);
0179     }
0180 
0181     /// @brief All widths on Y axis
0182     ///
0183     /// @note Only supported for continuous axes
0184     template <class T = EdgeT>
0185     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0186     yWidths(const bool includeOverflows = false) const {
0187       return static_cast<const Derived*>(this)->template widths<1>(includeOverflows);
0188     }
0189 
0190     /// @brief All mins on Y axis
0191     ///
0192     /// @note Only supported for continuous axes
0193     template <class T = EdgeT>
0194     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0195     yMins(const bool includeOverflows = false) const {
0196       return static_cast<const Derived*>(this)->template mins<1>(includeOverflows);
0197     }
0198 
0199     /// @brief All maxs on Y axis
0200     ///
0201     /// @note Only supported for continuous axes
0202     template <class T = EdgeT>
0203     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0204     yMaxs(const bool includeOverflows = false) const {
0205       return static_cast<const Derived*>(this)->template maxs<1>(includeOverflows);
0206     }
0207 
0208     /// @brief All mids on Y axis
0209     ///
0210     /// @note Only supported for continuous axes
0211     template <class T = EdgeT>
0212     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0213     yMids(const bool includeOverflows = false) const {
0214       return static_cast<const Derived*>(this)->template mids<1>(includeOverflows);
0215     }
0216 
0217     /// @brief Merge every group of @a n bins, from start to end inclusive
0218     ///
0219     /// @note Only supported for continuous axes
0220     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0221     void rebinYBy(unsigned int n, size_t begin=1, size_t end=UINT_MAX) {
0222       static_cast<Derived*>(this)->template rebinBy<1>(n, begin, end);
0223     }
0224 
0225     /// @brief Rebin to the given list of bin edges
0226     ///
0227     /// @note Only supported for continuous axes
0228     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0229     void rebinYTo(const std::vector<double>& newedges) {
0230       static_cast<Derived*>(this)->template rebinTo<1>(newedges);
0231     }
0232 
0233     /// @brief Overloaded alias for rebinYBy
0234     ///
0235     /// @note Only supported for continuous axes
0236     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0237     void rebinY(unsigned int n, size_t begin=1, size_t end=UINT_MAX) {
0238       static_cast<Derived*>(this)->template rebinBy<1>(n, begin, end);
0239     }
0240 
0241     /// @brief Overloaded alias for rebinYTo
0242     ///
0243     /// @note Only supported for continuous axes
0244     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0245     void rebinY(const std::vector<double>& newedges) {
0246       static_cast<Derived*>(this)->template rebinTo<1>(newedges);
0247     }
0248 
0249     /// @}
0250 
0251   };
0252 
0253   /// @brief CRTP mixin introducing convenience aliases to access statistics along Y axis.
0254   template <class Derived>
0255   struct YStatsMixin {
0256 
0257     /// @name Whole histo data
0258     /// @{
0259 
0260     /// @brief List of mean values on Y axis
0261     std::vector<double> yMeans(const bool includeOverflows=true) const noexcept {
0262       return static_cast<const Derived*>(this)->means(1, includeOverflows);
0263     }
0264 
0265     /// @brief Calculate the mean on Y axis
0266     double yMean(const bool includeOverflows=true) const noexcept {
0267       return static_cast<const Derived*>(this)->mean(1, includeOverflows);
0268     }
0269 
0270     /// @brief Calculate the variance on Y axis
0271     double yVariance(const bool includeOverflows=true) const noexcept {
0272       return static_cast<const Derived*>(this)->variance(1, includeOverflows);
0273     }
0274 
0275     /// @brief Calculate the standard deviation on Y axis
0276     double yStdDev(const bool includeOverflows=true) const noexcept {
0277       return static_cast<const Derived*>(this)->stdDev(1, includeOverflows);
0278     }
0279 
0280     /// @brief Calculate the standard error on Y axis
0281     double yStdErr(const bool includeOverflows=true) const noexcept {
0282       return static_cast<const Derived*>(this)->stdErr(1, includeOverflows);
0283     }
0284 
0285     /// @brief Calculate the RMS on Y axis
0286     double yRMS(const bool includeOverflows=true) const noexcept {
0287       return static_cast<const Derived*>(this)->rms(1, includeOverflows);
0288     }
0289 
0290     /// @}
0291 
0292   };
0293 
0294 
0295   /// @brief CRTP mixin introducing convenience aliases along Z axis.
0296   template <class Derived, typename EdgeT = double>
0297   struct ZAxisMixin {
0298 
0299     /// @name Bin accessors
0300     /// @{
0301 
0302     /// @brief Number of bins along the Z axis
0303     size_t numBinsZ(const bool includeOverflows=false) const {
0304       return static_cast<const Derived*>(this)->numBinsAt(2, includeOverflows);
0305     }
0306 
0307     /// @brief Low edge of second histo's axis
0308     template <class T = EdgeT>
0309     enable_if_CAxisT<T> zMin() const { return static_cast<const Derived*>(this)->template min<2>(); }
0310 
0311     /// @brief High edge of second histo's axis
0312     template <class T = EdgeT>
0313     enable_if_CAxisT<T> zMax() const { return static_cast<const Derived*>(this)->template max<2>(); }
0314 
0315     /// @brief All bin edges on Z axis. +-inf edges are included.
0316     std::vector<EdgeT> zEdges(const bool includeOverflows = false) const {
0317       return static_cast<const Derived*>(this)->template edges<2>(includeOverflows);
0318     }
0319 
0320     /// @brief All widths on Z axis
0321     ///
0322     /// @note Only supported for continuous axes
0323     template <class T = EdgeT>
0324     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0325     zWidths(const bool includeOverflows = false) const {
0326       return static_cast<const Derived*>(this)->template widths<2>(includeOverflows);
0327     }
0328 
0329     /// @brief All mins on Z axis
0330     ///
0331     /// @note Only supported for continuous axes
0332     template <class T = EdgeT>
0333     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0334     zMins(const bool includeOverflows = false) const {
0335       return static_cast<const Derived*>(this)->template mins<2>(includeOverflows);
0336     }
0337 
0338     /// @brief All maxs on Z axis
0339     ///
0340     /// @note Only supported for continuous axes
0341     template <class T = EdgeT>
0342     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0343     zMaxs(const bool includeOverflows = false) const {
0344       return static_cast<const Derived*>(this)->template maxs<2>(includeOverflows);
0345     }
0346 
0347     /// @brief All mids on Z axis
0348     ///
0349     /// @note Only supported for continuous axes
0350     template <class T = EdgeT>
0351     std::enable_if_t<std::is_floating_point<T>::value, std::vector<T>>
0352     zMids(const bool includeOverflows = false) const {
0353       return static_cast<const Derived*>(this)->template mids<2>(includeOverflows);
0354     }
0355 
0356     /// @brief Merge every group of @a n bins, from start to end inclusive
0357     ///
0358     /// @note Only supported for continuous axes
0359     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0360     void rebinZBy(unsigned int n, size_t begin=1, size_t end=UINT_MAX) {
0361       static_cast<Derived*>(this)->template rebinBy<2>(n, begin, end);
0362     }
0363 
0364     /// @brief Rebin to the given list of bin edges
0365     ///
0366     /// @note Only supported for continuous axes
0367     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0368     void rebinZTo(const std::vector<double>& newedges) {
0369       static_cast<Derived*>(this)->template rebinTo<2>(newedges);
0370     }
0371 
0372     /// @brief Overloaded alias for rebinZBy
0373     ///
0374     /// @note Only supported for continuous axes
0375     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0376     void rebinZ(unsigned int n, size_t begin=1, size_t end=UINT_MAX) {
0377       static_cast<Derived*>(this)->template rebinBy<2>(n, begin, end);
0378     }
0379 
0380     /// @brief Overloaded alias for rebinZTo
0381     ///
0382     /// @note Only supported for continuous axes
0383     template <class T = EdgeT, typename = std::enable_if_t<std::is_floating_point<T>::value>>
0384     void rebinZ(const std::vector<double>& newedges) {
0385       static_cast<Derived*>(this)->template rebinTo<2>(newedges);
0386     }
0387 
0388     /// @}
0389 
0390   };
0391 
0392   /// @brief CRTP mixin introducing convenience aliases to access statistics along Z axis.
0393   template <class Derived>
0394   struct ZStatsMixin {
0395 
0396     /// @name Whole histo data
0397     /// @{
0398 
0399     /// @brief List of mean values on Z axis
0400     std::vector<double> zMeans(const bool includeOverflows=true) const noexcept {
0401       return static_cast<const Derived*>(this)->means(2, includeOverflows);
0402     }
0403 
0404     /// @brief Calculate the mean on Z axis
0405     double zMean(const bool includeOverflows=true) const noexcept {
0406       return static_cast<const Derived*>(this)->mean(2, includeOverflows);
0407     }
0408 
0409     /// @brief Calculate the variance on Z axis
0410     double zVariance(const bool includeOverflows=true) const noexcept {
0411       return static_cast<const Derived*>(this)->variance(2, includeOverflows);
0412     }
0413 
0414     /// @brief Calculate the standard deviation on Z axis
0415     double zStdDev(const bool includeOverflows=true) const noexcept {
0416       return static_cast<const Derived*>(this)->stdDev(2, includeOverflows);
0417     }
0418 
0419     /// @brief Calculate the standard error on Z axis
0420     double zStdErr(const bool includeOverflows=true) const noexcept {
0421       return static_cast<const Derived*>(this)->stdErr(2, includeOverflows);
0422     }
0423 
0424     /// @brief Calculate the RMS on Z axis
0425     double zRMS(const bool includeOverflows=true) const noexcept {
0426       return static_cast<const Derived*>(this)->rms(2, includeOverflows);
0427     }
0428 
0429   };
0430 
0431   /// @}
0432 
0433 }
0434 
0435 #endif