Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-17 09:35:03

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_Profile_h
0007 #define YODA_Profile_h
0008 
0009 #include "YODA/BinnedDbn.h"
0010 
0011 namespace YODA {
0012 
0013 
0014   /// @brief Specialisation of the BinnedDbn for a 1D profile
0015   template <typename AxisT>
0016   class BinnedDbn<2, AxisT>
0017       : public DbnStorage<2, AxisT>,
0018         public XAxisMixin<BinnedDbn<2, AxisT>, AxisT>,
0019         public XStatsMixin<BinnedDbn<2, AxisT>> {
0020   public:
0021 
0022     using ProfileT = BinnedDbn<2, AxisT>;
0023     using BaseT = DbnStorage<2, AxisT>;
0024     using FillType = typename BaseT::FillType;
0025     using BinType = typename BaseT::BinT;
0026     using Ptr = std::shared_ptr<ProfileT>;
0027 
0028     /// @brief Inherit constructors.
0029     using BaseT::BaseT;
0030 
0031     BinnedDbn() = default;
0032     BinnedDbn(const ProfileT&) = default;
0033     BinnedDbn(ProfileT&&) = default;
0034     BinnedDbn& operator =(const ProfileT&) = default;
0035     BinnedDbn& operator =(ProfileT&&) = default;
0036     using AnalysisObject::operator =;
0037 
0038     /// @brief Copy constructor (needed for clone functions).
0039     ///
0040     /// @note Compiler won't generate this constructor automatically.
0041     BinnedDbn(const BaseT& other) : BaseT(other) {}
0042     //
0043     BinnedDbn(const ProfileT& other, const std::string& path) : BaseT(other, path) {}
0044 
0045     /// @brief Move constructor
0046     BinnedDbn(BaseT&& other) : BaseT(std::move(other)) {}
0047     //
0048     BinnedDbn(ProfileT&& other, const std::string& path) : BaseT(std::move(other), path) {}
0049 
0050     /// @brief Constructor with auto-setup of evenly spaced axes.
0051     ///
0052     /// The constructor argument uses double rather than EdgeT to
0053     /// allow for auto-conversion of int to double.
0054     ///
0055     /// @note This constructor is only supported when all axes are continuous.
0056     template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT>>
0057     BinnedDbn(size_t nbins, double lower, double upper,
0058               const std::string& path = "", const std::string& title = "")
0059         : BaseT({nbins}, {{lower, upper}}, path, title) {}
0060 
0061     /// @brief Make a copy on the stack
0062     ProfileT clone() const noexcept {
0063       return ProfileT(*this);
0064     }
0065 
0066     /// @brief Make a copy on the heap
0067     ProfileT* newclone() const noexcept {
0068       return new ProfileT(*this);
0069     }
0070 
0071     /// @brief Fill function with an explicit coordinate.
0072     virtual int fill(const AxisT valX, const double valY, const double weight = 1.0, const double fraction = 1.0) {
0073       return BaseT::fill({valX, valY}, weight, fraction);
0074     }
0075 
0076     /// @brief Fill function with FillType.
0077     virtual int fill(FillType&& coords, const double weight = 1.0, const double fraction = 1.0) {
0078       return BaseT::fill(std::move(coords), weight, fraction);
0079     }
0080 
0081     /// @brief Find bin index for given coordinates
0082     size_t indexAt(const AxisT xCoord) const noexcept {
0083       return BaseT::binAt( {xCoord} ).index();
0084     }
0085 
0086     /// @brief Mask/Unmask bin at given set of coordinates
0087     void maskBinAt(const AxisT xCoord, const bool status = true) noexcept {
0088       return BaseT::maskBin({xCoord}, status);
0089     }
0090 
0091   };
0092 
0093 
0094   /// @brief Specialisation of the BinnedDbn for a 2D profile
0095   template <typename AxisT1, typename AxisT2>
0096   class BinnedDbn<3, AxisT1, AxisT2>
0097       : public DbnStorage<3, AxisT1, AxisT2>,
0098         public XAxisMixin<BinnedDbn<3, AxisT1, AxisT2>, AxisT1>,
0099         public XStatsMixin<BinnedDbn<3, AxisT1, AxisT2>>,
0100         public YAxisMixin<BinnedDbn<3, AxisT1, AxisT2>, AxisT2>,
0101         public YStatsMixin<BinnedDbn<3, AxisT1, AxisT2>> {
0102   public:
0103 
0104     using ProfileT = BinnedDbn<3, AxisT1, AxisT2>;
0105     using BaseT = DbnStorage<3, AxisT1, AxisT2>;
0106     using FillType = typename BaseT::FillType;
0107     using BinType = typename BaseT::BinT;
0108     using Ptr = std::shared_ptr<ProfileT>;
0109 
0110     /// @brief Inherit constructors.
0111     using BaseT::BaseT;
0112 
0113     BinnedDbn() = default;
0114     BinnedDbn(const ProfileT&) = default;
0115     BinnedDbn(ProfileT&&) = default;
0116     BinnedDbn& operator =(const ProfileT&) = default;
0117     BinnedDbn& operator =(ProfileT&&) = default;
0118     using AnalysisObject::operator =;
0119 
0120     /// @brief Copy constructor (needed for clone functions).
0121     ///
0122     /// @note Compiler won't generate this constructor automatically.
0123     BinnedDbn(const BaseT& other) : BaseT(other) {}
0124     //
0125     BinnedDbn(const ProfileT& other, const std::string& path) : BaseT(other, path) {}
0126 
0127     /// @brief Move constructor
0128     BinnedDbn(BaseT&& other) : BaseT(std::move(other)) {}
0129     //
0130     BinnedDbn(ProfileT&& other, const std::string& path) : BaseT(std::move(other), path) {}
0131 
0132     /// @brief Constructor with auto-setup of evenly spaced axes.
0133     ///
0134     /// The constructor argument uses double rather than EdgeT to
0135     /// allow for auto-conversion of int to double.
0136     ///
0137     /// @note This constructor is only supported when all axes are continuous.
0138     template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT1, AxisT2>>
0139     BinnedDbn(size_t nbinsX, double lowerX, double upperX,
0140               size_t nbinsY, double lowerY, double upperY,
0141               const std::string& path = "", const std::string& title = "")
0142         : BaseT({nbinsX, nbinsY}, {{lowerX, upperX}, {lowerY, upperY}}, path, title) {}
0143 
0144     /// @brief Make a copy on the stack
0145     ProfileT clone() const noexcept {
0146       return ProfileT(*this);
0147     }
0148 
0149     /// @brief Make a copy on the heap
0150     ProfileT* newclone() const noexcept {
0151       return new ProfileT(*this);
0152     }
0153 
0154     /// @brief Fill function with two explicit coordinates.
0155     virtual int fill(const AxisT1 valX, const AxisT2 valY, const double valZ, const double weight = 1.0, const double fraction = 1.0) {
0156       return BaseT::fill({valX, valY, valZ}, weight, fraction);
0157     }
0158 
0159     /// @brief Fill function with FillType.
0160     virtual int fill(FillType&& coords, const double weight = 1.0, const double fraction = 1.0) {
0161       return BaseT::fill(std::move(coords), weight, fraction);
0162     }
0163 
0164     /// @brief Bin access using global index
0165     BinType& bin(const size_t index) noexcept {
0166       return BaseT::bin(index);
0167     }
0168 
0169     /// @brief Bin access using global index (const version)
0170     const BinType& bin(const size_t index) const noexcept {
0171       return BaseT::bin(index);
0172     }
0173 
0174     /// @brief Bin access using local indices
0175     BinType& bin(const size_t localX, const size_t localY) noexcept {
0176       return BaseT::bin( {localX, localY} );
0177     }
0178 
0179     /// @brief Bin access using local indices (const version)
0180     const BinType& bin(const size_t localX, const size_t localY) const noexcept {
0181       return BaseT::bin( {localX, localY} );
0182     }
0183 
0184     /// @brief Bin access using coordinates
0185     BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord) noexcept {
0186       return BaseT::binAt( {xCoord, yCoord} );
0187     }
0188 
0189     /// @brief Bin access using coordinates (const version)
0190     const BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord) const noexcept {
0191       return BaseT::binAt( {xCoord, yCoord} );
0192     }
0193 
0194     /// @brief Find bin index for given coordinates
0195     size_t indexAt(const AxisT1 xCoord, const AxisT2 yCoord) const noexcept {
0196       return BaseT::binAt( {xCoord, yCoord} ).index();
0197     }
0198 
0199     /// @brief Mask/Unmask bin at given set of coordinates
0200     void maskBinAt(const AxisT1 xCoord, const AxisT2 yCoord, const bool status = true) noexcept {
0201       return BaseT::maskBin({xCoord, yCoord}, status);
0202     }
0203 
0204   };
0205 
0206 
0207 
0208   /// @brief Specialisation of the BinnedDbn for a 2D profile
0209   template <typename AxisT1, typename AxisT2, typename AxisT3>
0210   class BinnedDbn<4, AxisT1, AxisT2, AxisT3>
0211       : public DbnStorage<4, AxisT1, AxisT2, AxisT3>,
0212         public XAxisMixin<BinnedDbn<4, AxisT1, AxisT2, AxisT3>, AxisT1>,
0213         public XStatsMixin<BinnedDbn<4, AxisT1, AxisT2, AxisT3>>,
0214         public YAxisMixin<BinnedDbn<4, AxisT1, AxisT2, AxisT3>, AxisT3>,
0215         public YStatsMixin<BinnedDbn<4, AxisT1, AxisT2, AxisT3>> {
0216   public:
0217 
0218     using ProfileT = BinnedDbn<4, AxisT1, AxisT2, AxisT3>;
0219     using BaseT = DbnStorage<4, AxisT1, AxisT2, AxisT3>;
0220     using FillType = typename BaseT::FillType;
0221     using BinType = typename BaseT::BinT;
0222     using Ptr = std::shared_ptr<ProfileT>;
0223 
0224     /// @brief Inherit constructors.
0225     using BaseT::BaseT;
0226 
0227     BinnedDbn() = default;
0228     BinnedDbn(const ProfileT&) = default;
0229     BinnedDbn(ProfileT&&) = default;
0230     BinnedDbn& operator =(const ProfileT&) = default;
0231     BinnedDbn& operator= (ProfileT&&) = default;
0232     using AnalysisObject::operator =;
0233 
0234     /// @brief Copy constructor (needed for clone functions).
0235     ///
0236     /// @note Compiler won't generate this constructor automatically.
0237     BinnedDbn(const BaseT& other) : BaseT(other) {}
0238     //
0239     BinnedDbn(const ProfileT& other, const std::string& path) : BaseT(other, path) {}
0240 
0241     /// @brief Move constructor
0242     BinnedDbn(BaseT&& other) : BaseT(std::move(other)) {}
0243     //
0244     BinnedDbn(ProfileT&& other, const std::string& path) : BaseT(std::move(other), path) {}
0245 
0246     /// @brief Constructor with auto-setup of evenly spaced axes.
0247     ///
0248     /// The constructor argument uses double rather than EdgeT to
0249     /// allow for auto-conversion of int to double.
0250     ///
0251     /// @note This constructor is only supported when all axes are continuous.
0252     template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT1, AxisT2, AxisT3>>
0253     BinnedDbn(size_t nbinsX, double lowerX, double upperX,
0254               size_t nbinsY, double lowerY, double upperY,
0255               size_t nbinsZ, double lowerZ, double upperZ,
0256               const std::string& path, const std::string& title = "")
0257         : BaseT({nbinsX, nbinsY, nbinsZ},
0258                 {{lowerX, upperX}, {lowerY, upperY},
0259                 {lowerZ, upperZ}}, path, title) {}
0260 
0261     /// @brief Make a copy on the stack
0262     ProfileT clone() const noexcept {
0263       return ProfileT(*this);
0264     }
0265 
0266     /// @brief Make a copy on the heap
0267     ProfileT* newclone() const noexcept {
0268       return new ProfileT(*this);
0269     }
0270 
0271     /// @brief Fill function with three explicit coordinates.
0272     virtual int fill(const AxisT1 valX, const AxisT2 valY, const AxisT3 valZ, const double valZplus,
0273                                                    const double weight = 1.0, const double fraction = 1.0) {
0274       return BaseT::fill({valX, valY, valZ, valZplus}, weight, fraction);
0275     }
0276 
0277     /// @brief Fill function with FillType.
0278     virtual int fill(FillType&& coords, const double weight = 1.0, const double fraction = 1.0) {
0279       return BaseT::fill(std::move(coords), weight, fraction);
0280     }
0281 
0282     /// @brief Bin access using global index
0283     BinType& bin(const size_t index) noexcept {
0284       return BaseT::bin(index);
0285     }
0286 
0287     /// @brief Bin access using global index (const version)
0288     const BinType& bin(const size_t index) const noexcept {
0289       return BaseT::bin(index);
0290     }
0291 
0292     /// @brief Bin access using local indices
0293     BinType& bin(const size_t localX, const size_t localY, const size_t localZ) noexcept {
0294       return BaseT::bin( {localX, localY, localZ} );
0295     }
0296 
0297     /// @brief Bin access using local indices (const version)
0298     const BinType& bin(const size_t localX, const size_t localY, const size_t localZ) const noexcept {
0299       return BaseT::bin( {localX, localY, localZ} );
0300     }
0301 
0302     /// @brief Bin access using coordinates
0303     BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) noexcept {
0304       return BaseT::binAt( {xCoord, yCoord, zCoord} );
0305     }
0306 
0307     /// @brief Bin access using coordinates (const version)
0308     const BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) const noexcept {
0309       return BaseT::binAt( {xCoord, yCoord, zCoord} );
0310     }
0311 
0312     /// @brief Find bin index for given coordinates
0313     size_t indexAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) const noexcept {
0314       return BaseT::binAt( {xCoord, yCoord, zCoord} ).index();
0315     }
0316 
0317     /// @brief Mask/Unmask bin at given set of coordinates
0318     void maskBinAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord, const bool status = true) noexcept {
0319       return BaseT::maskBin({xCoord, yCoord, zCoord}, status);
0320     }
0321 
0322   };
0323 
0324 
0325   /// Define dimension-specific short-hands (Cython sugar)
0326   template<typename A1>
0327   using BinnedProfile1D = BinnedProfile<A1>;
0328 
0329   template <typename A1, typename A2>
0330   using BinnedProfile2D = BinnedProfile<A1, A2>;
0331 
0332   template <typename A1, typename A2, typename A3>
0333   using BinnedProfile3D = BinnedProfile<A1, A2, A3>;
0334 
0335   /// Anonymous namespace to limit visibility
0336   namespace {
0337     template <class T>
0338     struct ProfileMaker;
0339 
0340     template<size_t... Is>
0341     struct ProfileMaker<std::index_sequence<Is...>> {
0342       using type = BinnedProfile< std::decay_t<decltype((void)Is, std::declval<double>())>... >;
0343     };
0344   }
0345 
0346   /// @brief User-friendly name for the N-dimensional profile with all-continuous axes
0347   template<size_t N>
0348   using ProfileND = typename ProfileMaker<std::make_index_sequence<N>>::type;
0349 
0350   /// User-friendly familiar names (continuous axes only)
0351   using Profile1D = BinnedProfile<double>;
0352   using Profile2D = BinnedProfile<double,double>;
0353   using Profile3D = BinnedProfile<double,double,double>;
0354 
0355 }
0356 
0357 #endif
0358