Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:03

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/BoundaryTolerance.hpp"
0014 #include "Acts/Surfaces/DiscBounds.hpp"
0015 #include "Acts/Surfaces/SurfaceBounds.hpp"
0016 
0017 #include <array>
0018 #include <cmath>
0019 #include <iosfwd>
0020 #include <numbers>
0021 #include <vector>
0022 
0023 namespace Acts {
0024 
0025 /// @brief Class that implements a (potentially asymmetric) bounds with
0026 /// difference between surface bound center and surface coordinate center
0027 ///
0028 /// These bounds combine two different systems:
0029 ///  * module system : radial bounds centred on the moduleOrigin
0030 ///  * strip system : phi bounds centred on the stripOrigin
0031 ///
0032 /// The measurement will be done in the strip system, with r/phi local
0033 /// coordinates.
0034 ///
0035 class AnnulusBounds : public DiscBounds {
0036  public:
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 inner radius, in module system
0050   /// @param maxR outer radius, in module system
0051   /// @param minPhiRel right angular edge, in strip system, rel to avgPhi
0052   /// @param maxPhiRel left angular edge, in strip system, rel to avgPhi
0053   /// @param moduleOrigin The origin offset between the two systems.
0054   /// @param avgPhi (Optional) internal rotation of this bounds object's local
0055   /// frame
0056   /// @note For @c morigin you need to actually calculate the cartesian
0057   /// offset
0058   AnnulusBounds(double minR, double maxR, double minPhiRel, double maxPhiRel,
0059                 const Vector2& moduleOrigin = {0, 0},
0060                 double avgPhi = 0) noexcept(false)
0061       : AnnulusBounds({minR, maxR, minPhiRel, maxPhiRel, avgPhi,
0062                        moduleOrigin.x(), moduleOrigin.y()}) {}
0063 
0064   /// Constructor - from parameters array
0065   ///
0066   /// @param values The parameter array
0067   AnnulusBounds(const std::array<double, eSize>& values) noexcept(false);
0068 
0069   AnnulusBounds(const AnnulusBounds& source) = default;
0070 
0071   BoundsType type() const final { return SurfaceBounds::eAnnulus; }
0072 
0073   /// Return the bound values as dynamically sized vector
0074   ///
0075   /// @return this returns a copy of the internal values
0076   std::vector<double> values() const final;
0077 
0078   /// Inside check for the bounds object driven by the boundary check directive
0079   /// Each Bounds has a method inside, which checks if a LocalPosition is inside
0080   /// the bounds  Inside can be called without/with tolerances.
0081   ///
0082   /// @param lposition Local position (assumed to be in right surface frame)
0083   /// @param boundaryTolerance boundary check directive
0084   /// @return boolean indicator for the success of this operation
0085   bool inside(const Vector2& lposition,
0086               const BoundaryTolerance& boundaryTolerance) const final;
0087 
0088   /// Outstream operator
0089   ///
0090   /// @param sl is the ostream to be dumped into
0091   std::ostream& toStream(std::ostream& sl) const final;
0092 
0093   /// Access to the bound values
0094   /// @param bValue the class nested enum for the array access
0095   double get(BoundValues bValue) const { return m_values[bValue]; }
0096 
0097   /// @brief Returns the right angular edge of the module
0098   /// @return The right side angle
0099   double phiMin() const { return get(eMinPhiRel) + get(eAveragePhi); }
0100 
0101   /// @brief Returns the left angular edge of the module
0102   /// @return The left side angle
0103   double phiMax() const { return get(eMaxPhiRel) + get(eAveragePhi); }
0104 
0105   /// Returns true for full phi coverage
0106   bool coversFullAzimuth() const final {
0107     return (std::abs((get(eMinPhiRel) - get(eMaxPhiRel)) - std::numbers::pi) <
0108             s_onSurfaceTolerance);
0109   }
0110 
0111   /// Checks if this is inside the radial coverage
0112   /// given the a tolerance
0113   bool insideRadialBounds(double R, double tolerance = 0.) const final {
0114     return ((R + tolerance) > get(eMinR) && (R - tolerance) < get(eMaxR));
0115   }
0116 
0117   /// Return a reference radius for binning
0118   double binningValueR() const final { return 0.5 * (get(eMinR) + get(eMaxR)); }
0119 
0120   /// Return a reference radius for binning
0121   double binningValuePhi() const final { return get(eAveragePhi); }
0122 
0123   /// @brief Returns moduleOrigin, but rotated out, so @c averagePhi is already
0124   /// considered. The module origin needs to consider the rotation introduced by
0125   /// @c averagePhi
0126   /// @return The origin of the local frame
0127   Vector2 moduleOrigin() const;
0128 
0129   /// This method returns the four corners of the bounds in polar coordinates
0130   /// Starting from the upper right (max R, pos locX) and proceeding clock-wise
0131   /// i.e. (max R; pos locX), (min R; pos locX), (min R; neg loc X), (max R: neg
0132   /// locX)
0133   std::vector<Vector2> corners() const;
0134 
0135   /// This method returns the xy coordinates of the four corners of the
0136   /// bounds in module coordinates (in x/y), and if quarterSegments is bigger or
0137   /// equal to 0, the curved part of the segment is included and approximated
0138   /// by the corresponding number of segments.
0139   ///
0140   /// Starting from the upper right (max R, pos locX) and proceeding clock-wise
0141   /// i.e. (max R; pos locX), (min R; pos locX), (min R; neg loc X), (max R: neg
0142   /// locX)
0143   ///
0144   /// @param quarterSegments the number of segments used to approximate
0145   /// a quarter of a circle
0146   ///
0147   /// @return vector for vertices in 2D
0148   std::vector<Vector2> vertices(
0149       unsigned int quarterSegments = 2u) const override;
0150 
0151   /// This method returns inner radius
0152   double rMin() const final { return get(eMinR); }
0153 
0154   /// This method returns outer radius
0155   double rMax() const final { return get(eMaxR); }
0156 
0157  private:
0158   std::array<double, eSize> m_values;
0159 
0160   // @TODO: Does this need to be in bound values?
0161   Vector2 m_moduleOrigin;
0162   Vector2 m_shiftXY;  // == -m_moduleOrigin
0163   Vector2 m_shiftPC;
0164   Transform2 m_rotationStripPC;
0165   Transform2 m_translation;
0166 
0167   // Vectors needed for inside checking
0168   Vector2 m_outLeftStripPC;
0169   Vector2 m_inLeftStripPC;
0170   Vector2 m_outRightStripPC;
0171   Vector2 m_inRightStripPC;
0172 
0173   Vector2 m_outLeftModulePC;
0174   Vector2 m_inLeftModulePC;
0175   Vector2 m_outRightModulePC;
0176   Vector2 m_inRightModulePC;
0177 
0178   Vector2 m_outLeftStripXY;
0179   Vector2 m_inLeftStripXY;
0180   Vector2 m_outRightStripXY;
0181   Vector2 m_inRightStripXY;
0182 
0183   /// Check the input values for consistency, will throw a logic_exception
0184   /// if consistency is not given
0185   void checkConsistency() noexcept(false);
0186 
0187   /// Inside check for the bounds object driven by the boundary check directive
0188   /// Each Bounds has a method inside, which checks if a LocalPosition is inside
0189   /// the bounds  Inside can be called without/with tolerances.
0190   ///
0191   /// @param lposition Local position (assumed to be in right surface frame)
0192   /// @param tolR tolerance on the radius
0193   /// @param tolPhi tolerance on the polar angle phi
0194   /// @return boolean indicator for the success of this operation
0195   virtual bool inside(const Vector2& lposition, double tolR,
0196                       double tolPhi) const final;
0197 
0198   /// Transform the strip cartesian
0199   /// into the module polar system
0200   ///
0201   /// @param vStripXY the position in the cartesian strip system
0202   /// @return the position in the module polar coordinate system
0203   Vector2 stripXYToModulePC(const Vector2& vStripXY) const;
0204 };
0205 
0206 }  // namespace Acts