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

fix: DetectorVolume containment check #2895

Merged
merged 32 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
140308a
Move DetectorVolume containment check after the Extent can be generated
ssdetlab Jan 23, 2024
f20babe
Fixing magBin issue + update unit test
ssdetlab Jan 23, 2024
6a4f8bb
Surfaces/subvolumes containment checks for DetectorVolume + minor fixes
ssdetlab Jan 24, 2024
28801bc
Merge branch 'acts-project:main' into detector-volume-containment-check
ssdetlab Jan 24, 2024
8ef7d02
Format + cleanup
ssdetlab Jan 24, 2024
a01e2db
Cleanup
ssdetlab Jan 24, 2024
6146eb4
Cleanup
ssdetlab Jan 24, 2024
892ffac
Forgotten overrides
ssdetlab Jan 24, 2024
ad6c4f9
Move containment check inside factory
ssdetlab Jan 24, 2024
530ba9e
Copy elision fix
ssdetlab Jan 24, 2024
d343558
Format
ssdetlab Jan 24, 2024
a72924e
Minor fixes
ssdetlab Jan 24, 2024
ff19f69
Format
ssdetlab Jan 24, 2024
98c1202
GenericCuboidVolumeBounds typo fix
ssdetlab Jan 24, 2024
65c7695
Merge branch 'main' into detector-volume-containment-check
asalzburger Jan 25, 2024
bc55650
DD4hep test geometry adjustments
ssdetlab Jan 25, 2024
5ea8f08
Making containment test optional + moving the canonicalBounds Boundin…
ssdetlab Jan 25, 2024
604e7b4
Format
ssdetlab Jan 25, 2024
7f23af8
Merge branch 'main' into detector-volume-containment-check
asalzburger Jan 25, 2024
cfc34ee
Merge branch 'main' into detector-volume-containment-check
ssdetlab Jan 26, 2024
937bfe4
Merge branch 'main' into detector-volume-containment-check
ssdetlab Jan 27, 2024
96602e1
Checking CI-perms
ssdetlab Jan 30, 2024
8047748
Checking CI-perms
ssdetlab Jan 30, 2024
5b77513
Merge branch 'main' into detector-volume-containment-check
asalzburger Jan 30, 2024
c412a72
Change canonicalBinning return to const ref
ssdetlab Feb 3, 2024
b35f79b
remove const refs on temps
ssdetlab Feb 3, 2024
81b457c
Merge branch 'main' into detector-volume-containment-check
ssdetlab Feb 24, 2024
992837f
Merge branch 'main' into detector-volume-containment-check
asalzburger Feb 28, 2024
abb56ff
Merge branch 'main' into detector-volume-containment-check
ssdetlab Mar 3, 2024
ead3aef
Merge branch 'main' into detector-volume-containment-check
asalzburger Mar 6, 2024
1ac2749
Merge branch 'main' into detector-volume-containment-check
ssdetlab Mar 12, 2024
e147aa2
Merge branch 'main' into detector-volume-containment-check
asalzburger Mar 13, 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
13 changes: 12 additions & 1 deletion Core/include/Acts/Detector/DetectorVolume.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,9 @@ class DetectorVolume : public std::enable_shared_from_this<DetectorVolume> {
/// @brief A detector volume factory which first constructs the detector volume
/// and then constructs the portals. This ensures that the std::shared_ptr
/// holding the detector volume is not weak when assigning to the portals.
///
/// @note Optional containment check is invoked by setting the number
/// of segments nSeg to be greater than 0
class DetectorVolumeFactory {
public:
/// Create a detector volume - from factory
Expand All @@ -494,11 +497,19 @@ class DetectorVolumeFactory {
const std::vector<std::shared_ptr<Surface>>& surfaces,
const std::vector<std::shared_ptr<DetectorVolume>>& volumes,
DetectorVolumeUpdater detectorVolumeUpdater,
SurfaceCandidatesUpdater surfaceCandidateUpdater) {
SurfaceCandidatesUpdater surfaceCandidateUpdater, int nSeg = -1) {
auto dVolume = DetectorVolume::makeShared(
gctx, name, transform, std::move(bounds), surfaces, volumes,
std::move(detectorVolumeUpdater), std::move(surfaceCandidateUpdater));
dVolume->construct(gctx, portalGenerator);

/// Volume extent is constructed from the portals
/// So the surface/subvolume containment
/// check has to happen here
if (nSeg > 0 && !dVolume->checkContainment(gctx, nSeg)) {
throw std::invalid_argument(
"DetectorVolume: surfaces or subvolumes are not contained by volume");
}
return dVolume;
}

Expand Down
8 changes: 8 additions & 0 deletions Core/include/Acts/Geometry/CuboidVolumeBounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ class CuboidVolumeBounds : public VolumeBounds {
const Vector3& envelope = {0, 0, 0},
const Volume* entity = nullptr) const final;

/// Get the canonical binning values, i.e. the binning values
/// for that fully describe the shape's extent
///
/// @return vector of canonical binning values
std::vector<Acts::BinningValue> canonicalBinning() const override {
return {Acts::binX, Acts::binY, Acts::binZ};
};

/// Binning borders in double
///
/// @param bValue is the binning schema used
Expand Down
8 changes: 8 additions & 0 deletions Core/include/Acts/Geometry/CutoutCylinderVolumeBounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ class CutoutCylinderVolumeBounds : public VolumeBounds {
const Vector3& envelope = {0, 0, 0},
const Volume* entity = nullptr) const final;

/// Get the canonical binning values, i.e. the binning values
/// for that fully describe the shape's extent
///
/// @return vector of canonical binning values
std::vector<Acts::BinningValue> canonicalBinning() const override {
ssdetlab marked this conversation as resolved.
Show resolved Hide resolved
return {Acts::binR, Acts::binPhi, Acts::binZ};
};

/// Write information about this instance to an outstream
///
/// @param sl The outstream
Expand Down
8 changes: 8 additions & 0 deletions Core/include/Acts/Geometry/CylinderVolumeBounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,14 @@ class CylinderVolumeBounds : public VolumeBounds {
const Vector3& envelope = {0, 0, 0},
const Volume* entity = nullptr) const final;

/// Get the canonical binning values, i.e. the binning values
/// for that fully describe the shape's extent
///
/// @return vector of canonical binning values
std::vector<Acts::BinningValue> canonicalBinning() const override {
return {Acts::binR, Acts::binPhi, Acts::binZ};
};

/// Binning offset - overloaded for some R-binning types
///
/// @param bValue is the type used for the binning
Expand Down
8 changes: 8 additions & 0 deletions Core/include/Acts/Geometry/GenericCuboidVolumeBounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ class GenericCuboidVolumeBounds : public VolumeBounds {
const Vector3& envelope = {0, 0, 0},
const Volume* entity = nullptr) const final;

/// Get the canonical binning values, i.e. the binning values
/// for that fully describe the shape's extent
///
/// @return vector of canonical binning values
std::vector<Acts::BinningValue> canonicalBinning() const override {
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
return {Acts::binX, Acts::binY, Acts::binZ};
};

/// @param sl is the output stream to be written into
std::ostream& toStream(std::ostream& sl) const override;

Expand Down
12 changes: 12 additions & 0 deletions Core/include/Acts/Geometry/VolumeBounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ class VolumeBounds {
const Transform3* trf = nullptr, const Vector3& envelope = {0, 0, 0},
const Volume* entity = nullptr) const = 0;

/// Get the canonical binning values, i.e. the binning values
/// for that fully describe the shape's extent
///
/// @return vector of canonical binning values
///
/// @note This is the default implementation that
/// returns the bounding box binning. Individual shapes
/// should override this method
virtual std::vector<Acts::BinningValue> canonicalBinning() const {
ssdetlab marked this conversation as resolved.
Show resolved Hide resolved
return {Acts::binX, Acts::binY, Acts::binZ};
};

/// Binning offset - overloaded for some R-binning types
///
/// @param bValue is the binning schema used
Expand Down
28 changes: 17 additions & 11 deletions Core/src/Detector/DetectorVolume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ Acts::Experimental::DetectorVolume::DetectorVolume(
}

[[maybe_unused]] const auto& gctx_ref = gctx;
assert(checkContainment(gctx) && "Objects are not contained by volume.");
}

Acts::Experimental::DetectorVolume::DetectorVolume(
Expand Down Expand Up @@ -264,20 +263,27 @@ Acts::Extent Acts::Experimental::DetectorVolume::extent(

bool Acts::Experimental::DetectorVolume::checkContainment(
const GeometryContext& gctx, std::size_t nseg) const {
// We don't have a logging instance here
// so can't throw a warning for shapes that are
// using the bounding box
auto binningValues = volumeBounds().canonicalBinning();

// Create the volume extent
auto volumeExtent = extent(gctx, nseg);
// Check surfaces
for (const auto* s : surfaces()) {
auto sExtent = s->polyhedronRepresentation(gctx, nseg).extent();
if (!volumeExtent.contains(sExtent)) {
return false;
for (auto b : binningValues) {
for (const auto* s : surfaces()) {
auto sExtent = s->polyhedronRepresentation(gctx, nseg).extent();
if (!volumeExtent.contains(sExtent, b)) {
return false;
}
}
}
// Check volumes
for (const auto* v : volumes()) {
auto vExtent = v->extent(gctx, nseg);
if (!volumeExtent.contains(vExtent)) {
return false;
// Check volumes
for (const auto* v : volumes()) {
auto vExtent = v->extent(gctx, nseg);
if (!volumeExtent.contains(vExtent, b)) {
return false;
}
}
}
// All contained
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct Options {
/// Write the identity transform explicitly
bool writeIdentity = false;
/// Apply a transpose to flip column/row order
bool transpose = true;
bool transpose = false;
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
};

/// @brief The Transform converter to json
Expand Down
71 changes: 71 additions & 0 deletions Tests/UnitTests/Core/Detector/DetectorVolumeTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "Acts/Navigation/SurfaceCandidatesUpdaters.hpp"
#include "Acts/Surfaces/CylinderBounds.hpp"
#include "Acts/Surfaces/CylinderSurface.hpp"
#include "Acts/Surfaces/PlaneSurface.hpp"
#include "Acts/Surfaces/RectangleBounds.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
#include "Acts/Utilities/BinningType.hpp"
Expand Down Expand Up @@ -53,6 +55,75 @@ Acts::GeometryContext tContext;

BOOST_AUTO_TEST_SUITE(Detector)

BOOST_AUTO_TEST_CASE(SurfaceVolumeContainment) {
// Create a surface that is placed way off
auto surfaceOutOfBounds = Acts::Surface::makeShared<Acts::CylinderSurface>(
Acts::Transform3::Identity() * Acts::Translation3(-1000, 0., 0.),
std::make_shared<Acts::CylinderBounds>(1, 1));

auto vBounds = Acts::CuboidVolumeBounds(10.0, 10.0, 10.0);
auto portalGenerator =
Acts::Experimental::defaultPortalAndSubPortalGenerator();
BOOST_CHECK_THROW(
Acts::Experimental::DetectorVolumeFactory::construct(
portalGenerator, Acts::GeometryContext(),
"CubeWithOutofBoundsSurface", Acts::Transform3::Identity(),
std::make_shared<Acts::CuboidVolumeBounds>(vBounds),
{surfaceOutOfBounds}, {}, Acts::Experimental::tryAllSubVolumes(),
Acts::Experimental::tryAllPortalsAndSurfaces(), 1000),
std::invalid_argument);

// Create a surface that is too big
auto surfaceTooBig = Acts::Surface::makeShared<Acts::PlaneSurface>(
Acts::Transform3::Identity() * Acts::Translation3(0, 0., 0.),
std::make_shared<Acts::RectangleBounds>(1, 100));

BOOST_CHECK_THROW(
Acts::Experimental::DetectorVolumeFactory::construct(
portalGenerator, Acts::GeometryContext(), "CubeWithSurfaceTooBig",
Acts::Transform3::Identity(),
std::make_shared<Acts::CuboidVolumeBounds>(vBounds), {surfaceTooBig},
{}, Acts::Experimental::tryAllSubVolumes(),
Acts::Experimental::tryAllPortalsAndSurfaces(), 1000),
std::invalid_argument);

// Envelope a bigger volume into a smaller one
auto bigVolume = Acts::Experimental::DetectorVolumeFactory::construct(
portalGenerator, Acts::GeometryContext(), "BigCube",
Acts::Transform3::Identity(),
std::make_shared<Acts::CuboidVolumeBounds>(vBounds), {}, {},
Acts::Experimental::tryAllSubVolumes(),
Acts::Experimental::tryAllPortalsAndSurfaces(), 1000);

auto smallBounds = Acts::CuboidVolumeBounds(1.0, 1.0, 1.0);
BOOST_CHECK_THROW(
Acts::Experimental::DetectorVolumeFactory::construct(
portalGenerator, Acts::GeometryContext(),
"SmallCubeWithBigCubeInside", Acts::Transform3::Identity(),
std::make_shared<Acts::CuboidVolumeBounds>(smallBounds), {},
{bigVolume}, Acts::Experimental::tryAllSubVolumes(),
Acts::Experimental::tryAllPortalsAndSurfaces(), 1000),
std::invalid_argument);

// Envelope a misaligned subvolume
auto smallVolumeMisaligned =
Acts::Experimental::DetectorVolumeFactory::construct(
portalGenerator, Acts::GeometryContext(), "SmallCubeMisaligned",
Acts::Transform3::Identity() * Acts::Translation3(9.5, 0., 0.),
std::make_shared<Acts::CuboidVolumeBounds>(smallBounds), {}, {},
Acts::Experimental::tryAllSubVolumes(),
Acts::Experimental::tryAllPortalsAndSurfaces(), 1000);

BOOST_CHECK_THROW(
Acts::Experimental::DetectorVolumeFactory::construct(
portalGenerator, Acts::GeometryContext(), "CubeWithMisalignedVolume",
Acts::Transform3::Identity(),
std::make_shared<Acts::CuboidVolumeBounds>(vBounds), {},
{smallVolumeMisaligned}, Acts::Experimental::tryAllSubVolumes(),
Acts::Experimental::tryAllPortalsAndSurfaces(), 1000),
std::invalid_argument);
}

BOOST_AUTO_TEST_CASE(CylindricalDetectorVolumePortals) {
Acts::ActsScalar rInner = 10.;
Acts::ActsScalar rOuter = 100.;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,10 @@ Acts::Test::CylindricalTrackingGeometry::DetectorStore generateXML() {
std::vector<std::array<Acts::ActsScalar, 2u>> innerOuter = {
{25., 35.}, {65., 75.}, {110., 120.}};
auto b0Surfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.14,
32., 3., 2., {16, 14});
31., 3., 2., {16, 14});

auto b1Surfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.14,
72., 3., 2., {32, 14});
71., 3., 2., {32, 14});

auto b2Surfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.14,
116., 3., 2., {52, 14});
Expand Down Expand Up @@ -192,7 +192,7 @@ Acts::Test::CylindricalTrackingGeometry::DetectorStore generateXML() {
cxml << beampipe_head_xml << '\n';
cxml << indent_12_xml << "<acts_passive_surface>" << '\n';
cxml << indent_12_xml
<< "<tubs rmin=\"25*mm\" rmax=\"25.8*mm\" dz=\"1800*mm\" "
<< "<tubs rmin=\"19*mm\" rmax=\"20*mm\" dz=\"800*mm\" "
"material=\"Air\"/>"
<< '\n';
cxml << indent_12_xml << "</acts_passive_surface>" << '\n';
Expand Down
6 changes: 3 additions & 3 deletions Tests/UnitTests/Plugins/Json/DetectorJsonConverterTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ BOOST_AUTO_TEST_CASE(BeamPipeEndcapBarrelDetector) {
Acts::Logging::VERBOSE));

Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
shapeConfig.boundValues = {20, 100, 10., M_PI, 0.};
shapeConfig.boundValues = {18, 100, 10., M_PI, 0.};
shapeConfig.transform = Acts::Transform3(Acts::Transform3::Identity())
.pretranslate(Acts::Vector3(0., 0., ep));
shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
Expand All @@ -202,7 +202,7 @@ BOOST_AUTO_TEST_CASE(BeamPipeEndcapBarrelDetector) {

// Central barrel
Acts::Experimental::VolumeStructureBuilder::Config innerShapeConfig;
innerShapeConfig.boundValues = {20., 60., 700., M_PI, 0.};
innerShapeConfig.boundValues = {18., 60., 700., M_PI, 0.};
innerShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;

auto innerShapeBuilder =
Expand Down Expand Up @@ -298,7 +298,7 @@ BOOST_AUTO_TEST_CASE(BeamPipeEndcapBarrelDetector) {

// Beam Pipe
Acts::Experimental::VolumeStructureBuilder::Config bpShapeConfig;
bpShapeConfig.boundValues = {0., 20., 720., M_PI, 0.};
bpShapeConfig.boundValues = {0., 18., 720., M_PI, 0.};
bpShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;

auto bpShapeBuilder =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "Acts/Detector/LayerStructureBuilder.hpp"
#include "Acts/Detector/PortalGenerators.hpp"
#include "Acts/Detector/VolumeStructureBuilder.hpp"
#include "Acts/Geometry/ConeVolumeBounds.hpp"
#include "Acts/Geometry/CylinderVolumeBounds.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Navigation/DetectorVolumeFinders.hpp"
Expand Down
Loading