File indexing completed on 2026-04-01 07:46:04
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/TrapezoidPortalShell.hpp"
0010
0011 #include "Acts/Geometry/Portal.hpp"
0012 #include "Acts/Geometry/PortalLinkBase.hpp"
0013 #include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
0014
0015 namespace Acts {
0016
0017 void TrapezoidPortalShell::fill(TrackingVolume& volume) {
0018 for (Face face : {NegativeZFaceXY, PositiveZFaceXY, TrapezoidFaceAlpha,
0019 TrapezoidFaceBeta, NegativeYFaceZX, PositiveYFaceZX}) {
0020 const auto& portalAtFace = portal(face);
0021 if (portalAtFace != nullptr) {
0022 portalAtFace->fill(volume);
0023 volume.addPortal(portalAtFace);
0024 }
0025 }
0026 }
0027
0028 SingleTrapezoidPortalShell::SingleTrapezoidPortalShell(
0029 const GeometryContext& gctx, TrackingVolume& volume)
0030 : m_volume{&volume} {
0031 if (m_volume->volumeBounds().type() != VolumeBounds::BoundsType::eTrapezoid) {
0032 throw std::invalid_argument("Invalid volume bounds - not trapezoid");
0033 }
0034
0035 const auto& bounds =
0036 dynamic_cast<const TrapezoidVolumeBounds&>(m_volume->volumeBounds());
0037
0038 std::vector<OrientedSurface> orientedSurfaces =
0039 bounds.orientedSurfaces(m_volume->localToGlobalTransform(gctx));
0040
0041 for (Face face : {NegativeZFaceXY, PositiveZFaceXY, TrapezoidFaceAlpha,
0042 TrapezoidFaceBeta, NegativeYFaceZX, PositiveYFaceZX}) {
0043 const auto& portalSurface = orientedSurfaces.at(toUnderlying(face));
0044
0045 m_portals.at(toUnderlying(face)) = std::make_shared<Portal>(
0046 portalSurface.direction, portalSurface.surface, *m_volume);
0047 }
0048 }
0049
0050 std::shared_ptr<Portal> SingleTrapezoidPortalShell::portal(Face face) {
0051 return m_portals.at(toUnderlying(face));
0052 }
0053
0054 void SingleTrapezoidPortalShell::setPortal(std::shared_ptr<Portal> portal,
0055 Face face) {
0056 assert(portal != nullptr);
0057 assert(portal->isValid());
0058 m_portals.at(toUnderlying(face)) = std::move(portal);
0059 }
0060
0061 std::size_t SingleTrapezoidPortalShell::size() const {
0062 std::size_t count = 0;
0063 std::ranges::for_each(
0064 m_portals, [&count](const auto& portal) { count += portal ? 1 : 0; });
0065 return count;
0066 }
0067
0068 void SingleTrapezoidPortalShell::applyToVolume() {
0069 for (std::size_t i = 0; i < m_portals.size(); i++) {
0070 const auto& portal = m_portals.at(i);
0071 if (portal != nullptr) {
0072 if (!portal->isValid()) {
0073 std::stringstream ss;
0074 ss << static_cast<Face>(i);
0075 throw std::runtime_error{"Invalid portal found in shell at " +
0076 ss.str()};
0077 }
0078 m_volume->addPortal(portal);
0079 }
0080 }
0081 }
0082
0083 bool SingleTrapezoidPortalShell::isValid() const {
0084 return std::ranges::all_of(m_portals, [](const auto& portal) {
0085 return portal == nullptr || portal->isValid();
0086 });
0087 }
0088
0089 std::string SingleTrapezoidPortalShell::label() const {
0090 std::stringstream ss;
0091 ss << "TrapezoidShell(vol=" << m_volume->volumeName() << ")";
0092 return ss.str();
0093 }
0094
0095 std::ostream& operator<<(std::ostream& os, TrapezoidPortalShell::Face face) {
0096 switch (face) {
0097 case TrapezoidPortalShell::NegativeZFaceXY:
0098 return os << "NegativeZFaceXY";
0099 case TrapezoidPortalShell::PositiveZFaceXY:
0100 return os << "PositiveZFaceXY";
0101 case TrapezoidPortalShell::TrapezoidFaceAlpha:
0102 return os << "TrapezoidFaceAlpha";
0103 case TrapezoidPortalShell::TrapezoidFaceBeta:
0104 return os << "TrapezoidFaceBeta";
0105 case TrapezoidPortalShell::NegativeYFaceZX:
0106 return os << "NegativeYFaceZX";
0107 case TrapezoidPortalShell::PositiveYFaceZX:
0108 return os << "PositiveYFaceZX";
0109 default:
0110 return os << "Invalid face";
0111 }
0112 }
0113
0114 }