Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:50

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