|
|
|||
File indexing completed on 2026-08-16 08:16:56
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/AxisSpec.hpp" 0012 #include "Acts/Utilities/IMultiAxis.hpp" 0013 0014 #include <array> 0015 #include <memory> 0016 #include <ostream> 0017 #include <span> 0018 #include <string> 0019 #include <vector> 0020 0021 namespace Acts { 0022 0023 class Surface; 0024 0025 /// @brief Specification of a multi-dimensional binning that builds the axes of 0026 /// a grid 0027 /// 0028 /// Bundles one @c AxisSpec per grid dimension, mirroring the 0029 /// @c IMultiAxis / @c IMultiAxisXD split: the dimension is known at runtime 0030 /// here and at compile time in the derived @c MultiAxisSpecXD . Unlike 0031 /// @c IMultiAxis this is a value type and can be held by configuration 0032 /// objects. 0033 /// 0034 /// The build API mirrors @c AxisSpec : fully specified specs build 0035 /// without input, deferred ones need one @c AxisSpec::Options per axis, in 0036 /// storage order. 0037 class MultiAxisSpec { 0038 public: 0039 /// Consumer supplied inputs, one @c AxisSpec::Options per axis, in axis 0040 /// order 0041 using Options = std::vector<AxisSpec::Options>; 0042 0043 /// Construct from one axis spec per dimension 0044 /// @param axisSpecs the axis specs, in axis order 0045 /// @throws std::invalid_argument if no axis spec is given 0046 explicit MultiAxisSpec(std::vector<AxisSpec> axisSpecs); 0047 0048 /// Copy constructor 0049 /// @param other the spec to copy from 0050 MultiAxisSpec(const MultiAxisSpec& other) = default; 0051 /// Move constructor 0052 /// @param other the spec to move from 0053 MultiAxisSpec(MultiAxisSpec&& other) noexcept = default; 0054 /// Copy assignment 0055 /// @param other the spec to copy from 0056 /// @return reference to this 0057 MultiAxisSpec& operator=(const MultiAxisSpec& other) = default; 0058 /// Move assignment 0059 /// @param other the spec to move from 0060 /// @return reference to this 0061 MultiAxisSpec& operator=(MultiAxisSpec&& other) noexcept = default; 0062 0063 virtual ~MultiAxisSpec() = default; 0064 0065 /// Get the number of axes spanning the grid 0066 /// @return number of axes (i.e. the dimension of the grid) 0067 std::size_t size() const; 0068 0069 /// Get the axis spec at the given dimension 0070 /// @param i index of the axis 0071 /// @return const reference to the requested axis spec 0072 const AxisSpec& axisSpec(std::size_t i) const; 0073 0074 /// Get all axis specs 0075 /// @return view onto the axis specs, in axis order 0076 std::span<const AxisSpec> axisSpecs() const; 0077 0078 /// Check if any of the contained specs is deferred, i.e. requires 0079 /// consumer supplied options to produce axes 0080 /// @return true if any axis spec is deferred 0081 bool isDeferred() const; 0082 0083 /// Build a multi-axis, one option set per axis or none at all 0084 /// @param options one option set per axis, in axis order, or empty 0085 /// @throws std::domain_error if a property is given by neither side, or the 0086 /// dimension exceeds the supported maximum of 3 0087 /// @throws std::invalid_argument if the number of option sets is neither 0088 /// zero nor the number of axes, or a property mismatches 0089 /// @return the created multi-axis 0090 std::unique_ptr<IMultiAxis> buildMultiAxis(const Options& options = {}) const; 0091 0092 protected: 0093 /// Build a multi-axis from a view onto the option sets 0094 /// @param options one option set per axis, in axis order, or empty 0095 /// @return the created multi-axis 0096 std::unique_ptr<IMultiAxis> buildMultiAxisImpl( 0097 std::span<const AxisSpec::Options> options) const; 0098 0099 public: 0100 /// Get a string representation of this spec 0101 /// @return the string representation 0102 std::string toString() const; 0103 0104 /// Check if two specs are equal 0105 /// @param lhs first spec 0106 /// @param rhs second spec 0107 /// @return true if all axis specs are equal 0108 friend bool operator==(const MultiAxisSpec& lhs, 0109 const MultiAxisSpec& rhs) = default; 0110 0111 /// Output stream operator 0112 /// @param os output stream 0113 /// @param multiAxisSpec the spec to be printed 0114 /// @return the output stream 0115 friend std::ostream& operator<<(std::ostream& os, 0116 const MultiAxisSpec& multiAxisSpec) { 0117 return os << multiAxisSpec.toString(); 0118 } 0119 0120 private: 0121 std::vector<AxisSpec> m_axisSpecs; 0122 }; 0123 0124 /// @brief Multi-dimensional binning spec of a compile-time dimension 0125 /// 0126 /// Adds a statically sized construction and build API on top of 0127 /// @c MultiAxisSpec , mirroring @c IMultiAxis and @c IMultiAxisXD . 0128 /// 0129 /// @tparam DIM number of axes (dimension of the grid) 0130 template <std::size_t DIM> 0131 class MultiAxisSpecXD : public MultiAxisSpec { 0132 public: 0133 static_assert(DIM >= 1 && DIM <= 3, 0134 "MultiAxisSpecXD supports 1 to 3 dimensions"); 0135 0136 /// Construct from one axis spec per dimension 0137 /// @param axisSpecs the axis specs, in axis order 0138 explicit MultiAxisSpecXD(std::array<AxisSpec, DIM> axisSpecs) 0139 : MultiAxisSpec( 0140 std::vector<AxisSpec>(std::make_move_iterator(axisSpecs.begin()), 0141 std::make_move_iterator(axisSpecs.end()))) {} 0142 0143 /// Consumer supplied inputs, one @c AxisSpec::Options per axis, in axis 0144 /// order; an all-default set leaves every property to the spec 0145 using Options = std::array<AxisSpec::Options, DIM>; 0146 0147 /// Build a multi-axis, one option set per axis 0148 /// @param options one option set per axis, in axis order 0149 /// @throws std::domain_error if a property is given by neither side 0150 /// @throws std::invalid_argument if a property mismatches 0151 /// @return the created multi-axis of dimension @c DIM 0152 std::unique_ptr<IMultiAxisXD<DIM>> buildMultiAxis( 0153 const Options& options = {}) const { 0154 return downcast(buildMultiAxisImpl(options)); 0155 } 0156 0157 private: 0158 /// Downcast a runtime-dimension multi-axis to the compile-time dimension 0159 /// @param multiAxis the multi-axis to downcast 0160 /// @return the downcasted multi-axis 0161 static std::unique_ptr<IMultiAxisXD<DIM>> downcast( 0162 std::unique_ptr<IMultiAxis> multiAxis) { 0163 auto* xd = dynamic_cast<IMultiAxisXD<DIM>*>(multiAxis.get()); 0164 if (xd == nullptr) { 0165 throw std::logic_error( 0166 "MultiAxisSpecXD: unexpected multi-axis dimension"); 0167 } 0168 multiAxis.release(); 0169 return std::unique_ptr<IMultiAxisXD<DIM>>(xd); 0170 } 0171 }; 0172 0173 /// Type alias for a multi-axis spec of dimension 1 0174 using MultiAxisSpec1D = MultiAxisSpecXD<1>; 0175 /// Type alias for a multi-axis spec of dimension 2 0176 using MultiAxisSpec2D = MultiAxisSpecXD<2>; 0177 0178 /// @brief Build the multi-axis of a surface binning against that surface 0179 /// 0180 /// A surface spans two local coordinates, so the binning is strictly 0181 /// two-dimensional; use a single bin in one direction to bin along the other 0182 /// only. Both specs are matched to the canonical local axis directions 0183 /// of the surface (see @c Surface::localAxes ), either positionally if 0184 /// neither carries a direction, or by direction if both do. Mixing the two is 0185 /// rejected. The axes are returned in canonical direction order. 0186 /// 0187 /// @param multiAxisSpec the binning spec to build from 0188 /// @param surface the surface to resolve the ranges against 0189 /// @throws std::invalid_argument if the directions cannot be matched or the 0190 /// surface is unsupported 0191 /// @throws std::domain_error if any spec is fully specified instead 0192 /// of deferred 0193 /// @return the created multi-axis, in canonical direction order 0194 std::unique_ptr<IMultiAxis2D> resolveMultiAxis( 0195 const MultiAxisSpec2D& multiAxisSpec, const Surface& surface); 0196 0197 } // 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 |
|