Back to home page

EIC code displayed by LXR

 
 

    


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

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/CylinderVolumeBounds.hpp"
0012 #include "Acts/Utilities/AxisDefinitions.hpp"
0013 #include "Acts/Utilities/Logger.hpp"
0014 
0015 #include <array>
0016 #include <memory>
0017 
0018 namespace Acts {
0019 
0020 class Portal;
0021 class TrackingVolume;
0022 class GeometryContext;
0023 
0024 /// @class PortalShellBase
0025 /// The portal shell of a volume is the set of portals that describes
0026 /// connections "outside" of the volume. Which boundary surfaces of a volume are
0027 /// included in the shell depends on the volume. Portal shells are only used
0028 /// during geometry construction, and are not part of the final geometry
0029 /// description.
0030 ///
0031 /// This class is the base class for all portal shells
0032 class PortalShellBase {
0033  public:
0034   /// Virtusl destructor
0035   virtual ~PortalShellBase() = default;
0036 
0037   /// Fill the open slots of the shell with a @c TrivialPortalLink
0038   /// to the given @p volume.
0039   /// @param volume The volume to connect
0040   virtual void fill(TrackingVolume& volume) = 0;
0041 
0042   /// Get the number of portals in the shell. This number depends on the volume
0043   /// type
0044   /// @return The number of portals in the shell
0045   virtual std::size_t size() const = 0;
0046 
0047   /// Instruct the shell to register the portals with the volume, handing over
0048   /// shared ownership in the process.
0049   /// @note The target volume depends on the shell type, e.g. composite shells
0050   ///       like the @c CylinerStackPortalShell register portals to the *correct*
0051   ///       volumes.
0052   virtual void applyToVolume() = 0;
0053 
0054   /// Check if a portal is *valid*, e.g. if non of the portals has two
0055   /// unconnected sides.
0056   /// @return True if the shell is valid, false otherwise
0057   virtual bool isValid() const = 0;
0058 
0059   /// Get a label for the portal shell for debugging purposes
0060   /// @return A label for the portal shell
0061   virtual std::string label() const = 0;
0062 };
0063 
0064 /// @class CylinderPortalShell
0065 /// Base class for cylinder shaped portal shells, e.g. shells for cylinder
0066 /// volumes
0067 class CylinderPortalShell : public PortalShellBase {
0068  public:
0069   using Face = CylinderVolumeBounds::Face;
0070 
0071   using enum CylinderVolumeBounds::Face;
0072 
0073   /// Retrieve the portal associated to the given face. Can be nullptr if unset.
0074   /// @param face The face to retrieve the portal for
0075   /// @return The portal associated to the face
0076   virtual Portal* portal(Face face) = 0;
0077 
0078   /// Retrieve a shared_ptr for the portal associated to the given face. Can be
0079   /// nullptr if unset.
0080   /// @param face The face to retrieve the portal for
0081   /// @return The portal associated to the face
0082   virtual std::shared_ptr<Portal> portalPtr(Face face) = 0;
0083 
0084   /// Set the portal associated to the given face.
0085   /// @param portal The portal to set
0086   /// @param face The face to set the portal
0087   virtual void setPortal(std::shared_ptr<Portal> portal, Face face) = 0;
0088 
0089   /// @copydoc PortalShellBase::fill
0090   void fill(TrackingVolume& volume) override;
0091 };
0092 
0093 /// Output stream operator for the CylinderPortalShell::Face enum
0094 /// @param os The output stream
0095 /// @param face The face to output
0096 /// @return The output stream
0097 std::ostream& operator<<(std::ostream& os, CylinderPortalShell::Face face);
0098 
0099 /// @class SingleCylinderPortalShell
0100 /// This class describes a cylinder shell containing a single volume. The
0101 /// available faces depend on the configuration of the cylinder volume bounds.
0102 /// If a phi sector is configured, the shell will have corresponding portal
0103 /// slots. If the inner radius is non-zero, the shell will have an inner
0104 /// cylinder portal slot.
0105 class SingleCylinderPortalShell : public CylinderPortalShell {
0106  public:
0107   /// Construct a single cylinder portal shell for the given volume
0108   /// @param volume The volume to create the shell for
0109   explicit SingleCylinderPortalShell(TrackingVolume& volume);
0110 
0111   /// @copydoc PortalShellBase::size
0112   std::size_t size() const final;
0113 
0114   /// @copydoc CylinderPortalShell::portal
0115   Portal* portal(Face face) final;
0116 
0117   /// @copydoc CylinderPortalShell::portalPtr
0118   std::shared_ptr<Portal> portalPtr(Face face) final;
0119 
0120   /// @copydoc CylinderPortalShell::setPortal
0121   void setPortal(std::shared_ptr<Portal> portal, Face face) final;
0122 
0123   /// @copydoc PortalShellBase::applyToVolume
0124   void applyToVolume() override;
0125 
0126   /// @copydoc PortalShellBase::isValid
0127   bool isValid() const override;
0128 
0129   /// @copydoc PortalShellBase::label
0130   std::string label() const override;
0131 
0132  private:
0133   std::array<std::shared_ptr<Portal>, 6> m_portals{};
0134 
0135   TrackingVolume* m_volume;
0136 };
0137 
0138 /// @class CylinderStackPortalShell
0139 /// This class describes a cylinder shell containing multiple volumes. The
0140 /// available faces depend on the configuration of the cylinder volume bounds.
0141 /// @note The stack shell currently does not support phi sectors
0142 /// The stack can be oriented along the (local) z or r direction, which drives
0143 /// the stacking. Depending on the direction, portals on the shells of children
0144 /// are merged or fused. Subsequently, portal access respects shared portals
0145 /// between shells. Below is an illustration of a stack in the r direction:
0146 ///
0147 ///  Fused         +-----------------+
0148 /// portals ----+  |                 |
0149 ///   |         |  v           OuterCylinder
0150 ///   |  +------+------+
0151 ///   |  |      |      |
0152 ///   |  |      |      |<--+
0153 ///   +--+---+  v      |   |
0154 ///      +---+---------+   |
0155 ///      |   |         |   |      Shared portal
0156 ///      |   |         |<--+---      (grid)
0157 ///      |   v         |   |      PositiveDisc
0158 ///      +-------------+   |
0159 /// r ^  |             |   |
0160 ///   |  |             |<--+
0161 ///   |  |             |
0162 ///   |  +-------------+       InnerCylinder
0163 ///   +----->      ^            (if rMin>0)
0164 ///          z     |                 |
0165 ///                +-----------------+
0166 ///
0167 /// @note The shells must be ordered in the given direction
0168 /// Depending on the stack direction, the portal lookup will return different
0169 /// portals. In the illustration above, the `PositiveDisc` portal is shared
0170 /// among all shells, while the `OuterCylinder` and `InnerCylinder` portals are
0171 /// looked up from the innermost and outermost shell in the r direction.
0172 class CylinderStackPortalShell : public CylinderPortalShell {
0173  public:
0174   /// Construct the portal shell stack from the given shells
0175   /// @param gctx The geometry context
0176   /// @param shells The shells to stack
0177   /// @note The shells must be ordered in the given direction
0178   /// @param direction The stacking direction
0179   /// @param logger A logging instance for debugging
0180   CylinderStackPortalShell(const GeometryContext& gctx,
0181                            std::vector<CylinderPortalShell*> shells,
0182                            AxisDirection direction,
0183                            const Logger& logger = getDummyLogger());
0184 
0185   /// @copydoc PortalShellBase::size
0186   std::size_t size() const final;
0187 
0188   /// @copydoc CylinderPortalShell::portal
0189   Portal* portal(Face face) final;
0190 
0191   /// @copydoc CylinderPortalShell::portalPtr
0192   std::shared_ptr<Portal> portalPtr(Face face) final;
0193 
0194   /// @copydoc CylinderPortalShell::setPortal
0195   void setPortal(std::shared_ptr<Portal> portal, Face face) final;
0196 
0197   void applyToVolume() override {
0198     // No-op, because it's a composite portal shell
0199   }
0200 
0201   /// @copydoc PortalShellBase::isValid
0202   bool isValid() const override;
0203 
0204   /// @copydoc PortalShellBase::label
0205   std::string label() const override;
0206 
0207  private:
0208   AxisDirection m_direction;
0209   std::vector<CylinderPortalShell*> m_shells;
0210   bool m_hasInnerCylinder{true};
0211 };
0212 
0213 }  // namespace Acts