Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-28 07:53:58

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 "Acts/Utilities/Axis.hpp"
0012 #include "Acts/Utilities/AxisDefinitions.hpp"
0013 #include "Acts/Utilities/Grid.hpp"
0014 #include "Acts/Utilities/IAxis.hpp"
0015 
0016 #include <memory>
0017 #include <vector>
0018 
0019 namespace Acts {
0020 /// This class is a pure run-time placeholder for the axis definition
0021 ///
0022 /// The IAxis allows via the visitor pattern to access the actual axis type
0023 /// which helps to create grid creation code by the compiler as done
0024 /// in the makeGrid helper functions.
0025 ///
0026 /// In addition to a simple axis definitions, it holds also a description
0027 /// of the axis direction.
0028 class ProtoAxis {
0029  public:
0030   /// Convenience constructors - for variable binning
0031   ///
0032   /// @param abType the axis boundary type
0033   /// @param edges the bin edges (variable binning)
0034   ProtoAxis(Acts::AxisBoundaryType abType, const std::vector<double>& edges);
0035 
0036   /// Convenience constructors - for equidistant binning
0037   ///
0038   /// @param abType the axis boundary type
0039   /// @param minE the lowest edge of the binning
0040   /// @param maxE the highest edge of the binning
0041   /// @param nbins the number of bins
0042   ProtoAxis(AxisBoundaryType abType, double minE, double maxE,
0043             std::size_t nbins);
0044 
0045   /// Placeholder constructor for auto-range binning
0046   ///
0047   /// @param abType the axis boundary type
0048   /// @param nbins the number of bins
0049   ///
0050   /// @note that auto-range is only supported for equidistant binning
0051   ProtoAxis(AxisBoundaryType abType, std::size_t nbins);
0052 
0053   /// Custom copy constructor
0054   /// @param other is the right hand side ProtoAxis
0055   ProtoAxis(const ProtoAxis& other);
0056 
0057   /// Custom assignment operator
0058   /// @param other is the right hand side ProtoAxis
0059   /// @return Reference to this ProtoAxis for assignment chaining
0060   ProtoAxis& operator=(const ProtoAxis& other);
0061 
0062   /// Move constructor
0063   ProtoAxis(ProtoAxis&&) = default;
0064   /// Move assignment operator
0065   /// @return Reference to this ProtoAxis for assignment chaining
0066   ProtoAxis& operator=(ProtoAxis&&) = default;
0067 
0068   ~ProtoAxis() = default;
0069 
0070   /// @brief Return the IAxis representation
0071   ///
0072   /// @return @c AxisType of this axis
0073   const IAxis& getAxis() const;
0074 
0075   /// Set the range, in case of autorange, this
0076   /// will toggle the autorange flag to false
0077   ///
0078   /// @throws an exception if minE > maxE
0079   ///
0080   /// @note In case of variable binning, it will clip the bins outside
0081   /// the new range off, i.e. it will potentially change the number
0082   /// of bins.
0083   ///
0084   /// @note In case of equidistant binning, it will adapt the bin size,
0085   /// and NOT change the number of bins.
0086   ///
0087   /// @param minE the lowest edge of the binning
0088   /// @param maxE the highest edge of the binning
0089   void setRange(double minE, double maxE);
0090 
0091   /// @brief check if this is an auto-range binning
0092   /// @return True if this axis uses auto-ranging
0093   bool isAutorange() const;
0094 
0095   /// Dump into a string
0096   /// @return the string representation
0097   std::string toString() const;
0098 
0099  private:
0100   /// @brief Hidden friend ostream operator
0101   /// @param os the output stream
0102   /// @param a the proto axis
0103   /// @return the streamed into operator
0104   friend std::ostream& operator<<(std::ostream& os, const ProtoAxis& a) {
0105     os << a.toString();
0106     return os;
0107   }
0108 
0109   /// Dispatch to the correct stream operator
0110   /// @param os output stream
0111   void toStream(std::ostream& os) const;
0112 
0113  protected:
0114   /// The axis representation
0115   std::unique_ptr<IAxis> m_axis = nullptr;
0116 
0117   /// Indicate if this is a place holder auto-range binning
0118   bool m_autorange = false;
0119 };
0120 
0121 /// @brief Helper method to create a 1D grid from a single proto axis
0122 ///
0123 /// @tparam payload_t the grid payloat type
0124 ///
0125 /// @param a the proto axis
0126 ///
0127 /// @return an IGrid unique ptr and hence transfers ownership
0128 template <typename payload_t>
0129 std::unique_ptr<IGrid> makeGrid(const ProtoAxis& a) {
0130   if (a.isAutorange()) {
0131     throw std::invalid_argument(
0132         "ProtoAxis::makeGrid: Auto-range of the proto axis is not (yet) "
0133         "resolved, call setRange() first.");
0134   }
0135 
0136   return a.getAxis().visit(
0137       [&]<typename AxisTypeA>(const AxisTypeA& axis) -> std::unique_ptr<IGrid> {
0138         using GridType = Grid<payload_t, AxisTypeA>;
0139         return std::make_unique<GridType>(axis);
0140       });
0141 }
0142 
0143 /// @brief Helper method to create a 2D grid from a two proto axes
0144 ///
0145 /// @tparam payload_t the grid payloat type
0146 ///
0147 /// @param a the first proto axis
0148 /// @param b the second proto axis
0149 ///
0150 /// @return an IGrid unique ptr and hence transfers ownership
0151 template <typename payload_t>
0152 std::unique_ptr<IGrid> makeGrid(const ProtoAxis& a, const ProtoAxis& b) {
0153   if (a.isAutorange() || b.isAutorange()) {
0154     throw std::invalid_argument(
0155         "ProtoAxis::makeGrid: Auto-range of the proto axis is not (yet) "
0156         "resolved, call setRange() first.");
0157   }
0158 
0159   return a.getAxis().visit([&]<typename AxisTypeA>(const AxisTypeA& axisA)
0160                                -> std::unique_ptr<IGrid> {
0161     return b.getAxis().visit([&]<typename AxisTypeB>(const AxisTypeB& axisB)
0162                                  -> std::unique_ptr<IGrid> {
0163       using GridType = Grid<payload_t, AxisTypeA, AxisTypeB>;
0164       return std::make_unique<GridType>(axisA, axisB);
0165     });
0166   });
0167 }
0168 
0169 /// A Directed proto axis
0170 struct DirectedProtoAxis : public ProtoAxis {
0171  public:
0172   /// Convenience constructors - for variable binning
0173   ///
0174   /// @param axisDir the axis direction
0175   /// @param abType the axis boundary type
0176   /// @param edges the bin edges (variable binning)
0177   DirectedProtoAxis(AxisDirection axisDir, AxisBoundaryType abType,
0178                     const std::vector<double>& edges);
0179 
0180   /// Convenience constructors - for equidistant binning
0181   ///
0182   /// @param axisDir the axis direction
0183   /// @param abType the axis boundary type
0184   /// @param minE the lowest edge of the binning
0185   /// @param maxE the highest edge of the binning
0186   /// @param nbins the number of bins
0187   DirectedProtoAxis(AxisDirection axisDir, AxisBoundaryType abType, double minE,
0188                     double maxE, std::size_t nbins);
0189 
0190   /// Placeholder constructor for auto-range binning
0191   ///
0192   /// @param axisDir the axis direction
0193   /// @param abType the axis boundary type
0194   /// @param nbins the number of bins
0195   ///
0196   /// @note that auto-range is only supported for equidistant binning
0197   DirectedProtoAxis(AxisDirection axisDir, AxisBoundaryType abType,
0198                     std::size_t nbins);
0199 
0200   virtual ~DirectedProtoAxis() = default;
0201 
0202   /// Access to the AxisDirection
0203   /// @return the axis direction
0204   AxisDirection getAxisDirection() const;
0205 
0206   /// Dump into a string
0207   /// @return the string representation
0208   std::string toString() const;
0209 
0210  private:
0211   /// @brief Hidden friend ostream operator
0212   /// @param os the output stream
0213   /// @param a the proto axis
0214   /// @return the streamed into operator
0215   friend std::ostream& operator<<(std::ostream& os,
0216                                   const DirectedProtoAxis& a) {
0217     os << a.toString();
0218     return os;
0219   }
0220 
0221   /// Dispatch to the correct stream operator
0222   /// @param os output stream
0223   void toStream(std::ostream& os) const;
0224 
0225   AxisDirection m_direction;
0226 };
0227 
0228 /// Stream operator for vector of ProtoAxis
0229 /// @param os Output stream
0230 /// @param a Vector of ProtoAxis to output
0231 /// @return Reference to output stream
0232 std::ostream& operator<<(std::ostream& os, const std::vector<ProtoAxis>& a);
0233 
0234 /// Stream operator for vector of DirectedProtoAxis
0235 /// @param os Output stream
0236 /// @param a Vector of DirectedProtoAxis to output
0237 /// @return Reference to output stream
0238 std::ostream& operator<<(std::ostream& os,
0239                          const std::vector<DirectedProtoAxis>& a);
0240 
0241 }  // namespace Acts