|
|
|||
File indexing completed on 2025-12-15 09:42:00
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/Common.hpp" 0013 #include "Acts/Detector/DetectorVolumeVisitorConcept.hpp" 0014 #include "Acts/Detector/Portal.hpp" 0015 #include "Acts/Detector/PortalGenerators.hpp" 0016 #include "Acts/Geometry/Extent.hpp" 0017 #include "Acts/Geometry/GeometryContext.hpp" 0018 #include "Acts/Geometry/GeometryIdentifier.hpp" 0019 #include "Acts/Geometry/VolumeBounds.hpp" 0020 #include "Acts/Material/IVolumeMaterial.hpp" 0021 #include "Acts/Navigation/NavigationDelegates.hpp" 0022 #include "Acts/Navigation/NavigationState.hpp" 0023 #include "Acts/Surfaces/BoundaryTolerance.hpp" 0024 #include "Acts/Surfaces/SurfaceVisitorConcept.hpp" 0025 #include "Acts/Utilities/BoundingBox.hpp" 0026 #include "Acts/Utilities/Delegate.hpp" 0027 #include "Acts/Utilities/Helpers.hpp" 0028 0029 #include <algorithm> 0030 #include <cstddef> 0031 #include <memory> 0032 #include <stdexcept> 0033 #include <string> 0034 #include <utility> 0035 #include <vector> 0036 0037 namespace Acts { 0038 0039 class Surface; 0040 class IVolumeMaterial; 0041 class VolumeBounds; 0042 0043 namespace Experimental { 0044 0045 class DetectorVolume; 0046 class Detector; 0047 0048 /// A detector volume description which can be: 0049 /// 0050 /// @note A detector volume holds non-const objects internally 0051 /// that are allowed to be modified as long as the geometry 0052 /// is not yet closed. Using this, material can be attached, 0053 /// and GeometryIdentifier can be set at construction time. 0054 /// 0055 /// @note The construction of DetectorVolumes is done via a dedicated 0056 /// factory, this is necessary as then the shared_ptr is non-weak and it 0057 /// can be registered in the portal generator for further geometry processing. 0058 /// 0059 /// @note Navigation is always done by plain pointers, while 0060 /// object ownership is done by shared/unique pointers. 0061 class DetectorVolume : public std::enable_shared_from_this<DetectorVolume> { 0062 public: 0063 /// Type alias for axis-aligned bounding box of detector volume 0064 using BoundingBox = 0065 Acts::AxisAlignedBoundingBox<Acts::Experimental::DetectorVolume, double, 0066 3>; 0067 0068 friend class DetectorVolumeFactory; 0069 0070 /// Nested object store that holds the internal (non-const), 0071 /// reference counted objects and provides an external 0072 /// (const raw pointer) access 0073 /// 0074 /// @tparam internal_type is the internal storage representation, 0075 /// has to comply with std::shared_ptr semantics 0076 /// 0077 template <typename internal_type> 0078 struct ObjectStore { 0079 /// The internal storage vector 0080 std::vector<internal_type> internal = {}; 0081 0082 /// The external storage vector, const raw pointer 0083 std::vector<const typename internal_type::element_type*> external = {}; 0084 0085 /// Store constructor 0086 /// 0087 /// @param objects are the ones copied into the internal store 0088 explicit ObjectStore(std::vector<internal_type> objects) 0089 : internal(std::move(objects)) { 0090 external = unpackConstSmartPointers(internal); 0091 } 0092 0093 ObjectStore() = default; 0094 }; 0095 0096 protected: 0097 /// Create a detector volume - with surfaces and/or inserted volumes 0098 /// 0099 /// @param gctx the geometry context while building - for future contextual store 0100 /// @param name the volume name 0101 /// @param transform the transform defining the volume position 0102 /// @param bounds the volume bounds 0103 /// @param surfaces are the contained surfaces of this volume 0104 /// @param volumes are the contains volumes of this volume 0105 /// @param externalNavigation is a Delegate to find the associated volume 0106 /// @param internalNavigation the navigation state updator for surfaces/portals 0107 /// 0108 /// @note throws exception if misconfigured: no bounds 0109 /// @note throws exception if ghe portal general or navigation 0110 /// state updator delegates are not connected 0111 DetectorVolume(const GeometryContext& gctx, std::string name, 0112 const Transform3& transform, 0113 std::shared_ptr<VolumeBounds> bounds, 0114 std::vector<std::shared_ptr<Surface>> surfaces, 0115 std::vector<std::shared_ptr<DetectorVolume>> volumes, 0116 ExternalNavigationDelegate externalNavigation, 0117 InternalNavigationDelegate internalNavigation) noexcept(false); 0118 0119 /// Create a detector volume - empty/gap volume constructor 0120 /// 0121 /// @param gctx the geometry context while building - for future contextual store 0122 /// @param name the volume name 0123 /// @param transform the transform defining the volume position 0124 /// @param bounds the volume bounds 0125 /// @param internalNavigation the navigation state updator for surfaces/portals 0126 /// 0127 /// @note throws exception if misconfigured: no bounds 0128 /// @note throws exception if ghe portal general or navigation 0129 /// state updator delegates are not connected 0130 DetectorVolume(const GeometryContext& gctx, std::string name, 0131 const Transform3& transform, 0132 std::shared_ptr<VolumeBounds> bounds, 0133 InternalNavigationDelegate internalNavigation) noexcept(false); 0134 0135 // === Factory Methods === 0136 0137 /// @fn static std::shared_ptr<DetectorVolume> makeShared(const GeometryContext& gctx, std::string name, const Transform3& transform, std::shared_ptr<VolumeBounds> bounds, std::vector<std::shared_ptr<Surface>> surfaces, std::vector<std::shared_ptr<DetectorVolume>> volumes, ExternalNavigationDelegate externalNavigation, InternalNavigationDelegate internalNavigation) 0138 /// @brief Protected factory method for producing memory managed instances of DetectorVolume. 0139 /// 0140 /// This overload creates a detector volume with full navigation capabilities, 0141 /// supporting both external navigation (to other volumes) and internal 0142 /// navigation (within the volume). It can contain both surfaces and 0143 /// sub-volumes for complex detector hierarchies. 0144 /// 0145 /// @param gctx The geometry context for this call 0146 /// @param name The name of the detector volume 0147 /// @param transform The transform3 object of the volume 0148 /// @param bounds Shared pointer to the volume bounds 0149 /// @param surfaces Vector of shared pointers to surfaces 0150 /// @param volumes Vector of shared pointers to sub-volumes 0151 /// @param externalNavigation The external navigation delegate 0152 /// @param internalNavigation The internal navigation delegate 0153 /// 0154 /// @return A shared pointer to the created detector volume 0155 /// 0156 /// @note This is called by the @class DetectorVolumeFactory 0157 /// @note This is the full-featured factory method for complex detector volumes 0158 /// @note This is a protected static method for controlled object creation 0159 static std::shared_ptr<DetectorVolume> makeShared( 0160 const GeometryContext& gctx, std::string name, 0161 const Transform3& transform, std::shared_ptr<VolumeBounds> bounds, 0162 std::vector<std::shared_ptr<Surface>> surfaces, 0163 std::vector<std::shared_ptr<DetectorVolume>> volumes, 0164 ExternalNavigationDelegate externalNavigation, 0165 InternalNavigationDelegate internalNavigation); 0166 0167 /// @fn static std::shared_ptr<DetectorVolume> makeShared(const GeometryContext& gctx, std::string name, const Transform3& transform, std::shared_ptr<VolumeBounds> bounds, InternalNavigationDelegate internalNavigation) 0168 /// @brief Protected factory method for producing memory managed instances of DetectorVolume. 0169 /// 0170 /// This overload creates a simpler detector volume with only internal 0171 /// navigation capabilities. It is suitable for volumes that don't need 0172 /// to navigate to other volumes or contain complex sub-structures. 0173 /// 0174 /// @param gctx The geometry context for this call 0175 /// @param name The name of the detector volume 0176 /// @param transform The transform3 object of the volume 0177 /// @param bounds Shared pointer to the volume bounds 0178 /// @param internalNavigation The internal navigation delegate 0179 /// 0180 /// @return A shared pointer to the created detector volume 0181 /// 0182 /// @note This is called by the @class DetectorVolumeFactory 0183 /// @note This is the simplified factory method for basic detector volumes 0184 /// @note This is a protected static method for controlled object creation 0185 static std::shared_ptr<DetectorVolume> makeShared( 0186 const GeometryContext& gctx, std::string name, 0187 const Transform3& transform, std::shared_ptr<VolumeBounds> bounds, 0188 InternalNavigationDelegate internalNavigation); 0189 0190 public: 0191 /// Retrieve a @c std::shared_ptr for this surface (non-const version) 0192 /// 0193 /// @note Will error if this was not created through the @c makeShared factory 0194 /// since it needs access to the original reference. In C++14 this is 0195 /// undefined behavior (but most likely implemented as a @c bad_weak_ptr 0196 /// exception), in C++17 it is defined as that exception. 0197 /// @note Only call this if you need shared ownership of this object. 0198 /// 0199 /// @return The shared pointer 0200 std::shared_ptr<DetectorVolume> getSharedPtr(); 0201 0202 /// Retrieve a @c std::shared_ptr for this surface (const version) 0203 /// 0204 /// @note Will error if this was not created through the @c makeShared factory 0205 /// since it needs access to the original reference. In C++14 this is 0206 /// undefined behavior, but most likely implemented as a @c bad_weak_ptr 0207 /// exception, in C++17 it is defined as that exception. 0208 /// @note Only call this if you need shared ownership of this object. 0209 /// 0210 /// @return The shared pointer 0211 std::shared_ptr<const DetectorVolume> getSharedPtr() const; 0212 0213 /// Const access to the transform 0214 /// 0215 /// @param gctx the geometry context 0216 /// 0217 /// @note the geometry context is currently ignored, but 0218 /// is a placeholder for eventually misaligned volumes 0219 /// 0220 /// @return const reference to the contextual transform 0221 const Transform3& transform( 0222 const GeometryContext& gctx = GeometryContext()) const; 0223 0224 /// Const access to the center 0225 /// 0226 /// @param gctx the geometry context 0227 /// 0228 /// @note the geometry context is currently ignored, but 0229 /// is a placeholder for eventually misaligned volumes 0230 /// 0231 /// @return a contextually created center 0232 Vector3 center(const GeometryContext& gctx = GeometryContext()) const; 0233 0234 /// Const access to the volume bounds 0235 /// 0236 /// @return const reference to the volume bounds object 0237 const VolumeBounds& volumeBounds() const; 0238 0239 /// Check if a point is inside this volume. Subvolumes will not be checked. 0240 /// 0241 /// @param gctx the geometry context 0242 /// @param position the position for the inside check 0243 /// 0244 /// @return a bool to indicate inside/outside 0245 bool inside(const GeometryContext& gctx, const Vector3& position) const; 0246 0247 /// Check if a point is exclusively inside this volume i.e. this point is not 0248 /// inside a subvolume. 0249 /// 0250 /// @param gctx the geometry context 0251 /// @param position the position for the inside check 0252 /// 0253 /// @return a bool to indicate inside/outside 0254 bool exclusivelyInside(const GeometryContext& gctx, 0255 const Vector3& position) const; 0256 0257 /// The Extent for this volume 0258 /// 0259 /// @param gctx is the geometry context 0260 /// @param nseg is the number of segments to approximate 0261 /// 0262 /// @return an Extent object 0263 Extent extent(const GeometryContext& gctx, std::size_t nseg = 1) const; 0264 0265 /// Initialize/update the navigation status in this environment 0266 /// 0267 /// This method calls: 0268 /// 0269 /// - the local navigation delegate for candidate surfaces 0270 /// - the portal navigation delegate for candidate exit portals 0271 /// - set the current detector volume 0272 /// 0273 /// @param gctx is the current geometry context 0274 /// @param nState [in,out] is the detector navigation state to be updated 0275 /// 0276 void updateNavigationState(const GeometryContext& gctx, 0277 NavigationState& nState) const; 0278 0279 /// Non-const access to the portals 0280 /// 0281 /// @return the portal shared pointer store 0282 std::vector<std::shared_ptr<Portal>>& portalPtrs(); 0283 0284 /// Non-const access to the surfaces 0285 /// 0286 /// @return the surfaces shared pointer store 0287 std::vector<std::shared_ptr<Surface>>& surfacePtrs(); 0288 0289 /// Non-const access to the volumes 0290 /// 0291 /// @return the volumes shared pointer store 0292 std::vector<std::shared_ptr<DetectorVolume>>& volumePtrs(); 0293 0294 /// Const access to the detector portals 0295 /// 0296 /// @note an empty vector indicates a container volume 0297 /// that has not been properly connected 0298 /// 0299 /// @return a vector to const Portal raw pointers 0300 const std::vector<const Portal*>& portals() const; 0301 0302 /// Const access to the surfaces 0303 /// 0304 /// @note an empty vector indicates either gap volume 0305 /// or container volume, a non-empty vector indicates 0306 /// a layer volume. 0307 /// 0308 /// @return a vector to const Surface raw pointers 0309 const std::vector<const Surface*>& surfaces() const; 0310 0311 /// Const access to sub volumes 0312 /// 0313 /// @note and empty vector indicates this is either a 0314 /// gap volume or a layer volume, in any case it means 0315 /// the volume is on navigation level and the portals 0316 /// need to be connected 0317 /// 0318 /// @return a vector to const DetectorVolume raw pointers 0319 const std::vector<const DetectorVolume*>& volumes() const; 0320 0321 /// Const access to the detector volume updator 0322 /// @return Reference to the external navigation delegate 0323 const ExternalNavigationDelegate& externalNavigation() const; 0324 0325 /// @brief Visit all reachable surfaces of the detector 0326 /// 0327 /// @tparam visitor_t Type of the callable visitor 0328 /// 0329 /// @param visitor will be called for each found surface, 0330 /// it will be handed down to contained volumes and portals 0331 template <SurfaceVisitor visitor_t> 0332 void visitSurfaces(visitor_t&& visitor) const { 0333 for (const auto& s : surfaces()) { 0334 visitor(s); 0335 } 0336 for (const auto& p : portals()) { 0337 p->visitSurface(std::forward<visitor_t>(visitor)); 0338 } 0339 for (const auto& v : volumes()) { 0340 v->visitSurfaces(std::forward<visitor_t>(visitor)); 0341 } 0342 } 0343 0344 /// @brief Visit all reachable surfaces of the detector - non-const 0345 /// 0346 /// @tparam visitor_t Type of the callable visitor 0347 /// 0348 /// @param visitor will be called for each found surface, 0349 /// it will be handed down to contained volumes and portals 0350 template <MutableSurfaceVisitor visitor_t> 0351 void visitMutableSurfaces(visitor_t&& visitor) { 0352 for (auto& s : surfacePtrs()) { 0353 visitor(s.get()); 0354 } 0355 for (auto& p : portalPtrs()) { 0356 p->visitMutableSurface(std::forward<visitor_t>(visitor)); 0357 } 0358 for (auto& v : volumePtrs()) { 0359 v->visitMutableSurfaces(std::forward<visitor_t>(visitor)); 0360 } 0361 } 0362 0363 /// @brief Visit all reachable detector volumes of the detector 0364 /// 0365 /// @tparam visitor_t Type of the callable visitor 0366 /// 0367 /// @param visitor will be handed to each root volume, 0368 /// eventually contained volumes within the root volumes are 0369 /// handled by the root volume 0370 /// 0371 /// @note if a context is needed for the visit, the vistitor has to provide 0372 /// it, e.g. as a private member 0373 template <DetectorVolumeVisitor visitor_t> 0374 void visitVolumes(visitor_t&& visitor) const { 0375 visitor(this); 0376 for (const auto& v : volumes()) { 0377 v->visitVolumes(std::forward<visitor_t>(visitor)); 0378 } 0379 } 0380 0381 /// @brief Visit all reachable detector volumes of the detector - non-const 0382 /// 0383 /// @tparam visitor_t Type of the callable visitor 0384 /// 0385 /// @param visitor will be handed to each root volume, 0386 /// eventually contained volumes within the root volumes are 0387 /// handled by the root volume 0388 /// 0389 /// @note if a context is needed for the visit, the vistitor has to provide 0390 /// it, e.g. as a private member 0391 template <MutableDetectorVolumeVisitor visitor_t> 0392 void visitMutableVolumes(visitor_t&& visitor) { 0393 visitor(this); 0394 for (auto& v : volumePtrs()) { 0395 v->visitMutableVolumes(std::forward<visitor_t>(visitor)); 0396 } 0397 } 0398 0399 /// This method allows to udate the navigation state updator 0400 /// module. 0401 /// 0402 /// @param internalNavigation the new navigation state updator for surfaces 0403 /// @param surfaces the surfaces the new navigation state updator points to 0404 /// @param volumes the volumes the new navigation state updator points to 0405 /// 0406 void assignInternalNavigation( 0407 InternalNavigationDelegate internalNavigation, 0408 const std::vector<std::shared_ptr<Surface>>& surfaces = {}, 0409 const std::vector<std::shared_ptr<DetectorVolume>>& volumes = {}); 0410 0411 /// Const access to the navigation state updator 0412 /// @return Reference to the internal navigation delegate 0413 const InternalNavigationDelegate& internalNavigation() const; 0414 0415 /// Update a portal given a portal index 0416 /// 0417 /// @param portal the portal to be updated 0418 /// @param pIndex the portal index 0419 /// 0420 /// @note throws exception if portal index out of bounds 0421 void updatePortal(std::shared_ptr<Portal> portal, 0422 unsigned int pIndex) noexcept(false); 0423 0424 /// Final closing of portal, i.e. this sets the end of world 0425 void closePortals(); 0426 0427 /// Assign the volume material description 0428 /// 0429 /// This method allows to load a material description during the 0430 /// detector geometry building, and assigning it (potentially multiple) 0431 /// times to detector volumes. 0432 /// 0433 /// @param material Material description associated to this volumw 0434 void assignVolumeMaterial(std::shared_ptr<const IVolumeMaterial> material); 0435 0436 /// Const access to the volume amterial 0437 /// @return Pointer to the volume material, nullptr if none assigned 0438 const IVolumeMaterial* volumeMaterial() const; 0439 0440 /// @return the name of the volume 0441 const std::string& name() const; 0442 0443 /// @return the geometry identifier 0444 const GeometryIdentifier& geometryId() const; 0445 0446 /// Set the geometry identifier 0447 /// @note no checking is done, it will overwrite any existing id 0448 /// 0449 /// @param geoID is the geometry Id that is set to the object 0450 void assignGeometryId(const GeometryIdentifier& geoID); 0451 0452 /// Assign Detector to this volume (for back navigation issues) 0453 /// @param detector the parenting detector class 0454 void assignDetector(const Detector& detector); 0455 0456 /// Const access to the detector 0457 /// @return Pointer to the parent detector, nullptr if none assigned 0458 const Detector* detector() const; 0459 0460 /// Get the bounding box of this detector volume 0461 /// @return Const reference to the bounding box 0462 const BoundingBox& getBoundingBox() const; 0463 0464 private: 0465 /// Internal construction method that calls the portal generator 0466 /// 0467 /// @param gctx the current geometry context object, e.g. alignment 0468 /// @param portalGenerator the generator for portals 0469 /// 0470 /// @note throws exception if provided parameters are inconsistent 0471 void construct(const GeometryContext& gctx, 0472 const PortalGenerator& portalGenerator) noexcept(false); 0473 0474 // Check containment - only in debug mode 0475 /// 0476 /// @param gctx the current geometry context object, e.g. alignment 0477 /// @param nseg is the number of segments to approximate 0478 /// 0479 /// @return a boolean indicating if the objects are properly contained 0480 bool checkContainment(const GeometryContext& gctx, 0481 std::size_t nseg = 1) const; 0482 0483 /// build the bounding box 0484 /// 0485 void createBoundingBox(const GeometryContext& gctx); 0486 0487 /// Name of the volume 0488 std::string m_name = "Unnamed"; 0489 0490 /// Transform to place the bolume 0491 Transform3 m_transform = Transform3::Identity(); 0492 0493 /// Volume boundaries 0494 std::shared_ptr<VolumeBounds> m_bounds = nullptr; 0495 0496 /// Portal store (internal/external) 0497 ObjectStore<std::shared_ptr<Portal>> m_portals; 0498 0499 /// Surface store (internal/external) 0500 ObjectStore<std::shared_ptr<Surface>> m_surfaces; 0501 0502 /// Volume store (internal/external) 0503 ObjectStore<std::shared_ptr<DetectorVolume>> m_volumes; 0504 0505 /// BoundingBox 0506 std::shared_ptr<const BoundingBox> m_boundingBox; 0507 0508 ExternalNavigationDelegate m_externalNavigation; 0509 0510 /// The navigation state updator 0511 InternalNavigationDelegate m_internalNavigation; 0512 0513 /// Volume material (optional) 0514 std::shared_ptr<const IVolumeMaterial> m_volumeMaterial = nullptr; 0515 0516 /// GeometryIdentifier of this volume 0517 GeometryIdentifier m_geometryId{0}; 0518 0519 /// The detector it belongs to 0520 const Detector* m_detector = nullptr; 0521 }; 0522 0523 /// @brief A detector volume factory which first constructs the detector volume 0524 /// and then constructs the portals. This ensures that the std::shared_ptr 0525 /// holding the detector volume is not weak when assigning to the portals. 0526 /// 0527 /// @note Optional containment check is invoked by setting the number 0528 /// of segments nSeg to be greater than 0 0529 class DetectorVolumeFactory { 0530 public: 0531 /// Create a detector volume - from factory 0532 /// @param portalGenerator Generator for volume portals 0533 /// @param gctx Geometry context for construction 0534 /// @param name Name of the detector volume 0535 /// @param transform Volume transformation 0536 /// @param bounds Volume boundaries 0537 /// @param surfaces Collection of surfaces within the volume 0538 /// @param volumes Collection of sub-volumes 0539 /// @param externalNavigation External navigation delegate 0540 /// @param internalNavigation Internal navigation delegate 0541 /// @param nSeg Number of segments for containment check 0542 /// @return Shared pointer to the constructed detector volume 0543 static std::shared_ptr<DetectorVolume> construct( 0544 const PortalGenerator& portalGenerator, const GeometryContext& gctx, 0545 const std::string& name, const Transform3& transform, 0546 std::shared_ptr<VolumeBounds> bounds, 0547 const std::vector<std::shared_ptr<Surface>>& surfaces, 0548 const std::vector<std::shared_ptr<DetectorVolume>>& volumes, 0549 ExternalNavigationDelegate externalNavigation, 0550 InternalNavigationDelegate internalNavigation, int nSeg = -1) { 0551 auto dVolume = DetectorVolume::makeShared( 0552 gctx, name, transform, std::move(bounds), surfaces, volumes, 0553 std::move(externalNavigation), std::move(internalNavigation)); 0554 dVolume->construct(gctx, portalGenerator); 0555 0556 /// Volume extent is constructed from the portals 0557 /// So the surface/subvolume containment 0558 /// check has to happen here 0559 if (nSeg > 0 && !dVolume->checkContainment(gctx, nSeg)) { 0560 throw std::invalid_argument( 0561 "DetectorVolume: surfaces or subvolumes are not contained by volume"); 0562 } 0563 return dVolume; 0564 } 0565 0566 /// Create a detector volume - from factory 0567 /// @param portalGenerator Generator for volume portals 0568 /// @param gctx Geometry context for construction 0569 /// @param name Name of the detector volume 0570 /// @param transform Volume transformation 0571 /// @param bounds Volume boundaries 0572 /// @param internalNavigation Internal navigation delegate 0573 /// @return Shared pointer to the constructed detector volume 0574 static std::shared_ptr<DetectorVolume> construct( 0575 const PortalGenerator& portalGenerator, const GeometryContext& gctx, 0576 std::string name, const Transform3& transform, 0577 std::shared_ptr<VolumeBounds> bounds, 0578 InternalNavigationDelegate internalNavigation) { 0579 auto dVolume = DetectorVolume::makeShared(gctx, std::move(name), transform, 0580 std::move(bounds), 0581 std::move(internalNavigation)); 0582 dVolume->construct(gctx, portalGenerator); 0583 return dVolume; 0584 } 0585 }; 0586 0587 /// Helper extractors: all portals 0588 struct AllPortalsExtractor { 0589 /// Extract the portals from the volume 0590 /// 0591 /// @param gctx the geometry contextfor this extraction call 0592 /// @param nState is the current navigation state 0593 /// 0594 /// @return a vector of raw Portal pointers 0595 inline static const std::vector<const Portal*> extract( 0596 [[maybe_unused]] const GeometryContext& gctx, 0597 const NavigationState& nState) { 0598 if (nState.currentVolume == nullptr) { 0599 throw std::runtime_error( 0600 "AllPortalsExtractor: no detector volume given."); 0601 } 0602 return nState.currentVolume->portals(); 0603 } 0604 }; 0605 0606 /// Helper extractors: all surfaces 0607 struct AllSurfacesExtractor { 0608 /// Extract the surfaces from the volume 0609 /// 0610 /// @param gctx the geometry contextfor this extraction call 0611 /// @param nState is the current navigation state 0612 /// @param indices is an ignored index vector 0613 /// 0614 /// @return a vector of raw Surface pointers 0615 inline static const std::vector<const Surface*> extract( 0616 [[maybe_unused]] const GeometryContext& gctx, 0617 const NavigationState& nState, 0618 [[maybe_unused]] const std::vector<std::size_t>& indices = {}) { 0619 if (nState.currentVolume == nullptr) { 0620 throw std::runtime_error( 0621 "AllSurfacesExtractor: no detector volume given."); 0622 } 0623 return nState.currentVolume->surfaces(); 0624 } 0625 }; 0626 0627 /// Helper extractors: indexed surfaces 0628 struct IndexedSurfacesExtractor { 0629 /// Extract the surfaces from the volume 0630 /// 0631 /// @param gctx the geometry contextfor this extraction call 0632 /// @param nState is the current navigation state 0633 /// @param indices are access indices into the surfaces store 0634 /// 0635 /// @note no out of boudns checking is done 0636 /// 0637 /// @return a vector of raw Surface pointers 0638 inline static const std::vector<const Surface*> extract( 0639 [[maybe_unused]] const GeometryContext& gctx, 0640 const NavigationState& nState, const std::vector<std::size_t>& indices) { 0641 if (nState.currentVolume == nullptr) { 0642 throw std::runtime_error( 0643 "IndexedSurfacesExtractor: no detector volume given."); 0644 } 0645 // Get the surface container 0646 const auto& surfaces = nState.currentVolume->surfaces(); 0647 // The extracted surfaces 0648 std::vector<const Surface*> eSurfaces; 0649 eSurfaces.reserve(indices.size()); 0650 std::ranges::for_each( 0651 indices, [&](const auto& i) { eSurfaces.push_back(surfaces[i]); }); 0652 return eSurfaces; 0653 } 0654 }; 0655 0656 /// Helper extractors: all sub volumes of a volume 0657 struct AllSubVolumesExtractor { 0658 /// Extract the sub volumes from the volume 0659 /// 0660 /// @param gctx the geometry contextfor this extraction call 0661 /// @param nState is the current navigation state 0662 /// @param indices are access indices into the volume store (ignored) 0663 /// 0664 /// @return a vector of raw DetectorVolume pointers 0665 inline static const std::vector<const DetectorVolume*> extract( 0666 [[maybe_unused]] const GeometryContext& gctx, 0667 const NavigationState& nState, 0668 [[maybe_unused]] const std::vector<std::size_t>& indices = {}) { 0669 if (nState.currentVolume == nullptr) { 0670 throw std::runtime_error( 0671 "AllSubVolumesExtractor: no detector volume given."); 0672 } 0673 return nState.currentVolume->volumes(); 0674 } 0675 }; 0676 0677 /// Helper extractors: indexed sub volume of a volume 0678 struct IndexedSubVolumesExtractor { 0679 /// Extract the sub volumes from the volume 0680 /// 0681 /// @param gctx the geometry contextfor this extraction call 0682 /// @param nState is the current navigation state 0683 /// @param indices are access indices into the volume store 0684 /// 0685 /// @return a vector of raw DetectorVolume pointers 0686 inline static const std::vector<const DetectorVolume*> extract( 0687 [[maybe_unused]] const GeometryContext& gctx, 0688 const NavigationState& nState, const std::vector<std::size_t>& indices) { 0689 if (nState.currentVolume == nullptr) { 0690 throw std::runtime_error( 0691 "AllSubVolumesExtractor: no detector volume given."); 0692 } 0693 // Get the sub volumes container 0694 const auto& volumes = nState.currentVolume->volumes(); 0695 // The extracted volumes 0696 std::vector<const DetectorVolume*> eVolumes; 0697 eVolumes.reserve(indices.size()); 0698 std::ranges::for_each( 0699 indices, [&](const auto& i) { eVolumes.push_back(volumes[i]); }); 0700 return eVolumes; 0701 } 0702 }; 0703 0704 } // namespace Experimental 0705 } // namespace Acts
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|