Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2022-2023 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/Common.hpp"
0013 #include "Acts/Detector/DetectorVolume.hpp"
0014 #include "Acts/Detector/DetectorVolumeVisitorConcept.hpp"
0015 #include "Acts/Geometry/GeometryContext.hpp"
0016 #include "Acts/Geometry/GeometryHierarchyMap.hpp"
0017 #include "Acts/Geometry/GeometryIdentifier.hpp"
0018 #include "Acts/Navigation/NavigationDelegates.hpp"
0019 #include "Acts/Surfaces/SurfaceVisitorConcept.hpp"
0020 #include "Acts/Utilities/Concepts.hpp"
0021 #include "Acts/Utilities/Delegate.hpp"
0022 
0023 #include <cstddef>
0024 #include <memory>
0025 #include <stdexcept>
0026 #include <string>
0027 #include <unordered_map>
0028 #include <vector>
0029 
0030 namespace Acts {
0031 
0032 class Surface;
0033 
0034 namespace Experimental {
0035 struct NavigationState;
0036 
0037 class Detector : public std::enable_shared_from_this<Detector> {
0038  protected:
0039   /// Create a detector from volumes
0040   ///
0041   /// @param name the detecor name
0042   /// @param rootVolumes the volumes contained by this detector
0043   /// @param detectorVolumeFinder is a Delegate to find the associated volume
0044   ///
0045   /// @note will throw an exception if volumes vector is empty
0046   /// @note will throw an exception if duplicate volume names exist
0047   /// @note will throw an exception if the delegate is not connected
0048   Detector(std::string name,
0049            std::vector<std::shared_ptr<DetectorVolume>> rootVolumes,
0050            ExternalNavigationDelegate detectorVolumeFinder) noexcept(false);
0051 
0052  public:
0053   /// Factory for producing memory managed instances of Detector.
0054   static std::shared_ptr<Detector> makeShared(
0055       std::string name,
0056       std::vector<std::shared_ptr<DetectorVolume>> rootVolumes,
0057       ExternalNavigationDelegate detectorVolumeFinder);
0058 
0059   /// Retrieve a @c std::shared_ptr for this surface (non-const version)
0060   ///
0061   /// @note Will error if this was not created through the @c makeShared factory
0062   ///       since it needs access to the original reference. In C++14 this is
0063   ///       undefined behavior (but most likely implemented as a @c bad_weak_ptr
0064   ///       exception), in C++17 it is defined as that exception.
0065   /// @note Only call this if you need shared ownership of this object.
0066   ///
0067   /// @return The shared pointer
0068   std::shared_ptr<Detector> getSharedPtr();
0069 
0070   /// Retrieve a @c std::shared_ptr for this surface (const version)
0071   ///
0072   /// @note Will error if this was not created through the @c makeShared factory
0073   ///       since it needs access to the original reference. In C++14 this is
0074   ///       undefined behavior, but most likely implemented as a @c bad_weak_ptr
0075   ///       exception, in C++17 it is defined as that exception.
0076   /// @note Only call this if you need shared ownership of this object.
0077   ///
0078   /// @return The shared pointer
0079   std::shared_ptr<const Detector> getSharedPtr() const;
0080 
0081   /// Non-const access to the root volumes
0082   ///
0083   /// @return the root volume shared pointer
0084   std::vector<std::shared_ptr<DetectorVolume>>& rootVolumePtrs();
0085 
0086   /// Const access to the root volumes
0087   ///
0088   /// @return a vector to const DetectorVolume raw pointers
0089   const std::vector<const DetectorVolume*>& rootVolumes() const;
0090 
0091   /// Non-const access to the root volume
0092   ///
0093   /// @return the volumes shared pointer store
0094   std::vector<std::shared_ptr<DetectorVolume>>& volumePtrs();
0095 
0096   /// Const access to sub volumes
0097   ///
0098   /// @return a vector to const DetectorVolume raw pointers
0099   const std::vector<const DetectorVolume*>& volumes() const;
0100 
0101   /// Const access to the hierarchy map of all sensitive surfaces
0102   ///
0103   /// @return the map which can be queried with GeometryID for ranges
0104   const GeometryHierarchyMap<const Surface*>& sensitiveHierarchyMap() const;
0105 
0106   /// @brief Visit all reachable surfaces of the detector
0107   ///
0108   /// @tparam visitor_t Type of the callable visitor
0109   ///
0110   /// @param visitor will be handed to each root volume,
0111   /// eventually contained volumes within the root volumes are
0112   /// handled by the root volume
0113   ///
0114   /// @note if a context is needed for the visit, the vistitor has to provide
0115   /// it, e.g. as a private member
0116   ///
0117   /// @note due to the fact that portals can be shared between volumes, multiple
0118   /// visits may occur, duplicated addressing needs to be taken care of by the
0119   /// visitor
0120   template <ACTS_CONCEPT(SurfaceVisitor) visitor_t>
0121   void visitSurfaces(visitor_t&& visitor) const {
0122     for (const auto& v : rootVolumes()) {
0123       v->template visitSurfaces<visitor_t>(std::forward<visitor_t>(visitor));
0124     }
0125   }
0126 
0127   /// @brief Visit all reachable surfaces of the detector - non-const
0128   ///
0129   /// @tparam visitor_t Type of the callable visitor
0130   ///
0131   /// @param visitor will be handed to each root volume,
0132   /// eventually contained volumes within the root volumes are
0133   /// handled by the root volume
0134   ///
0135   /// @note if a context is needed for the visit, the vistitor has to provide
0136   /// it, e.g. as a private member
0137   ///
0138   /// @note due to the fact that this doesn't run over root volumes, and
0139   /// due to the fact that portals can be shared between volumes, multiple
0140   /// visits may occur, duplicated addressing needs to be taken care of by the
0141   template <ACTS_CONCEPT(MutableSurfaceVisitor) visitor_t>
0142   void visitMutableSurfaces(visitor_t&& visitor) {
0143     for (auto& v : volumePtrs()) {
0144       v->template visitMutableSurfaces<visitor_t>(
0145           std::forward<visitor_t>(visitor));
0146     }
0147   }
0148 
0149   /// @brief Visit all reachable detector volumes of the detector
0150   ///
0151   /// @tparam visitor_t Type of the callable visitor
0152   ///
0153   /// @param visitor will be handed to each root volume,
0154   /// eventually contained volumes within the root volumes are
0155   /// handled by the root volume
0156   ///
0157   /// @note if a context is needed for the visit, the vistitor has to provide
0158   /// it, e.g. as a private member
0159   template <ACTS_CONCEPT(DetectorVolumeVisitor) visitor_t>
0160   void visitVolumes(visitor_t&& visitor) const {
0161     for (const auto& v : rootVolumes()) {
0162       v->template visitVolumes<visitor_t>(std::forward<visitor_t>(visitor));
0163     }
0164   }
0165 
0166   /// @brief Visit all reachable detector volumes of the detector - non-const
0167   ///
0168   /// @tparam visitor_t Type of the callable visitor
0169   ///
0170   /// @param visitor will be handed to each root volume,
0171   /// eventually contained volumes within the root volumes are
0172   /// handled by the root volume
0173   ///
0174   /// @note if a context is needed for the visit, the vistitor has to provide
0175   /// it, e.g. as a private member
0176   ///
0177   /// @note that due to non running over root volumes, multiple visits
0178   /// may occur, duplicated addressing needs to be taken care of by the
0179   /// visitor
0180   template <ACTS_CONCEPT(MutableDetectorVolumeVisitor) visitor_t>
0181   void visitMutableVolumes(visitor_t&& visitor) {
0182     for (const auto& v : volumePtrs()) {
0183       v->template visitMutableVolumes<visitor_t>(
0184           std::forward<visitor_t>(visitor));
0185     }
0186   }
0187 
0188   /// Update the current volume of a given navigation state
0189   ///
0190   /// @param gctx is the Geometry context of the call
0191   /// @param nState [in, out] is the navigation state
0192   ///
0193   void updateDetectorVolume(const GeometryContext& gctx,
0194                             NavigationState& nState) const;
0195 
0196   /// Find a volume from a position
0197   ///
0198   /// @param gctx is the Geometry context of the call
0199   /// @param position is the position of the call
0200   ///
0201   /// @note this creates internally a NavigationState object
0202   ///
0203   /// @return the volume pointer or nullptr (if outside)
0204   const DetectorVolume* findDetectorVolume(const GeometryContext& gctx,
0205                                            const Vector3& position) const;
0206 
0207   /// Find a volume by name
0208   ///
0209   /// @param name with which the volume is searched for
0210   ///
0211   /// @return the volume pointer or nullptr (if not found)
0212   const DetectorVolume* findDetectorVolume(const std::string& name) const;
0213 
0214   /// Update the volume finder
0215   ///
0216   /// @param detectorVolumeFinder the new volume finder
0217   void updateDetectorVolumeFinder(
0218       ExternalNavigationDelegate detectorVolumeFinder);
0219 
0220   /// Const access to the volume finder
0221   const ExternalNavigationDelegate& detectorVolumeFinder() const;
0222 
0223   /// Return the name of the detector
0224   const std::string& name() const;
0225 
0226  private:
0227   /// Name of the detector
0228   std::string m_name;
0229 
0230   /// Root volumes
0231   DetectorVolume::ObjectStore<std::shared_ptr<DetectorVolume>> m_rootVolumes;
0232 
0233   /// Volume store (internal/external)
0234   DetectorVolume::ObjectStore<std::shared_ptr<DetectorVolume>> m_volumes;
0235 
0236   /// A volume finder delegate
0237   ExternalNavigationDelegate m_volumeFinder;
0238 
0239   /// Name/index map to find volumes by name and detect duplicates
0240   std::unordered_map<std::string, std::size_t> m_volumeNameIndex;
0241 
0242   /// Geometry Id hierarchy map of all sensitive surfaces
0243   GeometryHierarchyMap<const Surface*> m_sensitiveHierarchyMap;
0244 };
0245 
0246 }  // namespace Experimental
0247 }  // namespace Acts