Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-24 08:18:47

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