Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add helper and fusing infrastructure for cuboidal detectors #2754

Merged
merged 33 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
635df4b
core examples tests
asalzburger Jul 21, 2023
dac7644
python formatting
asalzburger Jul 21, 2023
008df9c
setting the fused portals also to the original keep volume
asalzburger Nov 30, 2023
8cc3adc
fix spelling
asalzburger Nov 30, 2023
64ca360
adding infrastructure for cuboidal detectors
asalzburger Nov 30, 2023
3bac4c8
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Nov 30, 2023
33f80df
fixing low level check scripts
asalzburger Nov 30, 2023
dcff6a2
more explicit exception message
asalzburger Nov 30, 2023
4c00ee6
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Nov 30, 2023
4a52880
force Vector3 evaluation
asalzburger Nov 30, 2023
703ff49
make clang-tidy happy/happier
asalzburger Nov 30, 2023
7775903
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Nov 30, 2023
78d8e85
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Dec 1, 2023
10861ba
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Dec 6, 2023
caecbf8
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Dec 12, 2023
64bffbe
Update Core/include/Acts/Detector/detail/DetectorVolumeConsistency.hpp
asalzburger Dec 12, 2023
c2d75c5
Update Core/src/Detector/detail/CuboidalDetectorHelper.cpp
asalzburger Dec 12, 2023
3552625
Update Core/src/Detector/detail/CuboidalDetectorHelper.cpp
asalzburger Dec 12, 2023
a9a45c7
Update Core/src/Detector/detail/CuboidalDetectorHelper.cpp
asalzburger Dec 12, 2023
e0acd96
Update Tests/UnitTests/Core/Detector/CuboidalDetectorHelperTests.cpp
asalzburger Dec 12, 2023
fd83a8e
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Dec 16, 2023
9abfe03
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Dec 18, 2023
34e73e1
test for container connection
asalzburger Dec 18, 2023
545a292
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Dec 18, 2023
565cd89
fix warning
asalzburger Dec 18, 2023
2361f98
allowing same facing portals
asalzburger Dec 18, 2023
3b80930
Update Core/src/Detector/Portal.cpp
asalzburger Dec 19, 2023
3b02ec9
Update Core/src/Detector/Portal.cpp
asalzburger Dec 19, 2023
98cbc76
Update Core/src/Detector/Portal.cpp
asalzburger Dec 19, 2023
f8684d4
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Dec 19, 2023
11ae30f
adding consistency unit test
asalzburger Dec 19, 2023
0c630f4
Merge branch 'main' into feat-add-cuboidal-builders
kodiakhq[bot] Dec 19, 2023
4be3eb8
Merge branch 'main' into feat-add-cuboidal-builders
asalzburger Jan 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 26 additions & 20 deletions Core/src/Detector/Portal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,47 +69,53 @@ std::shared_ptr<Portal> Portal::fuse(std::shared_ptr<Portal>& aPortal,

if (noneConnected(*aPortal) || noneConnected(*bPortal)) {
throw std::invalid_argument(
"Portal: trying to fuse two portals where at least on has no links.");
"Portal: trying to fuse two portals where at least one has no links.");
}

// We checked they're not both empty, so one of them must be connected
Direction aDir = (aPortal->m_volumeUpdaters[0].connected())
// @TODO: There's no safety against fusing portals with different surfaces
// We model the fused portal after the portal a
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
std::shared_ptr<Portal> fused = std::make_shared<Portal>(aPortal->m_surface);

// Get the connection directions
Direction getA = (aPortal->m_volumeUpdaters[0].connected())
? Direction::fromIndex(0)
: Direction::fromIndex(1);
Direction getB = (bPortal->m_volumeUpdaters[0].connected())
? Direction::fromIndex(0)
: Direction::fromIndex(1);
Direction bDir = aDir.invert();

// And now check other direction
if (!bPortal->m_volumeUpdaters[bDir.index()].connected()) {
throw std::runtime_error(
"Portal: trying to fuse portal (discard) with no links.");
}
// Modelling the fused portal after the aPortal, leaves B as inverted
Direction setA = getA;
Direction setB = setA.invert();

// Checkif material is associated
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
const auto& aSurface = aPortal->surface();
const auto& bSurface = bPortal->surface();

// @TODO: There's no safety against fusing portals with different surfaces
std::shared_ptr<Portal> fused = std::make_shared<Portal>(aPortal->m_surface);

if (aSurface.surfaceMaterial() != nullptr &&
bSurface.surfaceMaterial() != nullptr) {
throw std::runtime_error(
"Portal: both surfaces have surface material, fusing will lead to "
"information loss.");
} else if (aSurface.surfaceMaterial() != nullptr) {
// We keep portal A modelling
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
fused->m_surface = aPortal->m_surface;
} else if (bSurface.surfaceMaterial() != nullptr) {
fused->m_surface = bPortal->m_surface;
// Remodel after the bPortal
setB = getB;
setA = setB.invert();
}

