From 20485bd6065dbf93df7b6e97bc278690553b5fb3 Mon Sep 17 00:00:00 2001 From: Paul Gessinger Date: Wed, 21 Aug 2024 16:11:04 +0200 Subject: [PATCH] link: PortalLinkBase is standalone file --- .../Acts/Geometry/CompositePortalLink.hpp | 1 + Core/include/Acts/Geometry/GridPortalLink.hpp | 1 + Core/include/Acts/Geometry/PortalLinkBase.hpp | 64 +++++++ .../Acts/Geometry/TrivialPortalLink.hpp | 1 + Core/src/Geometry/CMakeLists.txt | 1 + Core/src/Geometry/PortalLinkBase.cpp | 173 ++++++++++++++++++ 6 files changed, 241 insertions(+) create mode 100644 Core/include/Acts/Geometry/PortalLinkBase.hpp create mode 100644 Core/src/Geometry/PortalLinkBase.cpp diff --git a/Core/include/Acts/Geometry/CompositePortalLink.hpp b/Core/include/Acts/Geometry/CompositePortalLink.hpp index 39c2bf6e85a5..a4b0ab57652e 100644 --- a/Core/include/Acts/Geometry/CompositePortalLink.hpp +++ b/Core/include/Acts/Geometry/CompositePortalLink.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Geometry/Portal.hpp" +#include "Acts/Geometry/PortalLinkBase.hpp" #include diff --git a/Core/include/Acts/Geometry/GridPortalLink.hpp b/Core/include/Acts/Geometry/GridPortalLink.hpp index d84d99f8e1fe..4a1a951fcd43 100644 --- a/Core/include/Acts/Geometry/GridPortalLink.hpp +++ b/Core/include/Acts/Geometry/GridPortalLink.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Geometry/Portal.hpp" +#include "Acts/Geometry/PortalLinkBase.hpp" #include "Acts/Geometry/TrackingVolume.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/CylinderSurface.hpp" diff --git a/Core/include/Acts/Geometry/PortalLinkBase.hpp b/Core/include/Acts/Geometry/PortalLinkBase.hpp new file mode 100644 index 000000000000..21d429393568 --- /dev/null +++ b/Core/include/Acts/Geometry/PortalLinkBase.hpp @@ -0,0 +1,64 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/Logger.hpp" + +#include + +namespace Acts { + +class RegularSurface; +class TrackingVolume; +class GeometryContext; + +class PortalLinkBase { + public: + PortalLinkBase(std::shared_ptr surface) + : m_surface(std::move(surface)) {} + + virtual ~PortalLinkBase() = default; + + // @TODO: Does this need boundary tolerance? + virtual const TrackingVolume* resolveVolume( + const GeometryContext& gctx, const Vector3& position) const = 0; + + virtual const TrackingVolume* resolveVolume( + const GeometryContext& gctx, const Vector2& position) const = 0; + + static std::unique_ptr merge( + std::unique_ptr a, std::unique_ptr b, + BinningValue direction, const Logger& logger = getDummyLogger()); + + virtual void toStream(std::ostream& os) const = 0; + + friend std::ostream& operator<<(std::ostream& os, + const PortalLinkBase& link) { + link.toStream(os); + return os; + } + + const RegularSurface& surface() const { return *m_surface; } + void setSurface(std::shared_ptr surface) { + m_surface = std::move(surface); + } + + std::shared_ptr surfacePtr() const { return m_surface; } + + protected: + static void checkMergePreconditions(const PortalLinkBase& a, + const PortalLinkBase& b, + BinningValue direction); + + std::shared_ptr m_surface; +}; + +} // namespace Acts diff --git a/Core/include/Acts/Geometry/TrivialPortalLink.hpp b/Core/include/Acts/Geometry/TrivialPortalLink.hpp index 0d519f73473d..ddacad344923 100644 --- a/Core/include/Acts/Geometry/TrivialPortalLink.hpp +++ b/Core/include/Acts/Geometry/TrivialPortalLink.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Geometry/Portal.hpp" +#include "Acts/Geometry/PortalLinkBase.hpp" namespace Acts { diff --git a/Core/src/Geometry/CMakeLists.txt b/Core/src/Geometry/CMakeLists.txt index 19ab32f88057..082a4abcdab3 100644 --- a/Core/src/Geometry/CMakeLists.txt +++ b/Core/src/Geometry/CMakeLists.txt @@ -40,4 +40,5 @@ target_sources( GridPortalLinkMerging.cpp TrivialPortalLink.cpp CompositePortalLink.cpp + PortalLinkBase.cpp ) diff --git a/Core/src/Geometry/PortalLinkBase.cpp b/Core/src/Geometry/PortalLinkBase.cpp new file mode 100644 index 000000000000..9a6be75794c4 --- /dev/null +++ b/Core/src/Geometry/PortalLinkBase.cpp @@ -0,0 +1,173 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "Acts/Geometry/PortalLinkBase.hpp" + +#include "Acts/Geometry/CompositePortalLink.hpp" +#include "Acts/Geometry/GridPortalLink.hpp" +#include "Acts/Geometry/TrivialPortalLink.hpp" +#include "Acts/Surfaces/CylinderSurface.hpp" +#include "Acts/Surfaces/DiscSurface.hpp" +#include "Acts/Surfaces/RadialBounds.hpp" +#include "Acts/Surfaces/RegularSurface.hpp" +#include "Acts/Utilities/ThrowAssert.hpp" + +namespace Acts { + +void PortalLinkBase::checkMergePreconditions(const PortalLinkBase& a, + const PortalLinkBase& b, + BinningValue direction) { + const auto& surfaceA = a.surface(); + const auto& surfaceB = b.surface(); + + throw_assert(&surfaceA != &surfaceB, + "Cannot merge portals to the same surface"); + + throw_assert(surfaceA.type() == surfaceB.type(), + "Cannot merge portals of different surface types"); + + throw_assert(surfaceA.bounds().type() == surfaceB.bounds().type(), + "Cannot merge portals of different surface bounds"); + + if (const auto* cylA = dynamic_cast(&surfaceA); + cylA != nullptr) { + const auto* cylB = dynamic_cast(&surfaceB); + throw_assert(cylB != nullptr, + "Cannot merge CylinderSurface with " + "non-CylinderSurface"); + throw_assert( + direction == BinningValue::binZ || direction == BinningValue::binRPhi, + "Invalid binning direction: " + binningValueName(direction)); + } else if (const auto* discA = dynamic_cast(&surfaceA); + discA != nullptr) { + const auto* discB = dynamic_cast(&surfaceB); + throw_assert(discB != nullptr, + "Cannot merge DiscSurface with non-DiscSurface"); + throw_assert( + direction == BinningValue::binR || direction == BinningValue::binPhi, + "Invalid binning direction: " + binningValueName(direction)); + + throw_assert(dynamic_cast(&discA->bounds()) && + dynamic_cast(&discB->bounds()), + "DiscSurface bounds must be RadialBounds"); + + } else { + throw std::logic_error{"Surface type is not supported"}; + } +} + +std::unique_ptr PortalLinkBase::merge( + std::unique_ptr a, std::unique_ptr b, + BinningValue direction, const Logger& logger) { + ACTS_DEBUG("Merging two arbitrary portals"); + + ACTS_VERBOSE(" - a: " << *a); + ACTS_VERBOSE(" - b: " << *b); + + checkMergePreconditions(*a, *b, direction); + + // Three options: + // 1. Grid + // 2. Trivial + // 3. Composite + + // Grid Grid + // Grid Trivial + // Grid Composite + // Trivial Grid + // Trivial Trivial + // Trivial Composite + // Composite Grid + // Composite Trivial + // Composite Composite + + auto gridMerge = + [&](const GridPortalLink& aGrid, + const GridPortalLink& bGrid) -> std::unique_ptr { + assert(a != nullptr); + assert(b != nullptr); + auto merged = GridPortalLink::merge(aGrid, bGrid, direction, logger); + if (merged == nullptr) { + return std::make_unique(std::move(a), std::move(b), + direction); + } + return merged; + }; + + if (const auto* aGrid = dynamic_cast(a.get()); + aGrid != nullptr) { + if (const auto* bGrid = dynamic_cast(b.get()); + bGrid != nullptr) { + ACTS_VERBOSE("Merging two grid portals"); + return gridMerge(*aGrid, *bGrid); + + } else if (const auto* bTrivial = + dynamic_cast(b.get()); + bTrivial != nullptr) { + ACTS_VERBOSE("Merging a grid portal with a trivial portal"); + return gridMerge(*aGrid, *bTrivial->makeGrid(direction)); + + } else if (dynamic_cast(b.get()) != nullptr) { + ACTS_WARNING("Merging a grid portal with a composite portal"); + return std::make_unique(std::move(a), std::move(b), + direction); + + } else { + throw std::logic_error{"Portal link type is not supported"}; + } + + } else if (const auto* aTrivial = + dynamic_cast(a.get()); + aTrivial != nullptr) { + if (const auto* bGrid = dynamic_cast(b.get()); + bGrid) { + ACTS_VERBOSE("Merging a trivial portal with a grid portal"); + return gridMerge(*aTrivial->makeGrid(direction), *bGrid); + + } else if (const auto* bTrivial = + dynamic_cast(b.get()); + bTrivial != nullptr) { + ACTS_VERBOSE("Merging two trivial portals"); + return gridMerge(*aTrivial->makeGrid(direction), + *bTrivial->makeGrid(direction)); + + } else if (dynamic_cast(b.get()) != nullptr) { + ACTS_WARNING("Merging a trivial portal with a composite portal"); + return std::make_unique(std::move(a), std::move(b), + direction); + + } else { + throw std::logic_error{"Portal link type is not supported"}; + } + + } else if (dynamic_cast(a.get()) != nullptr) { + if (dynamic_cast(b.get()) != nullptr) { + ACTS_WARNING("Merging a composite portal with a grid portal"); + return std::make_unique(std::move(a), std::move(b), + direction); + + } else if (dynamic_cast(b.get()) != nullptr) { + ACTS_WARNING("Merging a composite portal with a trivial portal"); + return std::make_unique(std::move(a), std::move(b), + direction); + + } else if (dynamic_cast(b.get()) != nullptr) { + ACTS_WARNING("Merging two composite portals"); + return std::make_unique(std::move(a), std::move(b), + direction); + + } else { + throw std::logic_error{"Portal link type is not supported"}; + } + + } else { + throw std::logic_error{"Portal link type is not supported"}; + } +} + +} // namespace Acts