Skip to content

Commit

Permalink
link: PortalLinkBase is standalone file
Browse files Browse the repository at this point in the history
  • Loading branch information
paulgessinger committed Aug 21, 2024
1 parent 30de556 commit 20485bd
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 0 deletions.
1 change: 1 addition & 0 deletions Core/include/Acts/Geometry/CompositePortalLink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include "Acts/Geometry/Portal.hpp"
#include "Acts/Geometry/PortalLinkBase.hpp"

#include <boost/container/small_vector.hpp>

Expand Down
1 change: 1 addition & 0 deletions Core/include/Acts/Geometry/GridPortalLink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
64 changes: 64 additions & 0 deletions Core/include/Acts/Geometry/PortalLinkBase.hpp
Original file line number Diff line number Diff line change
@@ -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 <memory>

namespace Acts {

class RegularSurface;
class TrackingVolume;
class GeometryContext;

class PortalLinkBase {
public:
PortalLinkBase(std::shared_ptr<RegularSurface> 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<PortalLinkBase> merge(
std::unique_ptr<PortalLinkBase> a, std::unique_ptr<PortalLinkBase> 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<RegularSurface> surface) {
m_surface = std::move(surface);
}

std::shared_ptr<RegularSurface> surfacePtr() const { return m_surface; }

protected:
static void checkMergePreconditions(const PortalLinkBase& a,
const PortalLinkBase& b,
BinningValue direction);

std::shared_ptr<RegularSurface> m_surface;
};

} // namespace Acts
1 change: 1 addition & 0 deletions Core/include/Acts/Geometry/TrivialPortalLink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include "Acts/Geometry/Portal.hpp"
#include "Acts/Geometry/PortalLinkBase.hpp"

namespace Acts {

Expand Down
1 change: 1 addition & 0 deletions Core/src/Geometry/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ target_sources(
GridPortalLinkMerging.cpp
TrivialPortalLink.cpp
CompositePortalLink.cpp
PortalLinkBase.cpp
)
173 changes: 173 additions & 0 deletions Core/src/Geometry/PortalLinkBase.cpp
Original file line number Diff line number Diff line change
@@ -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<const CylinderSurface*>(&surfaceA);
cylA != nullptr) {
const auto* cylB = dynamic_cast<const CylinderSurface*>(&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<const DiscSurface*>(&surfaceA);
discA != nullptr) {
const auto* discB = dynamic_cast<const DiscSurface*>(&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<const RadialBounds*>(&discA->bounds()) &&
dynamic_cast<const RadialBounds*>(&discB->bounds()),
"DiscSurface bounds must be RadialBounds");

} else {
throw std::logic_error{"Surface type is not supported"};
}
}

std::unique_ptr<PortalLinkBase> PortalLinkBase::merge(
std::unique_ptr<PortalLinkBase> a, std::unique_ptr<PortalLinkBase> 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<PortalLinkBase> {
assert(a != nullptr);
assert(b != nullptr);
auto merged = GridPortalLink::merge(aGrid, bGrid, direction, logger);
if (merged == nullptr) {
return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
direction);
}
return merged;
};

if (const auto* aGrid = dynamic_cast<const GridPortalLink*>(a.get());
aGrid != nullptr) {
if (const auto* bGrid = dynamic_cast<const GridPortalLink*>(b.get());
bGrid != nullptr) {
ACTS_VERBOSE("Merging two grid portals");
return gridMerge(*aGrid, *bGrid);

} else if (const auto* bTrivial =
dynamic_cast<const TrivialPortalLink*>(b.get());
bTrivial != nullptr) {
ACTS_VERBOSE("Merging a grid portal with a trivial portal");
return gridMerge(*aGrid, *bTrivial->makeGrid(direction));

} else if (dynamic_cast<const CompositePortalLink*>(b.get()) != nullptr) {
ACTS_WARNING("Merging a grid portal with a composite portal");
return std::make_unique<CompositePortalLink>(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<const TrivialPortalLink*>(a.get());
aTrivial != nullptr) {
if (const auto* bGrid = dynamic_cast<const GridPortalLink*>(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<const TrivialPortalLink*>(b.get());
bTrivial != nullptr) {
ACTS_VERBOSE("Merging two trivial portals");
return gridMerge(*aTrivial->makeGrid(direction),
*bTrivial->makeGrid(direction));

} else if (dynamic_cast<const CompositePortalLink*>(b.get()) != nullptr) {
ACTS_WARNING("Merging a trivial portal with a composite portal");
return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
direction);

} else {
throw std::logic_error{"Portal link type is not supported"};
}

} else if (dynamic_cast<const CompositePortalLink*>(a.get()) != nullptr) {
if (dynamic_cast<const GridPortalLink*>(b.get()) != nullptr) {
ACTS_WARNING("Merging a composite portal with a grid portal");
return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
direction);

} else if (dynamic_cast<const TrivialPortalLink*>(b.get()) != nullptr) {
ACTS_WARNING("Merging a composite portal with a trivial portal");
return std::make_unique<CompositePortalLink>(std::move(a), std::move(b),
direction);

} else if (dynamic_cast<CompositePortalLink*>(b.get()) != nullptr) {
ACTS_WARNING("Merging two composite portals");
return std::make_unique<CompositePortalLink>(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

0 comments on commit 20485bd

Please sign in to comment.