Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:23:51

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/BlueprintOptions.hpp"
0013 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0014 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0015 #include "Acts/Geometry/GeometryContext.hpp"
0016 #include "Acts/Geometry/NavigationPolicyFactory.hpp"
0017 #include "Acts/Utilities/AxisDefinitions.hpp"
0018 #include "Acts/Utilities/Logger.hpp"
0019 #include "Acts/Utilities/TransformRange.hpp"
0020 
0021 #include <iosfwd>
0022 #include <memory>
0023 #include <string>
0024 #include <vector>
0025 
0026 namespace Acts {
0027 
0028 class Volume;
0029 class TrackingVolume;
0030 class VolumeBounds;
0031 class PortalShellBase;
0032 
0033 namespace Experimental {
0034 
0035 class MaterialDesignatorBlueprintNode;
0036 class StaticBlueprintNode;
0037 class LayerBlueprintNode;
0038 class GeometryIdentifierBlueprintNode;
0039 
0040 class CylinderContainerBlueprintNode;
0041 class CuboidContainerBlueprintNode;
0042 
0043 /// Base class for all nodes in the blueprint tree. This class defines the
0044 /// three-phase construction process. The three phases are
0045 ///
0046 /// -# **Build**: Construct volume representation + compute final sizing
0047 /// -# **Connect**: Create and connect portals at volume boundaries
0048 /// -# **Finalize**: Register portals with volumes + create acceleration
0049 ///    structures
0050 ///
0051 /// During the *build* phase, the `build` method of all nodes in the tree are
0052 /// called recursively. Some nodes, like @ref Acts::Experimental::ContainerBlueprintNode,
0053 /// will take action on the volumes returns from its children, and perform
0054 /// sizing to connect them. See the @ref Acts::Experimental::ContainerBlueprintNode
0055 /// and @ref Acts::CylinderVolumeStack documentation for details on how the
0056 /// sizing is carried out.
0057 class BlueprintNode {
0058  public:
0059   /// Virtual destructor to ensure correct cleanup
0060   virtual ~BlueprintNode() = default;
0061 
0062   /// Get the name of this node
0063   /// @return Reference to the node name string
0064   virtual const std::string& name() const = 0;
0065 
0066   /// @anchor construction
0067   /// @name Construction methods
0068   /// These methods constitute the primary interface of the node that
0069   /// participates in the geometry construction.
0070   /// @{
0071 
0072   /// This method is called during the *build* phase of the blueprint tree
0073   /// construction. It returns a single @ref Acts::Volume which represents transform
0074   /// and bounds of the entire subtree. This does not have to correspond to the
0075   /// final @ref Acts::TrackingVolume, some node types will produce temporary volume
0076   /// representations. Lifetime of the returned volume is managed by the source
0077   /// node!
0078   /// Nodes higher in the hierarchy will issue resizes down the tree hierarchy.
0079   /// This is not done through a direct hierarchy, but coordinated by the
0080   /// respective node type, by internally consulting its children.
0081   ///
0082   /// @note Generally, you should not need to to call this method directly.
0083   ///       The construction should usually be done through the special
0084   ///       @ref Acts::Experimental::Blueprint class.
0085   ///
0086   /// @param options The global construction options
0087   /// @param gctx The geometry context for construction (usually nominal)
0088   /// @param logger The logger to use for output during construction
0089   /// @return The volume used for communicating transform and size up the hierarchy
0090   virtual Volume& build(const BlueprintOptions& options,
0091                         const GeometryContext& gctx,
0092                         const Logger& logger = Acts::getDummyLogger()) = 0;
0093 
0094   /// This method is called during the *connect* phase. This phase handles the
0095   /// creation and connection of *portals* (instances of @ref Acts::PortalLinkBase).
0096   /// After the build-phase has completed, the volume sizes are **final**. Each
0097   /// node will consult its fully sized volume to produce *boundary surfaces*.
0098   /// Each boundary surface is then turned into a @ref Acts::TrivialPortalLink, which
0099   /// in turn produces a one-sided portal (see @ref Acts::Portal documentation)
0100   ///
0101   /// Some nodes (like @ref Acts::Experimental::ContainerBlueprintNode) will take action on
0102   /// their children, and unify the connected portals.
0103   ///
0104   /// After a node's processing has completed, it returns a reference to a @ref
0105   /// Acts::PortalShellBase, which represents a set of portals in a specific
0106   /// geometry arrangement. The returned object lifetime is managed by the
0107   /// returning node.
0108   ///
0109   /// @param options The global construction options
0110   /// @param gctx The geometry context for construction (usually nominal)
0111   /// @param logger The logger to use for output during construction
0112   /// @return Reference to portal shell containing connected portals for this node
0113   virtual PortalShellBase& connect(
0114       const BlueprintOptions& options, const GeometryContext& gctx,
0115       const Logger& logger = Acts::getDummyLogger()) = 0;
0116 
0117   /// This method is called during the *finalize* phase. This phase handles:
0118   ///
0119   /// - Registering portals into their final volumes
0120   /// - Registering volumes into their parents
0121   /// - Creating navigation policies
0122   /// - (In future) Handle geometry identification assignment
0123   ///
0124   /// At the end of this phase, each node will have transferred any temporary
0125   /// resources created during the build, that need to be retained, into the
0126   /// final @ref Acts::TrackingGeometry, and can be safely destroyed.
0127   ///
0128   /// @note The @p parent for volumes, portals, etc to be registered in is passed in **as an
0129   ///       argument**, rather than being implicitly determined from the
0130   ///       **parent node**. This is done so that nodes can remove themselves
0131   ///       from the final volume hierarchy, like container nodes or the
0132   ///       @ref Acts::Experimental::MaterialDesignatorBlueprintNode.
0133   ///
0134   /// @param options The global construction options
0135   /// @param gctx The geometry context for construction (usually nominal)
0136   /// @param parent The parent volume to register in
0137   /// @param logger The logger to use for output during construction
0138   virtual void finalize(const BlueprintOptions& options,
0139                         const GeometryContext& gctx, TrackingVolume& parent,
0140                         const Logger& logger = Acts::getDummyLogger()) = 0;
0141 
0142   /// @}
0143 
0144   /// @anchor convenience
0145   /// @name Convenience methods
0146   /// These methods are meant to make the construction of a blueprint tree in
0147   /// code more ergonomic.
0148   /// They usually take an optional `callback` parameter. The primary use for
0149   /// this parameter is structural, as it facilitates introducing scopes to
0150   /// indicate in code that objects are nested.
0151   ///
0152   /// ```cpp
0153   /// Blueprint::Config cfg;
0154   /// auto root = std::make_unique<Blueprint>(cfg);
0155   /// root->addStaticVolume(
0156   ///     base, std::make_shared<CylinderVolumeBounds>(50_mm, 400_mm, 1000_mm),
0157   ///     "PixelWrapper", [&](auto& wrapper) {
0158   ///         // This scope can be used to equip `wrapper`
0159   ///     });
0160   /// ```
0161   ///
0162   /// Alternatively, they can also be used without a callback, as the newly
0163   /// created node is also returned by reference:
0164   ///
0165   /// ```
0166   /// auto& wrapper = root->addStaticVolume(
0167   ///     base, std::make_shared<CylinderVolumeBounds>(50_mm, 400_mm, 1000_mm),
0168   ///     "PixelWrapper");
0169   /// ```
0170   ///
0171   /// In both cases, it's not necessary to register the newly created node
0172   /// with a parent node.
0173   ///
0174   /// @{
0175 
0176   /// This method creates a new @ref Acts::Experimental::StaticBlueprintNode wrapping @p
0177   /// volume and adds it to this node as a child.
0178   /// @param volume The volume to add
0179   /// @param callback An optional callback that receives the node as an argument
0180   /// @return A reference to the created node
0181   StaticBlueprintNode& addStaticVolume(
0182       std::unique_ptr<TrackingVolume> volume,
0183       const std::function<void(StaticBlueprintNode& cylinder)>& callback = {});
0184 
0185   /// Alternative overload for creating a @ref Acts::Experimental::StaticBlueprintNode. This
0186   /// overload will invoke the constructor of @ref Acts::TrackingVolume and use
0187   /// that volume to create the node.
0188   /// @param transform The transform of the volume
0189   /// @param volumeBounds The bounds of the volume
0190   /// @param volumeName The name of the volume
0191   /// @param callback An optional callback that receives the node as an argument
0192   /// @return Reference to the newly created static blueprint node
0193   StaticBlueprintNode& addStaticVolume(
0194       const Transform3& transform, std::shared_ptr<VolumeBounds> volumeBounds,
0195       const std::string& volumeName = "undefined",
0196       const std::function<void(StaticBlueprintNode& cylinder)>& callback = {});
0197 
0198   /// Convenience method for creating a cylinder specialization of @ref Acts::Experimental::ContainerBlueprintNode.
0199   /// @param name The name of the container node. This name is only reflected
0200   ///             in the node tree for debugging, as no extra volumes is created
0201   ///             for the container.
0202   /// @param direction The direction of the stack configuration. See
0203   ///                  @ref Acts::CylinderVolumeStack for details.
0204   /// @param callback An optional callback that receives the node as an argument
0205   /// @return Reference to the newly created cylinder container blueprint node
0206   CylinderContainerBlueprintNode& addCylinderContainer(
0207       const std::string& name, AxisDirection direction,
0208       const std::function<void(CylinderContainerBlueprintNode& cylinder)>&
0209           callback = {});
0210 
0211   /// Convenience method for creating a cuboid specialization of @ref Acts::Experimental::ContainerBlueprintNode.
0212   /// @param name The name of the container node. This name is only reflected
0213   ///             in the node tree for debugging, as no extra volumes is created
0214   ///             for the container.
0215   /// @param direction The direction of the stack configuration. See
0216   ///                  @ref Acts::CuboidVolumeStack for details.
0217   /// @param callback An optional callback that receives the node as an argument
0218   /// @return Reference to the newly created cuboid container blueprint node
0219   CuboidContainerBlueprintNode& addCuboidContainer(
0220       const std::string& name, AxisDirection direction,
0221       const std::function<void(CuboidContainerBlueprintNode& cylinder)>&
0222           callback = {});
0223 
0224   /// Convenience method for creating a @ref Acts::Experimental::MaterialDesignatorBlueprintNode.
0225   /// @param name The name of the material designator node. Used for debugging
0226   ///             the node tree only.
0227   /// @param callback An optional callback that receives the node as an argument
0228   /// @return Reference to the newly created material designator blueprint node
0229   MaterialDesignatorBlueprintNode& addMaterial(
0230       const std::string& name,
0231       const std::function<void(MaterialDesignatorBlueprintNode& material)>&
0232           callback = {});
0233 
0234   /// Convenience method for creating a @ref Acts::Experimental::LayerBlueprintNode.
0235   /// @param name The name of the layer node.
0236   /// @param callback An optional callback that receives the node as an argument
0237   /// @return Reference to the newly created layer blueprint node
0238   LayerBlueprintNode& addLayer(
0239       const std::string& name,
0240       const std::function<void(LayerBlueprintNode& layer)>& callback = {});
0241 
0242   /// Convenience method for creating a @ref Acts::Experimental::GeometryIdentifierBlueprintNode.
0243   /// @param callback An optional callback that receives the node as an argument
0244   /// @return Reference to the newly created geometry identifier blueprint node
0245   GeometryIdentifierBlueprintNode& withGeometryIdentifier(
0246       const std::function<void(
0247           GeometryIdentifierBlueprintNode& geometryIdentifier)>& callback = {});
0248 
0249   /// @}
0250 
0251   /// Register a @p child to this node.
0252   /// @warning This method throws if adding the child would create a
0253   ///          cycle in the blueprint tree!
0254   /// @param child The child node to add
0255   /// @return A reference this node (not the child!)
0256   BlueprintNode& addChild(std::shared_ptr<BlueprintNode> child);
0257 
0258   /// A range-like object that allows range based for loops and index access.
0259   /// This type's iterators and accessors return mutable references when
0260   /// dereferenced.
0261   using MutableChildRange =
0262       Acts::detail::TransformRange<Acts::detail::Dereference,
0263                                    std::vector<std::shared_ptr<BlueprintNode>>>;
0264 
0265   /// A range-like object that allows range based for loops and index access.
0266   /// This type's iterators and accessors return const references when
0267   /// dereferenced.
0268   using ChildRange = Acts::detail::TransformRange<
0269       Acts::detail::ConstDereference,
0270       const std::vector<std::shared_ptr<BlueprintNode>>>;
0271 
0272   /// Return a @ref MutableChildRange to the children of this node.
0273   /// @return A range-like object to the children
0274   MutableChildRange children();
0275 
0276   /// Return a @ref ChildRange to the children of this node.
0277   /// @return A range-like object to the children
0278   ChildRange children() const;
0279 
0280   /// Remove all children from this node
0281   void clearChildren();
0282 
0283   /// Return the depth of this node in the blueprint tree. A depth of zero means
0284   /// this node does not have a parent.
0285   /// @return The depth of this node
0286   std::size_t depth() const;
0287 
0288   /// Print the node tree starting from this node to graphviz format
0289   /// @param os The stream to print to
0290   void graphviz(std::ostream& os) const;
0291 
0292   /// Method that writes a representatiohn of **this node only** to graphviz.
0293   /// This should generally not be called on its own, but through the @ref
0294   /// BlueprintNode::graphviz method.
0295   /// @param os The stream to print to
0296   virtual void addToGraphviz(std::ostream& os) const;
0297 
0298   /// Print a representation of this node to the stream
0299   /// @param os The stream to print to
0300   /// @param node The node to print
0301   /// @return The output stream
0302   friend std::ostream& operator<<(std::ostream& os, const BlueprintNode& node) {
0303     node.toStream(os);
0304     return os;
0305   }
0306 
0307  protected:
0308   /// Virtual method to determine stream representation.
0309   /// @param os Output stream to write to
0310   /// @note This method is called by the stream operator.
0311   virtual void toStream(std::ostream& os) const;
0312 
0313   /// Set the depth to @p depth and update children recursively
0314   /// @param depth New depth value to set
0315   void setDepth(std::size_t depth);
0316 
0317   /// Printing helper returning a prefix including an indent depending on the
0318   /// depth.
0319   /// @return The prefix string
0320   std::string prefix() const;
0321 
0322   /// An indentation depending on the depth of this node.
0323   /// @return The indentation string
0324   std::string indent() const;
0325 
0326  private:
0327   std::size_t m_depth{0};
0328   std::vector<std::shared_ptr<BlueprintNode>> m_children{};
0329 };
0330 
0331 }  // namespace Experimental
0332 }  // namespace Acts