fused->m_volumeUpdaters[aDir.index()] =
std::move(aPortal->m_volumeUpdaters[aDir.index()]);
fused->m_attachedVolumes[aDir.index()] =
std::move(aPortal->m_attachedVolumes[aDir.index()]);
fused->m_volumeUpdaters[setA.index()] =
std::move(aPortal->m_volumeUpdaters[getA.index()]);
fused->m_attachedVolumes[setA.index()] =
std::move(aPortal->m_attachedVolumes[getA.index()]);

fused->m_volumeUpdaters[bDir.index()] =
std::move(bPortal->m_volumeUpdaters[bDir.index()]);
fused->m_attachedVolumes[bDir.index()] =
std::move(bPortal->m_attachedVolumes[bDir.index()]);
fused->m_volumeUpdaters[setB.index()] =
std::move(bPortal->m_volumeUpdaters[getB.index()]);
fused->m_attachedVolumes[setB.index()] =
std::move(bPortal->m_attachedVolumes[getB.index()]);

return fused;
}
Expand Down
28 changes: 7 additions & 21 deletions Core/src/Detector/detail/CuboidalDetectorHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Acts::Experimental::detail::CuboidalDetectorHelper::connect(

// Create the new RectangleBounds
// - there are conventions involved, regarding the bounds orientation
// - This is an anticyclic swap
// - this is an anticyclic swap
bool mergedInX = true;
switch (bValue) {
case binZ: {
Expand Down Expand Up @@ -208,6 +208,10 @@ Acts::Experimental::detail::CuboidalDetectorHelper::connect(
stitchBoundaries, (mergedInX ? binX : binY)));
}
}

// Attach the new volume updaters
PortalHelper::attachDetectorVolumeUpdaters(gctx, volumes, pReplacements);

// Return proto container
DetectorComponent::PortalContainer dShell;

