Skip to content

Commit

Permalink
work on portal tests
Browse files Browse the repository at this point in the history
  • Loading branch information
paulgessinger committed Aug 12, 2024
1 parent 472b427 commit 3b3fcea
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 15 deletions.
39 changes: 33 additions & 6 deletions Core/include/Acts/Geometry/Portal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,46 @@ class DiscSurface;

class PortalLinkBase;

class PortalMergingException : public std::exception {
const char* what() const noexcept override {
return "Failure to merge portals";
}
};

class Portal {
public:
Portal(Direction direction, std::unique_ptr<PortalLinkBase> link);

Portal(Direction direction, std::shared_ptr<RegularSurface> surface,
TrackingVolume& volume);

static std::shared_ptr<Portal> fuse(const std::shared_ptr<Portal>& aPortal,
Portal(std::unique_ptr<PortalLinkBase> alongNormal,
std::unique_ptr<PortalLinkBase> oppositeNormal);

// portal1 portal2
// +---+ +---+
// | | | |
// | | | |
// <----+ | + | +---->
// | | | |
// | | | |
// +---+ +---+
static std::unique_ptr<Portal> fuse(const std::shared_ptr<Portal>& aPortal,
const std::shared_ptr<Portal>& bPortal);

static std::shared_ptr<Portal> mergeAdjacent(
const std::shared_ptr<Portal>& aPortal,
const std::shared_ptr<Portal>& bPortal);
// ^ ^
// | |
// portal1| portal2|
// +-------+-------+ +-------+-------+
// | | + | |
// +-------+-------+ +-------+-------+
// | |
// | |
// v v
static std::unique_ptr<Portal> merge(const std::shared_ptr<Portal>& aPortal,
const std::shared_ptr<Portal>& bPortal,
BinningValue direction,
const Logger& logger = getDummyLogger());

const TrackingVolume* resolveVolume(const GeometryContext& gctx,
const Vector3& position,
Expand All @@ -54,8 +81,8 @@ class Portal {

std::shared_ptr<RegularSurface> m_surface;

std::unique_ptr<PortalLinkBase> m_alongNormal;
std::unique_ptr<PortalLinkBase> m_oppositeNormal;
std::shared_ptr<PortalLinkBase> m_alongNormal;
std::shared_ptr<PortalLinkBase> m_oppositeNormal;
};

template <typename S>
Expand Down
68 changes: 64 additions & 4 deletions Core/src/Geometry/Portal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ Portal::Portal(Direction direction, std::shared_ptr<RegularSurface> surface,
: Portal(direction,
std::make_unique<TrivialPortalLink>(std::move(surface), volume)) {}

Portal::Portal(std::unique_ptr<PortalLinkBase> alongNormal,
std::unique_ptr<PortalLinkBase> oppositeNormal) {
if (alongNormal != nullptr) {
setLink(Direction::AlongNormal, std::move(alongNormal));
}
if (oppositeNormal != nullptr) {
setLink(Direction::OppositeNormal, std::move(oppositeNormal));
}
}

void Portal::setLink(Direction direction,
std::unique_ptr<PortalLinkBase> link) {
assert(link != nullptr);
Expand Down Expand Up @@ -82,6 +92,56 @@ const TrackingVolume* Portal::resolveVolume(const GeometryContext& gctx,
}
}

std::unique_ptr<Portal> Portal::merge(const std::shared_ptr<Portal>& aPortal,
const std::shared_ptr<Portal>& bPortal,
BinningValue direction,
const Logger& logger) {
ACTS_DEBUG("Merging to portals along " << direction);
std::unique_ptr<PortalLinkBase> mergedAlongNormal = nullptr;
std::unique_ptr<PortalLinkBase> mergedOppositeNormal = nullptr;

bool aHasAlongNormal = aPortal->m_alongNormal != nullptr;
bool aHasOppositeNormal = aPortal->m_oppositeNormal != nullptr;
bool bHasAlongNormal = bPortal->m_alongNormal != nullptr;
bool bHasOppositeNormal = bPortal->m_oppositeNormal != nullptr;

if (aHasAlongNormal != bHasAlongNormal ||
aHasOppositeNormal != bHasOppositeNormal) {
ACTS_ERROR("Portals do not have the same links attached");
throw PortalMergingException();
}

if (aPortal->m_alongNormal != nullptr) {
if (bPortal->m_alongNormal == nullptr) {
ACTS_ERROR(
"Portal A has link along normal, while b does not. This is not "
"supported");
throw PortalMergingException();
}

ACTS_VERBOSE("Portals have links along normal, merging");
mergedAlongNormal = PortalLinkBase::merge(
aPortal->m_alongNormal, bPortal->m_alongNormal, direction, logger);
}

if (aPortal->m_oppositeNormal != nullptr) {
if (bPortal->m_oppositeNormal == nullptr) {
ACTS_ERROR(
"Portal A has link opposite normal, while b does not. This is not "
"supported");
throw PortalMergingException();
}

ACTS_VERBOSE("Portals have links opposite normal, merging");
mergedOppositeNormal =
PortalLinkBase::merge(aPortal->m_oppositeNormal,
bPortal->m_oppositeNormal, direction, logger);
}

return std::make_unique<Portal>(std::move(mergedAlongNormal),
std::move(mergedOppositeNormal));
}

void PortalLinkBase::checkMergePreconditions(const PortalLinkBase& a,
const PortalLinkBase& b,
BinningValue direction) {
Expand Down Expand Up @@ -130,7 +190,7 @@ std::unique_ptr<PortalLinkBase> PortalLinkBase::merge(
const Logger& logger) {
ACTS_DEBUG("Merging two arbitrary portals");

ACTS_VERBOSE(" - a: " << *a);
ACTS_VERBOSE(" - a: " << *a);
ACTS_VERBOSE(" - b: " << *b);

checkMergePreconditions(*a, *b, direction);
Expand All @@ -157,7 +217,7 @@ std::unique_ptr<PortalLinkBase> PortalLinkBase::merge(

} else if (auto bTrivial = std::dynamic_pointer_cast<TrivialPortalLink>(b);
bTrivial) {
ACTS_WARNING("Merging a grid portal with a trivial portal");
ACTS_VERBOSE("Merging a grid portal with a trivial portal");
return GridPortalLink::merge(aGrid, bTrivial->makeGrid(direction),
direction, logger);

Expand All @@ -175,14 +235,14 @@ std::unique_ptr<PortalLinkBase> PortalLinkBase::merge(
} else if (auto aTrivial = std::dynamic_pointer_cast<TrivialPortalLink>(a);
aTrivial) {
if (auto bGrid = std::dynamic_pointer_cast<GridPortalLink>(b); bGrid) {
ACTS_WARNING("Merging a trivial portal with a grid portal");
ACTS_VERBOSE("Merging a trivial portal with a grid portal");
return GridPortalLink::merge(aTrivial->makeGrid(direction), bGrid,
direction, logger);

} else if (auto bTrivial =
std::dynamic_pointer_cast<const TrivialPortalLink>(b);
bTrivial) {
ACTS_WARNING("Merging two trivial portals");
ACTS_VERBOSE("Merging two trivial portals");
return GridPortalLink::merge(aTrivial->makeGrid(direction),
bTrivial->makeGrid(direction), direction,
logger);
Expand Down
165 changes: 160 additions & 5 deletions Tests/UnitTests/Core/Geometry/PortalTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@
#include "Acts/Definitions/Units.hpp"
#include "Acts/Geometry/CylinderVolumeBounds.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Geometry/GridPortalLink.hpp"
#include "Acts/Geometry/Portal.hpp"
#include "Acts/Geometry/TrackingVolume.hpp"
#include "Acts/Geometry/TrivialPortalLink.hpp"
#include "Acts/Surfaces/CylinderSurface.hpp"
#include "Acts/Surfaces/DiscSurface.hpp"
#include "Acts/Surfaces/RadialBounds.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Surfaces/SurfaceMergingException.hpp"
#include "Acts/Utilities/BinningType.hpp"
#include "Acts/Utilities/ThrowAssert.hpp"

using namespace Acts::UnitLiterals;

Expand Down Expand Up @@ -53,13 +57,15 @@ BOOST_AUTO_TEST_SUITE(Merging)

BOOST_AUTO_TEST_CASE(Cylinder) {
auto vol1 = makeDummyVolume();
vol1->setVolumeName("vol1");
auto vol2 = makeDummyVolume();
vol2->setVolumeName("vol2");

auto cyl1 = Surface::makeShared<CylinderSurface>(
Transform3{Translation3{Vector3::UnitZ() * -50_mm}}, 50_mm, 100_mm);
Transform3{Translation3{Vector3::UnitZ() * -100_mm}}, 50_mm, 100_mm);

auto cyl2 = Surface::makeShared<CylinderSurface>(
Transform3{Translation3{Vector3::UnitZ() * 50_mm}}, 50_mm, 100_mm);
Transform3{Translation3{Vector3::UnitZ() * 100_mm}}, 50_mm, 100_mm);

auto portal1 = std::make_shared<Portal>(
Direction::AlongNormal, std::make_unique<TrivialPortalLink>(cyl1, *vol1));
Expand All @@ -76,6 +82,40 @@ BOOST_AUTO_TEST_CASE(Cylinder) {
auto portal2 = std::make_shared<Portal>(Direction::AlongNormal, cyl2, *vol2);
BOOST_REQUIRE(portal2);

BOOST_CHECK_EQUAL(portal2->resolveVolume(gctx, Vector3{50_mm, 0_mm, -50_mm},
-Vector3::UnitX()),
nullptr);

BOOST_CHECK_EQUAL(portal2->resolveVolume(gctx, Vector3{50_mm, 0_mm, -50_mm},
Vector3::UnitX()),
vol2.get());

auto portal3 = std::make_shared<Portal>(
std::make_unique<TrivialPortalLink>(cyl2, *vol2), nullptr);

BOOST_CHECK_NE(portal3->getLink(Direction::AlongNormal), nullptr);
BOOST_CHECK_EQUAL(portal3->getLink(Direction::OppositeNormal), nullptr);

auto portal4 = std::make_shared<Portal>(
nullptr, std::make_unique<TrivialPortalLink>(cyl2, *vol2));

BOOST_CHECK_EQUAL(portal4->getLink(Direction::AlongNormal), nullptr);
BOOST_CHECK_NE(portal4->getLink(Direction::OppositeNormal), nullptr);

// Not mergeable because 1 has portal along but 4 has portal oppsite
// ^
// |
// portal1| portal2
// +-------+-------+ + +---------------+
// | | | |
// +---------------+ +-------+-------+
// |
// |
// v
BOOST_CHECK_THROW(
Portal::merge(portal1, portal4, BinningValue::binZ, *logger),
PortalMergingException);

BOOST_CHECK_EQUAL(portal2->resolveVolume(gctx, Vector3{50_mm, 0_mm, 50_mm},
Vector3::UnitX()),
vol2.get());
Expand All @@ -84,10 +124,120 @@ BOOST_AUTO_TEST_CASE(Cylinder) {
-Vector3::UnitX()),
nullptr);

// @TODO: Test merging portals along z
// @TODO: Test portals in opposite directions fail to merge along z
BOOST_CHECK_THROW(
Portal::merge(portal1, portal2, BinningValue::binRPhi, *logger),
SurfaceMergingException);

// ^ ^
// | |
// portal1| portal2|
// +-------+-------+ + +-------+-------+
// | | | |
// +---------------+ +---------------+

auto merged12 = Portal::merge(portal1, portal2, BinningValue::binZ, *logger);
BOOST_REQUIRE(merged12);
BOOST_CHECK_NE(merged12->getLink(Direction::AlongNormal), nullptr);
BOOST_CHECK_EQUAL(merged12->getLink(Direction::OppositeNormal), nullptr);

auto grid12 = dynamic_cast<const GridPortalLink*>(
merged12->getLink(Direction::AlongNormal));
grid12->printContents(std::cout);

BOOST_CHECK_EQUAL(merged12->resolveVolume(gctx, Vector3{50_mm, 0_mm, -50_mm},
Vector3::UnitX()),
vol1.get());

BOOST_CHECK_EQUAL(merged12->resolveVolume(gctx, Vector3{50_mm, 0_mm, 50_mm},
Vector3::UnitX()),
vol2.get());

BOOST_CHECK_EQUAL(merged12->resolveVolume(gctx, Vector3{50_mm, 0_mm, -50_mm},
-Vector3::UnitX()),
nullptr);

BOOST_CHECK_EQUAL(merged12->resolveVolume(gctx, Vector3{50_mm, 0_mm, 50_mm},
-Vector3::UnitX()),
nullptr);

// Can't merge with self because surfaces are not mergeable
BOOST_CHECK_THROW(
Portal::merge(portal1, portal1, BinningValue::binZ, *logger),
AssertionFailureException);
}

BOOST_AUTO_TEST_CASE(Disc) {
auto vol1 = makeDummyVolume();
vol1->setVolumeName("vol1");
auto vol2 = makeDummyVolume();
vol2->setVolumeName("vol2");
auto vol3 = makeDummyVolume();
vol3->setVolumeName("vol3");
auto vol4 = makeDummyVolume();
vol4->setVolumeName("vol4");

auto disc1 = Surface::makeShared<DiscSurface>(
Transform3::Identity(), std::make_shared<RadialBounds>(50_mm, 100_mm));

auto disc2 = Surface::makeShared<DiscSurface>(
Transform3::Identity(), std::make_shared<RadialBounds>(100_mm, 150_mm));

auto portal1 = std::make_shared<Portal>(
std::make_unique<TrivialPortalLink>(disc1, *vol1),
std::make_unique<TrivialPortalLink>(disc1, *vol2));

auto portal2 = std::make_shared<Portal>(
std::make_unique<TrivialPortalLink>(disc2, *vol3),
std::make_unique<TrivialPortalLink>(disc2, *vol4));

BOOST_CHECK_EQUAL(portal1->resolveVolume(gctx, Vector3{55_mm, 0_mm, 0_mm},
Vector3::UnitZ()),
vol1.get());
BOOST_CHECK_EQUAL(portal1->resolveVolume(gctx, Vector3{55_mm, 0_mm, 0_mm},
-Vector3::UnitZ()),
vol2.get());

BOOST_CHECK_EQUAL(portal2->resolveVolume(gctx, Vector3{105_mm, 0_mm, 0_mm},
Vector3::UnitZ()),
vol3.get());
BOOST_CHECK_EQUAL(portal2->resolveVolume(gctx, Vector3{105_mm, 0_mm, 0_mm},
-Vector3::UnitZ()),
vol4.get());

BOOST_CHECK_THROW(
Portal::merge(portal1, portal2, BinningValue::binZ, *logger),
AssertionFailureException);

BOOST_CHECK_THROW(
Portal::merge(portal1, portal2, BinningValue::binPhi, *logger),
SurfaceMergingException);

// ^ ^
// | |
// portal1| portal2|
// +-------+-------+ +-------+-------+
// | | + | |
// +-------+-------+ +-------+-------+
// | |
// | |
// v v
auto merged12 = Portal::merge(portal1, portal2, BinningValue::binR, *logger);
BOOST_REQUIRE(merged12);

BOOST_CHECK_EQUAL(merged12->resolveVolume(gctx, Vector3{55_mm, 0_mm, 0_mm},
Vector3::UnitZ()),
vol1.get());
BOOST_CHECK_EQUAL(merged12->resolveVolume(gctx, Vector3{55_mm, 0_mm, 0_mm},
-Vector3::UnitZ()),
vol2.get());

BOOST_CHECK_EQUAL(merged12->resolveVolume(gctx, Vector3{105_mm, 0_mm, 0_mm},
Vector3::UnitZ()),
vol3.get());
BOOST_CHECK_EQUAL(merged12->resolveVolume(gctx, Vector3{105_mm, 0_mm, 0_mm},
-Vector3::UnitZ()),
vol4.get());
}
BOOST_AUTO_TEST_CASE(Disc) {}

BOOST_AUTO_TEST_SUITE_END() // Merging

Expand All @@ -101,6 +251,11 @@ BOOST_AUTO_TEST_CASE(ConstructionFromVolume) {
// - Cylinder
}

BOOST_AUTO_TEST_CASE(Construction) {
// @TODO: Displaced surfaces fail
// @TODO: Surface unification to same instance
}

BOOST_AUTO_TEST_SUITE_END() // Portals

BOOST_AUTO_TEST_SUITE_END() // Geometry
Expand Down

0 comments on commit 3b3fcea

Please sign in to comment.