File indexing completed on 2025-12-13 09:21:16
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/DiamondPortalShell.hpp"
0010
0011 #include "Acts/Geometry/DiamondVolumeBounds.hpp"
0012 #include "Acts/Geometry/Portal.hpp"
0013 #include "Acts/Geometry/PortalLinkBase.hpp"
0014
0015 #include <algorithm>
0016 #include <array>
0017 #include <cstddef>
0018 #include <numeric>
0019 #include <stdexcept>
0020 #include <unordered_map>
0021
0022 #include <boost/algorithm/string/join.hpp>
0023
0024 namespace Acts {
0025
0026 void DiamondPortalShell::fill(TrackingVolume& volume) {
0027 for (const auto face : {Face::NegativeZFaceXY, Face::PositiveZFaceXY,
0028 Face::NegativeXFaceYZ12, Face::PositiveXFaceYZ12,
0029 Face::NegativeXFaceYZ23, Face::PositiveXFaceYZ23,
0030 Face::NegativeYFaceZX, Face::PositiveYFaceZX}) {
0031 const auto& portalAtFace = portalPtr(face);
0032 if (portalAtFace != nullptr) {
0033 portalAtFace->fill(volume);
0034 volume.addPortal(portalAtFace);
0035 }
0036 }
0037 }
0038
0039 SingleDiamondPortalShell::SingleDiamondPortalShell(TrackingVolume& volume)
0040 : m_volume{&volume} {
0041 if (m_volume->volumeBounds().type() != VolumeBounds::BoundsType::eDiamond) {
0042 throw std::invalid_argument(
0043 "SingleDiamondPortalShell: Associated volume does not "
0044 "have DiamondVolumeBounds");
0045 }
0046
0047 const auto& bounds =
0048 dynamic_cast<const DiamondVolumeBounds&>(m_volume->volumeBounds());
0049
0050
0051 const auto surfaces = bounds.orientedSurfaces(m_volume->transform());
0052 for (Face face : {Face::NegativeZFaceXY, Face::PositiveZFaceXY,
0053 Face::NegativeXFaceYZ12, Face::PositiveXFaceYZ12,
0054 Face::NegativeXFaceYZ23, Face::PositiveXFaceYZ23,
0055 Face::NegativeYFaceZX, Face::PositiveYFaceZX}) {
0056 const auto& orientedSurface = surfaces.at(toUnderlying(face));
0057 m_portals.at(toUnderlying(face)) = std::make_shared<Portal>(
0058 orientedSurface.direction, orientedSurface.surface, *m_volume);
0059 }
0060 }
0061
0062 std::shared_ptr<Portal> SingleDiamondPortalShell::portalPtr(Face face) {
0063 return m_portals.at(toUnderlying(face));
0064 }
0065
0066 void SingleDiamondPortalShell::setPortal(std::shared_ptr<Portal> portal,
0067 Face face) {
0068 assert(portal != nullptr);
0069 assert(portal->isValid());
0070 m_portals.at(toUnderlying(face)) = std::move(portal);
0071 }
0072
0073 std::size_t SingleDiamondPortalShell::size() const {
0074 return std::ranges::count_if(
0075 m_portals, [](const auto& portal) { return portal != nullptr; });
0076 }
0077
0078 void SingleDiamondPortalShell::applyToVolume() {
0079 for (std::size_t p = 0; p < m_portals.size(); ++p) {
0080 const auto& portal = m_portals.at(p);
0081 if (portal != nullptr) {
0082 if (!portal->isValid()) {
0083 std::stringstream ss;
0084 ss << static_cast<Face>(p);
0085 throw std::runtime_error{"Invalid portal found in shell at" + ss.str()};
0086 }
0087 m_volume->addPortal(portal);
0088 }
0089 }
0090 }
0091
0092 bool SingleDiamondPortalShell::isValid() const {
0093 return std::ranges::all_of(m_portals, [](const auto& portal) {
0094 return portal == nullptr || portal->isValid();
0095 });
0096 }
0097
0098 std::string SingleDiamondPortalShell::label() const {
0099 std::stringstream ss;
0100 ss << "Single Diamond Portal Shell for vol = " + m_volume->volumeName()
0101 << " ";
0102 return ss.str();
0103 }
0104
0105 }