Expand All @@ -216,10 +220,6 @@ Acts::Experimental::detail::CuboidalDetectorHelper::connect(
for (auto& iv : volumes) {
ACTS_VERBOSE("- update portals of volume '" << iv->name() << "'.");
for (auto& [p, i, dir, boundaries, binning] : pReplacements) {
(void)dir;
(void)boundaries;
(void)binning;

// Fill the map
dShell[i] = p;
ACTS_VERBOSE("-- update portal with index " << i);
Expand All @@ -233,9 +233,9 @@ Acts::Experimental::detail::CuboidalDetectorHelper::connect(

Acts::Experimental::DetectorComponent::PortalContainer
Acts::Experimental::detail::CuboidalDetectorHelper::connect(
const GeometryContext& gctx,
const GeometryContext& /*gctx*/,
const std::vector<DetectorComponent::PortalContainer>& containers,
BinningValue bValue, const std::vector<unsigned int>& selectedOnly,
BinningValue bValue, const std::vector<unsigned int>& /*unused */,
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
Acts::Logging::Level logLevel) noexcept(false) {
// The local logger
ACTS_LOCAL_LOGGER(getDefaultLogger("CuboidalDetectorHelper", logLevel));
Expand Down Expand Up @@ -307,20 +307,6 @@ Acts::Experimental::detail::CuboidalDetectorHelper::connect(
}
}

// Strip the side volumes
auto sideVolumes =
PortalHelper::stripSideVolumes(containers, sidePortals, selectedOnly);

ACTS_VERBOSE("There remain " << sideVolumes.size()
<< " side volume packs to be connected");
for (auto [s, volumes] : sideVolumes) {
ACTS_VERBOSE(" - connect " << volumes.size() << " at selected side " << s);
auto pR = connect(gctx, volumes, bValue, {s}, logLevel);
if (pR.find(s) != pR.end()) {
dShell[s] = pR.find(s)->second;
}
}

// Done.
return dShell;
}
Expand Down
79 changes: 77 additions & 2 deletions Tests/UnitTests/Core/Detector/CuboidalDetectorHelperTests.cpp
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of the Acts project.
//
// Copyright (C) 2022 CERN for the benefit of the Acts project
// Copyright (C) 2023 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
Expand Down Expand Up @@ -83,7 +83,9 @@ BOOST_AUTO_TEST_CASE(SimpleBoxConnection) {
auto container =
Acts::Experimental::detail::CuboidalDetectorHelper::connect(
tContext, volumes, bVal, {}, Acts::Logging::VERBOSE);
// Check the container

// Check the container is constructed
BOOST_CHECK(!container.empty());

Acts::ObjVisualization3D obj;
Acts::GeometryView3D::drawDetectorVolume(obj, *volumeA, tContext);
Expand Down Expand Up @@ -160,6 +162,9 @@ BOOST_AUTO_TEST_CASE(IrregularBoxConnectionInZ) {
Acts::Experimental::detail::CuboidalDetectorHelper::connect(
tContext, volumes, bVal, {}, Acts::Logging::VERBOSE);

// Check the container is constructed
BOOST_CHECK(!container.empty());

Acts::ObjVisualization3D obj;
Acts::GeometryView3D::drawDetectorVolume(obj, *volumeA, tContext);
Acts::GeometryView3D::drawDetectorVolume(obj, *volumeB, tContext);
Expand All @@ -170,4 +175,74 @@ BOOST_AUTO_TEST_CASE(IrregularBoxConnectionInZ) {
}
}

BOOST_AUTO_TEST_CASE(ContainerConnection) {
// A perfect box shape
auto box = std::make_shared<Acts::CuboidVolumeBounds>(10, 10, 10);

// Create an AB container

// Create volume A
auto volumeA = Acts::Experimental::DetectorVolumeFactory::construct(
portalGenerator, tContext, "VolumeA", Acts::Transform3::Identity(), box,
Acts::Experimental::tryAllPortals());

// Move it into the bval direction
auto transformB = Acts::Transform3::Identity();
Acts::Vector3 translationB = Acts::Vector3::Zero();
translationB[Acts::binX] = 20;
transformB.pretranslate(translationB);
// Create volume B
auto volumeB = Acts::Experimental::DetectorVolumeFactory::construct(
portalGenerator, tContext, "VolumeB", transformB, box,
Acts::Experimental::tryAllPortals());
// Build the container
std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>> volumes = {
volumeA, volumeB};
auto containerAB =
Acts::Experimental::detail::CuboidalDetectorHelper::connect(
tContext, volumes, Acts::binX, {}, Acts::Logging::VERBOSE);

// Create a CD container

auto transformC = Acts::Transform3::Identity();
Acts::Vector3 translationC = Acts::Vector3::Zero();
translationC[Acts::binY] = 20;
transformC.pretranslate(translationC);

auto volumeC = Acts::Experimental::DetectorVolumeFactory::construct(
portalGenerator, tContext, "VolumeC", transformC, box,
Acts::Experimental::tryAllPortals());

auto transformD = Acts::Transform3::Identity();
Acts::Vector3 translationD = Acts::Vector3::Zero();
translationD[Acts::binX] = 20;
translationD[Acts::binY] = 20;
transformD.pretranslate(translationD);

auto volumeD = Acts::Experimental::DetectorVolumeFactory::construct(
portalGenerator, tContext, "VolumeD", transformD, box,
Acts::Experimental::tryAllPortals());

volumes = {volumeC, volumeD};
auto containerCD =
Acts::Experimental::detail::CuboidalDetectorHelper::connect(
tContext, volumes, Acts::binX, {}, Acts::Logging::VERBOSE);

auto containerABCD =
Acts::Experimental::detail::CuboidalDetectorHelper::connect(
tContext, {containerAB, containerCD}, Acts::binY, {},
Acts::Logging::VERBOSE);

// Check the container is constructed
BOOST_CHECK(!containerABCD.empty());

Acts::ObjVisualization3D obj;
Acts::GeometryView3D::drawDetectorVolume(obj, *volumeA, tContext);
Acts::GeometryView3D::drawDetectorVolume(obj, *volumeB, tContext);
Acts::GeometryView3D::drawDetectorVolume(obj, *volumeC, tContext);
Acts::GeometryView3D::drawDetectorVolume(obj, *volumeD, tContext);

obj.write("ConnectContainers_binX.obj");
}

BOOST_AUTO_TEST_SUITE_END()
19 changes: 0 additions & 19 deletions Tests/UnitTests/Core/Detector/PortalTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,25 +144,6 @@ BOOST_AUTO_TEST_CASE(PortalTest) {
// Portal A retains identical position to B
BOOST_CHECK_EQUAL(portalA->surface().center(gctx),
portalB->surface().center(gctx));

// An invalid fusing setup
auto linkToAIImpl = std::make_unique<const LinkToVolumeImpl>(volumeA);
auto linkToBIImpl = std::make_unique<const LinkToVolumeImpl>(volumeB);

auto portalAI = std::make_shared<Portal>(surface);
DetectorVolumeUpdater linkToAI;
linkToAI.connect<&LinkToVolumeImpl::link>(std::move(linkToAIImpl));
portalAI->assignDetectorVolumeUpdater(Acts::Direction::Positive,
std::move(linkToAI), {volumeA});

auto portalBI = std::make_shared<Portal>(surface);
DetectorVolumeUpdater linkToBI;
linkToBI.connect<&LinkToVolumeImpl::link>(std::move(linkToBIImpl));
portalBI->assignDetectorVolumeUpdater(Acts::Direction::Positive,
std::move(linkToBI), {volumeB});

BOOST_CHECK_THROW(Portal::fuse(portalAI, portalBI), std::runtime_error);
BOOST_CHECK_THROW(Portal::fuse(portalBI, portalAI), std::runtime_error);
}

BOOST_AUTO_TEST_CASE(PortalMaterialTest) {
Expand Down
Loading