Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-17 08:21: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/Alignment.hpp"
0013 #include "Acts/Definitions/Tolerance.hpp"
0014 #include "Acts/Definitions/TrackParametrization.hpp"
0015 #include "Acts/Geometry/GeometryContext.hpp"
0016 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0017 #include "Acts/Surfaces/LineBounds.hpp"
0018 #include "Acts/Surfaces/Surface.hpp"
0019 #include "Acts/Utilities/AxisDefinitions.hpp"
0020 #include "Acts/Utilities/Result.hpp"
0021 
0022 #include <memory>
0023 #include <string>
0024 
0025 namespace Acts {
0026 
0027 class LineBounds;
0028 class SurfaceBounds;
0029 
0030 ///  @class LineSurface
0031 ///
0032 ///  Base class for a linear surfaces in the TrackingGeometry
0033 ///  to describe dirft tube, straw like detectors or the Perigee
0034 ///  It inherits from Surface.
0035 ///
0036 ///  @note It leaves the type() method virtual, so it can not be instantiated
0037 ///
0038 /// @image html LineSurface.png
0039 class LineSurface : public Surface {
0040   friend class Surface;
0041 
0042  protected:
0043   /// Constructor for LineSurface from Transform3 and radial dimensions
0044   ///
0045   /// @param transform The transform that positions the line in the global frame
0046   /// @param radius The radius of the line
0047   /// @param halez The half length in z
0048   explicit LineSurface(const Transform3& transform, double radius,
0049                        double halez);
0050 
0051   /// Constructor for LineSurface from Transform3 and LineBounds
0052   ///
0053   /// @param transform The transform that positions the line in the global frame
0054   /// @param lbounds The bounds describing the line dimensions
0055   explicit LineSurface(const Transform3& transform,
0056                        std::shared_ptr<const LineBounds> lbounds = nullptr);
0057 
0058   /// Constructor from SurfacePlacementBase : Element proxy
0059   ///
0060   /// @param lbounds are the bounds describing the line dimensions, they must
0061   /// not be nullptr
0062   /// @param placement Reference to the surface placement
0063   /// @note The Surface does not take any ownership over the
0064   ///       `SurfacePlacementBase` it is expected that the user
0065   ///        ensures the life-time of the `SurfacePlacementBase`
0066   ///        and that the `Surface` is actually owned by
0067   ///        the `SurfacePlacementBase` instance
0068   explicit LineSurface(std::shared_ptr<const LineBounds> lbounds,
0069                        const SurfacePlacementBase& placement);
0070 
0071   /// Copy constructor
0072   ///
0073   /// @param other The source surface for copying
0074   LineSurface(const LineSurface& other);
0075 
0076   /// Copy constructor - with shift
0077   ///
0078   /// @param gctx The current geometry context object, e.g. alignment
0079   /// @param other is the source cone surface
0080   /// @param shift is the additional transform applied after copying
0081   explicit LineSurface(const GeometryContext& gctx, const LineSurface& other,
0082                        const Transform3& shift);
0083 
0084  public:
0085   ~LineSurface() override = default;
0086 
0087   /// Assignment operator
0088   ///
0089   /// @param other is the source surface dor copying
0090   /// @return Reference to this LineSurface after assignment
0091   LineSurface& operator=(const LineSurface& other);
0092 
0093   Vector3 normal(const GeometryContext& gctx, const Vector3& pos,
0094                  const Vector3& direction) const override;
0095 
0096   /// The binning position is the position calculated
0097   /// for a certain binning type
0098   ///
0099   /// @param gctx The current geometry context object, e.g. alignment
0100   /// @param aDir is the axis direction for the reference position request
0101   ///
0102   /// @return position that can beused for this binning
0103   Vector3 referencePosition(const GeometryContext& gctx,
0104                             AxisDirection aDir) const final;
0105 
0106   /// Return the measurement frame - this is needed for alignment, in particular
0107   ///
0108   /// for StraightLine and Perigee Surface
0109   ///  - the default implementation is the RotationMatrix3 of the transform
0110   ///
0111   /// @param gctx The current geometry context object, e.g. alignment
0112   /// @param position is the global position where the measurement frame is
0113   /// constructed
0114   /// @param direction is the momentum direction used for the measurement frame
0115   /// construction
0116   ///
0117   /// @return is a rotation matrix that indicates the measurement frame
0118   RotationMatrix3 referenceFrame(const GeometryContext& gctx,
0119                                  const Vector3& position,
0120                                  const Vector3& direction) const final;
0121 
0122   /// Calculate the jacobian from local to global which the surface knows best,
0123   /// hence the calculation is done here.
0124   ///
0125   /// @param gctx The current geometry context object, e.g. alignment
0126   /// @param position global 3D position
0127   /// @param direction global 3D momentum direction
0128   ///
0129   /// @return Jacobian from local to global
0130   BoundToFreeMatrix boundToFreeJacobian(const GeometryContext& gctx,
0131                                         const Vector3& position,
0132                                         const Vector3& direction) const final;
0133 
0134   /// Calculate the derivative of path length at the geometry constraint or
0135   /// point-of-closest-approach w.r.t. free parameters
0136   ///
0137   /// @param gctx The current geometry context object, e.g. alignment
0138   /// @param position global 3D position
0139   /// @param direction global 3D momentum direction
0140   ///
0141   /// @return Derivative of path length w.r.t. free parameters
0142   FreeToPathMatrix freeToPathDerivative(const GeometryContext& gctx,
0143                                         const Vector3& position,
0144                                         const Vector3& direction) const final;
0145 
0146   /// Local to global transformation
0147   ///
0148   /// @note for line surfaces the momentum direction is used in order to interpret the
0149   /// drift radius
0150   ///
0151   /// @param gctx The current geometry context object, e.g. alignment
0152   /// @param lposition is the local position to be transformed
0153   /// @param direction is the global momentum direction (used to sign the closest approach)
0154   ///
0155   /// @return global position by value
0156   Vector3 localToGlobal(const GeometryContext& gctx, const Vector2& lposition,
0157                         const Vector3& direction) const final;
0158 
0159   /// Specified for `LineSurface`: global to local method without dynamic
0160   /// memory allocation.
0161   ///
0162   /// This method is the true global -> local transformation. It makes use of
0163   /// @c globalToLocal and indicates the sign of the @c Acts::eBoundLoc0
0164   /// by the given momentum direction.
0165   ///
0166   /// The calculation of the sign of the radius (or @f$ d_0 @f$) can be done as
0167   /// follows:
0168   /// May @f$ \vec d = \vec m - \vec c @f$ denote the difference between the
0169   /// center of the line and the global position of the measurement/predicted
0170   /// state. Then, @f$ \vec d @f$ lies in the so-called measurement plane.
0171   /// The latter is determined by the two orthogonal vectors @f$
0172   /// \vec{\texttt{measY}} = \vec{e}_z @f$ and @f$
0173   /// \vec{\texttt{measX}} = \vec{\texttt{measY}} \times
0174   /// \frac{\vec{p}}{|\vec{p}|} @f$.
0175   ///
0176   /// The sign of the radius (or @f$ d_{0} @f$ ) is then defined by the projection
0177   /// of @f$ \vec{d} @f$ on @f$ \vec{measX} @f$:<br> @f$ sign = -sign(\vec{d}
0178   /// \cdot \vec{measX}) @f$
0179   ///
0180   /// @image html SignOfDriftCircleD0.gif
0181   ///
0182   /// @param gctx The current geometry context object, e.g. alignment
0183   /// @param position global 3D position - considered to be on surface but not
0184   /// inside bounds (check is done)
0185   /// @param direction global 3D momentum direction (optionally ignored)
0186   /// @param tolerance (unused)
0187   ///
0188   /// @return A `Result<Vector2>`, which is set to `!ok()` if the @p position is not
0189   /// the point of closest approach to the line surface.
0190   Result<Vector2> globalToLocal(
0191       const GeometryContext& gctx, const Vector3& position,
0192       const Vector3& direction,
0193       double tolerance = s_onSurfaceTolerance) const final;
0194 
0195   /// Calculate the straight-line intersection with the line surface.
0196   ///
0197   /// <b>Mathematical motivation:</b>
0198   ///
0199   /// Given two lines in parametric form:<br>
0200   ///
0201   /// @f$ \vec l_{a}(u) = \vec m_a + u \cdot \vec e_{a} @f$
0202   ///
0203   /// @f$ \vec l_{b}(\mu) = \vec m_b + \mu \cdot \vec e_{b} @f$
0204   ///
0205   /// The vector between any two points on the two lines is given by:
0206   ///
0207   /// @f$ \vec s(u, \mu) = \vec l_{b} - l_{a} = \vec m_{ab} + \mu
0208   /// \cdot
0209   /// \vec e_{b} - u \cdot \vec e_{a} @f$,
0210   ///
0211   /// where @f$ \vec m_{ab} = \vec m_{b} - \vec m_{a} @f$.
0212   ///
0213   /// @f$ \vec s(u_0, \mu_0) @f$ denotes the vector between the two
0214   /// closest points
0215   ///
0216   /// @f$ \vec l_{a,0} = l_{a}(u_0) @f$ and @f$ \vec l_{b,0} =
0217   /// l_{b}(\mu_0) @f$
0218   ///
0219   /// and is perpendicular to both, @f$ \vec e_{a} @f$ and @f$ \vec e_{b} @f$.
0220   ///
0221   /// This results in a system of two linear equations:
0222   ///
0223   /// - (i) @f$ 0 = \vec s(u_0, \mu_0) \cdot \vec e_a = \vec m_{ab} \cdot
0224   /// \vec e_a + \mu_0 \vec e_a \cdot \vec e_b - u_0 @f$ <br>
0225   /// - (ii) @f$ 0 = \vec s(u_0, \mu_0) \cdot \vec e_b = \vec m_{ab} \cdot
0226   /// \vec e_b + \mu_0  - u_0 \vec e_b \cdot \vec e_a @f$ <br>
0227   ///
0228   /// Solving (i) and (ii) for @f$ u @f$ and @f$ \mu_0 @f$ yields:
0229   ///
0230   /// - @f$ u_0 = \frac{(\vec m_{ab} \cdot \vec e_a)-(\vec m_{ab} \cdot \vec
0231   /// e_b)(\vec e_a \cdot \vec e_b)}{1-(\vec e_a \cdot \vec e_b)^2} @f$ <br>
0232   /// - @f$ \mu_0 = - \frac{(\vec m_{ab} \cdot \vec e_b)-(\vec m_{ab} \cdot \vec
0233   /// e_a)(\vec e_a \cdot \vec e_b)}{1-(\vec e_a \cdot \vec e_b)^2} @f$ <br>
0234   ///
0235   /// The function checks if @f$ u_0 \simeq 0@f$ to check if the current @p
0236   /// position is at the point of closest approach, i.e. the intersection
0237   /// point, in which case it will return an @c onSurace intersection result.
0238   /// Otherwise, the path length from @p position to the point of closest
0239   /// approach (@f$ u_0 @f$) is returned in a @c reachable intersection.
0240   ///
0241   /// @param gctx The current geometry context object, e.g. alignment
0242   /// @param position The global position as a starting point
0243   /// @param direction The global direction at the starting point
0244   ///        @note expected to be normalized
0245   /// @param boundaryTolerance The boundary check directive for the estimate
0246   /// @param tolerance the tolerance used for the intersection
0247   /// @return is the intersection object
0248   MultiIntersection3D intersect(
0249       const GeometryContext& gctx, const Vector3& position,
0250       const Vector3& direction,
0251       const BoundaryTolerance& boundaryTolerance =
0252           BoundaryTolerance::Infinite(),
0253       double tolerance = s_onSurfaceTolerance) const final;
0254 
0255   /// the pathCorrection for derived classes with thickness
0256   /// is by definition 1 for LineSurfaces
0257   ///
0258   /// @param gctx Geometry context (ignored)
0259   /// @param position Position parameter (ignored)
0260   /// @param direction Direction parameter (ignored)
0261   /// @note input parameters are ignored
0262   /// @note there's no material associated to the line surface
0263   /// @return Always returns 1.0 for line surfaces
0264   double pathCorrection(const GeometryContext& gctx, const Vector3& position,
0265                         const Vector3& direction) const override;
0266 
0267   /// This method returns the bounds of the surface by reference
0268   /// @return Reference to the surface bounds
0269   const SurfaceBounds& bounds() const final;
0270   /// This method returns the shared_ptr to the LineBounds
0271   /// @return Shared pointer to the line bounds
0272   const std::shared_ptr<const LineBounds>& boundsPtr() const;
0273   /// Overwrite the existing surface bounds with new ones
0274   /// @param newBounds: Pointer to the new bounds
0275   void assignSurfaceBounds(std::shared_ptr<const LineBounds> newBounds);
0276 
0277   /// Return properly formatted class name for screen output
0278   /// @return String representation of the class name
0279   std::string name() const override;
0280 
0281   /// Calculate the derivative of path length at the geometry constraint or
0282   /// point-of-closest-approach w.r.t. alignment parameters of the surface (i.e.
0283   /// local frame origin in global 3D Cartesian coordinates and its rotation
0284   /// represented with extrinsic Euler angles)
0285   ///
0286   /// @param gctx The current geometry context object, e.g. alignment
0287   /// @param position global 3D position
0288   /// @param direction global 3D momentum direction
0289   ///
0290   /// @return Derivative of path length w.r.t. the alignment parameters
0291   AlignmentToPathMatrix alignmentToPathDerivative(
0292       const GeometryContext& gctx, const Vector3& position,
0293       const Vector3& direction) const final;
0294 
0295   /// Calculate the derivative of bound track parameters local position w.r.t.
0296   /// position in local 3D Cartesian coordinates
0297   ///
0298   /// @param gctx The current geometry context object, e.g. alignment
0299   /// @param position The position of the parameters in global
0300   ///
0301   /// @return Derivative of bound local position w.r.t. position in local 3D
0302   /// cartesian coordinates
0303   Matrix<2, 3> localCartesianToBoundLocalDerivative(
0304       const GeometryContext& gctx, const Vector3& position) const final;
0305 
0306   /// Get the line direction in global coordinates
0307   /// @param gctx The geometry context
0308   /// @return The direction vector of the line surface
0309   Vector3 lineDirection(const GeometryContext& gctx) const;
0310 
0311  protected:
0312   std::shared_ptr<const LineBounds> m_bounds;  ///< bounds (shared)
0313 
0314   /// @copydoc Surface::localAxes
0315   std::array<AxisDirection, 2> localAxes() const override {
0316     return {AxisDirection::AxisR, AxisDirection::AxisZ};
0317   }
0318 
0319  private:
0320   /// helper function to apply the globalToLocal with out transform
0321   ///
0322   /// @param gctx The current geometry context object, e.g. alignment
0323   /// @param position is the global position
0324   /// @param direction is the momentum direction
0325   /// @param lposition is the local position to be filled
0326   bool globalToLocalPlain(const GeometryContext& gctx, const Vector3& position,
0327                           const Vector3& direction, Vector2& lposition) const;
0328 };
0329 
0330 }  // namespace Acts