Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 08:07:09

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2016-2024 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/Alignment.hpp"
0013 #include "Acts/Definitions/Common.hpp"
0014 #include "Acts/Definitions/Tolerance.hpp"
0015 #include "Acts/Definitions/TrackParametrization.hpp"
0016 #include "Acts/Geometry/DetectorElementBase.hpp"
0017 #include "Acts/Geometry/GeometryContext.hpp"
0018 #include "Acts/Geometry/GeometryObject.hpp"
0019 #include "Acts/Geometry/Polyhedron.hpp"
0020 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0021 #include "Acts/Surfaces/SurfaceBounds.hpp"
0022 #include "Acts/Surfaces/SurfaceError.hpp"
0023 #include "Acts/Surfaces/detail/AlignmentHelper.hpp"
0024 #include "Acts/Utilities/BinnedArray.hpp"
0025 #include "Acts/Utilities/BinningType.hpp"
0026 #include "Acts/Utilities/Intersection.hpp"
0027 #include "Acts/Utilities/Result.hpp"
0028 
0029 #include <array>
0030 #include <cstddef>
0031 #include <memory>
0032 #include <ostream>
0033 #include <string>
0034 #include <tuple>
0035 #include <utility>
0036 
0037 namespace Acts {
0038 
0039 class DetectorElementBase;
0040 class SurfaceBounds;
0041 class ISurfaceMaterial;
0042 class Layer;
0043 class TrackingVolume;
0044 class IVisualization3D;
0045 class Surface;
0046 
0047 /// Typedef of the surface intersection
0048 using SurfaceIntersection = ObjectIntersection<Surface>;
0049 /// Typedef of the surface multi-intersection
0050 using SurfaceMultiIntersection = ObjectMultiIntersection<Surface>;
0051 
0052 /// @class Surface
0053 ///
0054 /// @brief Abstract Base Class for tracking surfaces
0055 ///
0056 /// The Surface class builds the core of the Acts Tracking Geometry.
0057 /// All other geometrical objects are either extending the surface or
0058 /// are built from it.
0059 ///
0060 /// Surfaces are either owned by Detector elements or the Tracking Geometry,
0061 /// in which case they are not copied within the data model objects.
0062 ///
0063 class Surface : public virtual GeometryObject,
0064                 public std::enable_shared_from_this<Surface> {
0065  public:
0066   friend struct GeometryContextOstreamWrapper<Surface>;
0067 
0068   /// @enum SurfaceType
0069   ///
0070   /// This enumerator simplifies the persistency & calculations,
0071   /// by saving a dynamic_cast, e.g. for persistency
0072   enum SurfaceType {
0073     Cone = 0,
0074     Cylinder = 1,
0075     Disc = 2,
0076     Perigee = 3,
0077     Plane = 4,
0078     Straw = 5,
0079     Curvilinear = 6,
0080     Other = 7
0081   };
0082 
0083   /// Helper strings for screen output
0084   static std::array<std::string, SurfaceType::Other> s_surfaceTypeNames;
0085 
0086  protected:
0087   /// Constructor with Transform3 as a shared object
0088   ///
0089   /// @param transform Transform3 positions the surface in 3D global space
0090   /// @note also acts as default constructor
0091   Surface(const Transform3& transform = Transform3::Identity());
0092 
0093   /// Copy constructor
0094   ///
0095   /// @note copy construction invalidates the association
0096   /// to detector element and layer
0097   ///
0098   /// @param other Source surface for copy.
0099   Surface(const Surface& other);
0100 
0101   /// Constructor from DetectorElementBase: Element proxy
0102   ///
0103   /// @param detelement Detector element which is represented by this surface
0104   Surface(const DetectorElementBase& detelement);
0105 
0106   /// Copy constructor with optional shift
0107   ///
0108   /// @note copy construction invalidates the association
0109   /// to detector element and layer
0110   ///
0111   /// @param gctx The current geometry context object, e.g. alignment
0112   /// @param other Source surface for copy
0113   /// @param shift Additional transform applied as: shift * transform
0114   Surface(const GeometryContext& gctx, const Surface& other,
0115           const Transform3& shift);
0116 
0117  public:
0118   virtual ~Surface();
0119 
0120   /// Factory for producing memory managed instances of Surface.
0121   /// Will forward all parameters and will attempt to find a suitable
0122   /// constructor.
0123   template <class T, typename... Args>
0124   static std::shared_ptr<T> makeShared(Args&&... args) {
0125     return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
0126   }
0127 
0128   /// Retrieve a @c std::shared_ptr for this surface (non-const version)
0129   ///
0130   /// @note Will error if this was not created through the @c makeShared factory
0131   ///       since it needs access to the original reference. In C++14 this is
0132   ///       undefined behavior (but most likely implemented as a @c bad_weak_ptr
0133   ///       exception), in C++17 it is defined as that exception.
0134   /// @note Only call this if you need shared ownership of this object.
0135   ///
0136   /// @return The shared pointer
0137   std::shared_ptr<Surface> getSharedPtr();
0138 
0139   /// Retrieve a @c std::shared_ptr for this surface (const version)
0140   ///
0141   /// @note Will error if this was not created through the @c makeShared factory
0142   ///       since it needs access to the original reference. In C++14 this is
0143   ///       undefined behavior, but most likely implemented as a @c bad_weak_ptr
0144   ///       exception, in C++17 it is defined as that exception.
0145   /// @note Only call this if you need shared ownership of this object.
0146   ///
0147   /// @return The shared pointer
0148   std::shared_ptr<const Surface> getSharedPtr() const;
0149 
0150   /// Assignment operator
0151   /// @note copy construction invalidates the association
0152   /// to detector element and layer
0153   ///
0154   /// @param other Source surface for the assignment
0155   Surface& operator=(const Surface& other);
0156 
0157   /// Comparison (equality) operator
0158   /// The strategy for comparison is
0159   /// (a) first pointer comparison
0160   /// (b) then type comparison
0161   /// (c) then bounds comparison
0162   /// (d) then transform comparison
0163   ///
0164   /// @param other source surface for the comparison
0165   virtual bool operator==(const Surface& other) const;
0166 
0167   /// Comparison (non-equality) operator
0168   ///
0169   /// @param sf Source surface for the comparison
0170   virtual bool operator!=(const Surface& sf) const;
0171 
0172  public:
0173   /// Return method for the Surface type to avoid dynamic casts
0174   virtual SurfaceType type() const = 0;
0175 
0176   /// Return method for the surface Transform3 by reference
0177   /// In case a detector element is associated the surface transform
0178   /// is just forwarded to the detector element in order to keep the
0179   /// (mis-)alignment cache cetrally handled
0180   ///
0181   /// @param gctx The current geometry context object, e.g. alignment
0182   ///
0183   /// @return the contextual transform
0184   virtual const Transform3& transform(const GeometryContext& gctx) const;
0185 
0186   /// Return method for the surface center by reference
0187   /// @note the center is always recalculated in order to not keep a cache
0188   ///
0189   /// @param gctx The current geometry context object, e.g. alignment
0190   ///
0191   /// @return center position by value
0192   virtual Vector3 center(const GeometryContext& gctx) const;
0193 
0194   /// Return the surface normal at a given @p position and @p direction.
0195   /// This method is fully generic, and valid for all surface types.
0196   /// @note For some surface types, the @p direction is ignored, but
0197   ///       it is **not safe** to pass in a zero vector!
0198   /// @param gctx The current geometry context object, e.g. alignment
0199   /// @param pos The position at which to calculate the normal
0200   /// @param direction The direction at which to calculate the normal
0201   /// @return The normal vector at the given position and direction
0202   virtual Vector3 normal(const GeometryContext& gctx, const Vector3& pos,
0203                          const Vector3& direction) const = 0;
0204 
0205   /// Return method for SurfaceBounds
0206   /// @return SurfaceBounds by reference
0207   virtual const SurfaceBounds& bounds() const = 0;
0208 
0209   /// Return method for the associated Detector Element
0210   /// @return plain pointer to the DetectorElement, can be nullptr
0211   const DetectorElementBase* associatedDetectorElement() const;
0212 
0213   /// Return method for the associated Layer in which the surface is embedded
0214   /// @return Layer by plain pointer, can be nullptr
0215   const Layer* associatedLayer() const;
0216 
0217   /// Set Associated Layer
0218   /// Many surfaces can be associated to a Layer, but it might not be known yet
0219   /// during construction of the layer, this can be set afterwards
0220   ///
0221   /// @param lay the assignment Layer by reference
0222   void associateLayer(const Layer& lay);
0223 
0224   /// Return method for the associated Material to this surface
0225   /// @return SurfaceMaterial as plain pointer, can be nullptr
0226   const ISurfaceMaterial* surfaceMaterial() const;
0227 
0228   /// Return method for the shared pointer to the associated Material
0229   /// @return SurfaceMaterial as shared_pointer, can be nullptr
0230   const std::shared_ptr<const ISurfaceMaterial>& surfaceMaterialSharedPtr()
0231       const;
0232 
0233   /// Assign a detector element
0234   ///
0235   /// @param detelement Detector element which is represented by this surface
0236   void assignDetectorElement(const DetectorElementBase& detelement);
0237 
0238   /// Assign the surface material description
0239   ///
0240   /// The material is usually derived in a complicated way and loaded from
0241   /// a framework given source. As various surfaces may share the same source
0242   /// this is provided by a shared pointer
0243   ///
0244   /// @param material Material description associated to this surface
0245   void assignSurfaceMaterial(std::shared_ptr<const ISurfaceMaterial> material);
0246 
0247   /// The geometric onSurface method
0248   ///
0249   /// Geometrical check whether position is on Surface
0250   ///
0251   /// @param gctx The current geometry context object, e.g. alignment
0252   /// @param position global position to be evaludated
0253   /// @param direction global momentum direction (required for line-type surfaces)
0254   /// @param boundaryTolerance BoundaryTolerance directive for this onSurface check
0255   /// @param tolerance optional tolerance within which a point is considered on surface
0256   ///
0257   /// @return boolean indication if operation was successful
0258   bool isOnSurface(
0259       const GeometryContext& gctx, const Vector3& position,
0260       const Vector3& direction,
0261       const BoundaryTolerance& boundaryTolerance = BoundaryTolerance::None(),
0262       double tolerance = s_onSurfaceTolerance) const;
0263 
0264   /// The insideBounds method for local positions
0265   ///
0266   /// @param lposition The local position to check
0267   /// @param boundaryTolerance BoundaryTolerance directive for this onSurface check
0268   /// @return boolean indication if operation was successful
0269   virtual bool insideBounds(const Vector2& lposition,
0270                             const BoundaryTolerance& boundaryTolerance =
0271                                 BoundaryTolerance::None()) const;
0272 
0273   /// Local to global transformation
0274   /// Generalized local to global transformation for the surface types. Since
0275   /// some surface types need the global momentum/direction to resolve sign
0276   /// ambiguity this is also provided
0277   ///
0278   /// @param gctx The current geometry context object, e.g. alignment
0279   /// @param lposition local 2D position in specialized surface frame
0280   /// @param direction global 3D momentum direction
0281   ///
0282   /// @return The global position by value
0283   virtual Vector3 localToGlobal(const GeometryContext& gctx,
0284                                 const Vector2& lposition,
0285                                 const Vector3& direction) const = 0;
0286 
0287   /// Global to local transformation
0288   /// Generalized global to local transformation for the surface types. Since
0289   /// some surface types need the global momentum/direction to resolve sign
0290   /// ambiguity this is also provided
0291   ///
0292   /// @param gctx The current geometry context object, e.g. alignment
0293   /// @param position global 3D position - considered to be on surface but not
0294   /// inside bounds (check is done)
0295   /// @param direction global 3D momentum direction
0296   /// @param tolerance optional tolerance within which a point is considered
0297   /// valid on surface
0298   ///
0299   /// @return a Result<Vector2> which can be !ok() if the operation fails
0300   virtual Result<Vector2> globalToLocal(
0301       const GeometryContext& gctx, const Vector3& position,
0302       const Vector3& direction,
0303       double tolerance = s_onSurfaceTolerance) const = 0;
0304 
0305   /// Return method for the reference frame
0306   /// This is the frame in which the covariance matrix is defined (specialized
0307   /// by all surfaces)
0308   ///
0309   /// @param gctx The current geometry context object, e.g. alignment
0310   /// @param position global 3D position - considered to be on surface but not
0311   /// inside bounds (check is done)
0312   /// @param direction global 3D momentum direction (optionally ignored)
0313   ///
0314   /// @return RotationMatrix3 which defines the three axes of the measurement
0315   /// frame
0316   virtual Acts::RotationMatrix3 referenceFrame(const GeometryContext& gctx,
0317                                                const Vector3& position,
0318                                                const Vector3& direction) const;
0319 
0320   /// Calculate the jacobian from local to global which the surface knows best,
0321   /// hence the calculation is done here.
0322   ///
0323   /// @note In principle, the input could also be a free parameters
0324   /// vector as it could be transformed to a bound parameters. But the transform
0325   /// might fail in case the parameters is not on surface. To avoid the check
0326   /// inside this function, it takes directly the bound parameters as input
0327   /// (then the check might be done where this function is called).
0328   ///
0329   /// @todo this mixes track parameterisation and geometry
0330   /// should move to :
0331   /// "Acts/EventData/detail/coordinate_transformations.hpp"
0332   ///
0333   /// @param gctx The current geometry context object, e.g. alignment
0334   /// @param position global 3D position
0335   /// @param direction global 3D momentum direction
0336   ///
0337   /// @return Jacobian from local to global
0338   virtual BoundToFreeMatrix boundToFreeJacobian(const GeometryContext& gctx,
0339                                                 const Vector3& position,
0340                                                 const Vector3& direction) const;
0341 
0342   /// Calculate the jacobian from global to local which the surface knows best,
0343   /// hence the calculation is done here.
0344   ///
0345   /// @note It assumes the input free parameters is on surface, hence no
0346   /// onSurface check is done inside this function.
0347   ///
0348   /// @todo this mixes track parameterisation and geometry
0349   /// should move to :
0350   /// "Acts/EventData/detail/coordinate_transformations.hpp"
0351   ///
0352   /// @param gctx The current geometry context object, e.g. alignment
0353   /// @param position global 3D position
0354   /// @param direction global 3D momentum direction
0355   ///
0356   /// @return Jacobian from global to local
0357   virtual FreeToBoundMatrix freeToBoundJacobian(const GeometryContext& gctx,
0358                                                 const Vector3& position,
0359                                                 const Vector3& direction) const;
0360 
0361   /// Calculate the derivative of path length at the geometry constraint or
0362   /// point-of-closest-approach w.r.t. free parameters. The calculation is
0363   /// identical for all surfaces where the reference frame does not depend on
0364   /// the direction
0365   ///
0366   /// @todo this mixes track parameterisation and geometry
0367   /// should move to :
0368   /// "Acts/EventData/detail/coordinate_transformations.hpp"
0369   ///
0370   /// @param gctx The current geometry context object, e.g. alignment
0371   /// @param position global 3D position
0372   /// @param direction global 3D momentum direction
0373   ///
0374   /// @return Derivative of path length w.r.t. free parameters
0375   virtual FreeToPathMatrix freeToPathDerivative(const GeometryContext& gctx,
0376                                                 const Vector3& position,
0377                                                 const Vector3& direction) const;
0378 
0379   /// Calucation of the path correction for incident
0380   ///
0381   /// @param gctx The current geometry context object, e.g. alignment
0382   /// @param position global 3D position
0383   /// @note The @p position is either ignored, or it is coerced to be on the surface,
0384   ///       depending on the surface type.
0385   /// @param direction global 3D momentum direction
0386   ///
0387   /// @return Path correction with respect to the nominal incident.
0388   virtual double pathCorrection(const GeometryContext& gctx,
0389                                 const Vector3& position,
0390                                 const Vector3& direction) const = 0;
0391 
0392   /// Straight line intersection schema from position/direction
0393   ///
0394   /// @param gctx The current geometry context object, e.g. alignment
0395   /// @param position The position to start from
0396   /// @param direction The direction at start
0397   /// @param boundaryTolerance the BoundaryTolerance
0398   /// @param tolerance the tolerance used for the intersection
0399   ///
0400   /// @return @c SurfaceMultiIntersection object (contains intersection & surface)
0401   virtual SurfaceMultiIntersection intersect(
0402       const GeometryContext& gctx, const Vector3& position,
0403       const Vector3& direction,
0404       const BoundaryTolerance& boundaryTolerance =
0405           BoundaryTolerance::Infinite(),
0406       ActsScalar tolerance = s_onSurfaceTolerance) const = 0;
0407 
0408   /// Helper method for printing: the returned object captures the
0409   /// surface and the geometry context and will print the surface
0410   /// @param gctx The current geometry context object, e.g. alignment
0411   /// @return The wrapper object for printing
0412   GeometryContextOstreamWrapper<Surface> toStream(
0413       const GeometryContext& gctx) const {
0414     return {*this, gctx};
0415   }
0416 
0417   /// Output into a std::string
0418   ///
0419   /// @param gctx The current geometry context object, e.g. alignment
0420   std::string toString(const GeometryContext& gctx) const;
0421 
0422   /// Return properly formatted class name
0423   virtual std::string name() const = 0;
0424 
0425   /// Return a Polyhedron for this object
0426   ///
0427   /// @param gctx The current geometry context object, e.g. alignment
0428   /// @param lseg Number of segments along curved lines, if the lseg
0429   /// is set to one, only the corners and the extrema are given,
0430   /// otherwise it represents the number of segments for a full 2*M_PI
0431   /// circle and is scaled to the relevant sector
0432   ///
0433   /// @note An internal surface transform can invalidate the extrema
0434   /// in the transformed space
0435   ///
0436   /// @return A list of vertices and a face/facett description of it
0437   virtual Polyhedron polyhedronRepresentation(const GeometryContext& gctx,
0438                                               std::size_t lseg) const = 0;
0439 
0440   /// The derivative of bound track parameters w.r.t. alignment
0441   /// parameters of its reference surface (i.e. local frame origin in
0442   /// global 3D Cartesian coordinates and its rotation represented with
0443   /// extrinsic Euler angles)
0444   ///
0445   /// @param gctx The current geometry context object, e.g. alignment
0446   /// change of alignment parameters
0447   /// @param position global 3D position
0448   /// @param direction global 3D momentum direction
0449   /// @param pathDerivative is the derivative of free parameters w.r.t. path
0450   /// length
0451   ///
0452   /// @return Derivative of bound track parameters w.r.t. local frame
0453   /// alignment parameters
0454   AlignmentToBoundMatrix alignmentToBoundDerivative(
0455       const GeometryContext& gctx, const Vector3& position,
0456       const Vector3& direction, const FreeVector& pathDerivative) const;
0457 
0458   /// Calculate the derivative of path length at the geometry constraint or
0459   /// point-of-closest-approach w.r.t. alignment parameters of the surface (i.e.
0460   /// local frame origin in global 3D Cartesian coordinates and its rotation
0461   /// represented with extrinsic Euler angles)
0462   ///
0463   /// @note Re-implementation is needed for surface whose intersection with
0464   /// track is not its local xy plane, e.g. LineSurface, CylinderSurface and
0465   /// ConeSurface
0466   ///
0467   /// @param gctx The current geometry context object, e.g. alignment
0468   /// @param position global 3D position
0469   /// @param direction global 3D momentum direction
0470   ///
0471   /// @return Derivative of path length w.r.t. the alignment parameters
0472   virtual AlignmentToPathMatrix alignmentToPathDerivative(
0473       const GeometryContext& gctx, const Vector3& position,
0474       const Vector3& direction) const;
0475 
0476   /// Calculate the derivative of bound track parameters local position w.r.t.
0477   /// position in local 3D Cartesian coordinates
0478   ///
0479   /// @param gctx The current geometry context object, e.g. alignment
0480   /// @param position The position of the parameters in global
0481   ///
0482   /// @return Derivative of bound local position w.r.t. position in local 3D
0483   /// cartesian coordinates
0484   virtual ActsMatrix<2, 3> localCartesianToBoundLocalDerivative(
0485       const GeometryContext& gctx, const Vector3& position) const = 0;
0486 
0487  protected:
0488   /// Output Method for std::ostream, to be overloaded by child classes
0489   ///
0490   /// @param gctx The current geometry context object, e.g. alignment
0491   /// @param sl is the ostream to be dumped into
0492   virtual std::ostream& toStreamImpl(const GeometryContext& gctx,
0493                                      std::ostream& sl) const;
0494 
0495   /// Transform3 definition that positions
0496   /// (translation, rotation) the surface in global space
0497   std::unique_ptr<const Transform3> m_transform{};
0498 
0499   /// Pointer to the a DetectorElementBase
0500   const DetectorElementBase* m_associatedDetElement{nullptr};
0501 
0502   /// The associated layer Layer - layer in which the Surface is be embedded,
0503   /// nullptr if not associated
0504   const Layer* m_associatedLayer{nullptr};
0505 
0506   /// The associated TrackingVolume - tracking volume in case the surface is a
0507   /// boundary surface, nullptr if not associated
0508   const TrackingVolume* m_associatedTrackingVolume{nullptr};
0509 
0510   /// Possibility to attach a material description
0511   std::shared_ptr<const ISurfaceMaterial> m_surfaceMaterial;
0512 
0513  private:
0514   /// Calculate the derivative of bound track parameters w.r.t.
0515   /// alignment parameters of its reference surface (i.e. origin in global 3D
0516   /// Cartesian coordinates and its rotation represented with extrinsic Euler
0517   /// angles) without any path correction
0518   ///
0519   /// @note This function should be used together with alignment to path
0520   /// derivative to get the full alignment to bound derivatives
0521   ///
0522   /// @param gctx The current geometry context object, e.g. alignment
0523   /// @param position global 3D position
0524   /// @param direction global 3D momentum direction
0525   ///
0526   /// @return Derivative of bound track parameters w.r.t. local frame alignment
0527   /// parameters without path correction
0528   AlignmentToBoundMatrix alignmentToBoundDerivativeWithoutCorrection(
0529       const GeometryContext& gctx, const Vector3& position,
0530       const Vector3& direction) const;
0531 };
0532 
0533 }  // namespace Acts