Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:23:22

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0013 #include "Acts/Geometry/Volume.hpp"
0014 #include "Acts/Utilities/BinningType.hpp"
0015 #include "Acts/Utilities/Logger.hpp"
0016 
0017 #include <vector>
0018 
0019 namespace Acts {
0020 
0021 /// @class CylinderVolumeStack
0022 /// This class implements a z-aligned or r-aligned stack
0023 /// of cylinder volumes with synchronized bounds.
0024 /// Externally, it presents as a single volume.
0025 /// On construction, the input volumes are modified so that
0026 /// they are connected in z and r and have synchronized bounds.
0027 /// The way this is done can be configured using an *attachment*
0028 /// and a *resize* strategy. Depending on the configuration,
0029 /// the input volumes are either extended or gap volumes are created.
0030 ///
0031 /// @note The volumes are never shrunk, because this would potentially
0032 ///       result in overlaps of the resulting volumes bounds.
0033 class CylinderVolumeStack : public Volume {
0034  public:
0035   /// The attachment strategy defines how the volumes are attached
0036   /// Attachment always happens pair-wise
0037   enum class AttachmentStrategy {
0038     /// Given two volumes, the *left* one, i.e. the one with the lower **local**
0039     /// z or r value is extended
0040     First,
0041     /// Given two volumes, the *right* one, i.e. the one with the higher
0042     /// **local** z or r value is extended
0043     Second,
0044     /// Given two volumes, the *midpoint* between the two volumes is found
0045     Midpoint,
0046     /// A gap volume is created to fit between the two volumes
0047     Gap,
0048   };
0049 
0050   /// The resize strategy defines how the volumes are resized
0051   enum class ResizeStrategy {
0052     /// Extend the volume connected to the respective edge to fit the new bounds
0053     Expand,
0054     /// Create a gap volume at the respective edge to fit the new bounds
0055     Gap,
0056   };
0057 
0058   /// Constructor from a vector of volumes and direction
0059   /// @param volumes is the vector of volumes
0060   /// @param direction is the binning 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 CylinderVolumeStack
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 CylinerVolumeBounds
0073   ///      and cannot have a @f$\phi@f$ sector or bevels.
0074   /// @note Preconditions are checked on construction
0075   CylinderVolumeStack(
0076       std::vector<Volume*>& volumes, BinningValue direction,
0077       AttachmentStrategy strategy = AttachmentStrategy::Midpoint,
0078       ResizeStrategy resizeStrategy = ResizeStrategy::Expand,
0079       const Logger& logger = Acts::getDummyLogger());
0080 
0081   /// Update the volume bounds and transform. This
0082   /// will update the bounds of all volumes in the stack
0083   /// to accommodate the new bounds and optionally create
0084   /// gap volumes according to the resize strategy set during
0085   /// construction.
0086   /// @param volbounds is the new bounds
0087   /// @param transform is the new transform
0088   /// @pre The volume bounds need to be of type
0089   ///      @c CylinderVolumeBounds.
0090   void update(std::shared_ptr<const VolumeBounds> volbounds,
0091               std::optional<Transform3> transform = std::nullopt) override;
0092 
0093   /// Update the volume bounds and transform. This
0094   /// will update the bounds of all volumes in the stack
0095   /// to accommodate the new bounds and optionally create
0096   /// gap volumes according to the resize strategy set during
0097   /// construction.
0098   /// @param newBounds is the new bounds
0099   /// @param transform is the new transform
0100   /// @param logger is the logger
0101   /// @pre The volume bounds need to be of type
0102   ///      @c CylinderVolumeBounds.
0103   void update(std::shared_ptr<const CylinderVolumeBounds> newBounds,
0104               std::optional<Transform3> transform, const Logger& logger);
0105 
0106   /// Access the gap volume that were created during attachment or resizing.
0107   /// @return the vector of gap volumes
0108   const std::vector<std::shared_ptr<Volume>>& gaps() const;
0109 
0110  private:
0111   /// Helper to get the first volume in the input, and throw an exception if
0112   /// there is not one.
0113   /// @param volumes is the vector of volumes
0114   /// @return the first volume
0115   static Volume& initialVolume(const std::vector<Volume*>& volumes);
0116 
0117   /// Helper function called during construction that performs the
0118   /// internal attachment and produces the overall outer volume bounds.
0119   /// @param direction is the binning direction
0120   /// @param strategy is the attachment strategy
0121   /// @param logger is the logger
0122   void initializeOuterVolume(BinningValue direction,
0123                              AttachmentStrategy strategy, const Logger& logger);
0124 
0125   struct VolumeTuple;
0126 
0127   /// Helper function to pretty print the internal volume representation
0128   /// @param volumes is the vector of volumes
0129   /// @param logger is the logger
0130   /// @param lvl is the logging level
0131   static void printVolumeSequence(const std::vector<VolumeTuple>& volumes,
0132                                   const Logger& logger,
0133                                   Acts::Logging::Level lvl);
0134 
0135   /// Helper function that prints output helping in debugging overlaps
0136   /// @param a is the first volume
0137   /// @param b is the second volume
0138   /// @param logger is the logger
0139   static void overlapPrint(const VolumeTuple& a, const VolumeTuple& b,
0140                            const Logger& logger);
0141 
0142   /// Helper function that checks if volumes are properly aligned
0143   /// for attachment.
0144   /// @param volumes is the vector of volumes
0145   /// @param logger is the logger
0146   static void checkVolumeAlignment(const std::vector<VolumeTuple>& volumes,
0147                                    const Logger& logger);
0148 
0149   /// Helper function that checks overlaps and attaches in z direction
0150   /// @param volumes is the vector of volumes
0151   /// @param strategy is the attachment strategy
0152   /// @param logger is the logger
0153   /// @return vector of gap volumes. Can be empty if none were created.
0154   std::vector<VolumeTuple> checkOverlapAndAttachInZ(
0155       std::vector<VolumeTuple>& volumes, AttachmentStrategy strategy,
0156       const Logger& logger);
0157 
0158   /// Helper function to synchronize the r bounds of the volumes
0159   /// @param volumes is the vector of volumes
0160   /// @param logger is the logger
0161   /// @return tuple of the minimum and maximum radii
0162   std::pair<ActsScalar, ActsScalar> synchronizeRBounds(
0163       std::vector<VolumeTuple>& volumes, const Logger& logger);
0164 
0165   /// Helper function that checks overlaps and attaches in r direction
0166   /// @param volumes is the vector of volumes
0167   /// @param strategy is the attachment strategy
0168   /// @param logger is the logger
0169   /// @return vector of gap volumes. Can be empty if none were created.
0170   std::vector<VolumeTuple> checkOverlapAndAttachInR(
0171       std::vector<VolumeTuple>& volumes, AttachmentStrategy strategy,
0172       const Logger& logger);
0173 
0174   /// Helper function to synchronize the z bounds of the volumes
0175   /// @param volumes is the vector of volumes
0176   /// @param logger is the logger
0177   /// @return tuple of the minimum and maximum z extent
0178   std::pair<ActsScalar, ActsScalar> synchronizeZBounds(
0179       std::vector<VolumeTuple>& volumes, const Logger& logger);
0180 
0181   /// Helper functions that checks if the cylinder volume bounds
0182   /// given do not contain any phi sectors or bevels.
0183   /// @param bounds is the cylinder volume bounds
0184   /// @param logger is the logger
0185   static void checkNoPhiOrBevel(const CylinderVolumeBounds& bounds,
0186                                 const Logger& logger);
0187 
0188   /// Helper function to create a gap volume with given bounds and register it.
0189   /// @param transform is the transform of the gap volume
0190   /// @param bounds is the bounds of the gap volume
0191   /// @return the shared pointer to the gap volume
0192   std::shared_ptr<Volume> addGapVolume(
0193       const Transform3& transform, const std::shared_ptr<VolumeBounds>& bounds);
0194 
0195   BinningValue m_direction{};
0196   ResizeStrategy m_resizeStrategy{};
0197   Transform3 m_groupTransform{};
0198   std::vector<std::shared_ptr<Volume>> m_gaps{};
0199   std::vector<Volume*>& m_volumes;
0200 };
0201 
0202 /// Output operator for the attachment strategy
0203 /// @param os is the output stream
0204 /// @param strategy is the attachment strategy
0205 /// @return the output stream
0206 std::ostream& operator<<(std::ostream& os,
0207                          CylinderVolumeStack::AttachmentStrategy strategy);
0208 
0209 /// Output operator for the resize strategy
0210 /// @param os is the output stream
0211 /// @param strategy is the resize strategy
0212 /// @return the output stream
0213 std::ostream& operator<<(std::ostream& os,
0214                          CylinderVolumeStack::ResizeStrategy strategy);
0215 
0216 }  // namespace Acts