Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-08 09:44:48

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/SurfaceBounds.hpp"
0014 
0015 #include <array>
0016 #include <cmath>
0017 #include <iostream>
0018 #include <numbers>
0019 #include <vector>
0020 
0021 namespace Acts {
0022 
0023 /// @class CylinderBounds
0024 /// @image html CylinderBounds.gif
0025 ///
0026 /// Bounds for a cylindrical Surface.
0027 ///
0028 /// These bounds may be used for a CylinderSurface
0029 /// In case of bounds for a StraightLineSurface the radius determines the radius
0030 /// within a localPosition
0031 /// is regarded as inside bounds.
0032 ///
0033 /// CylinderBounds also enhance the possibility of a cylinder segment with an
0034 /// opening angle @f$ 2\cdot\phi_{half}@f$
0035 /// around an average @f$ \phi @f$ angle @f$ \phi_{ave} @f$.
0036 ///
0037 /// CylinderBounds also supports beveled sides defined by an angle.
0038 /// Different angles can be defined on both sides of the cylinder.
0039 /// A positive angle is defined as "extruding" from the defined Zlength,
0040 /// while a negative angle is "intruding" on the Zlength.
0041 /// +    -            -   +
0042 /// ________________________
0043 /// \  |  /          \  |  /
0044 ///  \ | /            \ | /
0045 ///   \|/______________\|/
0046 ///     2 * ZhalfLength
0047 ///
0048 class CylinderBounds : public SurfaceBounds {
0049  public:
0050   /// @enum BoundValues
0051   /// Enumeration for the bound values
0052   enum BoundValues : int {
0053     eR = 0,
0054     eHalfLengthZ = 1,
0055     eHalfPhiSector = 2,
0056     eAveragePhi = 3,
0057     eBevelMinZ = 4,
0058     eBevelMaxZ = 5,
0059     eSize = 6
0060   };
0061 
0062   /// Constructor - full cylinder
0063   ///
0064   /// @param r The radius of the cylinder
0065   /// @param halfZ The half length in z
0066   /// @param halfPhi The half opening angle
0067   /// @param avgPhi (optional) The phi value from which the opening angle spans
0068   /// @param bevelMinZ (optional) The bevel on the negative z side
0069   /// @param bevelMaxZ (optional) The bevel on the positive z sid The bevel on the positive z side
0070   CylinderBounds(double r, double halfZ, double halfPhi = std::numbers::pi,
0071                  double avgPhi = 0., double bevelMinZ = 0.,
0072                  double bevelMaxZ = 0.) noexcept(false)
0073       : m_values({r, halfZ, halfPhi, avgPhi, bevelMinZ, bevelMaxZ}),
0074         m_closed(std::abs(halfPhi - std::numbers::pi) < s_epsilon) {
0075     checkConsistency();
0076   }
0077 
0078   /// Constructor from array
0079   /// @param values The bound values stored in an array
0080   explicit CylinderBounds(const std::array<double, eSize>& values) noexcept(
0081       false)
0082       : m_values(values),
0083         m_closed(std::abs(values[eHalfPhiSector] - std::numbers::pi) <
0084                  s_epsilon) {
0085     checkConsistency();
0086   }
0087 
0088   /// @copydoc SurfaceBounds::type
0089   BoundsType type() const final { return eCylinder; }
0090 
0091   /// @copydoc SurfaceBounds::isCartesian
0092   bool isCartesian() const final { return true; }
0093 
0094   /// @copydoc SurfaceBounds::boundToCartesianJacobian
0095   SquareMatrix2 boundToCartesianJacobian(const Vector2& lposition) const final {
0096     static_cast<void>(lposition);
0097     return SquareMatrix2::Identity();
0098   }
0099 
0100   /// @copydoc SurfaceBounds::boundToCartesianMetric
0101   SquareMatrix2 boundToCartesianMetric(const Vector2& lposition) const final {
0102     static_cast<void>(lposition);
0103     return SquareMatrix2::Identity();
0104   }
0105 
0106   /// Return the bound values as dynamically sized vector
0107   /// @return this returns a copy of the internal values
0108   std::vector<double> values() const final;
0109 
0110   /// @copydoc SurfaceBounds::inside
0111   bool inside(const Vector2& lposition) const final;
0112 
0113   /// @copydoc SurfaceBounds::closestPoint
0114   Vector2 closestPoint(const Vector2& lposition,
0115                        const SquareMatrix2& metric) const final;
0116 
0117   using SurfaceBounds::inside;
0118 
0119   /// Access to the bound values
0120   /// @param bValue the class nested enum for the array access
0121   /// @return Value of the specified bound parameter
0122   double get(BoundValues bValue) const { return m_values[bValue]; }
0123 
0124   /// Returns true for full phi coverage
0125   /// @return True if the cylinder covers full azimuthal range
0126   bool coversFullAzimuth() const { return m_closed; }
0127 
0128   /// Create the bow/circle vertices on either side of the cylinder
0129   ///
0130   /// @param transform is the global transform
0131   /// @param quarterSegments is the number of segments to approximate a quarter
0132   /// of a circle. In order to symmetrize fully closed and sectoral cylinders,
0133   /// also in the first case the two end points are given (albeit they overlap)
0134   /// in -pi / pi
0135   ///
0136   /// @return a singlevector containing the vertices from one side and then
0137   /// from the other side consecutively
0138   std::vector<Vector3> circleVertices(const Transform3 transform,
0139                                       unsigned int quarterSegments) const;
0140 
0141   /// @copydoc SurfaceBounds::center
0142   /// @note For CylinderBounds: returns (averagePhi, 0) in local (rphi, z) coordinates
0143   Vector2 center() const final;
0144 
0145   /// Output Method for std::ostream
0146   /// @param sl The output stream to write to
0147   /// @return Reference to the output stream after writing
0148   std::ostream& toStream(std::ostream& sl) const final;
0149 
0150  private:
0151   /// The bound radius, half Z, half phi and average phi
0152   std::array<double, eSize> m_values;
0153   /// Indicator if the bounds are closed
0154   bool m_closed{false};
0155 
0156   /// Check the input values for consistency, will throw a logic_exception
0157   /// if consistency is not given
0158   void checkConsistency() noexcept(false);
0159 
0160   /// Helper method to shift into the phi-frame
0161   /// @param lposition the polar coordinates in the global frame
0162   Vector2 shifted(const Vector2& lposition) const;
0163 };
0164 
0165 }  // namespace Acts