Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-13 07:50:26

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   ProtoAxis& operator=(const ProtoAxis& other);
0060 
0061   ProtoAxis(ProtoAxis&&) = default;
0062   ProtoAxis& operator=(ProtoAxis&&) = default;
0063 
0064   ~ProtoAxis() = default;
0065 
0066   /// @brief Return the IAxis representation
0067   ///
0068   /// @return @c AxisType of this axis
0069   const IAxis& getAxis() const;
0070 
0071   /// Set the range, in case of autorange, this
0072   /// will toggle the autorange flag to false
0073   ///
0074   /// @throws an exception if minE > maxE
0075   ///
0076   /// @note In case of variable binning, it will clip the bins outside
0077   /// the new range off, i.e. it will potentially change the number
0078   /// of bins.
0079   ///
0080   /// @note In case of equidistant binning, it will adapt the bin size,
0081   /// and NOT change the number of bins.
0082   ///
0083   /// @param minE the lowest edge of the binning
0084   /// @param maxE the highest edge of the binning
0085   void setRange(double minE, double maxE);
0086 
0087   /// @brief check if this is an auto-range binning
0088   bool isAutorange() const;
0089 
0090   /// Dump into a string
0091   /// @return the string representation
0092   std::string toString() const;
0093 
0094  private:
0095   /// @brief Hidden friend ostream operator
0096   /// @param os the output stream
0097   /// @param a the proto axis
0098   /// @return the streamed into operator
0099   friend std::ostream& operator<<(std::ostream& os, const ProtoAxis& a) {
0100     os << a.toString();
0101     return os;
0102   }
0103 
0104   /// Dispatch to the correct stream operator
0105   /// @param os output stream
0106   void toStream(std::ostream& os) const;
0107 
0108  protected:
0109   /// The axis representation
0110   std::unique_ptr<IAxis> m_axis = nullptr;
0111 
0112   /// Indicate if this is a place holder auto-range binning
0113   bool m_autorange = false;
0114 };
0115 
0116 /// @brief Helper method to create a 1D grid from a single proto axis
0117 ///
0118 /// @tparam payload_t the grid payloat type
0119 ///
0120 /// @param a the proto axis
0121 ///
0122 /// @return an IGrid unique ptr and hence transfers ownership
0123 template <typename payload_t>
0124 std::unique_ptr<IGrid> makeGrid(const ProtoAxis& a) {
0125   if (a.isAutorange()) {
0126     throw std::invalid_argument(
0127         "ProtoAxis::makeGrid: Auto-range of the proto axis is not (yet) "
0128         "resolved, call setRange() first.");
0129   }
0130 
0131   return a.getAxis().visit(
0132       [&]<typename AxisTypeA>(const AxisTypeA& axis) -> std::unique_ptr<IGrid> {
0133         using GridType = Grid<payload_t, AxisTypeA>;
0134         return std::make_unique<GridType>(axis);
0135       });
0136 }
0137 
0138 /// @brief Helper method to create a 2D grid from a two proto axes
0139 ///
0140 /// @tparam payload_t the grid payloat type
0141 ///
0142 /// @param a the first proto axis
0143 /// @param b the second proto axis
0144 ///
0145 /// @return an IGrid unique ptr and hence transfers ownership
0146 template <typename payload_t>
0147 std::unique_ptr<IGrid> makeGrid(const ProtoAxis& a, const ProtoAxis& b) {
0148   if (a.isAutorange() || b.isAutorange()) {
0149     throw std::invalid_argument(
0150         "ProtoAxis::makeGrid: Auto-range of the proto axis is not (yet) "
0151         "resolved, call setRange() first.");
0152   }
0153 
0154   return a.getAxis().visit([&]<typename AxisTypeA>(const AxisTypeA& axisA)
0155                                -> std::unique_ptr<IGrid> {
0156     return b.getAxis().visit([&]<typename AxisTypeB>(const AxisTypeB& axisB)
0157                                  -> std::unique_ptr<IGrid> {
0158       using GridType = Grid<payload_t, AxisTypeA, AxisTypeB>;
0159       return std::make_unique<GridType>(axisA, axisB);
0160     });
0161   });
0162 }
0163 
0164 /// A Directed proto axis
0165 struct DirectedProtoAxis : public ProtoAxis {
0166  public:
0167   /// Convenience constructors - for variable binning
0168   ///
0169   /// @param axisDir the axis direction
0170   /// @param abType the axis boundary type
0171   /// @param edges the bin edges (variable binning)
0172   DirectedProtoAxis(AxisDirection axisDir, AxisBoundaryType abType,
0173                     const std::vector<double>& edges);
0174 
0175   /// Convenience constructors - for equidistant binning
0176   ///
0177   /// @param axisDir the axis direction
0178   /// @param abType the axis boundary type
0179   /// @param minE the lowest edge of the binning
0180   /// @param maxE the highest edge of the binning
0181   /// @param nbins the number of bins
0182   DirectedProtoAxis(AxisDirection axisDir, AxisBoundaryType abType, double minE,
0183                     double maxE, std::size_t nbins);
0184 
0185   /// Placeholder constructor for auto-range binning
0186   ///
0187   /// @param axisDir the axis direction
0188   /// @param abType the axis boundary type
0189   /// @param nbins the number of bins
0190   ///
0191   /// @note that auto-range is only supported for equidistant binning
0192   DirectedProtoAxis(AxisDirection axisDir, AxisBoundaryType abType,
0193                     std::size_t nbins);
0194 
0195   virtual ~DirectedProtoAxis() = default;
0196 
0197   /// Access to the AxisDirection
0198   /// @return the axis direction
0199   AxisDirection getAxisDirection() const;
0200 
0201   /// Dump into a string
0202   /// @return the string representation
0203   std::string toString() const;
0204 
0205  private:
0206   /// @brief Hidden friend ostream operator
0207   /// @param os the output stream
0208   /// @param a the proto axis
0209   /// @return the streamed into operator
0210   friend std::ostream& operator<<(std::ostream& os,
0211                                   const DirectedProtoAxis& a) {
0212     os << a.toString();
0213     return os;
0214   }
0215 
0216   /// Dispatch to the correct stream operator
0217   /// @param os output stream
0218   void toStream(std::ostream& os) const;
0219 
0220   AxisDirection m_direction;
0221 };
0222 
0223 std::ostream& operator<<(std::ostream& os, const std::vector<ProtoAxis>& a);
0224 
0225 std::ostream& operator<<(std::ostream& os,
0226                          const std::vector<DirectedProtoAxis>& a);
0227 
0228 }  // namespace Acts