Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:23:34

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/Tolerance.hpp"
0014 #include "Acts/Definitions/TrackParametrization.hpp"
0015 #include "Acts/Geometry/GeometryContext.hpp"
0016 #include "Acts/Geometry/Polyhedron.hpp"
0017 #include "Acts/Surfaces/BoundaryCheck.hpp"
0018 #include "Acts/Surfaces/CylinderBounds.hpp"
0019 #include "Acts/Surfaces/RegularSurface.hpp"
0020 #include "Acts/Surfaces/Surface.hpp"
0021 #include "Acts/Surfaces/SurfaceConcept.hpp"
0022 #include "Acts/Utilities/BinningType.hpp"
0023 #include "Acts/Utilities/Concepts.hpp"
0024 #include "Acts/Utilities/Logger.hpp"
0025 #include "Acts/Utilities/Result.hpp"
0026 #include "Acts/Utilities/detail/RealQuadraticEquation.hpp"
0027 
0028 #include <cmath>
0029 #include <cstddef>
0030 #include <memory>
0031 #include <string>
0032 
0033 namespace Acts {
0034 class DetectorElementBase;
0035 
0036 /// @class CylinderSurface
0037 ///
0038 /// Class for a CylinderSurface in the TrackingGeometry.
0039 /// It inherits from Surface.
0040 ///
0041 /// The cylinder surface has a special role in the TrackingGeometry,
0042 /// since it builds the surfaces of all TrackingVolumes at container level
0043 /// for a cylindrical tracking geometry.
0044 ///
0045 /// @image html CylinderSurface.png
0046 
0047 class CylinderSurface : public RegularSurface {
0048   friend class Surface;
0049 
0050  protected:
0051   /// Constructor from Transform3 and CylinderBounds
0052   ///
0053   /// @param transform The transform to position the surface
0054   /// @param radius The radius of the cylinder
0055   /// @param halfz The half length in z
0056   /// @param halfphi The half opening angle
0057   /// @param avphi The phi value from which the opening angle spans (both sides)
0058   /// @param bevelMinZ (optional) The bevel on the negative z side
0059   /// @param bevelMaxZ (optional) The bevel on the positive z sid The bevel on the positive z side
0060   CylinderSurface(const Transform3& transform, double radius, double halfz,
0061                   double halfphi = M_PI, double avphi = 0.,
0062                   double bevelMinZ = 0., double bevelMaxZ = 0.);
0063 
0064   /// Constructor from Transform3 and CylinderBounds arguments
0065   ///
0066   /// @param transform The transform to position the surface
0067   /// @param cbounds is a shared pointer to a cylindeer bounds object,
0068   /// it must exist (assert test)
0069   CylinderSurface(const Transform3& transform,
0070                   std::shared_ptr<const CylinderBounds> cbounds);
0071 
0072   /// Constructor from DetectorElementBase: Element proxy
0073   ///
0074   /// @param cbounds are the provided cylinder bounds (shared)
0075   /// @param detelement is the linked detector element to this surface
0076   CylinderSurface(std::shared_ptr<const CylinderBounds> cbounds,
0077                   const DetectorElementBase& detelement);
0078 
0079   /// Copy constructor
0080   ///
0081   /// @param other is the source cylinder for the copy
0082   CylinderSurface(const CylinderSurface& other);
0083 
0084   /// Copy constructor - with shift
0085   ///
0086   /// @param gctx The current geometry context object, e.g. alignment
0087   /// @param other is the source cone surface
0088   /// @param shift is the additional transform applied after copying
0089   CylinderSurface(const GeometryContext& gctx, const CylinderSurface& other,
0090                   const Transform3& shift);
0091 
0092  public:
0093   ~CylinderSurface() override = default;
0094   CylinderSurface() = delete;
0095 
0096   /// Assignment operator
0097   ///
0098   /// @param other is the source cylinder for the copy
0099   CylinderSurface& operator=(const CylinderSurface& other);
0100 
0101   /// The binning position method - is overloaded for r-type binning
0102   ///
0103   /// @param gctx The current geometry context object, e.g. alignment
0104   /// @param bValue is the type of global binning to be done
0105   ///
0106   /// @return is the global position to be used for binning
0107   Vector3 binningPosition(const GeometryContext& gctx,
0108                           BinningValue bValue) const final;
0109 
0110   /// Return the measurement frame - this is needed for alignment, in particular
0111   /// The measurement frame of a cylinder is the tangential plane at a given
0112   /// position
0113   ///
0114   /// @param gctx The current geometry context object, e.g. alignment
0115   /// @param position is the position where the measurement frame is defined
0116   /// @param direction is the momentum direction vector (ignored)
0117   /// @return rotation matrix that defines the measurement frame
0118   RotationMatrix3 referenceFrame(const GeometryContext& gctx,
0119                                  const Vector3& position,
0120                                  const Vector3& direction) const final;
0121 
0122   /// Return the surface type
0123   SurfaceType type() const override;
0124 
0125   /// Return method for surface normal information
0126   /// @note for a Cylinder a local position is always required for the normal
0127   /// vector
0128   ///
0129   /// @param gctx The current geometry context object, e.g. alignment
0130   /// @param lposition is the local position for which the normal vector is
0131   /// requested
0132   ///
0133   /// @return normal vector at the local position by value
0134   Vector3 normal(const GeometryContext& gctx,
0135                  const Vector2& lposition) const final;
0136 
0137   /// Return method for surface normal information
0138   /// @note for a Cylinder a local position is always required for the normal
0139   /// vector
0140   ///
0141   /// @param gctx The current geometry context object, e.g. alignment
0142   /// @param position is the global position for which the normal vector is
0143   /// requested
0144   ///
0145   /// @return normal vector at the global position by value
0146   Vector3 normal(const GeometryContext& gctx,
0147                  const Vector3& position) const final;
0148 
0149   // Use overloads from `RegularSurface`
0150   using RegularSurface::globalToLocal;
0151   using RegularSurface::localToGlobal;
0152   using RegularSurface::normal;
0153 
0154   /// Return method for the rotational symmetry axis
0155   ///
0156   /// @param gctx The current geometry context object, e.g. alignment
0157   ///
0158   /// @return  the z-Axis of transform
0159   virtual Vector3 rotSymmetryAxis(const GeometryContext& gctx) const;
0160 
0161   /// This method returns the CylinderBounds by reference
0162   const CylinderBounds& bounds() const final;
0163 
0164   /// Local to global transformation
0165   ///
0166   /// @param gctx The current geometry context object, e.g. alignment
0167   /// @param lposition is the local position to be transformed
0168   ///
0169   /// @return The global position by value
0170   Vector3 localToGlobal(const GeometryContext& gctx,
0171                         const Vector2& lposition) const final;
0172 
0173   /// Global to local transformation
0174   ///
0175   /// @param gctx The current geometry context object, e.g. alignment
0176   /// @param position is the global position to be transformed
0177   /// @param tolerance optional tolerance within which a point is considered
0178   /// valid on surface
0179   ///
0180   /// @return a Result<Vector2> which can be !ok() if the operation fails
0181   Result<Vector2> globalToLocal(
0182       const GeometryContext& gctx, const Vector3& position,
0183       double tolerance = s_onSurfaceTolerance) const final;
0184 
0185   /// Straight line intersection schema from position/direction
0186   ///
0187   /// @param gctx The current geometry context object, e.g. alignment
0188   /// @param position The position to start from
0189   /// @param direction The direction at start
0190   /// @param bcheck the Boundary Check
0191   /// @param tolerance the tolerance used for the intersection
0192   ///
0193   /// If possible returns both solutions for the cylinder
0194   ///
0195   /// @return SurfaceIntersection object (contains intersection & surface)
0196   SurfaceMultiIntersection intersect(
0197       const GeometryContext& gctx, const Vector3& position,
0198       const Vector3& direction,
0199       const BoundaryCheck& bcheck = BoundaryCheck(false),
0200       ActsScalar tolerance = s_onSurfaceTolerance) const final;
0201 
0202   /// Path correction due to incident of the track
0203   ///
0204   /// @param gctx The current geometry context object, e.g. alignment
0205   /// @param position is the global position as a starting point
0206   /// @param direction is the global momentum direction at the starting point
0207   ///
0208   /// @return is the correction factor due to incident
0209   double pathCorrection(const GeometryContext& gctx, const Vector3& position,
0210                         const Vector3& direction) const final;
0211 
0212   /// Return method for properly formatted output string
0213   std::string name() const override;
0214 
0215   /// Return a Polyhedron for a cylinder
0216   ///
0217   /// @param gctx The current geometry context object, e.g. alignment
0218   /// @param lseg Number of segments along curved lines, it represents
0219   /// the full 2*M_PI coverange, if lseg is set to 1 only the extrema
0220   /// are given
0221   ///
0222   /// @return A list of vertices and a face/facett description of it
0223   Polyhedron polyhedronRepresentation(const GeometryContext& gctx,
0224                                       std::size_t lseg) const override;
0225 
0226   /// Calculate the derivative of path length at the geometry constraint or
0227   /// point-of-closest-approach w.r.t. alignment parameters of the surface (i.e.
0228   /// local frame origin in global 3D Cartesian coordinates and its rotation
0229   /// represented with extrinsic Euler angles)
0230   ///
0231   /// @param gctx The current geometry context object, e.g. alignment
0232   /// @param position global 3D position
0233   /// @param direction global 3D momentum direction
0234   ///
0235   /// @return Derivative of path length w.r.t. the alignment parameters
0236   AlignmentToPathMatrix alignmentToPathDerivative(
0237       const GeometryContext& gctx, const Vector3& position,
0238       const Vector3& direction) const final;
0239 
0240   /// Calculate the derivative of bound track parameters local position w.r.t.
0241   /// position in local 3D Cartesian coordinates
0242   ///
0243   /// @param gctx The current geometry context object, e.g. alignment
0244   /// @param position The position of the parameters in global
0245   ///
0246   /// @return Derivative of bound local position w.r.t. position in local 3D
0247   /// cartesian coordinates
0248   ActsMatrix<2, 3> localCartesianToBoundLocalDerivative(
0249       const GeometryContext& gctx, const Vector3& position) const final;
0250 
0251   /// Merge two cylinder surfaces into a single one.
0252   /// @image html Cylinder_Merging.svg
0253   /// @note The surfaces need to be *compatible*, i.e. have cylinder bounds
0254   ///       that align, and have the same radius
0255   /// @param gctx The current geometry context object, e.g. alignment
0256   /// @param other The other cylinder surface to merge with
0257   /// @param direction The binning direction: either @c binZ or @c binRPhi
0258   /// @param logger The logger to use
0259   /// @return The merged cylinder surface
0260   std::shared_ptr<CylinderSurface> mergedWith(
0261       const GeometryContext& gctx, const CylinderSurface& other,
0262       BinningValue direction, const Logger& logger = getDummyLogger()) const;
0263 
0264  protected:
0265   std::shared_ptr<const CylinderBounds> m_bounds;  //!< bounds (shared)
0266 
0267  private:
0268   /// Implementation of the intersection solver
0269   ///
0270   ///  <b>mathematical motivation:</b>
0271   ///
0272   /// The cylinder is given by :
0273   ///   - cylinder center: ccenter (C)
0274   ///   - the direction of the cylinder axis: cdirection (DZ)
0275   ///   - the radius r
0276   /// The line is given by :
0277   ///   - a reference position : lposition (L0)
0278   ///   - the line direction: ldirection (DL)
0279   ///   the parametric form for the line is then : L(t) = L0 + t * DL
0280   ///
0281   /// Any point P on infinite cylinder if :
0282   ///      ((P - C) x DZ)^2 = r^2 * DZ^2
0283   /// We know that DZ is a unit vector:
0284   ///   DZ^2 == 1
0285   /// When expanded with the line equation, this is  :
0286   ///      ((L0 - C) x DZ + t * (DL x DZ))^2 = r^2 * DZ^2
0287   /// which is a quadratic equation in the form (X + t * Y)^2 = d, where :
0288   ///  X = (L0 - C) x DZ
0289   ///  Y = DL x DZ
0290   ///  d = r^2 * (DZ)^2
0291   /// Now, expand the equation :
0292   /// t^2 * (Y . Y) + t * (2 * (X . Y)) + (X . X) - d = 0
0293   /// => second order equation in the form : a*t^2 + b*t + c = 0 where
0294   /// a = (Y . Y)
0295   /// b = 2 * (X . Y)
0296   /// c = (X . X) - d
0297   /// finally solve the second order equation : a*t^2 + b*t + c = 0
0298   /// reinsertion into the line equation.
0299   ///
0300   /// @return the quadratic equation
0301   detail::RealQuadraticEquation intersectionSolver(
0302       const Transform3& transform, const Vector3& position,
0303       const Vector3& direction) const;
0304 };
0305 
0306 ACTS_STATIC_CHECK_CONCEPT(RegularSurfaceConcept, CylinderSurface);
0307 
0308 }  // namespace Acts