Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:23:34

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2020 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 http://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/Definitions/TrackParametrization.hpp"
0014 #include "Acts/Surfaces/BoundaryCheck.hpp"
0015 #include "Acts/Surfaces/DiscBounds.hpp"
0016 #include "Acts/Surfaces/SurfaceBounds.hpp"
0017 #include "Acts/Utilities/detail/periodic.hpp"
0018 
0019 #include <array>
0020 #include <cmath>
0021 #include <exception>
0022 #include <iosfwd>
0023 #include <stdexcept>
0024 #include <vector>
0025 
0026 namespace Acts {
0027 
0028 /// @brief Class that implements a (potentially asymmetric) bounds with
0029 /// difference between surface bound center and surface coordinate center
0030 ///
0031 /// These bounds combine two different systems:
0032 ///  * module system : radial bounds centred on the moduleOrigin
0033 ///  * strip system : phi bounds centred on the stripOrigin
0034 ///
0035 /// The measurement will be done in the strip system, with r/phi local
0036 /// coordinates.
0037 ///
0038 class AnnulusBounds : public DiscBounds {
0039  public:
0040   enum BoundValues : int {
0041     eMinR = 0,
0042     eMaxR = 1,
0043     eMinPhiRel = 2,
0044     eMaxPhiRel = 3,
0045     eAveragePhi = 4,
0046     eOriginX = 5,
0047     eOriginY = 6,
0048     eSize = 7
0049   };
0050 
0051   AnnulusBounds() = delete;
0052 
0053   /// @brief Default constructor from parameters
0054   /// @param minR inner radius, in module system
0055   /// @param maxR outer radius, in module system
0056   /// @param minPhiRel right angular edge, in strip system, rel to avgPhi
0057   /// @param maxPhiRel left angular edge, in strip system, rel to avgPhi
0058   /// @param moduleOrigin The origin offset between the two systems.
0059   /// @param avgPhi (Optional) internal rotation of this bounds object's local
0060   /// frame
0061   /// @note For @c morigin you need to actually calculate the cartesian
0062   /// offset
0063   AnnulusBounds(double minR, double maxR, double minPhiRel, double maxPhiRel,
0064                 const Vector2& moduleOrigin = {0, 0},
0065                 double avgPhi = 0) noexcept(false)
0066       : AnnulusBounds({minR, maxR, minPhiRel, maxPhiRel, avgPhi,
0067                        moduleOrigin.x(), moduleOrigin.y()}) {}
0068 
0069   /// Constructor - from parameters array
0070   ///
0071   /// @param values The parameter array
0072   AnnulusBounds(const std::array<double, eSize>& values) noexcept(false);
0073 
0074   AnnulusBounds(const AnnulusBounds& source) = default;
0075 
0076   SurfaceBounds::BoundsType type() const final;
0077 
0078   /// Return the bound values as dynamically sized vector
0079   ///
0080   /// @return this returns a copy of the internal values
0081   std::vector<double> values() const final;
0082 
0083   /// Inside check for the bounds object driven by the boundary check directive
0084   /// Each Bounds has a method inside, which checks if a LocalPosition is inside
0085   /// the bounds  Inside can be called without/with tolerances.
0086   ///
0087   /// @param lposition Local position (assumed to be in right surface frame)
0088   /// @param bcheck boundary check directive
0089   /// @return boolean indicator for the success of this operation
0090   bool inside(const Vector2& lposition,
0091               const BoundaryCheck& bcheck) const final;
0092 
0093   /// Outstream operator
0094   ///
0095   /// @param sl is the ostream to be dumped into
0096   std::ostream& toStream(std::ostream& sl) const final;
0097 
0098   /// Access to the bound values
0099   /// @param bValue the class nested enum for the array access
0100   double get(BoundValues bValue) const { return m_values[bValue]; }
0101 
0102   /// @brief Returns the right angular edge of the module
0103   /// @return The right side angle
0104   double phiMin() const;
0105 
0106   /// @brief Returns the left angular edge of the module
0107   /// @return The left side angle
0108   double phiMax() const;
0109 
0110   /// Returns true for full phi coverage
0111   bool coversFullAzimuth() const final;
0112 
0113   /// Checks if this is inside the radial coverage
0114   /// given the a tolerance
0115   bool insideRadialBounds(double R, double tolerance = 0.) const final;
0116 
0117   /// Return a reference radius for binning
0118   double binningValueR() const final;
0119 
0120   /// Return a reference radius for binning
0121   double binningValuePhi() const final;
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)
0137   /// Starting from the upper right (max R, pos locX) and proceeding clock-wise
0138   /// i.e. (max R; pos locX), (min R; pos locX), (min R; neg loc X), (max R: neg
0139   /// locX)
0140   ///
0141   /// @param lseg the number of segments used to approximate
0142   /// and eventually curved line
0143   ///
0144   /// @note that that if @c lseg > 0, the extrema points are given,
0145   ///  which may slightly alter the number of segments returned
0146   ///
0147   /// @return vector for vertices in 2D
0148   std::vector<Vector2> vertices(unsigned int lseg) const override;
0149 
0150   /// This method returns inner radius
0151   double rMin() const final;
0152 
0153   /// This method returns outer radius
0154   double rMax() const final;
0155 
0156  private:
0157   std::array<double, eSize> m_values;
0158 
0159   // @TODO: Does this need to be in bound values?
0160   Vector2 m_moduleOrigin;
0161   Vector2 m_shiftXY;  // == -m_moduleOrigin
0162   Vector2 m_shiftPC;
0163   Transform2 m_rotationStripPC;
0164   Transform2 m_translation;
0165 
0166   // Vectors needed for inside checking
0167   Vector2 m_outLeftStripPC;
0168   Vector2 m_inLeftStripPC;
0169   Vector2 m_outRightStripPC;
0170   Vector2 m_inRightStripPC;
0171 
0172   Vector2 m_outLeftModulePC;
0173   Vector2 m_inLeftModulePC;
0174   Vector2 m_outRightModulePC;
0175   Vector2 m_inRightModulePC;
0176 
0177   Vector2 m_outLeftStripXY;
0178   Vector2 m_inLeftStripXY;
0179   Vector2 m_outRightStripXY;
0180   Vector2 m_inRightStripXY;
0181 
0182   /// Check the input values for consistency, will throw a logic_exception
0183   /// if consistency is not given
0184   void checkConsistency() noexcept(false);
0185 
0186   /// Inside check for the bounds object driven by the boundary check directive
0187   /// Each Bounds has a method inside, which checks if a LocalPosition is inside
0188   /// the bounds  Inside can be called without/with tolerances.
0189   ///
0190   /// @param lposition Local position (assumed to be in right surface frame)
0191   /// @param tolR tolerance on the radius
0192   /// @param tolPhi tolerance on the polar angle phi
0193   /// @return boolean indicator for the success of this operation
0194   virtual bool inside(const Vector2& lposition, double tolR,
0195                       double tolPhi) const final;
0196 
0197   /// Transform the strip cartesian
0198   /// into the module polar system
0199   ///
0200   /// @param vStripXY the position in the cartesian strip system
0201   /// @return the position in the module polar coordinate system
0202   Vector2 stripXYToModulePC(const Vector2& vStripXY) const;
0203 
0204   /// Private helper method
0205   Vector2 closestOnSegment(const Vector2& a, const Vector2& b, const Vector2& p,
0206                            const SquareMatrix2& weight) const;
0207 
0208   /// Private helper method
0209   double squaredNorm(const Vector2& v, const SquareMatrix2& weight) const;
0210 };
0211 
0212 inline SurfaceBounds::BoundsType AnnulusBounds::type() const {
0213   return SurfaceBounds::eAnnulus;
0214 }
0215 
0216 inline double AnnulusBounds::rMin() const {
0217   return get(eMinR);
0218 }
0219 
0220 inline double AnnulusBounds::rMax() const {
0221   return get(eMaxR);
0222 }
0223 
0224 inline double AnnulusBounds::phiMin() const {
0225   return get(eMinPhiRel) + get(eAveragePhi);
0226 }
0227 
0228 inline double AnnulusBounds::phiMax() const {
0229   return get(eMaxPhiRel) + get(eAveragePhi);
0230 }
0231 
0232 inline bool AnnulusBounds::coversFullAzimuth() const {
0233   return (std::abs((get(eMinPhiRel) - get(eMaxPhiRel)) - M_PI) <
0234           s_onSurfaceTolerance);
0235 }
0236 
0237 inline bool AnnulusBounds::insideRadialBounds(double R,
0238                                               double tolerance) const {
0239   return ((R + tolerance) > get(eMinR) && (R - tolerance) < get(eMaxR));
0240 }
0241 
0242 inline double AnnulusBounds::binningValueR() const {
0243   return 0.5 * (get(eMinR) + get(eMaxR));
0244 }
0245 
0246 inline double AnnulusBounds::binningValuePhi() const {
0247   return get(eAveragePhi);
0248 }
0249 
0250 inline std::vector<double> AnnulusBounds::values() const {
0251   std::vector<double> valvector;
0252   valvector.insert(valvector.begin(), m_values.begin(), m_values.end());
0253   return valvector;
0254 }
0255 
0256 inline void AnnulusBounds::checkConsistency() noexcept(false) {
0257   if (get(eMinR) < 0. || get(eMaxR) < 0. || get(eMinR) > get(eMaxR) ||
0258       std::abs(get(eMinR) - get(eMaxR)) < s_epsilon) {
0259     throw std::invalid_argument("AnnulusBounds: invalid radial setup.");
0260   }
0261   if (get(eMinPhiRel) != detail::radian_sym(get(eMinPhiRel)) ||
0262       get(eMaxPhiRel) != detail::radian_sym(get(eMaxPhiRel)) ||
0263       get(eMinPhiRel) > get(eMaxPhiRel)) {
0264     throw std::invalid_argument("AnnulusBounds: invalid phi boundary setup.");
0265   }
0266   if (get(eAveragePhi) != detail::radian_sym(get(eAveragePhi))) {
0267     throw std::invalid_argument("AnnulusBounds: invalid phi positioning.");
0268   }
0269 }
0270 
0271 }  // namespace Acts