diff --git a/Core/src/Detector/Detector.cpp b/Core/src/Detector/Detector.cpp index 9e40b0e0340..96c136117e0 100644 --- a/Core/src/Detector/Detector.cpp +++ b/Core/src/Detector/Detector.cpp @@ -53,6 +53,9 @@ Acts::Experimental::Detector::Detector( // Fill the surface map std::unordered_map surfaceGeoIdMap; + // Map for the volume geometry id + std::unordered_map volumeGeoIdMap; + // Check for unique names and fill the volume name / index map for (auto [iv, v] : enumerate(m_volumes.internal)) { // Assign this detector @@ -67,8 +70,40 @@ Acts::Experimental::Detector::Detector( } m_volumeNameIndex[vName] = iv; + // --------------------------------------------------------------- + // Check volume geometry id + auto vgeoID = v->geometryId(); + // Check for undefined geometry id + if (vgeoID.value() == 0u) { + throw std::invalid_argument("Detector: volume '" + v->name() + + "' with undefined geometry id detected" + + ". Make sure a GeometryIdGenerator is used."); + } + if (volumeGeoIdMap.find(vgeoID) != volumeGeoIdMap.end()) { + std::stringstream ss; + ss << vgeoID; + throw std::invalid_argument("Detector: duplicate volume geometry id '" + + ss.str() + "' detected" + + ". Make sure a GeometryIdGenerator is used."); + } + volumeGeoIdMap.emplace(vgeoID, v.get()); + // --------------------------------------------------------------- + for (const auto* s : v->surfaces()) { auto sgeoID = s->geometryId(); + + // --------------------------------------------------------------- + // Check for undefined geometry id + if (sgeoID.value() == 0u) { + std::stringstream ss; + ss << s->name(); + throw std::invalid_argument( + "Detector: surface '" + ss.str() + "' with undefined geometry id " + + "detected in volume '" + v->name() + + "'. Make sure a GeometryIdGenerator is used."); + } + // --------------------------------------------------------------- + if (surfaceGeoIdMap.find(sgeoID) != surfaceGeoIdMap.end()) { std::stringstream ss; ss << sgeoID; diff --git a/Plugins/Json/src/DetectorVolumeJsonConverter.cpp b/Plugins/Json/src/DetectorVolumeJsonConverter.cpp index 8397c7a690d..bf1217b65eb 100644 --- a/Plugins/Json/src/DetectorVolumeJsonConverter.cpp +++ b/Plugins/Json/src/DetectorVolumeJsonConverter.cpp @@ -49,6 +49,7 @@ nlohmann::json Acts::DetectorVolumeJsonConverter::toJson( const Options& options) { nlohmann::json jVolume; jVolume["name"] = volume.name(); + jVolume["geometryId"] = volume.geometryId().volume(); jVolume["transform"] = Transform3JsonConverter::toJson( volume.transform(gctx), options.transformOptions); jVolume["bounds"] = VolumeBoundsJsonConverter::toJson(volume.volumeBounds()); @@ -156,6 +157,8 @@ std::shared_ptr Acts::DetectorVolumeJsonConverter::fromJson(const GeometryContext& gctx, const nlohmann::json& jVolume) { std::string name = jVolume["name"]; + GeometryIdentifier geoId; + geoId.setVolume(jVolume["geometryId"]); Transform3 transform = Transform3JsonConverter::fromJson(jVolume["transform"]); auto bounds = VolumeBoundsJsonConverter::fromJson(jVolume["bounds"]); @@ -167,9 +170,11 @@ Acts::DetectorVolumeJsonConverter::fromJson(const GeometryContext& gctx, auto portalGenerator = Experimental::defaultPortalGenerator(); if (jSurfaces.empty() && jVolumes.empty()) { - return Experimental::DetectorVolumeFactory::construct( + auto volume = Experimental::DetectorVolumeFactory::construct( portalGenerator, gctx, name, transform, std::move(bounds), Experimental::tryAllPortals()); + volume->assignGeometryId(geoId); + return volume; } // Convert the surfaces std::vector> surfaces; @@ -184,8 +189,10 @@ Acts::DetectorVolumeJsonConverter::fromJson(const GeometryContext& gctx, auto jSurfaceNavigation = jVolume["surface_navigation"]; - return Experimental::DetectorVolumeFactory::construct( + auto volume = Experimental::DetectorVolumeFactory::construct( portalGenerator, gctx, name, transform, std::move(bounds), surfaces, volumes, Experimental::tryRootVolumes(), IndexedSurfacesJsonConverter::fromJson(jSurfaceNavigation)); + volume->assignGeometryId(geoId); + return volume; } diff --git a/Tests/UnitTests/Core/Detector/CylindricalDetectorHelperTests.cpp b/Tests/UnitTests/Core/Detector/CylindricalDetectorHelperTests.cpp index 67e92fbb8b7..66583ba2432 100644 --- a/Tests/UnitTests/Core/Detector/CylindricalDetectorHelperTests.cpp +++ b/Tests/UnitTests/Core/Detector/CylindricalDetectorHelperTests.cpp @@ -12,6 +12,7 @@ #include "Acts/Detector/Detector.hpp" #include "Acts/Detector/DetectorComponents.hpp" #include "Acts/Detector/DetectorVolume.hpp" +#include "Acts/Detector/GeometryIdGenerator.hpp" #include "Acts/Detector/PortalGenerators.hpp" #include "Acts/Detector/detail/CylindricalDetectorHelper.hpp" #include "Acts/Geometry/CuboidVolumeBounds.hpp" @@ -149,6 +150,16 @@ BOOST_AUTO_TEST_CASE(ConnectInR) { BOOST_CHECK_EQUAL(rVolumes[0u]->portalPtrs()[0u], protoContainer[0u]); BOOST_CHECK_EQUAL(rVolumes[0u]->portalPtrs()[1u], protoContainer[1u]); + // Assign geometry ids to the volumes + Acts::Experimental::GeometryIdGenerator::Config generatorConfig; + GeometryIdGenerator generator( + generatorConfig, Acts::getDefaultLogger("SequentialIdGenerator", + Acts::Logging::VERBOSE)); + auto cache = generator.generateCache(); + for (auto& vol : rVolumes) { + generator.assignGeometryId(cache, *vol); + } + // A detector construction that should work auto detector = Detector::makeShared("DetectorInR", rVolumes, tryRootVolumes()); @@ -274,6 +285,16 @@ BOOST_AUTO_TEST_CASE(ConnectInZ) { BOOST_CHECK_EQUAL(protoContainer[ip], zVolumes[0u]->portalPtrs()[ip]); } + // Assign geometry ids to the volumes + Acts::Experimental::GeometryIdGenerator::Config generatorConfig; + GeometryIdGenerator generator( + generatorConfig, Acts::getDefaultLogger("SequentialIdGenerator", + Acts::Logging::VERBOSE)); + auto cache = generator.generateCache(); + for (auto& vol : zVolumes) { + generator.assignGeometryId(cache, *vol); + } + auto detector = Detector::makeShared("DetectorInZ", zVolumes, tryRootVolumes()); } @@ -357,6 +378,16 @@ BOOST_AUTO_TEST_CASE(ConnectInPhi) { } } + // Assign geometry ids to the volumes + Acts::Experimental::GeometryIdGenerator::Config generatorConfig; + GeometryIdGenerator generator( + generatorConfig, Acts::getDefaultLogger("SequentialIdGenerator", + Acts::Logging::VERBOSE)); + auto cache = generator.generateCache(); + for (auto& vol : phiVolumes) { + generator.assignGeometryId(cache, *vol); + } + auto detector = Detector::makeShared("DetectorInPhi", phiVolumes, tryRootVolumes()); } @@ -534,6 +565,16 @@ BOOST_AUTO_TEST_CASE(ProtoContainerZR) { dVolumes.push_back(pecInner); dVolumes.push_back(pecOuter); + // Assign geometry ids to the volumes + Acts::Experimental::GeometryIdGenerator::Config generatorConfig; + GeometryIdGenerator generator( + generatorConfig, Acts::getDefaultLogger("SequentialIdGenerator", + Acts::Logging::VERBOSE)); + auto cache = generator.generateCache(); + for (auto& vol : dVolumes) { + generator.assignGeometryId(cache, *vol); + } + auto detector = Detector::makeShared("DetectorFromProtoContainer", dVolumes, tryRootVolumes()); } // test with different innermost radii diff --git a/Tests/UnitTests/Core/Detector/DetectorBuilderTests.cpp b/Tests/UnitTests/Core/Detector/DetectorBuilderTests.cpp index 041aef288eb..e5732b5f3fa 100644 --- a/Tests/UnitTests/Core/Detector/DetectorBuilderTests.cpp +++ b/Tests/UnitTests/Core/Detector/DetectorBuilderTests.cpp @@ -60,6 +60,10 @@ class CompBuilder final : public Acts::Experimental::IDetectorComponentBuilder { portalContainer[ip] = p; } + Acts::GeometryIdentifier geoID; + geoID.setVolume(1); + dVolume->assignGeometryId(geoID); + return Acts::Experimental::DetectorComponent{ {dVolume}, portalContainer, diff --git a/Tests/UnitTests/Core/Detector/DetectorTests.cpp b/Tests/UnitTests/Core/Detector/DetectorTests.cpp index 840847958e6..6f63c7eea2b 100644 --- a/Tests/UnitTests/Core/Detector/DetectorTests.cpp +++ b/Tests/UnitTests/Core/Detector/DetectorTests.cpp @@ -11,6 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Detector/Detector.hpp" #include "Acts/Detector/DetectorVolume.hpp" +#include "Acts/Detector/GeometryIdGenerator.hpp" #include "Acts/Detector/PortalGenerators.hpp" #include "Acts/Geometry/CylinderVolumeBounds.hpp" #include "Acts/Geometry/GeometryContext.hpp" @@ -87,6 +88,16 @@ BOOST_AUTO_TEST_CASE(DetectorConstruction) { std::vector> volumes012 = {cyl0, cyl1, cyl2}; + + Acts::Experimental::GeometryIdGenerator::Config generatorConfig; + Acts::Experimental::GeometryIdGenerator generator( + generatorConfig, + Acts::getDefaultLogger("SequentialIdGenerator", Acts::Logging::VERBOSE)); + auto cache = generator.generateCache(); + for (auto& vol : volumes012) { + generator.assignGeometryId(cache, *vol); + } + auto det012 = Acts::Experimental::Detector::makeShared( "Det012", volumes012, Acts::Experimental::tryRootVolumes()); @@ -133,6 +144,8 @@ BOOST_AUTO_TEST_CASE(DetectorConstruction) { std::move(unconnected)), std::invalid_argument); + generator.assignGeometryId(cache, *cyl0nameDup); + // Misconfigured - duplicate name std::vector> volumes002 = {cyl0, cyl0nameDup, cyl2}; @@ -166,6 +179,14 @@ BOOST_AUTO_TEST_CASE(DetectorConstructionWithHierarchyMap) { Acts::Experimental::tryNoVolumes(), Acts::Experimental::tryAllPortalsAndSurfaces()); + Acts::Experimental::GeometryIdGenerator::Config generatorConfig; + Acts::Experimental::GeometryIdGenerator generator( + generatorConfig, + Acts::getDefaultLogger("SequentialIdGenerator", Acts::Logging::VERBOSE)); + + auto cache = generator.generateCache(); + generator.assignGeometryId(cache, *cylVolume); + auto det = Acts::Experimental::Detector::makeShared( "DetWithSurfaces", {cylVolume}, Acts::Experimental::tryRootVolumes()); diff --git a/Tests/UnitTests/Core/Detector/IndexedRootVolumeFinderBuilderTests.cpp b/Tests/UnitTests/Core/Detector/IndexedRootVolumeFinderBuilderTests.cpp index 7aaeed47c7a..e2713694b0f 100644 --- a/Tests/UnitTests/Core/Detector/IndexedRootVolumeFinderBuilderTests.cpp +++ b/Tests/UnitTests/Core/Detector/IndexedRootVolumeFinderBuilderTests.cpp @@ -10,6 +10,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Detector/DetectorVolume.hpp" +#include "Acts/Detector/GeometryIdGenerator.hpp" #include "Acts/Detector/IndexedRootVolumeFinderBuilder.hpp" #include "Acts/Detector/PortalGenerators.hpp" #include "Acts/Geometry/CylinderVolumeBounds.hpp" @@ -72,6 +73,15 @@ BOOST_AUTO_TEST_CASE(IndexedRootVolumeFinderBuilderCylindrical) { // Let's construct a detector auto rootVolumeFinder = builder.construct(tContext, rootVolumes); + Acts::Experimental::GeometryIdGenerator::Config generatorConfig; + Acts::Experimental::GeometryIdGenerator generator( + generatorConfig, + Acts::getDefaultLogger("SequentialIdGenerator", Acts::Logging::VERBOSE)); + auto cache = generator.generateCache(); + for (auto& vol : rootVolumes) { + generator.assignGeometryId(cache, *vol); + } + auto detectorIndexed = Detector::makeShared("IndexedDetector", rootVolumes, std::move(rootVolumeFinder)); diff --git a/Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp b/Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp index 3f51555959e..9353d186266 100644 --- a/Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp +++ b/Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp @@ -56,6 +56,10 @@ BOOST_AUTO_TEST_CASE(DetectorNavigator) { Acts::Experimental::tryAllSubVolumes(), Acts::Experimental::tryAllPortalsAndSurfaces()); + Acts::GeometryIdentifier innerGeoID; + innerGeoID.setVolume(1); + innerVolume->assignGeometryId(innerGeoID); + auto detectorVolume = Acts::Experimental::DetectorVolumeFactory::construct( Acts::Experimental::defaultPortalAndSubPortalGenerator(), tgContext, "Detector Volume", Acts::Transform3::Identity(), @@ -66,6 +70,10 @@ BOOST_AUTO_TEST_CASE(DetectorNavigator) { Acts::Experimental::tryAllSubVolumes(), Acts::Experimental::tryAllPortalsAndSurfaces()); + Acts::GeometryIdentifier geoID; + geoID.setVolume(2); + detectorVolume->assignGeometryId(geoID); + auto detector = Acts::Experimental::Detector::makeShared( "Detector", {detectorVolume}, Acts::Experimental::tryRootVolumes()); diff --git a/Tests/UnitTests/Core/Navigation/DetectorVolumeFindersTests.cpp b/Tests/UnitTests/Core/Navigation/DetectorVolumeFindersTests.cpp index b2a8b563849..33778ad6af5 100644 --- a/Tests/UnitTests/Core/Navigation/DetectorVolumeFindersTests.cpp +++ b/Tests/UnitTests/Core/Navigation/DetectorVolumeFindersTests.cpp @@ -11,6 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Detector/Detector.hpp" #include "Acts/Detector/DetectorVolume.hpp" +#include "Acts/Detector/GeometryIdGenerator.hpp" #include "Acts/Detector/PortalGenerators.hpp" #include "Acts/Geometry/CylinderVolumeBounds.hpp" #include "Acts/Geometry/GeometryContext.hpp" @@ -66,13 +67,24 @@ auto cyl2 = Acts::Experimental::DetectorVolumeFactory::construct( std::vector> volumes012 = { cyl0, cyl1, cyl2}; -auto det012 = Acts::Experimental::Detector::makeShared( - "Det012", volumes012, Acts::Experimental::tryRootVolumes()); + +Acts::Experimental::GeometryIdGenerator::Config generatorConfig; +Acts::Experimental::GeometryIdGenerator generator( + generatorConfig, + Acts::getDefaultLogger("SequentialIdGenerator", Acts::Logging::VERBOSE)); BOOST_AUTO_TEST_SUITE(Experimental) // Test finding detectors by trial and error BOOST_AUTO_TEST_CASE(RootVolumeFinder) { + auto cache = generator.generateCache(); + for (auto& vol : volumes012) { + generator.assignGeometryId(cache, *vol); + } + + auto det012 = Acts::Experimental::Detector::makeShared( + "Det012", volumes012, Acts::Experimental::tryRootVolumes()); + nState.currentDetector = det012.get(); Acts::Experimental::RootVolumeFinder rvf; // Cylinder 0 @@ -94,6 +106,14 @@ BOOST_AUTO_TEST_CASE(RootVolumeFinder) { // Test finding detectors beu trial and error BOOST_AUTO_TEST_CASE(IndexedDetectorVolumeFinder) { + auto cache = generator.generateCache(); + for (auto& vol : volumes012) { + generator.assignGeometryId(cache, *vol); + } + + auto det012 = Acts::Experimental::Detector::makeShared( + "Det012", volumes012, Acts::Experimental::tryRootVolumes()); + nState.currentDetector = det012.get(); using SingleIndex = std::size_t; diff --git a/Tests/UnitTests/Plugins/Json/DetectorJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/DetectorJsonConverterTests.cpp index fa90624dc35..b4508076a2c 100644 --- a/Tests/UnitTests/Plugins/Json/DetectorJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/DetectorJsonConverterTests.cpp @@ -84,6 +84,15 @@ BOOST_AUTO_TEST_CASE(SingleEmptyVolumeDetector) { std::vector> volumes = { volume}; + Acts::Experimental::GeometryIdGenerator::Config generatorConfig; + Acts::Experimental::GeometryIdGenerator generator( + generatorConfig, + Acts::getDefaultLogger("SequentialIdGenerator", Acts::Logging::VERBOSE)); + auto cache = generator.generateCache(); + for (auto& vol : volumes) { + generator.assignGeometryId(cache, *vol); + } + auto detector = Acts::Experimental::Detector::makeShared( "Detector", volumes, Acts::Experimental::tryRootVolumes()); @@ -114,6 +123,15 @@ BOOST_AUTO_TEST_CASE(SingleVolumeOneSurfaceDetector) { std::vector> volumes = { volume}; + Acts::Experimental::GeometryIdGenerator::Config generatorConfig; + Acts::Experimental::GeometryIdGenerator generator( + generatorConfig, + Acts::getDefaultLogger("SequentialIdGenerator", Acts::Logging::VERBOSE)); + auto cache = generator.generateCache(); + for (auto& vol : volumes) { + generator.assignGeometryId(cache, *vol); + } + auto detector = Acts::Experimental::Detector::makeShared( "Detector", volumes, Acts::Experimental::tryRootVolumes());