Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2019-2020 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/Volume.hpp"
0013 #include "Acts/Geometry/VolumeBounds.hpp"
0014 
0015 #include <array>
0016 #include <iosfwd>
0017 #include <memory>
0018 #include <stdexcept>
0019 #include <vector>
0020 
0021 namespace Acts {
0022 
0023 class CylinderBounds;
0024 class DiscBounds;
0025 
0026 /// Class which implements a cutout cylinder. This shape is basically a
0027 /// cylinder, with another, smaller cylinder subtracted from the center.
0028 /// --------------------- rmax
0029 /// |                   |
0030 /// |    |---------|    | rmed
0031 /// |    |         |    |
0032 /// ------         ------ rmin
0033 ///       -- hlZc --
0034 /// --------- hlZ -------
0035 ///
0036 ///
0037 /// @todo add sectoral cutouts
0038 class CutoutCylinderVolumeBounds : public VolumeBounds {
0039  public:
0040   /// @enum BoundValues for streaming and access
0041   enum BoundValues : int {
0042     eMinR = 0,
0043     eMedR = 1,
0044     eMaxR = 2,
0045     eHalfLengthZ = 3,
0046     eHalfLengthZcutout = 4,
0047     eSize
0048   };
0049 
0050   CutoutCylinderVolumeBounds() = delete;
0051 
0052   /// Constructor from defining parameters
0053   ///
0054   /// @param rmin Minimum radius at the "choke points"
0055   /// @param rmed The medium radius (outer radius of the cutout)
0056   /// @param rmax The outer radius of the overall shape
0057   /// @param hlZ The longer halflength of the shape
0058   /// @param hlZc The cutout halflength of the shape
0059   CutoutCylinderVolumeBounds(double rmin, double rmed, double rmax, double hlZ,
0060                              double hlZc) noexcept(false)
0061       : m_values({rmin, rmed, rmax, hlZ, hlZc}) {
0062     checkConsistency();
0063     buildSurfaceBounds();
0064   }
0065 
0066   /// Constructor - from a fixed size array
0067   ///
0068   /// @param values The bound values
0069   CutoutCylinderVolumeBounds(const std::array<double, eSize>& values) noexcept(
0070       false)
0071       : m_values(values) {
0072     checkConsistency();
0073     buildSurfaceBounds();
0074   }
0075 
0076   ~CutoutCylinderVolumeBounds() override = default;
0077 
0078   VolumeBounds::BoundsType type() const final {
0079     return VolumeBounds::eCutoutCylinder;
0080   }
0081 
0082   /// Return the bound values as dynamically sized vector
0083   ///
0084   /// @return this returns a copy of the internal values
0085   std::vector<double> values() const final;
0086 
0087   /// Inside method to test whether a point is inside the shape
0088   ///
0089   /// @param gpos The point to test
0090   /// @param tol The tolerance to test with
0091   /// @return Whether the point is inside or not.
0092   bool inside(const Vector3& gpos, double tol = 0) const override;
0093 
0094   /// Oriented surfaces, i.e. the decomposed boundary surfaces and the
0095   /// according navigation direction into the volume given the normal
0096   /// vector on the surface
0097   ///
0098   /// @param transform is the 3D transform to be applied to the boundary
0099   /// surfaces to position them in 3D space
0100   ///
0101   /// It will throw an exception if the orientation prescription is not adequate
0102   ///
0103   /// @return a vector of surfaces bounding this volume
0104   std::vector<OrientedSurface> orientedSurfaces(
0105       const Transform3& transform = Transform3::Identity()) const override;
0106 
0107   /// Construct bounding box for this shape
0108   ///
0109   /// @param trf Optional transform
0110   /// @param envelope Optional envelope to add / subtract from min/max
0111   /// @param entity Entity to associate this bounding box with
0112   /// @return Constructed bounding box
0113   Volume::BoundingBox boundingBox(const Transform3* trf = nullptr,
0114                                   const Vector3& envelope = {0, 0, 0},
0115                                   const Volume* entity = nullptr) const final;
0116 
0117   /// Get the canonical binning values, i.e. the binning values
0118   /// for that fully describe the shape's extent
0119   ///
0120   /// @return vector of canonical binning values
0121   std::vector<Acts::BinningValue> canonicalBinning() const override {
0122     return {Acts::binR, Acts::binPhi, Acts::binZ};
0123   };
0124 
0125   /// Write information about this instance to an outstream
0126   ///
0127   /// @param sl The outstream
0128   /// @return The outstream
0129   std::ostream& toStream(std::ostream& sl) const override;
0130 
0131   /// Access to the bound values
0132   /// @param bValue the class nested enum for the array access
0133   double get(BoundValues bValue) const { return m_values[bValue]; }
0134 
0135  private:
0136   std::array<double, eSize> m_values;
0137 
0138   // The surface bound objects
0139   std::shared_ptr<const CylinderBounds> m_innerCylinderBounds{nullptr};
0140   std::shared_ptr<const CylinderBounds> m_cutoutCylinderBounds{nullptr};
0141   std::shared_ptr<const CylinderBounds> m_outerCylinderBounds{nullptr};
0142   std::shared_ptr<const DiscBounds> m_outerDiscBounds{nullptr};
0143   std::shared_ptr<const DiscBounds> m_innerDiscBounds{nullptr};
0144 
0145   /// Create the surface bound objects
0146   void buildSurfaceBounds();
0147 
0148   /// Check the input values for consistency,
0149   /// will throw a logic_exception if consistency is not given
0150   void checkConsistency() noexcept(false);
0151 };
0152 
0153 inline std::vector<double> CutoutCylinderVolumeBounds::values() const {
0154   std::vector<double> valvector;
0155   valvector.insert(valvector.begin(), m_values.begin(), m_values.end());
0156   return valvector;
0157 }
0158 
0159 inline void CutoutCylinderVolumeBounds::checkConsistency() noexcept(false) {
0160   if (get(eMinR) < 0. || get(eMedR) <= 0. || get(eMaxR) <= 0. ||
0161       get(eMinR) >= get(eMedR) || get(eMinR) >= get(eMaxR) ||
0162       get(eMedR) >= get(eMaxR)) {
0163     throw std::invalid_argument(
0164         "CutoutCylinderVolumeBounds: invalid radial input.");
0165   }
0166   if (get(eHalfLengthZ) <= 0 || get(eHalfLengthZcutout) <= 0. ||
0167       get(eHalfLengthZcutout) > get(eHalfLengthZ)) {
0168     throw std::invalid_argument(
0169         "CutoutCylinderVolumeBounds: invalid longitudinal input.");
0170   }
0171 }
0172 
0173 }  // namespace Acts