Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:33:27

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