|
|
|||
File indexing completed on 2026-09-15 08:18:41
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/AxisDefinitions.hpp" 0012 0013 #include <iosfwd> 0014 #include <memory> 0015 #include <optional> 0016 #include <vector> 0017 0018 namespace Acts { 0019 0020 /// Common base class for all Axis instances. This allows generice handling 0021 /// such as for inspection. 0022 class IAxis { 0023 public: 0024 IAxis() = default; 0025 0026 /// Constructs a new axis with the given direction 0027 /// @param direction the optional direction of the axis 0028 explicit IAxis(std::optional<AxisDirection> direction) 0029 : m_direction(direction) {} 0030 0031 virtual ~IAxis() = default; 0032 0033 /// Returns whether the axis is equidistant 0034 /// @return bool is equidistant 0035 virtual bool isEquidistant() const = 0; 0036 0037 /// Returns whether the axis is variable 0038 /// @return bool is variable 0039 virtual bool isVariable() const = 0; 0040 0041 /// Returns the type of the axis 0042 /// @return @c AxisType of this axis 0043 virtual AxisType getType() const = 0; 0044 0045 /// Returns the boundary type set in the template param 0046 /// @return @c AxisBoundaryType of this axis 0047 virtual AxisBoundaryType getBoundaryType() const = 0; 0048 0049 /// Returns the direction of the axis 0050 /// @return @c AxisDirection of this axis 0051 std::optional<AxisDirection> getDirection() const { return m_direction; } 0052 0053 /// Returns a vector of bin edges 0054 /// @return Vector which contains the bin edges 0055 virtual std::vector<double> getBinEdges() const = 0; 0056 0057 /// Get minimum of binning range 0058 /// @return minimum of binning range 0059 virtual double getMin() const = 0; 0060 0061 /// Get maximum of binning range 0062 /// @return maximum of binning range 0063 virtual double getMax() const = 0; 0064 0065 /// Get total number of bins 0066 /// @return total number of bins (excluding under-/overflow bins) 0067 virtual std::size_t getNBins() const = 0; 0068 0069 /// Get corresponding bin index for given coordinate 0070 /// @param [in] x input coordinate 0071 /// @return index of bin containing the given value 0072 /// @note Bin indices start at @c 1. The underflow bin has the index @c 0 0073 /// while the index <tt>nBins + 1</tt> indicates the overflow bin . 0074 virtual std::size_t getBin(double x) const = 0; 0075 0076 /// Check whether value is inside axis limits 0077 /// @param x The value to check 0078 /// @return @c true if the value is within the axis range, otherwise @c false 0079 /// @post If @c true is returned, the bin containing the given value is a 0080 /// valid bin, i.e. it is neither the underflow nor the overflow bin. 0081 virtual bool isInside(double x) const = 0; 0082 0083 /// Get bin width 0084 /// @param bin index of bin 0085 /// @return width of given bin 0086 virtual double getBinWidth(std::size_t bin) const = 0; 0087 0088 /// Get lower bound of bin 0089 /// @param bin index of bin 0090 /// @return lower bin boundary 0091 /// @note Bin intervals have a closed lower bound, i.e. the lower boundary 0092 /// belongs to the bin with the given bin index. 0093 virtual double getBinLowerBound(std::size_t bin) const = 0; 0094 0095 /// Get upper bound of bin 0096 /// @param bin index of bin 0097 /// @return upper bin boundary 0098 /// @note Bin intervals have an open upper bound, i.e. the upper boundary 0099 /// does @b not belong to the bin with the given bin index. 0100 virtual double getBinUpperBound(std::size_t bin) const = 0; 0101 0102 /// Get bin center 0103 /// @param bin index of bin 0104 /// @return bin center position 0105 virtual double getBinCenter(std::size_t bin) const = 0; 0106 0107 /// Centralized axis factory for equidistant binning 0108 /// @param aBoundaryType the axis boundary type 0109 /// @param min the minimum edge of the axis 0110 /// @param max the maximum edge of the axis 0111 /// @param nbins the number of bins 0112 /// @param direction the optional direction of the axis 0113 /// @throws std::invalid_argument if min >= max or nbins == 0 0114 /// @return a unique pointer to the axis 0115 static std::unique_ptr<IAxis> createEquidistant( 0116 AxisBoundaryType aBoundaryType, double min, double max, std::size_t nbins, 0117 std::optional<AxisDirection> direction = std::nullopt); 0118 0119 /// Centralized axis factory for variable binning 0120 /// @param aBoundaryType the axis boundary type 0121 /// @param edges are the bin edges 0122 /// @param direction the optional direction of the axis 0123 /// @throws std::invalid_argument if edges is empty or not strictly increasing 0124 /// @return a unique pointer to the axis 0125 static std::unique_ptr<IAxis> createVariable( 0126 AxisBoundaryType aBoundaryType, const std::vector<double>& edges, 0127 std::optional<AxisDirection> direction = std::nullopt); 0128 0129 /// Helper function that dispatches from the @c IAxis base class 0130 /// to a concrete axis type. It will call the provided @p callable 0131 /// with a const reference to the concrete axis type. 0132 /// @tparam callable_t the callable type 0133 /// @param callable the callable object 0134 /// @return the value returned by the callable 0135 template <typename callable_t> 0136 decltype(auto) visit(const callable_t& callable) const { 0137 auto switchOnType = 0138 [this, &callable]<AxisBoundaryType bdt>(AxisBoundaryTypeTag<bdt>) { 0139 switch (getType()) { 0140 using enum AxisType; 0141 case Equidistant: 0142 return callable( 0143 dynamic_cast<const Axis<AxisType::Equidistant, bdt>&>(*this)); 0144 case Variable: 0145 return callable( 0146 dynamic_cast<const Axis<AxisType::Variable, bdt>&>(*this)); 0147 default: 0148 throw std::logic_error("Unknown axis type"); 0149 } 0150 }; 0151 0152 switch (getBoundaryType()) { 0153 using enum AxisBoundaryType; 0154 case Open: 0155 return switchOnType(AxisOpen); 0156 case Bound: 0157 return switchOnType(AxisBound); 0158 case Closed: 0159 return switchOnType(AxisClosed); 0160 default: 0161 throw std::logic_error("Unknown axis type"); 0162 } 0163 } 0164 0165 /// Check if two axes are equal 0166 /// @param lhs first axis 0167 /// @param rhs second axis 0168 /// @return true if the axes are equal 0169 friend bool operator==(const IAxis& lhs, const IAxis& rhs) { 0170 return lhs.getType() == rhs.getType() && 0171 lhs.getBoundaryType() == rhs.getBoundaryType() && 0172 lhs.getMin() == rhs.getMin() && lhs.getMax() == rhs.getMax() && 0173 lhs.getNBins() == rhs.getNBins() && 0174 lhs.getBinEdges() == rhs.getBinEdges(); 0175 } 0176 0177 /// Output stream operator 0178 /// @param os output stream 0179 /// @param axis the axis to be printed 0180 /// @return the output stream 0181 friend std::ostream& operator<<(std::ostream& os, const IAxis& axis) { 0182 axis.toStream(os); 0183 return os; 0184 } 0185 0186 protected: 0187 /// Dispatch to the correct stream operator 0188 /// @param os output stream 0189 virtual void toStream(std::ostream& os) const = 0; 0190 0191 private: 0192 std::optional<AxisDirection> m_direction; 0193 }; 0194 0195 template <typename T> 0196 concept AxisConcept = std::derived_from<T, IAxis>; 0197 0198 } // namespace Acts
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|