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/Definitions/Algebra.hpp"
0012 #include "Acts/Utilities/AxisDefinitions.hpp"
0013 
0014 #include <iosfwd>
0015 #include <memory>
0016 #include <vector>
0017 
0018 namespace Acts {
0019 
0020 /// Common base class for all Axis instance. This allows generice handling
0021 /// such as for inspection.
0022 class IAxis {
0023  public:
0024   /// Virtual destructor
0025   virtual ~IAxis() = default;
0026 
0027   /// @brief returns whether the axis is equidistant
0028   ///
0029   /// @return bool is equidistant
0030   virtual bool isEquidistant() const = 0;
0031 
0032   /// @brief returns whether the axis is variable
0033   ///
0034   /// @return bool is variable
0035   virtual bool isVariable() const = 0;
0036 
0037   /// @brief returns the type of the axis
0038   /// @return @c AxisType of this axis
0039   virtual AxisType getType() const = 0;
0040 
0041   /// @brief returns the boundary type set in the template param
0042   ///
0043   /// @return @c AxisBoundaryType of this axis
0044   virtual AxisBoundaryType getBoundaryType() const = 0;
0045 
0046   /// @brief Return a vector of bin edges
0047   /// @return Vector which contains the bin edges
0048   virtual std::vector<double> getBinEdges() const = 0;
0049 
0050   /// @brief get minimum of binning range
0051   ///
0052   /// @return minimum of binning range
0053   virtual double getMin() const = 0;
0054 
0055   /// @brief get maximum of binning range
0056   ///
0057   /// @return maximum of binning range
0058   virtual double getMax() const = 0;
0059 
0060   /// @brief get total number of bins
0061   ///
0062   /// @return total number of bins (excluding under-/overflow bins)
0063   virtual std::size_t getNBins() const = 0;
0064 
0065   /// Centralized axis factory for equidistant binning
0066   ///
0067   /// @param aBoundaryType the axis boundary type
0068   /// @param min the minimum edge of the axis
0069   /// @param max the maximum edge of the axis
0070   /// @param nbins the number of bins
0071   ///
0072   /// @throws std::invalid_argument if min >= max or nbins == 0
0073   ///
0074   /// @return a unique pointer to the axis
0075   static std::unique_ptr<IAxis> createEquidistant(
0076       AxisBoundaryType aBoundaryType, double min, double max,
0077       std::size_t nbins);
0078 
0079   /// Centralized axis factory for variable binning
0080   ///
0081   /// @param aBoundaryType the axis boundary type
0082   /// @param edges are the bin edges
0083   ///
0084   /// @throws std::invalid_argument if edges is empty or not strictly increasing
0085   ///
0086   /// @return a unique pointer to the axis
0087   static std::unique_ptr<IAxis> createVariable(
0088       AxisBoundaryType aBoundaryType, const std::vector<double>& edges);
0089 
0090   /// Helper function that dispatches from the @c IAxis base class
0091   /// to a concrete axis type. It will call the provided @p callable
0092   /// with a const reference to the concrete axis type.
0093   /// @tparam callable_t the callable type
0094   /// @param callable the callable object
0095   /// @return the value returned by the callable
0096   template <typename callable_t>
0097   decltype(auto) visit(const callable_t& callable) const {
0098     auto switchOnType =
0099         [this, &callable]<AxisBoundaryType bdt>(AxisBoundaryTypeTag<bdt>) {
0100           switch (getType()) {
0101             using enum AxisType;
0102             case Equidistant:
0103               return callable(
0104                   dynamic_cast<const Axis<AxisType::Equidistant, bdt>&>(*this));
0105             case Variable:
0106               return callable(
0107                   dynamic_cast<const Axis<AxisType::Variable, bdt>&>(*this));
0108             default:
0109               throw std::logic_error("Unknown axis type");
0110           }
0111         };
0112 
0113     switch (getBoundaryType()) {
0114       using enum AxisBoundaryType;
0115       case Open:
0116         return switchOnType(AxisOpen);
0117       case Bound:
0118         return switchOnType(AxisBound);
0119       case Closed:
0120         return switchOnType(AxisClosed);
0121       default:
0122         throw std::logic_error("Unknown axis type");
0123     }
0124   }
0125 
0126   /// Check if two axes are equal
0127   /// @param lhs first axis
0128   /// @param rhs second axis
0129   /// @return true if the axes are equal
0130   friend bool operator==(const IAxis& lhs, const IAxis& rhs) {
0131     return lhs.getType() == rhs.getType() &&
0132            lhs.getBoundaryType() == rhs.getBoundaryType() &&
0133            lhs.getMin() == rhs.getMin() && lhs.getMax() == rhs.getMax() &&
0134            lhs.getNBins() == rhs.getNBins() &&
0135            lhs.getBinEdges() == rhs.getBinEdges();
0136   }
0137 
0138   /// Output stream operator
0139   /// @param os output stream
0140   /// @param axis the axis to be printed
0141   /// @return the output stream
0142   friend std::ostream& operator<<(std::ostream& os, const IAxis& axis) {
0143     axis.toStream(os);
0144     return os;
0145   }
0146 
0147  protected:
0148   /// Dispatch to the correct stream operator
0149   /// @param os output stream
0150   virtual void toStream(std::ostream& os) const = 0;
0151 };
0152 
0153 template <typename T>
0154 concept AxisConcept = std::derived_from<T, IAxis>;
0155 
0156 }  // namespace Acts