Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:13:56

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/Volume.hpp"
0013 #include "Acts/Geometry/VolumeAttachmentStrategy.hpp"
0014 #include "Acts/Geometry/VolumeResizeStrategy.hpp"
0015 #include "Acts/Utilities/AxisDefinitions.hpp"
0016 #include "Acts/Utilities/Logger.hpp"
0017 
0018 #include <cstddef>
0019 #include <vector>
0020 
0021 namespace Acts {
0022 
0023 /// @class CuboidVolumeStack
0024 /// This class implements a x-. y-. z-aligned stack
0025 /// of cuboid volumes with synchronized bounds.
0026 /// Externally, it presents as a single volume.
0027 /// On construction, the input volumes are modified so that
0028 /// they are connected in x, y, z and have synchronized bounds.
0029 /// The way this is done can be configured using an *attachment*
0030 /// and a *resize* strategy. Depending on the configuration,
0031 /// the input volumes are either extended or gap volumes are created.
0032 ///
0033 /// @note The size adjustment convention is that volumes are never shrunk
0034 class CuboidVolumeStack : public Volume {
0035  public:
0036   /// Constructor from a vector of volumes and direction
0037   /// @param volumes is the vector of volumes
0038   /// @param direction is the axis direction
0039   /// @param strategy is the attachment strategy
0040   /// @param resizeStrategy is the resize strategy
0041   /// @note @p resizeStrategy only affects resizing along
0042   ///       @p direction. Resizing in the other direction
0043   ///       is always delegated to the child volumes,
0044   ///       which might in turn be @c CuboidVolumeStack
0045   /// @param logger is the logger
0046   /// @pre The volumes need to have a common coordinate
0047   ///      system relative to @p direction. I.e. they need
0048   ///      to be aligned in @c z and cannot have a rotation
0049   ///      in @c x or @c y.
0050   /// @pre The volumes all need to have @c CuboidVolumeBounds
0051   /// @note Preconditions are checked on construction
0052   CuboidVolumeStack(
0053       std::vector<Volume*>& volumes, AxisDirection direction,
0054       VolumeAttachmentStrategy strategy = VolumeAttachmentStrategy::Midpoint,
0055       VolumeResizeStrategy resizeStrategy = VolumeResizeStrategy::Expand,
0056       const Logger& logger = Acts::getDummyLogger());
0057 
0058   /// Constructor from a vector of volumes and direction
0059   /// @param volumes is the vector of volumes
0060   /// @param direction is the vector specifying the global direction
0061   /// @param strategy is the attachment strategy
0062   /// @param resizeStrategy is the resize strategy
0063   /// @note @p resizeStrategy only affects resizing along
0064   ///       @p direction. Resizing in the other direction
0065   ///       is always delegated to the child volumes,
0066   ///       which might in turn be @c CuboidVolumeStack
0067   /// @param logger is the logger
0068   /// @pre The volumes need to have a common coordinate
0069   ///      system relative to @p direction. I.e. they need
0070   ///      to be aligned in @c z and cannot have a rotation
0071   ///      in @c x or @c y.
0072   /// @pre The volumes all need to have @c CuboidVolumeBounds
0073   /// @note Preconditions are checked on construction
0074   CuboidVolumeStack(
0075       std::vector<Volume*>& volumes, const Vector3& direction,
0076       VolumeAttachmentStrategy strategy = VolumeAttachmentStrategy::Midpoint,
0077       VolumeResizeStrategy resizeStrategy = VolumeResizeStrategy::Expand,
0078       const Logger& logger = Acts::getDummyLogger());
0079 
0080   /// Update the volume bounds and transform. This
0081   /// will update the bounds of all volumes in the stack
0082   /// to accommodate the new bounds and optionally create
0083   /// gap volumes according to the resize strategy set during
0084   /// construction.
0085   /// @param volbounds is the new bounds
0086   /// @param transform is the new transform
0087   /// @param logger is the logger
0088   /// @pre The volume bounds need to be of type
0089   ///      @c CuboidVolumeBounds.
0090   void update(std::shared_ptr<VolumeBounds> volbounds,
0091               std::optional<Transform3> transform = std::nullopt,
0092               const Logger& logger = getDummyLogger()) override;
0093 
0094   /// Access the gap volume that were created during attachment or resizing.
0095   /// @return the vector of gap volumes
0096   const std::vector<std::shared_ptr<Volume>>& gaps() const;
0097 
0098   /// Convert axis direction to an array index according to
0099   /// stack convention. For example, AxisX --> 0
0100   /// @param direction is the axis direction to convert
0101   static std::size_t axisToIndex(AxisDirection direction);
0102 
0103   /// Get axis directions orthogonal to the given one according
0104   /// to stack convention. For example AxisX --> <AxisY, AxisZ>
0105   /// @param direction is the axis direction to find the orthogonal for
0106   static std::pair<AxisDirection, AxisDirection> getOrthogonalAxes(
0107       AxisDirection direction);
0108 
0109  private:
0110   /// Helper to get the first volume in the input, and throw an exception if
0111   /// there is not one.
0112   /// @param volumes is the vector of volumes
0113   /// @return the first volume
0114   static Volume& initialVolume(const std::vector<Volume*>& volumes);
0115 
0116   /// Helper function called during construction that performs the
0117   /// internal attachment and produces the overall outer volume bounds.
0118   /// @param strategy is the attachment strategy
0119   /// @param logger is the logger
0120   void initializeOuterVolume(VolumeAttachmentStrategy strategy,
0121                              const Logger& logger);
0122 
0123   struct VolumeTuple;
0124 
0125   /// Helper function to pretty print the internal volume representation
0126   /// @param volumes is the vector of volumes
0127   /// @param logger is the logger
0128   /// @param lvl is the logging level
0129   static void printVolumeSequence(const std::vector<VolumeTuple>& volumes,
0130                                   const Logger& logger,
0131                                   Acts::Logging::Level lvl);
0132 
0133   /// Helper function that prints output helping in debugging overlaps
0134   /// @param a is the first volume
0135   /// @param b is the second volume
0136   /// @param logger is the logger
0137   void overlapPrint(const VolumeTuple& a, const VolumeTuple& b,
0138                     const Logger& logger);
0139 
0140   /// Helper function that checks if volumes are properly aligned
0141   /// for attachment.
0142   /// @param volumes is the vector of volumes
0143   /// @param logger is the logger
0144   void checkVolumeAlignment(const std::vector<VolumeTuple>& volumes,
0145                             const Logger& logger) const;
0146 
0147   /// Helper function that checks overlaps and attaches along the stacking
0148   /// direction
0149   /// @param volumes is the vector of volumes
0150   /// @param strategy is the attachment strategy
0151   /// @param logger is the logger
0152   /// @return vector of gap volumes. Can be empty if none were created.
0153   std::vector<VolumeTuple> checkOverlapAndAttach(
0154       std::vector<VolumeTuple>& volumes, VolumeAttachmentStrategy strategy,
0155       const Logger& logger);
0156 
0157   /// Helper function to synchronize the bounds of the volumes
0158   /// @param volumes is the vector of volumes
0159   /// @param logger is the logger
0160   /// @return tuple of the minimum and maximum radii
0161   std::pair<double, double> synchronizeBounds(std::vector<VolumeTuple>& volumes,
0162                                               const Logger& logger);
0163 
0164   /// Helper function to create a gap volume with given bounds and register it.
0165   /// @param transform is the transform of the gap volume
0166   /// @param bounds is the bounds of the gap volume
0167   /// @return the shared pointer to the gap volume
0168   std::shared_ptr<Volume> addGapVolume(
0169       const Transform3& transform, const std::shared_ptr<VolumeBounds>& bounds);
0170 
0171   /// Merging direction of the stack
0172   /// in local group coordinates
0173   AxisDirection m_dir{};
0174 
0175   /// Directions orthogonal to the
0176   /// merging direction of the stack
0177   /// in local group coordinates
0178   AxisDirection m_dirOrth1{};
0179   AxisDirection m_dirOrth2{};
0180 
0181   VolumeResizeStrategy m_resizeStrategy{};
0182   Transform3 m_groupTransform{};
0183   std::vector<std::shared_ptr<Volume>> m_gaps{};
0184   std::vector<Volume*>& m_volumes;
0185 };
0186 
0187 }  // namespace Acts