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