Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-28 08:11:31

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/Navigation/INavigationPolicy.hpp"
0012 #include "Acts/Navigation/NavigationStream.hpp"
0013 
0014 namespace Acts {
0015 
0016 class TrackingVolume;
0017 class GeometryContext;
0018 class Logger;
0019 
0020 /// Optimized navigation policy for cylindrical volumes that intelligently
0021 /// selects which portals to add as candidates based on geometric analysis.
0022 ///
0023 /// This policy performs geometric calculations to determine which cylinder
0024 /// faces (inner/outer cylinder, positive/negative discs) are reachable from
0025 /// the current position and direction, avoiding unnecessary intersection
0026 /// calculations with unreachable portals.
0027 ///
0028 /// Algorithm overview:
0029 /// 1. Transform position/direction to volume-local coordinates
0030 /// 2. Check disc intersection: If not parallel to z-axis, calculate
0031 ///    intersection with appropriate disc (positive/negative based on
0032 ///    direction) and verify if intersection point lies within the annular disc
0033 ///    bounds
0034 /// 3. Check inner cylinder intersection: Find point of closest approach to
0035 ///    the z-axis in the xy-plane. If this point is closer than inner radius
0036 ///    and lies within the forward ray direction, add inner cylinder as
0037 ///    candidate
0038 /// 4. Optimization: If both inner cylinder and disc are hit, compare their 3D
0039 ///    distances along the ray. If the inner cylinder is closer, discard the
0040 ///    disc candidate as it will be blocked and never reached
0041 /// 5. Default fallback: If neither disc nor inner cylinder are hit, add outer
0042 ///    cylinder as the target (particle will exit through outer boundary)
0043 ///
0044 /// Constraints:
0045 /// - Only works with cylindrical volumes having non-zero inner radius
0046 /// - Requires exactly 4 portals (inner cylinder, outer cylinder, ±z discs)
0047 /// - Does not handle contained sub-volumes
0048 ///
0049 /// Performance benefits:
0050 /// - Reduces intersection calculations by ~2-3x compared to trying all portals
0051 /// - Eliminates false positive intersections that would be filtered later
0052 class CylinderNavigationPolicy final : public INavigationPolicy {
0053  public:
0054   /// Constructor from a volume
0055   /// @param gctx is the geometry context
0056   /// @param volume is the volume to navigate
0057   /// @param logger is the logger
0058   CylinderNavigationPolicy(const GeometryContext& gctx,
0059                            const TrackingVolume& volume, const Logger& logger);
0060 
0061   /// Intelligently select and add portal candidates based on geometric analysis
0062   ///
0063   /// The algorithm determines which portals are geometrically reachable:
0064   /// - Disc portals: Added if ray intersects the annular disc area
0065   /// - Inner cylinder: Added if ray's closest approach to z-axis is within
0066   /// inner radius
0067   /// - Outer cylinder: Added as fallback when no other portals are reachable
0068   ///
0069   /// @param args are the navigation arguments containing position and direction
0070   /// @param stream is the navigation stream to update with selected candidates
0071   /// @param logger is the logger for debugging output
0072   void initializeCandidates(const NavigationArguments& args,
0073                             AppendOnlyNavigationStream& stream,
0074                             const Logger& logger) const;
0075 
0076   /// Connect the policy to a navigation delegate
0077   /// @param delegate is the navigation delegate
0078   void connect(NavigationDelegate& delegate) const override;
0079 
0080  private:
0081   /// Pointer to the cylindrical tracking volume this policy navigates
0082   const TrackingVolume* m_volume;
0083 
0084   /// Inverse transform for converting global to local coordinates (optional)
0085   /// Only computed if volume transform is not identity
0086   std::optional<Transform3> m_itransform;
0087 
0088   /// Cached cylinder bounds for efficient access during navigation
0089   double m_halfLengthZ;  ///< Half-length of cylinder in z-direction
0090   double m_rMin2;        ///< Squared inner radius for fast comparison
0091   double m_rMax2;        ///< Squared outer radius for fast comparison
0092 
0093   /// Direct portal references for efficient candidate addition
0094   /// Index corresponds to CylinderVolumeBounds::Face enum values
0095   std::array<const Portal*, 4> m_portals{};
0096 };
0097 
0098 static_assert(NavigationPolicyConcept<CylinderNavigationPolicy>);
0099 
0100 }  // namespace Acts