Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /acts/Core/src/Geometry/CuboidVolumeBounds.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0010 
0011 #include "Acts/Definitions/Direction.hpp"
0012 #include "Acts/Surfaces/LineSurface.hpp"
0013 #include "Acts/Surfaces/PlaneSurface.hpp"
0014 #include "Acts/Surfaces/RectangleBounds.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Utilities/BoundingBox.hpp"
0017 
0018 #include <algorithm>
0019 #include <array>
0020 #include <stdexcept>
0021 #include <utility>
0022 
0023 namespace Acts {
0024 
0025 CuboidVolumeBounds::CuboidVolumeBounds(double halex, double haley, double halez)
0026     : VolumeBounds(), m_values({halex, haley, halez}) {
0027   checkConsistency();
0028   buildSurfaceBounds();
0029 }
0030 
0031 CuboidVolumeBounds::CuboidVolumeBounds(const std::array<double, eSize>& values)
0032     : m_values(values) {
0033   checkConsistency();
0034   buildSurfaceBounds();
0035 }
0036 
0037 CuboidVolumeBounds::CuboidVolumeBounds(
0038     std::initializer_list<std::pair<BoundValues, double>> keyValues)
0039     : m_values({-1, -1, -1}) {
0040   for (const auto& [key, value] : keyValues) {
0041     m_values[key] = value;
0042   }
0043   // Throw error here instead of consistency check for clarity
0044   if (std::any_of(m_values.begin(), m_values.end(),
0045                   [](const auto& val) { return val == -1; })) {
0046     throw std::logic_error("Missing bound values");
0047   }
0048   checkConsistency();
0049   buildSurfaceBounds();
0050 }
0051 
0052 std::vector<double> CuboidVolumeBounds::values() const {
0053   return {m_values.begin(), m_values.end()};
0054 }
0055 
0056 std::vector<Acts::OrientedSurface> Acts::CuboidVolumeBounds::orientedSurfaces(
0057     const Transform3& transform) const {
0058   std::vector<OrientedSurface> oSurfaces;
0059   oSurfaces.reserve(6);
0060   // Face surfaces xy -------------------------------------
0061   //   (1) - at negative local z
0062   auto sf = Surface::makeShared<PlaneSurface>(
0063       transform * Translation3(0., 0., -get(eHalfLengthZ)), m_xyBounds);
0064   oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()});
0065   //   (2) - at positive local z
0066   sf = Surface::makeShared<PlaneSurface>(
0067       transform * Translation3(0., 0., get(eHalfLengthZ)), m_xyBounds);
0068   oSurfaces.push_back(
0069       OrientedSurface{std::move(sf), Direction::OppositeNormal()});
0070   // Face surfaces yz -------------------------------------
0071   //   (3) - at negative local x
0072   sf = Surface::makeShared<PlaneSurface>(
0073       transform * Translation3(-get(eHalfLengthX), 0., 0.) * s_planeYZ,
0074       m_yzBounds);
0075   oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()});
0076   //   (4) - at positive local x
0077   sf = Surface::makeShared<PlaneSurface>(
0078       transform * Translation3(get(eHalfLengthX), 0., 0.) * s_planeYZ,
0079       m_yzBounds);
0080   oSurfaces.push_back(
0081       OrientedSurface{std::move(sf), Direction::OppositeNormal()});
0082   // Face surfaces zx -------------------------------------
0083   //   (5) - at negative local y
0084   sf = Surface::makeShared<PlaneSurface>(
0085       transform * Translation3(0., -get(eHalfLengthY), 0.) * s_planeZX,
0086       m_zxBounds);
0087   oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()});
0088   //   (6) - at positive local y
0089   sf = Surface::makeShared<PlaneSurface>(
0090       transform * Translation3(0., get(eHalfLengthY), 0.) * s_planeZX,
0091       m_zxBounds);
0092   oSurfaces.push_back(
0093       OrientedSurface{std::move(sf), Direction::OppositeNormal()});
0094 
0095   return oSurfaces;
0096 }
0097 
0098 std::ostream& CuboidVolumeBounds::toStream(std::ostream& os) const {
0099   os << std::setiosflags(std::ios::fixed);
0100   os << std::setprecision(5);
0101   os << "Acts::CuboidVolumeBounds: (halfLengthX, halfLengthY, halfLengthZ) = ";
0102   os << "(" << get(eHalfLengthX) << ", " << get(eHalfLengthY) << ", "
0103      << get(eHalfLengthZ) << ")";
0104   return os;
0105 }
0106 
0107 Volume::BoundingBox CuboidVolumeBounds::boundingBox(
0108     const Transform3* trf, const Vector3& envelope,
0109     const Volume* entity) const {
0110   Vector3 vmin(-get(eHalfLengthX), -get(eHalfLengthY), -get(eHalfLengthZ));
0111   Vector3 vmax(get(eHalfLengthX), get(eHalfLengthY), get(eHalfLengthZ));
0112 
0113   Volume::BoundingBox box(entity, vmin - envelope, vmax + envelope);
0114   return trf == nullptr ? box : box.transformed(*trf);
0115 }
0116 
0117 void CuboidVolumeBounds::buildSurfaceBounds() {
0118   m_xyBounds = std::make_shared<const RectangleBounds>(get(eHalfLengthX),
0119                                                        get(eHalfLengthY));
0120   m_yzBounds = std::make_shared<const RectangleBounds>(get(eHalfLengthY),
0121                                                        get(eHalfLengthZ));
0122   m_zxBounds = std::make_shared<const RectangleBounds>(get(eHalfLengthZ),
0123                                                        get(eHalfLengthX));
0124 }
0125 
0126 double CuboidVolumeBounds::referenceBorder(AxisDirection aDir) const {
0127   if (aDir <= AxisDirection::AxisZ) {
0128     return m_values[toUnderlying(aDir)];
0129   }
0130   if (aDir == AxisDirection::AxisR) {
0131     return std::sqrt(m_values[toUnderlying(AxisDirection::AxisX)] *
0132                          m_values[toUnderlying(AxisDirection::AxisX)] +
0133                      m_values[toUnderlying(AxisDirection::AxisY)] *
0134                          m_values[toUnderlying(AxisDirection::AxisY)]);
0135   }
0136   return 0.0;
0137 }
0138 
0139 bool CuboidVolumeBounds::inside(const Vector3& pos, double tol) const {
0140   return (std::abs(pos.x()) <= get(eHalfLengthX) + tol &&
0141           std::abs(pos.y()) <= get(eHalfLengthY) + tol &&
0142           std::abs(pos.z()) <= get(eHalfLengthZ) + tol);
0143 }
0144 
0145 void CuboidVolumeBounds::checkConsistency() noexcept(false) {
0146   if (get(eHalfLengthX) <= 0 || get(eHalfLengthY) <= 0 ||
0147       get(eHalfLengthZ) <= 0.) {
0148     throw std::invalid_argument(
0149         "CuboidVolumeBounds: invalid input, zero or negative.");
0150   }
0151 }
0152 
0153 void CuboidVolumeBounds::set(BoundValues bValue, double value) {
0154   set({{bValue, value}});
0155 }
0156 
0157 void CuboidVolumeBounds::set(
0158     std::initializer_list<std::pair<BoundValues, double>> keyValues) {
0159   std::array<double, eSize> previous = m_values;
0160   for (const auto& [key, value] : keyValues) {
0161     m_values[key] = value;
0162   }
0163   try {
0164     checkConsistency();
0165     buildSurfaceBounds();
0166   } catch (std::invalid_argument& e) {
0167     m_values = previous;
0168     throw e;
0169   }
0170 }
0171 
0172 CuboidVolumeBounds::BoundValues CuboidVolumeBounds::boundsFromAxisDirection(
0173     AxisDirection direction) {
0174   using enum AxisDirection;
0175   switch (direction) {
0176     case AxisX:
0177       return BoundValues::eHalfLengthX;
0178     case AxisY:
0179       return BoundValues::eHalfLengthY;
0180     case AxisZ:
0181       return BoundValues::eHalfLengthZ;
0182     default:
0183       throw std::invalid_argument("Invalid axis direction");
0184   }
0185 }
0186 
0187 std::tuple<CuboidVolumeBounds::Face, CuboidVolumeBounds::Face,
0188            std::array<CuboidVolumeBounds::Face, 4>>
0189 CuboidVolumeBounds::facesFromAxisDirection(AxisDirection direction) {
0190   using enum AxisDirection;
0191   using enum CuboidVolumeBounds::Face;
0192   if (direction == AxisX) {
0193     return {NegativeXFace,
0194             PositiveXFace,
0195             {NegativeZFace, PositiveZFace, NegativeYFace, PositiveYFace}};
0196   } else if (direction == AxisY) {
0197     return {NegativeYFace,
0198             PositiveYFace,
0199             {NegativeZFace, PositiveZFace, NegativeXFace, PositiveXFace}};
0200   } else if (direction == AxisZ) {
0201     return {NegativeZFace,
0202             PositiveZFace,
0203             {NegativeXFace, PositiveXFace, NegativeYFace, PositiveYFace}};
0204   } else {
0205     throw std::invalid_argument("Invalid axis direction");
0206   }
0207 }
0208 
0209 }  // namespace Acts
0210 
0211 // Define operator<< for CuboidVolumeBounds::Face outside the class
0212 std::ostream& operator<<(std::ostream& os,
0213                          Acts::CuboidVolumeBounds::Face face) {
0214   using enum Acts::CuboidVolumeBounds::Face;
0215   switch (face) {
0216     case NegativeXFace:
0217       return os << "NegativeXFace";
0218     case PositiveXFace:
0219       return os << "PositiveXFace";
0220     case NegativeYFace:
0221       return os << "NegativeYFace";
0222     case PositiveYFace:
0223       return os << "PositiveYFace";
0224     case NegativeZFace:
0225       return os << "NegativeZFace";
0226     case PositiveZFace:
0227       return os << "PositiveZFace";
0228     default:
0229       return os << "UnknownFace";
0230   }
0231 }