Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 07:49:48

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 <type_traits>
0012 #include <utility>
0013 
0014 namespace Acts {
0015 
0016 class TrackingVolume;
0017 class Portal;
0018 class Surface;
0019 class Layer;
0020 
0021 template <typename T>
0022 class BoundarySurfaceT;
0023 /// @brief Base class for tracking geometry visitors
0024 ///
0025 /// This class provides a common interface for both const and mutable visitors
0026 /// to the tracking geometry hierarchy. It allows decide on the visiting order
0027 /// based on the visitInDepth flag. If true, the visiting happens from the
0028 /// outermost volume and goes deeper to the volumes into the hierarchy.
0029 class ITrackingGeometryVisitor {
0030  public:
0031   virtual ~ITrackingGeometryVisitor() = 0;
0032 
0033   explicit ITrackingGeometryVisitor(bool visitDepthFirst = false)
0034       : m_visitDepthFirst(visitDepthFirst) {}
0035 
0036   /// @brief indicate the order of visiting
0037   /// @note default is outermost --> innermost volume visiting
0038   bool visitDepthFirst() const { return m_visitDepthFirst; }
0039 
0040  private:
0041   /// Flag to indicate if the visitor should follow from the outermost to the
0042   /// innermost volume depth
0043   bool m_visitDepthFirst{false};
0044 };
0045 
0046 /// @brief Visitor interface for traversing the tracking geometry hierarchy
0047 ///
0048 /// This visitor allows for const access to traverse and inspect the tracking
0049 /// geometry components without modifying them. It's used for operations like
0050 /// visualization, validation, or collecting information about the geometry
0051 /// structure.
0052 class TrackingGeometryVisitor : public ITrackingGeometryVisitor {
0053  public:
0054   /// @brief Constructor from base class
0055   using ITrackingGeometryVisitor::ITrackingGeometryVisitor;
0056 
0057   ~TrackingGeometryVisitor() override;
0058 
0059   /// @brief Visit a tracking volume in the geometry
0060   /// @param volume The tracking volume being visited
0061   /// @note Called for each volume in the geometry hierarchy during traversal
0062   virtual void visitVolume(const TrackingVolume& volume);
0063 
0064   /// @brief Visit a portal (boundary between volumes)
0065   /// @param portal The portal being visited
0066   /// @note Called for each portal encountered during geometry traversal
0067   virtual void visitPortal(const Portal& portal);
0068 
0069   /// @brief Visit a surface in the geometry
0070   /// @param surface The surface being visited
0071   /// @note Called for each surface encountered during geometry traversal
0072   virtual void visitSurface(const Surface& surface);
0073 
0074   // Gen 1
0075   /// @brief Visit a detector layer
0076   /// @param layer The layer being visited
0077   /// @note Called for each layer encountered during geometry traversal
0078   virtual void visitLayer(const Layer& layer);
0079 
0080   /// @brief Visit a boundary surface between tracking volumes
0081   /// @param boundary The boundary surface being visited
0082   /// @note Called for each boundary surface encountered during geometry traversal
0083   virtual void visitBoundarySurface(
0084       const BoundarySurfaceT<TrackingVolume>& boundary);
0085 };
0086 
0087 /// @brief Mutable visitor interface for modifying the tracking geometry hierarchy
0088 ///
0089 /// This visitor allows for non-const access to traverse and modify the
0090 /// tracking geometry components. It's used for operations like geometry
0091 /// construction, material decoration, or geometry ID assignment.
0092 class TrackingGeometryMutableVisitor : public ITrackingGeometryVisitor {
0093  public:
0094   /// @brief Constructor
0095   using ITrackingGeometryVisitor::ITrackingGeometryVisitor;
0096 
0097   ~TrackingGeometryMutableVisitor() override;
0098 
0099   /// @brief Visit and potentially modify a tracking volume
0100   /// @param volume The tracking volume being visited
0101   /// @note Called for each volume in the geometry hierarchy during traversal
0102   virtual void visitVolume(TrackingVolume& volume);
0103 
0104   /// @brief Visit and potentially modify a portal
0105   /// @param portal The portal being visited
0106   /// @note Called for each portal encountered during geometry traversal
0107   virtual void visitPortal(Portal& portal);
0108 
0109   /// @brief Visit and potentially modify a surface
0110   /// @param surface The surface being visited
0111   /// @note Called for each surface encountered during geometry traversal
0112   virtual void visitSurface(Surface& surface);
0113 
0114   // Gen 1
0115   /// @brief Visit and potentially modify a detector layer
0116   /// @param layer The layer being visited
0117   /// @note Called for each layer encountered during geometry traversal
0118   virtual void visitLayer(Layer& layer);
0119 
0120   /// @brief Visit and potentially modify a boundary surface
0121   /// @param boundary The boundary surface being visited
0122   /// @note Called for each boundary surface encountered during geometry traversal
0123   virtual void visitBoundarySurface(BoundarySurfaceT<TrackingVolume>& boundary);
0124 };
0125 
0126 namespace detail {
0127 
0128 template <typename Callable>
0129 consteval bool callableWithAnyMutable() {
0130   return std::is_invocable_v<Callable, Surface&> ||
0131          std::is_invocable_v<Callable, TrackingVolume&> ||
0132          std::is_invocable_v<Callable, BoundarySurfaceT<TrackingVolume>&> ||
0133          std::is_invocable_v<Callable, Layer&> ||
0134          std::is_invocable_v<Callable, Portal&>;
0135 }
0136 
0137 template <typename Callable>
0138 consteval bool callableWithAnyConst() {
0139   return std::is_invocable_v<Callable, const Surface&> ||
0140          std::is_invocable_v<Callable, const TrackingVolume&> ||
0141          std::is_invocable_v<Callable,
0142                              const BoundarySurfaceT<TrackingVolume>&> ||
0143          std::is_invocable_v<Callable, const Layer&> ||
0144          std::is_invocable_v<Callable, const Portal&>;
0145 }
0146 
0147 template <typename Callable>
0148 consteval bool callableWithAny() {
0149   return callableWithAnyMutable<Callable>() || callableWithAnyConst<Callable>();
0150 }
0151 
0152 template <typename Callable>
0153   requires(callableWithAnyConst<Callable>())
0154 class TrackingGeometryLambdaVisitor : public TrackingGeometryVisitor {
0155  public:
0156   explicit TrackingGeometryLambdaVisitor(Callable callable)
0157       : m_callable(std::move(callable)) {}
0158 
0159   void visitSurface(const Surface& surface) override {
0160     if constexpr (std::is_invocable_v<Callable, const Surface&>) {
0161       m_callable(surface);
0162     }
0163   }
0164 
0165   void visitVolume(const TrackingVolume& volume) override {
0166     if constexpr (std::is_invocable_v<Callable, const TrackingVolume&>) {
0167       m_callable(volume);
0168     }
0169   }
0170 
0171   void visitBoundarySurface(
0172       const BoundarySurfaceT<TrackingVolume>& boundary) override {
0173     if constexpr (std::is_invocable_v<
0174                       Callable, const BoundarySurfaceT<TrackingVolume>&>) {
0175       m_callable(boundary);
0176     }
0177   }
0178 
0179   void visitLayer(const Layer& layer) override {
0180     if constexpr (std::is_invocable_v<Callable, const Layer&>) {
0181       m_callable(layer);
0182     }
0183   }
0184 
0185   void visitPortal(const Portal& portal) override {
0186     if constexpr (std::is_invocable_v<Callable, const Portal&>) {
0187       m_callable(portal);
0188     }
0189   }
0190 
0191  private:
0192   Callable m_callable;
0193 };
0194 
0195 template <typename Callable>
0196   requires(callableWithAnyMutable<Callable>())
0197 class TrackingGeometryLambdaMutableVisitor
0198     : public TrackingGeometryMutableVisitor {
0199  public:
0200   explicit TrackingGeometryLambdaMutableVisitor(Callable callable)
0201       : m_callable(std::move(callable)) {}
0202 
0203   void visitSurface(Surface& surface) override {
0204     if constexpr (std::is_invocable_v<Callable, Surface&>) {
0205       m_callable(surface);
0206     }
0207   }
0208 
0209   void visitVolume(TrackingVolume& volume) override {
0210     if constexpr (std::is_invocable_v<Callable, TrackingVolume&>) {
0211       m_callable(volume);
0212     }
0213   }
0214 
0215   void visitBoundarySurface(
0216       BoundarySurfaceT<TrackingVolume>& boundary) override {
0217     if constexpr (std::is_invocable_v<Callable,
0218                                       BoundarySurfaceT<TrackingVolume>&>) {
0219       m_callable(boundary);
0220     }
0221   }
0222 
0223   void visitLayer(Layer& layer) override {
0224     if constexpr (std::is_invocable_v<Callable, Layer&>) {
0225       m_callable(layer);
0226     }
0227   }
0228 
0229   void visitPortal(Portal& portal) override {
0230     if constexpr (std::is_invocable_v<Callable, Portal&>) {
0231       m_callable(portal);
0232     }
0233   }
0234 
0235  private:
0236   Callable m_callable;
0237 };
0238 
0239 }  // namespace detail
0240 
0241 }  // namespace Acts