Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-05 07:57:20

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