Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-15 08:12:20

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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   // Three options:
0088   // 1. Grid
0089   // 2. Trivial
0090   // 3. Composite
0091 
0092   // Grid Grid
0093   // Grid Trivial
0094   // Grid Composite
0095   // Trivial Grid
0096   // Trivial Trivial
0097   // Trivial Composite
0098   // Composite Grid
0099   // Composite Trivial
0100   // Composite Composite
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 }  // namespace Acts