|
|
|||
File indexing completed on 2025-11-06 09:17:10
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/Definitions/Tolerance.hpp" 0013 #include "Acts/Surfaces/DiscBounds.hpp" 0014 #include "Acts/Surfaces/SurfaceBounds.hpp" 0015 0016 #include <array> 0017 #include <cmath> 0018 #include <iosfwd> 0019 #include <numbers> 0020 #include <vector> 0021 0022 namespace Acts { 0023 0024 /// @brief Class that implements a (potentially asymmetric) bounds with 0025 /// difference between surface bound center and surface coordinate center 0026 /// 0027 /// These bounds combine two different systems: 0028 /// * module system : radial bounds centred on the moduleOrigin 0029 /// * strip system : phi bounds centred on the stripOrigin 0030 /// 0031 /// The measurement will be done in the strip system, with r/phi local 0032 /// coordinates. 0033 /// 0034 class AnnulusBounds : public DiscBounds { 0035 public: 0036 /// Enumeration for the different bound values 0037 enum BoundValues : int { 0038 eMinR = 0, 0039 eMaxR = 1, 0040 eMinPhiRel = 2, 0041 eMaxPhiRel = 3, 0042 eAveragePhi = 4, 0043 eOriginX = 5, 0044 eOriginY = 6, 0045 eSize = 7 0046 }; 0047 0048 /// @brief Default constructor from parameters 0049 /// @param minR The inner radius of the annulus 0050 /// @param maxR The outer radius of the annulus 0051 /// @param minPhiRel The minimum phi relative to average phi 0052 /// @param maxPhiRel The maximum phi relative to average phi 0053 /// @param moduleOrigin The origin of the module in the strip frame 0054 /// @param avgPhi The average phi value 0055 /// @note For @c morigin you need to actually calculate the cartesian 0056 /// offset 0057 explicit AnnulusBounds(double minR, double maxR, double minPhiRel, 0058 double maxPhiRel, const Vector2& moduleOrigin = {0, 0}, 0059 double avgPhi = 0) noexcept(false) 0060 : AnnulusBounds({minR, maxR, minPhiRel, maxPhiRel, avgPhi, 0061 moduleOrigin.x(), moduleOrigin.y()}) {} 0062 0063 /// Constructor - from fixed size array 0064 /// 0065 /// @param values The bound values stored in a fixed size array 0066 explicit AnnulusBounds(const std::array<double, eSize>& values) noexcept( 0067 false); 0068 0069 BoundsType type() const final { return eAnnulus; } 0070 0071 /// @copydoc SurfaceBounds::isCartesian 0072 bool isCartesian() const final { return false; } 0073 0074 /// @copydoc SurfaceBounds::boundToCartesianJacobian 0075 SquareMatrix2 boundToCartesianJacobian(const Vector2& lposition) const final; 0076 0077 /// @copydoc SurfaceBounds::boundToCartesianMetric 0078 SquareMatrix2 boundToCartesianMetric(const Vector2& lposition) const final; 0079 0080 /// Return the bound values as dynamically sized vector 0081 /// @return this returns a copy of the internal values 0082 std::vector<double> values() const final; 0083 0084 /// @copydoc SurfaceBounds::inside 0085 bool inside(const Vector2& lposition) const final; 0086 0087 /// @copydoc SurfaceBounds::closestPoint 0088 Vector2 closestPoint(const Vector2& lposition, 0089 const SquareMatrix2& metric) const final; 0090 0091 using SurfaceBounds::inside; 0092 0093 /// @copydoc SurfaceBounds::center 0094 /// @note For AnnulusBounds: returns pre-calculated center from corner vertices in strip polar coordinates (r, phi), accounting for average phi rotation 0095 Vector2 center() const final; 0096 0097 /// Outstream operator 0098 /// @param sl is the ostream to be dumped into 0099 /// @return Reference to the output stream 0100 std::ostream& toStream(std::ostream& sl) const final; 0101 0102 /// Access to the bound values 0103 /// @param bValue the class nested enum for the array access 0104 /// @return The value of the specified bound parameter 0105 double get(BoundValues bValue) const { return m_values[bValue]; } 0106 0107 /// @brief Returns the right angular edge of the module 0108 /// @return The right side angle 0109 double phiMin() const { return get(eMinPhiRel) + get(eAveragePhi); } 0110 0111 /// @brief Returns the left angular edge of the module 0112 /// @return The left side angle 0113 double phiMax() const { return get(eMaxPhiRel) + get(eAveragePhi); } 0114 0115 /// Returns true for full phi coverage 0116 /// @return True if the annulus covers the full azimuthal range, false otherwise 0117 bool coversFullAzimuth() const final { 0118 return (std::abs((get(eMinPhiRel) - get(eMaxPhiRel)) - std::numbers::pi) < 0119 s_onSurfaceTolerance); 0120 } 0121 0122 /// Checks if this is inside the radial coverage 0123 /// given the a tolerance 0124 /// @param R The radius value to check 0125 /// @param tolerance The tolerance for the check 0126 /// @return True if the radius is within bounds (plus tolerance), false otherwise 0127 bool insideRadialBounds(double R, double tolerance = 0.) const final { 0128 return ((R + tolerance) > get(eMinR) && (R - tolerance) < get(eMaxR)); 0129 } 0130 0131 /// Return a reference radius for binning 0132 /// @return Average radius for binning purposes 0133 double binningValueR() const final { return 0.5 * (get(eMinR) + get(eMaxR)); } 0134 0135 /// Return a reference phi for binning 0136 /// @return Average phi angle for binning purposes 0137 double binningValuePhi() const final { return get(eAveragePhi); } 0138 0139 /// @brief Returns moduleOrigin, but rotated out, so @c averagePhi is already 0140 /// considered. The module origin needs to consider the rotation introduced by 0141 /// @c averagePhi 0142 /// @return The origin of the local frame 0143 Vector2 moduleOrigin() const; 0144 0145 /// This method returns the four corners of the bounds in polar coordinates 0146 /// Starting from the upper right (max R, pos locX) and proceeding clock-wise 0147 /// i.e. (max R; pos locX), (min R; pos locX), (min R; neg loc X), (max R: neg 0148 /// locX) 0149 /// @return Vector of corner points in polar coordinates 0150 std::vector<Vector2> corners() const; 0151 0152 /// This method returns the xy coordinates of the four corners of the 0153 /// bounds in module coordinates (in x/y), and if quarterSegments is bigger or 0154 /// equal to 0, the curved part of the segment is included and approximated 0155 /// by the corresponding number of segments. 0156 /// 0157 /// Starting from the upper right (max R, pos locX) and proceeding clock-wise 0158 /// i.e. (max R; pos locX), (min R; pos locX), (min R; neg loc X), (max R: neg 0159 /// locX) 0160 /// 0161 /// @param quarterSegments the number of segments used to approximate 0162 /// a quarter of a circle 0163 /// 0164 /// @return vector for vertices in 2D 0165 std::vector<Vector2> vertices( 0166 unsigned int quarterSegments = 2u) const override; 0167 0168 /// This method returns inner radius 0169 /// @return Minimum radius of the annulus 0170 double rMin() const final { return get(eMinR); } 0171 0172 /// This method returns outer radius 0173 /// @return Maximum radius of the annulus 0174 double rMax() const final { return get(eMaxR); } 0175 0176 private: 0177 std::array<double, eSize> m_values; 0178 0179 // @TODO: Does this need to be in bound values? 0180 Vector2 m_moduleOrigin{ 0181 Vector2::Zero()}; ///< The origin of the module in the strip frame 0182 Vector2 m_shiftXY{Vector2::Zero()}; // == -m_moduleOrigin 0183 Vector2 m_shiftPC{Vector2::Zero()}; 0184 Transform2 m_rotationStripPC{Transform2::Identity()}; ///< Rotation to strip 0185 Transform2 m_translation{Transform2::Identity()}; ///< Translation to strip 0186 0187 // Vectors needed for inside checking 0188 Vector2 m_outLeftStripPC{Vector2::Zero()}; 0189 Vector2 m_inLeftStripPC{Vector2::Zero()}; 0190 Vector2 m_outRightStripPC{Vector2::Zero()}; 0191 Vector2 m_inRightStripPC{Vector2::Zero()}; 0192 0193 Vector2 m_outLeftModulePC{Vector2::Zero()}; 0194 Vector2 m_inLeftModulePC{Vector2::Zero()}; 0195 Vector2 m_outRightModulePC{Vector2::Zero()}; 0196 Vector2 m_inRightModulePC{Vector2::Zero()}; 0197 0198 Vector2 m_outLeftStripXY{Vector2::Zero()}; 0199 Vector2 m_inLeftStripXY{Vector2::Zero()}; 0200 Vector2 m_outRightStripXY{Vector2::Zero()}; 0201 Vector2 m_inRightStripXY{Vector2::Zero()}; 0202 0203 /// Pre-calculated center point (average of vertices) 0204 Vector2 m_center{Vector2::Zero()}; 0205 0206 /// Check the input values for consistency, will throw a logic_exception 0207 /// if consistency is not given 0208 void checkConsistency() noexcept(false); 0209 0210 /// Transform the strip cartesian into the module polar system 0211 /// 0212 /// @param vStripXY the position in the cartesian strip system 0213 /// @return the position in the module polar coordinate system 0214 Vector2 stripXYToModulePC(const Vector2& vStripXY) const; 0215 0216 Vector2 stripPCToModulePC(const Vector2& vStripPC) const; 0217 0218 Vector2 modulePCToStripPC(const Vector2& vModulePC) const; 0219 0220 SquareMatrix2 stripPCToModulePCJacobian( 0221 const Vector2& lpositionRotated) const; 0222 }; 0223 0224 } // 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 |
|