File indexing completed on 2025-07-15 08:12:20
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/PortalLinkBase.hpp"
0010
0011 #include "Acts/Geometry/CompositePortalLink.hpp"
0012 #include "Acts/Geometry/GridPortalLink.hpp"
0013 #include "Acts/Geometry/TrivialPortalLink.hpp"
0014 #include "Acts/Surfaces/CylinderSurface.hpp"
0015 #include "Acts/Surfaces/DiscSurface.hpp"
0016 #include "Acts/Surfaces/RadialBounds.hpp"
0017 #include "Acts/Surfaces/RectangleBounds.hpp"
0018 #include "Acts/Surfaces/RegularSurface.hpp"
0019 #include "Acts/Utilities/ThrowAssert.hpp"
0020
0021 namespace Acts {
0022
0023 void PortalLinkBase::checkMergePreconditions(const PortalLinkBase& a,
0024 const PortalLinkBase& b,
0025 AxisDirection direction) {
0026 const auto& surfaceA = a.surface();
0027 const auto& surfaceB = b.surface();
0028
0029 throw_assert(&surfaceA != &surfaceB,
0030 "Cannot merge portals to the same surface");
0031
0032 throw_assert(surfaceA.type() == surfaceB.type(),
0033 "Cannot merge portals of different surface types");
0034
0035 throw_assert(surfaceA.bounds().type() == surfaceB.bounds().type(),
0036 "Cannot merge portals of different surface bounds");
0037
0038 if (const auto* cylA = dynamic_cast<const CylinderSurface*>(&surfaceA);
0039 cylA != nullptr) {
0040 const auto* cylB = dynamic_cast<const CylinderSurface*>(&surfaceB);
0041 throw_assert(cylB != nullptr,
0042 "Cannot merge CylinderSurface with "
0043 "non-CylinderSurface");
0044 throw_assert(direction == AxisDirection::AxisZ ||
0045 direction == AxisDirection::AxisRPhi,
0046 "Invalid binning direction: " + axisDirectionName(direction));
0047 } else if (const auto* discA = dynamic_cast<const DiscSurface*>(&surfaceA);
0048 discA != nullptr) {
0049 const auto* discB = dynamic_cast<const DiscSurface*>(&surfaceB);
0050 throw_assert(discB != nullptr,
0051 "Cannot merge DiscSurface with non-DiscSurface");
0052 throw_assert(direction == AxisDirection::AxisR ||
0053 direction == AxisDirection::AxisPhi,
0054 "Invalid binning direction: " + axisDirectionName(direction));
0055
0056 throw_assert(dynamic_cast<const RadialBounds*>(&discA->bounds()) &&
0057 dynamic_cast<const RadialBounds*>(&discB->bounds()),
0058 "DiscSurface bounds must be RadialBounds");
0059
0060 } else if (const auto* planeA = dynamic_cast<const PlaneSurface*>(&surfaceA);
0061 planeA != nullptr) {
0062 const auto* planeB = dynamic_cast<const PlaneSurface*>(&surfaceB);
0063 throw_assert(planeB != nullptr,
0064 "Cannot merge PlaneSurface with non-PlaneSurface");
0065 throw_assert(
0066 direction == AxisDirection::AxisX || direction == AxisDirection::AxisY,
0067 "Invalid binning direction: " + axisDirectionName(direction));
0068
0069 throw_assert(dynamic_cast<const RectangleBounds*>(&planeA->bounds()) &&
0070 dynamic_cast<const RectangleBounds*>(&planeB->bounds()),
0071 "PlaneSurface bounds must be RectangleBounds");
0072 } else {
0073 throw std::logic_error{"Surface type is not supported"};
0074 }
0075 }
0076
0077 std::unique_ptr<PortalLinkBase> PortalLinkBase::merge(
0078 std::unique_ptr<PortalLinkBase> a, std::unique_ptr<PortalLinkBase> b,
0079 AxisDirection direction, const Logger& logger) {
0080 ACTS_VERBOSE("Merging two arbitrary portals");
0081
0082 ACTS_VERBOSE(" - a: " << *a);
0083 ACTS_VERBOSE(" - b: " << *b);
0084
0085 checkMergePreconditions(*a, *b, direction);
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 auto gridMerge =
0103 [&](const GridPortalLink& aGrid,
0104 const GridPortalLink& bGrid) -> std::unique_ptr<PortalLinkBase> {
0105 assert(a != nullptr);
0106 assert(b != nullptr);
0107 auto merged = GridPortalLink::merge(aGrid, bGrid, direction, logger);
0108 if (merged == nullptr) {
0109 return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
0110 direction);
0111 }
0112 return merged;
0113 };
0114
0115 if (const auto* aGrid = dynamic_cast<const GridPortalLink*>(a.get());
0116 aGrid != nullptr) {
0117 if (const auto* bGrid = dynamic_cast<const GridPortalLink*>(b.get());
0118 bGrid != nullptr) {
0119 ACTS_VERBOSE("Merging two grid portals");
0120 return gridMerge(*aGrid, *bGrid);
0121
0122 } else if (const auto* bTrivial =
0123 dynamic_cast<const TrivialPortalLink*>(b.get());
0124 bTrivial != nullptr) {
0125 ACTS_WARNING(
0126 "Merging a grid portal with a trivial portal (via composite)");
0127 return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
0128 direction);
0129
0130 } else if (dynamic_cast<const CompositePortalLink*>(b.get()) != nullptr) {
0131 ACTS_WARNING("Merging a grid portal with a composite portal");
0132 return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
0133 direction);
0134
0135 } else {
0136 throw std::logic_error{"Portal link type is not supported"};
0137 }
0138
0139 } else if (const auto* aTrivial =
0140 dynamic_cast<const TrivialPortalLink*>(a.get());
0141 aTrivial != nullptr) {
0142 if (const auto* bGrid = dynamic_cast<const GridPortalLink*>(b.get());
0143 bGrid) {
0144 ACTS_WARNING(
0145 "Merging a trivial portal with a grid portal (via composite)");
0146 return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
0147 direction);
0148
0149 } else if (const auto* bTrivial =
0150 dynamic_cast<const TrivialPortalLink*>(b.get());
0151 bTrivial != nullptr) {
0152 ACTS_VERBOSE("Merging two trivial portals (via composite");
0153 return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
0154 direction);
0155
0156 } else if (dynamic_cast<const CompositePortalLink*>(b.get()) != nullptr) {
0157 ACTS_VERBOSE("Merging a trivial portal with a composite portal");
0158 return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
0159 direction);
0160
0161 } else {
0162 throw std::logic_error{"Portal link type is not supported"};
0163 }
0164
0165 } else if (dynamic_cast<const CompositePortalLink*>(a.get()) != nullptr) {
0166 if (dynamic_cast<const GridPortalLink*>(b.get()) != nullptr) {
0167 ACTS_WARNING("Merging a composite portal with a grid portal");
0168 return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
0169 direction);
0170
0171 } else if (dynamic_cast<const TrivialPortalLink*>(b.get()) != nullptr) {
0172 ACTS_VERBOSE("Merging a composite portal with a trivial portal");
0173 return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
0174 direction);
0175
0176 } else if (dynamic_cast<CompositePortalLink*>(b.get()) != nullptr) {
0177 ACTS_VERBOSE("Merging two composite portals");
0178 return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
0179 direction);
0180
0181 } else {
0182 throw std::logic_error{"Portal link type is not supported"};
0183 }
0184
0185 } else {
0186 throw std::logic_error{"Portal link type is not supported"};
0187 }
0188 }
0189
0190 }