Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-02 08:17:11

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/Geometry/BlueprintNode.hpp"
0012 #include "Acts/Geometry/BlueprintOptions.hpp"
0013 #include "Acts/Geometry/PortalShell.hpp"
0014 #include "Acts/Geometry/TrackingVolume.hpp"
0015 #include "Acts/Geometry/VolumeAttachmentStrategy.hpp"
0016 #include "Acts/Geometry/VolumeResizeStrategy.hpp"
0017 #include "Acts/Geometry/VolumeStack.hpp"
0018 #include "Acts/Utilities/AxisDefinitions.hpp"
0019 #include "Acts/Utilities/GraphViz.hpp"
0020 #include "Acts/Utilities/Logger.hpp"
0021 #include "Acts/Utilities/ThrowAssert.hpp"
0022 
0023 #include <map>
0024 
0025 namespace Acts {
0026 
0027 /// @class ContainerBlueprintNode
0028 ///
0029 /// A blueprint node that can contain multiple child volumes. It is responsible
0030 /// for managing the child volumes and their shells. The child volumes can be
0031 /// either gap volumes or volumes from child nodes.
0032 ///
0033 /// The container node is responsible for:
0034 /// 1. Managing the child volumes and their shells
0035 /// 2. Creating gap volumes between child volumes
0036 /// 3. Collecting shells from child nodes and gap volumes
0037 /// 4. Building the volume stack
0038 ///
0039 /// The container node is an abstract base class. Derived classes must
0040 /// implement:
0041 /// 1. makeStack - to create the appropriate volume stack
0042 /// 2. typeName - to provide the type name for debug output
0043 ///
0044 class ContainerBlueprintNode : public BlueprintNode {
0045  public:
0046   /// Main constructor for the container node.
0047   /// @param name The name of the node (for debug only)
0048   /// @param axis The stacking axis direction in local reference frame
0049   /// @param attachmentStrategy The attachment strategy for the stack
0050   /// @param resizeStrategy The resize strategy for the stack
0051   ContainerBlueprintNode(
0052       const std::string& name, AxisDirection axis,
0053       VolumeAttachmentStrategy attachmentStrategy =
0054           VolumeAttachmentStrategy::Midpoint,
0055       VolumeResizeStrategy resizeStrategy = VolumeResizeStrategy::Expand);
0056 
0057   /// Main constructor for the container node.
0058   /// @param name The name of the node (for debug only)
0059   /// @param axis The stacking axis direction in local reference frame
0060   /// @param attachmentStrategy The attachment strategy for the stack
0061   /// @param resizeStrategies The resize strategies for the stack
0062   ContainerBlueprintNode(
0063       const std::string& name, AxisDirection axis,
0064       VolumeAttachmentStrategy attachmentStrategy,
0065       std::pair<VolumeResizeStrategy, VolumeResizeStrategy> resizeStrategies);
0066 
0067   /// @copydoc BlueprintNode::name
0068   const std::string& name() const override;
0069 
0070   /// This participates in the construction of the geometry via the blueprint
0071   /// tree. The steps are approximately as follows:
0072   /// -# Collect all child volumes
0073   /// -# Package them into a VolumeStack (cuboid or cylinder), which performs
0074   ///    sizing and/or gap creation
0075   /// -# Return the VolumeStack as a volume up the tree
0076   ///
0077   /// @param options The global blueprint options
0078   /// @param gctx The geometry context (nominal usually)
0079   /// @param logger The logger to use
0080   /// @return The combined VolumeStack
0081   Volume& build(const BlueprintOptions& options, const GeometryContext& gctx,
0082                 const Logger& logger = Acts::getDummyLogger()) override;
0083 
0084   /// This participates in the construction of the geometry via the blueprint
0085   /// tree. The steps are approximately as follows:
0086   /// -# Register portals created for gap volumes, as they're not handled by
0087   ///    dedicated nodes
0088   /// -# Register gap volumes in the @p parent volume
0089   /// -# Create a configured @ref Acts::INavigationPolicy for the gap
0090   /// -# Call `finalize` on all children while passing through @p parent.
0091   ///
0092   /// @param options The global blueprint options
0093   /// @param gctx The geometry context (nominal usually)
0094   /// @param parent The parent volume
0095   /// @param logger The logger to use
0096   void finalize(const BlueprintOptions& options, const GeometryContext& gctx,
0097                 TrackingVolume& parent, const Logger& logger) override;
0098 
0099   /// Setter for the stacking direction
0100   /// @param direction The stacking direction
0101   /// @return This node for chaining
0102   ContainerBlueprintNode& setDirection(AxisDirection direction);
0103 
0104   /// Setter for the attachment strategy
0105   /// @param attachmentStrategy The attachment strategy
0106   /// @return This node for chaining
0107   ContainerBlueprintNode& setAttachmentStrategy(
0108       VolumeAttachmentStrategy attachmentStrategy);
0109 
0110   /// Setter for the resize strategy
0111   /// @param resizeStrategy The resize strategy
0112   /// @note @p resizeStrategy is used for both sides of the container
0113   /// @return This node for chaining
0114   ContainerBlueprintNode& setResizeStrategy(
0115       VolumeResizeStrategy resizeStrategy);
0116 
0117   /// Setter for the resize strategies
0118   /// @param inner The inner resize strategy
0119   /// @param outer The outer resize strategy
0120   /// @return This node for chaining
0121   ContainerBlueprintNode& setResizeStrategies(VolumeResizeStrategy inner,
0122                                               VolumeResizeStrategy outer);
0123 
0124   /// Accessor to the stacking direction
0125   /// @return The stacking direction
0126   AxisDirection direction() const;
0127 
0128   /// Accessor to the attachment strategy
0129   /// @return The attachment strategy
0130   VolumeAttachmentStrategy attachmentStrategy() const;
0131 
0132   /// Accessor to the resize strategies
0133   /// @return The resize strategies
0134   std::pair<VolumeResizeStrategy, VolumeResizeStrategy> resizeStrategies()
0135       const;
0136 
0137   /// @copydoc BlueprintNode::addToGraphviz
0138   void addToGraphviz(std::ostream& os) const override;
0139 
0140  protected:
0141   /// Make the volume stack for the container. This is called by the build
0142   /// method and is implemented by the derived classes.
0143   /// @param gctx The current geometry context object, e.g. alignment
0144   /// @param volumes The volumes to stack
0145   /// @param logger The logger to use
0146   /// @return The volume stack
0147   virtual std::unique_ptr<VolumeStack> makeStack(const GeometryContext& gctx,
0148                                                  std::vector<Volume*>& volumes,
0149                                                  const Logger& logger) = 0;
0150 
0151   /// Get the type name of the container. This is used for the debug output
0152   /// of the container and encoding the volume shape in the dot graph.
0153   /// @return The type name
0154   virtual const std::string& typeName() const = 0;
0155 
0156   /// Collect shells from child nodes and gap volumes
0157   ///
0158   /// This function is responsible for collecting shells from child nodes and
0159   /// creating shells for gap volumes. It is used by the connect method to
0160   /// prepare the shells for the volume stack.
0161   ///
0162   /// The function processes each volume in m_childVolumes in two ways:
0163   /// 1. For gap volumes:
0164   ///    - Creates a TrackingVolume from the gap volume
0165   ///    - Assigns a unique name (ContainerName::GapN)
0166   ///    - Creates a single shell for the gap volume
0167   ///    - Stores both the shell and gap volume in m_gaps for later use
0168   ///
0169   /// 2. For child volumes:
0170   ///    - Looks up the corresponding child node in m_volumeToNode
0171   ///    - Calls connect() on the child node to get its shell
0172   ///    - Validates that the shell type matches the expected type
0173   ///    - Ensures the shell is valid
0174   ///
0175   /// The function maintains the order of volumes as they appear in
0176   /// m_childVolumes, which is important for the final stack shell construction.
0177   ///
0178   /// @tparam BaseShell The base shell type (e.g. CylinderPortalShell)
0179   /// @tparam SingleShell The single shell type (e.g. SingleCylinderPortalShell)
0180   /// @param options The blueprint options
0181   /// @param gctx The geometry context
0182   /// @param stack The volume stack
0183   /// @param prefix The prefix for debug output
0184   /// @param logger The logger to use
0185   /// @return A vector of shells in the same order as m_childVolumes
0186   template <typename BaseShell, typename SingleShell>
0187   std::vector<BaseShell*> collectChildShells(const BlueprintOptions& options,
0188                                              const GeometryContext& gctx,
0189                                              VolumeStack& stack,
0190                                              const std::string& prefix,
0191                                              const Logger& logger);
0192 
0193   /// Implementation of the connect method for container nodes
0194   ///
0195   /// This method is responsible for:
0196   /// 1. Collecting shells from child nodes and gap volumes
0197   /// 2. Validating that the number of shells matches the number of child
0198   /// volumes
0199   /// 3. Ensuring all shells are valid
0200   /// 4. Creating a merged stack shell from all collected shells
0201   ///
0202   /// @tparam BaseShell The base shell type (e.g. CylinderPortalShell)
0203   /// @tparam SingleShell The single shell type (e.g. SingleCylinderPortalShell)
0204   /// @tparam ShellStack The stack shell type (e.g. StackCylinderPortalShell)
0205   /// @param options The blueprint options
0206   /// @param gctx The geometry context
0207   /// @param stack The volume stack
0208   /// @param prefix The prefix for debug output
0209   /// @param logger The logger to use
0210   /// @return The merged stack shell
0211   template <typename BaseShell, typename SingleShell, typename ShellStack>
0212   PortalShellBase& connectImpl(const BlueprintOptions& options,
0213                                const GeometryContext& gctx, VolumeStack* stack,
0214                                const std::string& prefix, const Logger& logger);
0215 
0216   /// Name of the container node for debugging purposes
0217   std::string m_name;
0218   /// Stacking axis direction in local reference frame
0219   AxisDirection m_direction = AxisDirection::AxisZ;
0220   /// Volume attachment strategy for connecting volumes in the stack
0221   VolumeAttachmentStrategy m_attachmentStrategy{
0222       VolumeAttachmentStrategy::Midpoint};
0223 
0224   /// Resize strategies for inner and outer sides of the container
0225   std::pair<VolumeResizeStrategy, VolumeResizeStrategy> m_resizeStrategies{
0226       VolumeResizeStrategy::Expand, VolumeResizeStrategy::Expand};
0227 
0228   /// Container of child volumes managed by this blueprint node
0229   std::vector<Volume*> m_childVolumes;
0230   /// Volume stack instance created by derived classes during build phase
0231   /// @note This is populated during the build process by makeStack implementations
0232   std::unique_ptr<VolumeStack> m_stack{nullptr};
0233   /// Mapping from child volumes to their corresponding blueprint nodes
0234   std::map<const Volume*, BlueprintNode*> m_volumeToNode;
0235 
0236   /// Portal shell representation of this container for geometry connection
0237   std::unique_ptr<PortalShellBase> m_shell{nullptr};
0238   /// Container of gap volumes and their portal shells created between child
0239   /// volumes
0240   std::vector<std::pair<std::unique_ptr<PortalShellBase>,
0241                         std::unique_ptr<TrackingVolume>>>
0242       m_gaps;
0243 };
0244 
0245 /// Container blueprint node stacking cylindrical volumes.
0246 class CylinderContainerBlueprintNode final : public ContainerBlueprintNode {
0247  public:
0248   using ContainerBlueprintNode::ContainerBlueprintNode;
0249 
0250   /// This participates in the construction of the geometry via the blueprint
0251   /// tree. The steps are approximately as follows:
0252   /// -# Walk through all volumes that were created by the build phase
0253   /// -# Check if they are: *real* child volumes or gap volumes
0254   ///   - If gap volume: produce a @ref Acts::TrackingVolume, and wrap it in a single use shell
0255   ///   - If child volume: locate the right child node it came from, call
0256   ///   ` connect` and collect the returned shell
0257   /// -# Produce a combined StackPortalShell (cuboid or cylinder) from all the
0258   /// shells
0259   /// -# Return that shell representation
0260   ///
0261   /// @param options The global blueprint options
0262   /// @param gctx The geometry context (nominal usually)
0263   /// @param logger The logger to use
0264   /// @return The combined StackPortalShell (cuboid or cylinder)
0265   PortalShellBase& connect(
0266       const BlueprintOptions& options, const GeometryContext& gctx,
0267       const Logger& logger = Acts::getDummyLogger()) override;
0268 
0269   std::unique_ptr<VolumeStack> makeStack(const GeometryContext& gctx,
0270                                          std::vector<Volume*>& volumes,
0271                                          const Logger& logger) override;
0272 
0273  protected:
0274   /// @brief Type name for cylinder container
0275   inline static const std::string s_typeName = "Cylinder";
0276   const std::string& typeName() const override;
0277 };
0278 
0279 /// Container blueprint node stacking cuboid volumes.
0280 class CuboidContainerBlueprintNode final : public ContainerBlueprintNode {
0281  public:
0282   using ContainerBlueprintNode::ContainerBlueprintNode;
0283 
0284   /// This participates in the construction of the geometry via the blueprint
0285   /// tree. The steps are approximately as follows:
0286   /// -# Walk through all volumes that were created by the build phase
0287   /// -# Check if they are: *real* child volumes or gap volumes
0288   ///   - If gap volume: produce a @ref Acts::TrackingVolume, and wrap it in a single use shell
0289   ///   - If child volume: locate the right child node it came from, call
0290   ///   ` connect` and collect the returned shell
0291   /// -# Produce a combined StackPortalShell (cuboid or cylinder) from all the
0292   /// shells
0293   /// -# Return that shell representation
0294   ///
0295   /// @param options The global blueprint options
0296   /// @param gctx The geometry context (nominal usually)
0297   /// @param logger The logger to use
0298   /// @return The combined StackPortalShell (cuboid or cylinder)
0299   PortalShellBase& connect(
0300       const BlueprintOptions& options, const GeometryContext& gctx,
0301       const Logger& logger = Acts::getDummyLogger()) override;
0302 
0303   std::unique_ptr<VolumeStack> makeStack(const GeometryContext& gctx,
0304                                          std::vector<Volume*>& volumes,
0305                                          const Logger& logger) override;
0306 
0307  protected:
0308   /// @brief Type name for cuboid container
0309   inline static const std::string s_typeName = "Cuboid";
0310   const std::string& typeName() const override;
0311 };
0312 
0313 namespace Experimental {
0314 /// @deprecated The blueprint geometry moved out of the `Acts::Experimental`
0315 ///             namespace. Use the un-namespaced `Acts::` types instead. These
0316 ///             aliases are kept for backward compatibility and will be removed.
0317 using ContainerBlueprintNode
0318     [[deprecated("Acts::Experimental::ContainerBlueprintNode moved to "
0319                  "Acts::ContainerBlueprintNode")]] =
0320         Acts::ContainerBlueprintNode;
0321 /// @deprecated Acts::Experimental::CylinderContainerBlueprintNode moved to
0322 ///             Acts::CylinderContainerBlueprintNode.
0323 using CylinderContainerBlueprintNode
0324     [[deprecated("Acts::Experimental::CylinderContainerBlueprintNode moved to "
0325                  "Acts::CylinderContainerBlueprintNode")]] =
0326         Acts::CylinderContainerBlueprintNode;
0327 /// @deprecated Acts::Experimental::CuboidContainerBlueprintNode moved to
0328 ///             Acts::CuboidContainerBlueprintNode.
0329 using CuboidContainerBlueprintNode
0330     [[deprecated("Acts::Experimental::CuboidContainerBlueprintNode moved to "
0331                  "Acts::CuboidContainerBlueprintNode")]] =
0332         Acts::CuboidContainerBlueprintNode;
0333 }  // namespace Experimental
0334 
0335 }  // namespace Acts