Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-20 07:46:33

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/Definitions/TrackParametrization.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Geometry/Polyhedron.hpp"
0016 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0017 #include "Acts/Surfaces/DiscBounds.hpp"
0018 #include "Acts/Surfaces/RegularSurface.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "Acts/Surfaces/SurfaceConcept.hpp"
0021 #include "Acts/Utilities/AxisDefinitions.hpp"
0022 #include "Acts/Utilities/Result.hpp"
0023 
0024 #include <memory>
0025 #include <numbers>
0026 #include <string>
0027 
0028 namespace Acts {
0029 
0030 class DiscBounds;
0031 class SurfaceBounds;
0032 
0033 /// @class DiscSurface
0034 ///
0035 /// Class for a disc surface (or a segment thereof)
0036 ///
0037 /// The DiscSurface is defined by the local polar coordinates @f$ (r,phi) @f$.
0038 ///
0039 /// The surface transform positions the disc such that the origin
0040 /// is at @f$ r=0 @f$, independent of the provided \c DiscBounds.
0041 /// The normal vector of the disc (i.e., the local @f$z@f$-axis) is given by
0042 /// @f$ \vec e_{z} = \vec e_{r} \times\vec e_{phi} @f$.
0043 ///
0044 /// The disc surface The only surface type for which the
0045 /// covariance matrix is NOT given in the reference frame.
0046 /// A conversion from polar to cartesian coordinates needs
0047 /// to happen to transfer the local coordinates onto the
0048 /// cartesian reference frame coordinates.
0049 ///
0050 /// @image html DiscSurface.png
0051 ///
0052 class DiscSurface : public RegularSurface {
0053   friend class Surface;
0054 
0055  protected:
0056   /// Constructor for Discs from Transform3, \f$ r_{min}, r_{max} \f$
0057   ///
0058   /// @param transform is transform that places the disc in the global 3D space
0059   /// @param rmin The inner radius of the disc surface
0060   /// @param rmax The outer radius of the disc surface
0061   /// @param hphisec The opening angle of the disc surface and is optional
0062   ///        the default is a full disc
0063   explicit DiscSurface(const Transform3& transform, double rmin, double rmax,
0064                        double hphisec = std::numbers::pi);
0065 
0066   /// Constructor for Discs from Transform3, \f$ r_{min}, r_{max}, hx_{min},
0067   /// hx_{max} \f$
0068   /// This is n this case you have DiscTrapezoidBounds
0069   ///
0070   /// @param transform is transform that places the disc in the global 3D space
0071   /// @param minhalfx The half length in x at minimal r
0072   /// @param maxhalfx The half length in x at maximal r
0073   /// @param minR The outer radius of the disc surface
0074   /// @param maxR The inner radius of the disc surface
0075   /// @param avephi The position in phi (default is 0.)
0076   /// @param stereo The optional stereo angle
0077   explicit DiscSurface(const Transform3& transform, double minhalfx,
0078                        double maxhalfx, double minR, double maxR,
0079                        double avephi = 0., double stereo = 0.);
0080 
0081   /// Constructor for Discs from Transform3 and shared DiscBounds
0082   ///
0083   /// @param transform The transform that positions the disc in global 3D
0084   /// @param dbounds The disc bounds describing the surface coverage
0085   explicit DiscSurface(const Transform3& transform,
0086                        std::shared_ptr<const DiscBounds> dbounds = nullptr);
0087 
0088   /// Constructor from SurfacePlacementBase : Element proxy
0089   ///
0090   /// @param dbounds The disc bounds describing the surface coverage
0091   /// @param placement Reference to the surface placement
0092   /// @note The Surface does not take any ownership over the
0093   ///       `SurfacePlacementBase` it is expected that the user
0094   ///        ensures the life-time of the `SurfacePlacementBase`
0095   ///        and that the `Surface` is actually owned by
0096   ///        the `SurfacePlacementBase` instance
0097   explicit DiscSurface(std::shared_ptr<const DiscBounds> dbounds,
0098                        const SurfacePlacementBase& placement);
0099 
0100   /// Copy Constructor
0101   ///
0102   /// @param other The source surface for the copy
0103   DiscSurface(const DiscSurface& other);
0104 
0105   /// Copy constructor - with shift
0106   ///
0107   /// @param gctx The current geometry context object, e.g. alignment
0108   /// @param other is the source cone surface
0109   /// @param shift is the additional transform applied after copying
0110   DiscSurface(const GeometryContext& gctx, const DiscSurface& other,
0111               const Transform3& shift);
0112 
0113  public:
0114   /// Assignment operator
0115   ///
0116   /// @param other The source sourface for the assignment
0117   /// @return Reference to this DiscSurface after assignment
0118   DiscSurface& operator=(const DiscSurface& other);
0119 
0120   /// Return the surface type
0121   /// @return Surface type identifier
0122   SurfaceType type() const override;
0123 
0124   // User overloads from `RegularSurface`
0125   using RegularSurface::globalToLocal;
0126   using RegularSurface::localToGlobal;
0127   using RegularSurface::normal;
0128 
0129   /// Normal vector return
0130   ///
0131   /// @param gctx The current geometry context object, e.g. alignment
0132   /// @param lposition The local position is ignored
0133   ///
0134   /// @return a Vector3 by value
0135   Vector3 normal(const GeometryContext& gctx,
0136                  const Vector2& lposition) const final;
0137 
0138   /// Get the normal vector of this surface at a given global position
0139   /// @note The @p position is required to be on-surface.
0140   /// @param gctx The current geometry context object, e.g. alignment
0141   /// @param position is the global positiono (for @ref DiscSurface this is ignored)
0142   /// @return The normal vector
0143   Vector3 normal(const GeometryContext& gctx,
0144                  const Vector3& position) const final;
0145 
0146   /// Get the normal vector, independent of the location
0147   /// @param gctx The current geometry context object, e.g. alignment
0148   /// @return The normal vector
0149   Vector3 normal(const GeometryContext& gctx) const;
0150 
0151   /// A reference position for a given axis direction
0152   ///
0153   /// @param gctx The current geometry context object, e.g. alignment
0154   /// @param aDir The axis direction for the reference position request
0155   /// @return position that can beused for this binning
0156   Vector3 referencePosition(const GeometryContext& gctx,
0157                             AxisDirection aDir) const final;
0158 
0159   /// A reference position value for a given axis direction
0160   ///
0161   /// @param gctx The current geometry context object, e.g. alignment
0162   /// @param aDir the value generated for the reference position
0163   ///
0164   /// @note This calls the parent method except for AxisR
0165   ///
0166   /// @return float to be used for the binning schema
0167   double referencePositionValue(const GeometryContext& gctx,
0168                                 AxisDirection aDir) const final;
0169 
0170   /// This method returns the bounds by reference
0171   /// @return Reference to the surface bounds
0172   const SurfaceBounds& bounds() const final;
0173   /// This method returns the shared_ptr to the DiscBounds
0174   /// @return Shared pointer to the disc bounds
0175   const std::shared_ptr<const DiscBounds>& boundsPtr() const;
0176   /// Overwrite the existing surface bounds with new ones
0177   /// @param newBounds: Pointer to the new bounds
0178   void assignSurfaceBounds(std::shared_ptr<const DiscBounds> newBounds);
0179 
0180   /// Local to global transformation
0181   /// For planar surfaces the momentum direction is ignored in the local to
0182   /// global transformation
0183   ///
0184   /// @param gctx The current geometry context object, e.g. alignment
0185   /// @param lposition local 2D position in specialized surface frame
0186   ///
0187   /// @return global position by value
0188   Vector3 localToGlobal(const GeometryContext& gctx,
0189                         const Vector2& lposition) const final;
0190 
0191   /// Global to local transformation
0192   /// @note the direction is ignored for Disc surfaces in this calculateion
0193   ///
0194   /// @param gctx The current geometry context object, e.g. alignment
0195   /// @param position global 3D position - considered to be on surface but not
0196   /// inside bounds (check is done)
0197   /// @param tolerance optional tolerance within which a point is considered
0198   /// valid on surface
0199   ///
0200   /// @return a Result<Vector2> which can be !ok() if the operation fails
0201   Result<Vector2> globalToLocal(
0202       const GeometryContext& gctx, const Vector3& position,
0203       double tolerance = s_onSurfaceTolerance) const final;
0204 
0205   /// Special method for DiscSurface : local<->local transformations polar <->
0206   /// cartesian
0207   ///
0208   /// @param lpolar is a local position in polar coordinates
0209   ///
0210   /// @return values is local 2D position in cartesian coordinates  @todo check
0211   Vector2 localPolarToCartesian(const Vector2& lpolar) const;
0212 
0213   /// Special method for Disc surface : local<->local transformations polar <->
0214   /// cartesian
0215   ///
0216   /// @param lcart is local 2D position in cartesian coordinates
0217   ///
0218   /// @return value is a local position in polar coordinates
0219   Vector2 localCartesianToPolar(const Vector2& lcart) const;
0220 
0221   /// Special method for DiscSurface : local<->local transformations polar <->
0222   /// cartesian
0223   ///
0224   /// @param locpol is a local position in polar coordinates
0225   ///
0226   /// @return values is local 2D position in cartesian coordinates
0227   Vector2 localPolarToLocalCartesian(const Vector2& locpol) const;
0228 
0229   /// Special method for DiscSurface :  local<->global transformation when
0230   /// provided cartesian coordinates
0231   ///
0232   /// @param gctx The current geometry context object, e.g. alignment
0233   /// @param lposition is local 2D position in cartesian coordinates
0234   ///
0235   /// @return value is a global cartesian 3D position
0236   Vector3 localCartesianToGlobal(const GeometryContext& gctx,
0237                                  const Vector2& lposition) const;
0238 
0239   /// Special method for DiscSurface : global<->local from cartesian coordinates
0240   ///
0241   /// @param gctx The current geometry context object, e.g. alignment
0242   /// @param position is a global cartesian 3D position
0243   /// @param tol The absolute tolerance parameter
0244   ///
0245   /// @return value is a local polar
0246   Vector2 globalToLocalCartesian(const GeometryContext& gctx,
0247                                  const Vector3& position,
0248                                  double tol = 0.) const;
0249 
0250   /// Calculate the jacobian from local to global which the surface knows best,
0251   /// hence the calculation is done here.
0252   ///
0253   /// @param gctx The current geometry context object, e.g. alignment
0254   /// @param position global 3D position
0255   /// @param direction global 3D momentum direction
0256   ///
0257   /// @return Jacobian from local to global
0258   BoundToFreeMatrix boundToFreeJacobian(const GeometryContext& gctx,
0259                                         const Vector3& position,
0260                                         const Vector3& direction) const final;
0261 
0262   /// Calculate the jacobian from global to local which the surface knows best,
0263   /// hence the calculation is done here.
0264   ///
0265   /// @param gctx The current geometry context object, e.g. alignment
0266   /// @param position global 3D position
0267   /// @param direction global 3D momentum direction
0268   ///
0269   /// @return Jacobian from global to local
0270   FreeToBoundMatrix freeToBoundJacobian(const GeometryContext& gctx,
0271                                         const Vector3& position,
0272                                         const Vector3& direction) const final;
0273 
0274   /// Path correction due to incident of the track
0275   ///
0276   /// @param gctx The current geometry context object, e.g. alignment
0277   /// @param position The global position as a starting point
0278   /// @param direction The global momentum direction at the starting point
0279   /// @return The correction factor due to incident
0280   double pathCorrection(const GeometryContext& gctx, const Vector3& position,
0281                         const Vector3& direction) const final;
0282 
0283   /// @brief Straight line intersection schema
0284   ///
0285   /// @param gctx The current geometry context object, e.g. alignment
0286   /// @param position The global position as a starting point
0287   /// @param direction The global direction at the starting point
0288   ///        @note expected to be normalized (no checking)
0289   /// @param boundaryTolerance The boundary check prescription
0290   /// @param tolerance the tolerance used for the intersection
0291   ///
0292   /// <b>Mathematical motivation:</b>
0293   ///
0294   /// the equation of the plane is given by: <br>
0295   /// @f$ \vec n \cdot \vec x = \vec n \cdot \vec p,@f$ <br>
0296   /// where @f$ \vec n = (n_{x}, n_{y}, n_{z})@f$ denotes the normal vector of
0297   /// the plane, @f$ \vec p = (p_{x}, p_{y}, p_{z})@f$ one specific point on
0298   /// the plane and @f$ \vec x = (x,y,z) @f$ all possible points
0299   /// on the plane.<br>
0300   /// Given a line with:<br>
0301   /// @f$ \vec l(u) = \vec l_{1} + u \cdot \vec v @f$, <br>
0302   /// the solution for @f$ u @f$ can be written:
0303   /// @f$ u = \frac{\vec n (\vec p - \vec l_{1})}{\vec n \vec v}@f$ <br>
0304   /// If the denominator is 0 then the line lies:
0305   /// - either in the plane
0306   /// - perpendicular to the normal of the plane
0307   ///
0308   /// @return The @c MultiIntersection3D object
0309   MultiIntersection3D intersect(
0310       const GeometryContext& gctx, const Vector3& position,
0311       const Vector3& direction,
0312       const BoundaryTolerance& boundaryTolerance =
0313           BoundaryTolerance::Infinite(),
0314       double tolerance = s_onSurfaceTolerance) const final;
0315 
0316   /// Return properly formatted class name for screen output
0317   /// @return String representation of the class name
0318   std::string name() const override;
0319 
0320   /// Return a Polyhedron for the surfaces
0321   ///
0322   /// @param gctx The current geometry context object, e.g. alignment
0323   /// @param quarterSegments Number of segments used to describe the
0324   /// quarter of a full circle
0325   ///
0326   /// @return A list of vertices and a face/facett description of it
0327   Polyhedron polyhedronRepresentation(
0328       const GeometryContext& gctx, unsigned int quarterSegments) const override;
0329 
0330   /// Calculate the derivative of bound track parameters local position w.r.t.
0331   /// position in local 3D Cartesian coordinates
0332   ///
0333   /// @param gctx The current geometry context object, e.g. alignment
0334   /// @param position The position of the parameters in global
0335   ///
0336   /// @return Derivative of bound local position w.r.t. position in local 3D
0337   /// cartesian coordinates
0338   Matrix<2, 3> localCartesianToBoundLocalDerivative(
0339       const GeometryContext& gctx, const Vector3& position) const final;
0340 
0341   /// Merge two disc surfaces into a single one.
0342   /// @image html Disc_Merging.svg
0343   /// @note The surfaces need to be *compatible*, i.e. have disc bounds
0344   ///       that align
0345   /// @param other The other disc surface to merge with
0346   /// @param direction The binning direction: either @c AxisR or @c AxisPhi
0347   /// @param externalRotation If true, any phi rotation is done in the transform
0348   /// @param logger The logger to use
0349   /// @return The merged disc surface and a boolean indicating if surfaces are reversed
0350   /// @note The returned boolean is `false` if `this` is *left* or
0351   ///       *counter-clockwise* of @p other, and `true` if not.
0352   std::pair<std::shared_ptr<DiscSurface>, bool> mergedWith(
0353       const DiscSurface& other, AxisDirection direction, bool externalRotation,
0354       const Logger& logger = getDummyLogger()) const;
0355 
0356  protected:
0357   std::shared_ptr<const DiscBounds> m_bounds;  ///< bounds (shared)
0358 };
0359 
0360 static_assert(RegularSurfaceConcept<DiscSurface>,
0361               "DiscSurface does not fulfill RegularSurfaceConcept");
0362 
0363 }  // namespace Acts