Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 07:52:26

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/Geometry/BoundarySurfaceFace.hpp"
0013 #include "Acts/Geometry/BoundarySurfaceT.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Geometry/GeometryIdentifier.hpp"
0016 #include "Acts/Geometry/Layer.hpp"
0017 #include "Acts/Geometry/Portal.hpp"
0018 #include "Acts/Geometry/TrackingGeometryVisitor.hpp"
0019 #include "Acts/Geometry/TrackingVolumeVisitorConcept.hpp"
0020 #include "Acts/Geometry/Volume.hpp"
0021 #include "Acts/Material/IVolumeMaterial.hpp"
0022 #include "Acts/Navigation/NavigationDelegate.hpp"
0023 #include "Acts/Navigation/NavigationStream.hpp"
0024 #include "Acts/Surfaces/Surface.hpp"
0025 #include "Acts/Surfaces/SurfaceVisitorConcept.hpp"
0026 #include "Acts/Utilities/BinnedArray.hpp"
0027 #include "Acts/Utilities/Logger.hpp"
0028 #include "Acts/Utilities/TransformRange.hpp"
0029 #include "Acts/Visualization/ViewConfig.hpp"
0030 
0031 #include <cstddef>
0032 #include <memory>
0033 #include <string>
0034 #include <unordered_map>
0035 #include <utility>
0036 #include <vector>
0037 
0038 #include <boost/container/container_fwd.hpp>
0039 
0040 namespace Acts {
0041 
0042 class GlueVolumesDescriptor;
0043 class VolumeBounds;
0044 template <typename object_t>
0045 struct NavigationOptions;
0046 class IMaterialDecorator;
0047 class ISurfaceMaterial;
0048 class IVolumeMaterial;
0049 class Surface;
0050 class TrackingVolume;
0051 struct GeometryIdentifierHook;
0052 class Portal;
0053 class INavigationPolicy;
0054 
0055 /// Interface types of the Gen1 geometry model
0056 /// @note This interface is being replaced, and is subject to removal
0057 /// @{
0058 
0059 // master typedefs
0060 using TrackingVolumePtr = std::shared_ptr<const TrackingVolume>;
0061 using MutableTrackingVolumePtr = std::shared_ptr<TrackingVolume>;
0062 
0063 using TrackingVolumeBoundaryPtr =
0064     std::shared_ptr<const BoundarySurfaceT<TrackingVolume>>;
0065 using TrackingVolumeBoundaries = std::vector<TrackingVolumeBoundaryPtr>;
0066 
0067 // possible contained
0068 using TrackingVolumeArray = BinnedArray<TrackingVolumePtr>;
0069 using TrackingVolumeVector = std::vector<TrackingVolumePtr>;
0070 using MutableTrackingVolumeVector = std::vector<MutableTrackingVolumePtr>;
0071 using LayerArray = BinnedArray<LayerPtr>;
0072 using LayerVector = std::vector<LayerPtr>;
0073 
0074 /// Intersection with @c Layer
0075 using LayerIntersection = std::pair<SurfaceIntersection, const Layer*>;
0076 /// Multi-intersection with @c Layer
0077 using LayerMultiIntersection =
0078     std::pair<SurfaceMultiIntersection, const Layer*>;
0079 
0080 /// BoundarySurface of a volume
0081 using BoundarySurface = BoundarySurfaceT<TrackingVolume>;
0082 /// Intersection with a @c BoundarySurface
0083 using BoundaryIntersection =
0084     std::pair<SurfaceIntersection, const BoundarySurface*>;
0085 /// Multi-intersection with a @c BoundarySurface
0086 using BoundaryMultiIntersection =
0087     std::pair<SurfaceMultiIntersection, const BoundarySurface*>;
0088 
0089 /// @}
0090 
0091 /// @class TrackingVolume
0092 ///
0093 /// Full Volume description used in Tracking,
0094 /// it inherits from Volume to get the geometrical structure.
0095 ///
0096 ///     A TrackingVolume at navigation level can provide the (layer) material
0097 /// information / internal navigation with in
0098 ///     5 different ways:
0099 ///
0100 ///         --- a) Static confinement of Layers
0101 ///         --- b) detached sub volumes
0102 ///         --- b) unordered (arbitrarily oriented) layers
0103 ///         --- d) unordered sub volumes
0104 ///         --- e) unordered layers AND unordered subvolumes
0105 ///
0106 ///    The TrackingVolume can also be a simple container of other
0107 ///    TrackingVolumes
0108 ///
0109 /// In addition it is capable of holding a subarray of Layers and
0110 /// TrackingVolumes.
0111 ///
0112 class TrackingVolume : public Volume {
0113   friend class TrackingGeometry;
0114 
0115  public:
0116   TrackingVolume() = delete;
0117   ~TrackingVolume() override;
0118   TrackingVolume(const TrackingVolume&) = delete;
0119   TrackingVolume& operator=(const TrackingVolume&) = delete;
0120   TrackingVolume(TrackingVolume&&) noexcept;
0121   TrackingVolume& operator=(TrackingVolume&&) noexcept;
0122 
0123   /// Constructor for a container Volume
0124   /// - vacuum filled volume either as a for other tracking volumes
0125   ///
0126   /// @param transform is the global 3D transform to position the volume in
0127   /// space
0128   /// @param volbounds is the description of the volume boundaries
0129   /// @param volumeName is a string identifier
0130   TrackingVolume(const Transform3& transform,
0131                  std::shared_ptr<VolumeBounds> volbounds,
0132                  const std::string& volumeName = "undefined");
0133 
0134   /// Constructor for a full equipped Tracking Volume
0135   ///
0136   /// @param transform is the global 3D transform to position the volume in
0137   /// space
0138   /// @param volumeBounds is the description of the volume boundaries
0139   /// @param volumeMaterial is are materials of the tracking volume
0140   /// @param staticLayerArray is the confined layer array (optional)
0141   /// @param containedVolumeArray are the sub volumes if the volume is a
0142   /// container
0143   /// @param denseVolumeVector  The contained dense volumes
0144   /// @param volumeName is a string identifier
0145   TrackingVolume(
0146       const Transform3& transform, std::shared_ptr<VolumeBounds> volumeBounds,
0147       std::shared_ptr<const IVolumeMaterial> volumeMaterial,
0148       std::unique_ptr<const LayerArray> staticLayerArray = nullptr,
0149       std::shared_ptr<const TrackingVolumeArray> containedVolumeArray = nullptr,
0150       MutableTrackingVolumeVector denseVolumeVector = {},
0151       const std::string& volumeName = "undefined");
0152 
0153   /// Constructor from a regular volume
0154   /// @param volume is the volume to be converted
0155   /// @param volumeName is a string identifier
0156   explicit TrackingVolume(Volume& volume,
0157                           const std::string& volumeName = "undefined");
0158 
0159   /// Return the associated sub Volume, returns THIS if no subVolume exists
0160   /// @param gctx The current geometry context object, e.g. alignment
0161   /// @param position is the global position associated with that search
0162   /// @param tol Search position tolerance for dense volumes
0163   ///
0164   /// @return plain pointer to associated with the position
0165   const TrackingVolume* lowestTrackingVolume(const GeometryContext& gctx,
0166                                              const Vector3& position,
0167                                              const double tol = 0.) const;
0168 
0169   /// @brief Visit all reachable surfaces
0170   ///
0171   /// @tparam visitor_t Type of the callable visitor
0172   ///
0173   /// @param visitor The callable. Will be called for each reachable surface
0174   /// that is found, a selection of the surfaces can be done in the visitor
0175   /// @param restrictToSensitives If true, only sensitive surfaces are visited
0176   ///
0177   /// @note If a context is needed for the visit, the vistitor has to provide
0178   /// this, e.g. as a private member
0179   template <SurfaceVisitor visitor_t>
0180   void visitSurfaces(visitor_t&& visitor, bool restrictToSensitives) const {
0181     apply([&visitor, restrictToSensitives](const Surface& surface) {
0182       if (restrictToSensitives && surface.geometryId().sensitive() == 0) {
0183         return;
0184       }
0185       visitor(&surface);
0186     });
0187   }
0188 
0189   /// @brief Visit all sensitive surfaces
0190   ///
0191   /// @tparam visitor_t Type of the callable visitor
0192   ///
0193   /// @param visitor The callable. Will be called for each sensitive surface
0194   /// that is found, a selection of the surfaces can be done in the visitor
0195   ///
0196   /// @note If a context is needed for the visit, the vistitor has to provide
0197   /// this, e.g. as a private member
0198   template <SurfaceVisitor visitor_t>
0199   void visitSurfaces(visitor_t&& visitor) const {
0200     visitSurfaces(std::forward<visitor_t>(visitor), true);
0201   }
0202 
0203   /// @brief Visit all reachable tracking volumes
0204   ///
0205   /// @tparam visitor_t Type of the callable visitor
0206   ///
0207   /// @param visitor The callable. Will be called for each reachable volume
0208   /// that is found, a selection of the volumes can be done in the visitor
0209   ///
0210   /// @note If a context is needed for the visit, the vistitor has to provide
0211   /// this, e.g. as a private member
0212   template <TrackingVolumeVisitor visitor_t>
0213   void visitVolumes(visitor_t&& visitor) const {
0214     apply([&visitor](const TrackingVolume& volume) { visitor(&volume); });
0215   }
0216 
0217   /// @brief Apply a visitor to the tracking volume
0218   ///
0219   /// @param visitor The visitor to apply
0220   ///
0221   void apply(TrackingGeometryVisitor& visitor) const;
0222 
0223   /// @brief Apply a mutable visitor to the tracking volume
0224   ///
0225   /// @param visitor The visitor to apply
0226   ///
0227   void apply(TrackingGeometryMutableVisitor& visitor);
0228 
0229   /// @brief Apply an arbitrary callable as a visitor to the tracking volume
0230   ///
0231   /// @param callable The callable to apply
0232   ///
0233   /// @note The visitor can be overloaded on any of the arguments that
0234   ///       the methods in @c TrackingGeometryVisitor receive.
0235   template <typename Callable>
0236   void apply(Callable&& callable)
0237     requires(detail::callableWithAnyMutable<Callable>() &&
0238              !detail::callableWithAnyConst<Callable>())
0239   {
0240     detail::TrackingGeometryLambdaMutableVisitor visitor{
0241         std::forward<Callable>(callable)};
0242     apply(visitor);
0243   }
0244 
0245   /// @brief Apply an arbitrary callable as a visitor to the tracking volume
0246   ///
0247   /// @param callable The callable to apply
0248   ///
0249   /// @note The visitor can be overloaded on any of the arguments that
0250   ///       the methods in @c TrackingGeometryMutableVisitor receive.
0251   template <typename Callable>
0252   void apply(Callable&& callable) const
0253     requires(detail::callableWithAnyConst<Callable>())
0254   {
0255     detail::TrackingGeometryLambdaVisitor visitor{
0256         std::forward<Callable>(callable)};
0257     apply(visitor);
0258   }
0259 
0260   /// Returns the VolumeName - for debug reason, might be depreciated later
0261   const std::string& volumeName() const;
0262 
0263   /// Set the volume name to @p volumeName
0264   /// @param volumeName is the new name of
0265   void setVolumeName(const std::string& volumeName);
0266 
0267   /// Return the material of the volume
0268   const IVolumeMaterial* volumeMaterial() const;
0269 
0270   /// Return the material of the volume as shared pointer
0271   const std::shared_ptr<const IVolumeMaterial>& volumeMaterialPtr() const;
0272 
0273   /// Set the volume material description
0274   ///
0275   /// The material is usually derived in a complicated way and loaded from
0276   /// a framework given source. As various volumes could potentially share the
0277   /// the same material description, it is provided as a shared object
0278   ///
0279   /// @param material Material description of this volume
0280   void assignVolumeMaterial(std::shared_ptr<const IVolumeMaterial> material);
0281 
0282   /// Return the MotherVolume - if it exists
0283   const TrackingVolume* motherVolume() const;
0284 
0285   /// Return the MotherVolume - if it exists
0286   TrackingVolume* motherVolume();
0287 
0288   /// Set the MotherVolume
0289   ///
0290   /// @param mvol is the mother volume
0291   void setMotherVolume(TrackingVolume* mvol);
0292 
0293   using MutableVolumeRange =
0294       detail::TransformRange<detail::Dereference,
0295                              std::vector<std::unique_ptr<TrackingVolume>>>;
0296   using VolumeRange = detail::TransformRange<
0297       detail::ConstDereference,
0298       const std::vector<std::unique_ptr<TrackingVolume>>>;
0299 
0300   /// Return all volumes registered under this tracking volume
0301   /// @return the range of volumes
0302   VolumeRange volumes() const;
0303 
0304   /// Return mutable view of the registered volumes under this tracking volume
0305   /// @return the range of volumes
0306   MutableVolumeRange volumes();
0307 
0308   using MutablePortalRange =
0309       detail::TransformRange<detail::Dereference,
0310                              std::vector<std::shared_ptr<Portal>>>;
0311 
0312   using PortalRange =
0313       detail::TransformRange<detail::ConstDereference,
0314                              const std::vector<std::shared_ptr<Portal>>>;
0315 
0316   /// Return all portals registered under this tracking volume
0317   /// @return the range of portals
0318   PortalRange portals() const;
0319 
0320   /// Return mutable view of the registered portals under this tracking volume
0321   /// @return the range of portals
0322   MutablePortalRange portals();
0323 
0324   /// Add a portal to this tracking volume
0325   /// @param portal The portal to add
0326   void addPortal(std::shared_ptr<Portal> portal);
0327 
0328   using MutableSurfaceRange =
0329       detail::TransformRange<detail::Dereference,
0330                              std::vector<std::shared_ptr<Surface>>>;
0331   using SurfaceRange =
0332       detail::TransformRange<detail::ConstDereference,
0333                              const std::vector<std::shared_ptr<Surface>>>;
0334 
0335   /// Return all surfaces registered under this tracking volume
0336   /// @return the range of surfaces
0337   SurfaceRange surfaces() const;
0338 
0339   /// Return mutable view of the registered surfaces under this tracking volume
0340   /// @return the range of surfaces
0341   MutableSurfaceRange surfaces();
0342 
0343   /// Add a surface to this tracking volume
0344   /// @param surface The surface to add
0345   void addSurface(std::shared_ptr<Surface> surface);
0346 
0347   /// Add a child volume to this tracking volume
0348   /// @param volume The volume to add
0349   /// @note The @p volume will have its mother volume assigned to @p this.
0350   ///       It will throw if @p volume already has a mother volume set
0351   /// @return Reference to the added volume
0352   TrackingVolume& addVolume(std::unique_ptr<TrackingVolume> volume);
0353 
0354   /// Interface of @c TrackingVolume in the Gen1 geometry model
0355   /// @note This interface is being replaced, and is subject to removal
0356   ///
0357   /// @{
0358 
0359   /// Return the associated Layer to the global position
0360   ///
0361   /// @param gctx The current geometry context object, e.g. alignment
0362   /// @param position is the associated global position
0363   ///
0364   /// @return plain pointer to layer object
0365   const Layer* associatedLayer(const GeometryContext& gctx,
0366                                const Vector3& position) const;
0367 
0368   /// @brief Resolves the volume into (compatible) Layers
0369   ///
0370   /// This is the method for the propagator/extrapolator
0371   /// @tparam options_t Type of navigation options object for decomposition
0372   ///
0373   /// @param gctx The current geometry context object, e.g. alignment
0374   /// @param position Position for the search
0375   /// @param direction Direction for the search
0376   /// @param options The templated navigation options
0377   ///
0378   /// @return vector of compatible intersections with layers
0379   boost::container::small_vector<LayerIntersection, 10> compatibleLayers(
0380       const GeometryContext& gctx, const Vector3& position,
0381       const Vector3& direction, const NavigationOptions<Layer>& options) const;
0382 
0383   /// @brief Returns all boundary surfaces sorted by the user.
0384   ///
0385   /// @tparam options_t Type of navigation options object for decomposition
0386   /// @tparam sorter_t Type of the boundary surface sorter
0387   ///
0388   /// @param gctx The current geometry context object, e.g. alignment
0389   /// @param position The position for searching
0390   /// @param direction The direction for searching
0391   /// @param options The templated navigation options
0392   /// @param logger A @c Logger instance
0393   ///
0394   /// @return is the templated boundary intersection
0395   boost::container::small_vector<BoundaryIntersection, 4> compatibleBoundaries(
0396       const GeometryContext& gctx, const Vector3& position,
0397       const Vector3& direction, const NavigationOptions<Surface>& options,
0398       const Logger& logger = getDummyLogger()) const;
0399 
0400   /// Return the confined static layer array - if it exists
0401   /// @return the BinnedArray of static layers if exists
0402   const LayerArray* confinedLayers() const;
0403 
0404   /// Return the confined volumes of this container array - if it exists
0405   std::shared_ptr<const TrackingVolumeArray> confinedVolumes() const;
0406 
0407   /// Return the confined dense volumes
0408   const MutableTrackingVolumeVector denseVolumes() const;
0409 
0410   /// Method to return the BoundarySurfaces
0411   const TrackingVolumeBoundaries& boundarySurfaces() const;
0412 
0413   /// Set the boundary surface material description
0414   ///
0415   /// The material is usually derived in a complicated way and loaded from
0416   /// a framework given source. As various volumes could potentially share the
0417   /// the same material description, it is provided as a shared object
0418   ///
0419   /// @param surfaceMaterial Material description of this volume
0420   /// @param bsFace Specifies which boundary surface to assign the material to
0421   void assignBoundaryMaterial(
0422       std::shared_ptr<const ISurfaceMaterial> surfaceMaterial,
0423       BoundarySurfaceFace bsFace);
0424 
0425   /// Glue another tracking volume to this one
0426   ///  - if common face is set the glued volumes are sharing the boundary, down
0427   /// to the last navigation volume
0428   ///
0429   /// @param gctx The current geometry context object, e.g. alignment
0430   /// @param bsfMine is the boundary face indicater where to glue
0431   /// @param neighbor is the TrackingVolume to be glued
0432   /// @param bsfNeighbor is the boundary surface of the neighbor
0433   void glueTrackingVolume(const GeometryContext& gctx,
0434                           BoundarySurfaceFace bsfMine, TrackingVolume* neighbor,
0435                           BoundarySurfaceFace bsfNeighbor);
0436 
0437   /// Glue another tracking volume to this one
0438   ///  - if common face is set the glued volumes are sharing the boundary, down
0439   /// to the last navigation volume
0440   ///
0441   /// @param gctx The current geometry context object, e.g. alignment
0442   /// @param bsfMine is the boundary face indicater where to glue
0443   /// @param neighbors are the TrackingVolumes to be glued
0444   /// @param bsfNeighbor are the boundary surface of the neighbors
0445   void glueTrackingVolumes(
0446       const GeometryContext& gctx, BoundarySurfaceFace bsfMine,
0447       const std::shared_ptr<TrackingVolumeArray>& neighbors,
0448       BoundarySurfaceFace bsfNeighbor);
0449 
0450   /// Provide a new BoundarySurface from the glueing
0451   ///
0452   /// @param bsf is the boundary face indicater where to glue
0453   /// @param bs is the new boundary surface
0454   /// @param checkmaterial is a flag how to deal with material, if true:
0455   /// - if the old boundary surface had a material description
0456   ///   but the new one has not, keep the current one
0457   /// - in all other cases just assign the new boundary surface
0458   void updateBoundarySurface(
0459       BoundarySurfaceFace bsf,
0460       std::shared_ptr<const BoundarySurfaceT<TrackingVolume>> bs,
0461       bool checkmaterial = true);
0462 
0463   /// Register the outside glue volumes -
0464   /// ordering is in the TrackingVolume Frame:
0465   ///  - negativeFaceXY
0466   ///  - (faces YZ, ZY, radial faces)
0467   ///  - positiveFaceXY
0468   ///
0469   /// @param gvd register a new GlueVolumeDescriptor
0470   void registerGlueVolumeDescriptor(std::unique_ptr<GlueVolumesDescriptor> gvd);
0471 
0472   /// Clear boundary surfaces for this tracking volume
0473   void clearBoundarySurfaces();
0474 
0475   /// Register the outside glue volumes -
0476   /// ordering is in the TrackingVolume Frame:
0477   ///  - negativeFaceXY
0478   ///  - (faces YZ, ZY, radial faces)
0479   ///  - positiveFaceXY
0480   GlueVolumesDescriptor& glueVolumesDescriptor();
0481 
0482   /// Produces a 3D visualization of this tracking volume
0483   /// @param helper The visualization helper describing the output format
0484   /// @param gctx The geometry context
0485   /// @param viewConfig The view configuration
0486   /// @param portalViewConfig View configuration for portals
0487   /// @param sensitiveViewConfig View configuration for sensitive surfaces
0488   void visualize(IVisualization3D& helper, const GeometryContext& gctx,
0489                  const ViewConfig& viewConfig,
0490                  const ViewConfig& portalViewConfig,
0491                  const ViewConfig& sensitiveViewConfig) const;
0492 
0493   /// Register a navigation policy with this volume. The argument can not be
0494   /// nullptr.
0495   /// @param policy is the navigation policy to be registered
0496   void setNavigationPolicy(std::unique_ptr<INavigationPolicy> policy);
0497 
0498   /// Populate the navigation stream with navigation candidates from this
0499   /// volume. Internally, this consults the registered navigation policy, where
0500   /// the default is a noop.
0501   /// @param args are the navigation arguments
0502   /// @param stream is the navigation stream to be updated
0503   /// @param logger is the logger
0504   void initializeNavigationCandidates(const NavigationArguments& args,
0505                                       AppendOnlyNavigationStream& stream,
0506                                       const Logger& logger) const;
0507 
0508  private:
0509   void connectDenseBoundarySurfaces(
0510       MutableTrackingVolumeVector& confinedDenseVolumes);
0511 
0512   /// interlink the layers in this TrackingVolume
0513   void interlinkLayers();
0514 
0515   /// Create Boundary Surface
0516   void createBoundarySurfaces();
0517 
0518   /// method to synchronize the layers with potentially updated volume bounds:
0519   /// - adapts the layer dimensions to the new volumebounds + envelope
0520   ///
0521   /// @param envelope is the clearance between volume boundary and layer
0522   void synchronizeLayers(double envelope = 1.) const;
0523 
0524   // the boundary surfaces
0525   std::vector<TrackingVolumeBoundaryPtr> m_boundarySurfaces;
0526 
0527   ///(a) static configuration ordered by Binned arrays
0528   /// static layers
0529   std::unique_ptr<const LayerArray> m_confinedLayers = nullptr;
0530 
0531   /// Array of Volumes inside the Volume when acting as container
0532   std::shared_ptr<const TrackingVolumeArray> m_confinedVolumes = nullptr;
0533 
0534   /// confined dense
0535   MutableTrackingVolumeVector m_confinedDenseVolumes;
0536 
0537   /// Volumes to glue Volumes from the outside
0538   std::unique_ptr<GlueVolumesDescriptor> m_glueVolumeDescriptor{nullptr};
0539 
0540   /// @}
0541 
0542  private:
0543   /// The volume based material the TrackingVolume consists of
0544   std::shared_ptr<const IVolumeMaterial> m_volumeMaterial{nullptr};
0545 
0546   /// Remember the mother volume
0547   TrackingVolume* m_motherVolume{nullptr};
0548 
0549   /// Volume name for debug reasons & screen output
0550   std::string m_name;
0551 
0552   std::vector<std::unique_ptr<TrackingVolume>> m_volumes;
0553   std::vector<std::shared_ptr<Portal>> m_portals;
0554   std::vector<std::shared_ptr<Surface>> m_surfaces;
0555 
0556   std::unique_ptr<INavigationPolicy> m_navigationPolicy;
0557 
0558   NavigationDelegate m_navigationDelegate{};
0559 };
0560 
0561 }  // namespace Acts