Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:01:48

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