File indexing completed on 2026-04-17 07:46:38
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/detail/AlignablePortalVisitor.hpp"
0010
0011 #include "Acts/Definitions/Tolerance.hpp"
0012 #include "Acts/Geometry/VolumeBounds.hpp"
0013 #include "Acts/Geometry/detail/TrackingGeometryPrintVisitor.hpp"
0014 #include "Acts/Surfaces/RegularSurface.hpp"
0015 #include "Acts/Utilities/StringHelpers.hpp"
0016
0017 #include <cassert>
0018
0019 namespace {
0020
0021
0022
0023 inline bool isSame(const Acts::Transform3& a, const Acts::Transform3& b) {
0024 const Acts::Transform3 c = a * b.inverse();
0025 if (c.translation().norm() > Acts::s_onSurfaceTolerance) {
0026 return false;
0027 }
0028 for (std::size_t d = 0; d < 3; ++d) {
0029 const Acts::Vector3 e = Acts::Vector3::Unit(d);
0030 if (std::abs(e.dot(c * e) - 1.) > Acts::s_onSurfaceTolerance) {
0031 return false;
0032 }
0033 }
0034 return true;
0035 }
0036 }
0037
0038 namespace Acts::detail {
0039
0040 AlignablePortalVisitor::AlignablePortalVisitor(const GeometryContext& gctx,
0041 const Logger& logger)
0042 : TrackingGeometryMutableVisitor{true}, m_gctx{gctx}, m_logger{logger} {}
0043
0044 void AlignablePortalVisitor::visitVolume(TrackingVolume& volume) {
0045 if (!volume.isAlignable()) {
0046 ACTS_VERBOSE("AlignablePortalVisitor() - the volume "
0047 << volume.geometryId() << ", " << volume.volumeBounds()
0048 << " is not alignable");
0049 return;
0050 }
0051 ACTS_DEBUG("AlignablePortalVisitor() - Found alignable volume "
0052 << volume.geometryId() << ", " << volume.volumeBounds());
0053 std::vector<std::shared_ptr<RegularSurface>> alignable{};
0054
0055 for (Portal& portal : volume.portals()) {
0056 ACTS_DEBUG("AlignablePortalVisitor() - Check wheher portal "
0057 << portal.surface().geometryId() << " is a boundary surface");
0058 if (portal.surface().isAlignable()) {
0059 continue;
0060 }
0061 alignable.push_back(
0062 dynamic_pointer_cast<RegularSurface>(portal.surface().getSharedPtr()));
0063 assert(alignable.back() != nullptr);
0064 }
0065 ACTS_DEBUG("AlignablePortalVisitor() - Associate "
0066 << alignable.size() << " portals with the volume.");
0067 std::vector<Transform3> portalTrfBefore{};
0068
0069
0070 if (m_doInspect) {
0071 std::ranges::transform(alignable, std::back_inserter(portalTrfBefore),
0072 [&](const std::shared_ptr<RegularSurface>& surface) {
0073 return surface->localToGlobalTransform(m_gctx);
0074 });
0075 }
0076 volume.volumePlacement()->makePortalsAlignable(m_gctx, alignable);
0077
0078
0079
0080 if (std::ranges::any_of(volume.volumes(), [](const Volume& childVol) {
0081 return !childVol.isAlignable();
0082 })) {
0083 TrackingGeometryPrintVisitor printVisitor{m_gctx};
0084 volume.apply(printVisitor);
0085 ACTS_ERROR("AlignablePortalVisitor() - The volume "
0086 << volume.volumeName() << " has non alignable children: \n"
0087 << printVisitor.stream().str());
0088 throw std::logic_error(
0089 "AlignablePortalVisitor() - Subvolumes of aliganble volumes must be "
0090 "also alignable");
0091 }
0092 if (!m_doInspect) {
0093 return;
0094 }
0095
0096 for (std::size_t p = 0; p < alignable.size(); ++p) {
0097 if (!alignable[p]->isAlignable()) {
0098 ACTS_ERROR("AlignablePortalVisitor() - the "
0099 << p << "-the portal remains not alignable");
0100 throw std::runtime_error(
0101 "AlignablePortalVisitor() - The portal alignment failed");
0102 }
0103 if (alignable[p]->isSensitive()) {
0104 ACTS_ERROR("AlignablePortalVisitor() - the "
0105 << p << "-the portal became sensitive");
0106 throw std::runtime_error(
0107 "AlignablePortalVisitor() - The portal alignment failed");
0108 }
0109 if (!isSame(alignable[p]->localToGlobalTransform(m_gctx),
0110 portalTrfBefore[p])) {
0111 ACTS_ERROR("AlignablePortalVisitor() - the "
0112 << p << "-the portal transforms\n --- aligned: "
0113 << toString(alignable[p]->localToGlobalTransform(m_gctx))
0114 << "\n --- unaligned: " << toString(portalTrfBefore[p])
0115 << " are not the same");
0116 throw std::runtime_error(
0117 "AlignablePortalVisitor() - The portal alignment failed");
0118 }
0119 }
0120 }
0121
0122 const Logger& AlignablePortalVisitor::logger() const {
0123 return m_logger;
0124 }
0125
0126 void AlignablePortalVisitor::enableInspection() {
0127 m_doInspect = true;
0128 }
0129
0130 }