File indexing completed on 2025-10-23 08:24:02
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Detector/Detector.hpp"
0013 #include "Acts/Detector/DetectorVolume.hpp"
0014 #include "Acts/Detector/GeometryIdGenerator.hpp"
0015 #include "Acts/Detector/PortalGenerators.hpp"
0016 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0017 #include "Acts/Geometry/GeometryContext.hpp"
0018 #include "Acts/Geometry/GeometryHierarchyMap.hpp"
0019 #include "Acts/Geometry/GeometryIdentifier.hpp"
0020 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0021 #include "Acts/Material/HomogeneousVolumeMaterial.hpp"
0022 #include "Acts/Material/Material.hpp"
0023 #include "Acts/Material/MaterialSlab.hpp"
0024 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0025 #include "Acts/Navigation/InternalNavigation.hpp"
0026 #include "Acts/Navigation/NavigationDelegates.hpp"
0027 #include "Acts/Navigation/NavigationState.hpp"
0028 #include "Acts/Surfaces/CylinderBounds.hpp"
0029 #include "ActsTests/CommonHelpers/DetectorElementStub.hpp"
0030
0031 #include <memory>
0032 #include <stdexcept>
0033 #include <string>
0034 #include <utility>
0035 #include <vector>
0036
0037 using namespace Acts;
0038
0039 namespace ActsTests {
0040
0041
0042
0043
0044
0045
0046
0047
0048 template <typename referenced_type>
0049 std::shared_ptr<referenced_type> unpackToShared(referenced_type& rt) {
0050 return rt.getSharedPtr();
0051 }
0052
0053 GeometryContext tContext;
0054
0055 BOOST_AUTO_TEST_SUITE(DetectorSuite)
0056
0057 BOOST_AUTO_TEST_CASE(DetectorConstruction) {
0058 double r0 = 0.;
0059 double r1 = 10.;
0060 double r2 = 100.;
0061 double r3 = 200.;
0062 double zHalfL = 200.;
0063
0064 Transform3 nominal = Transform3::Identity();
0065
0066
0067 auto cyl0Bounds = std::make_unique<CylinderVolumeBounds>(r0, r1, zHalfL);
0068
0069 auto cyl0BoundsCopy = std::make_unique<CylinderVolumeBounds>(r0, r1, zHalfL);
0070
0071 auto cyl1Bounds = std::make_unique<CylinderVolumeBounds>(r1, r2, zHalfL);
0072
0073 auto cyl2Bounds = std::make_unique<CylinderVolumeBounds>(r2, r3, zHalfL);
0074
0075 auto portalGenerator = Experimental::defaultPortalGenerator();
0076
0077 auto cyl0 = Experimental::DetectorVolumeFactory::construct(
0078 portalGenerator, tContext, "Cyl0", nominal, std::move(cyl0Bounds),
0079 Experimental::tryAllPortals());
0080
0081 auto cyl0nameDup = Experimental::DetectorVolumeFactory::construct(
0082 portalGenerator, tContext, "Cyl0", nominal, std::move(cyl0BoundsCopy),
0083 Experimental::tryAllPortals());
0084
0085 auto cyl1 = Experimental::DetectorVolumeFactory::construct(
0086 portalGenerator, tContext, "Cyl1", nominal, std::move(cyl1Bounds),
0087 Experimental::tryAllPortals());
0088
0089 auto cyl2 = Experimental::DetectorVolumeFactory::construct(
0090 portalGenerator, tContext, "Cyl2", nominal, std::move(cyl2Bounds),
0091 Experimental::tryAllPortals());
0092
0093 std::vector<std::shared_ptr<Experimental::DetectorVolume>> volumes012 = {
0094 cyl0, cyl1, cyl2};
0095
0096 Experimental::GeometryIdGenerator::Config generatorConfig;
0097 Experimental::GeometryIdGenerator generator(
0098 generatorConfig,
0099 getDefaultLogger("SequentialIdGenerator", Logging::VERBOSE));
0100 auto cache = generator.generateCache();
0101 for (auto& vol : volumes012) {
0102 generator.assignGeometryId(cache, *vol);
0103 }
0104
0105 auto det012 = Experimental::Detector::makeShared(
0106 "Det012", volumes012, Experimental::tryRootVolumes());
0107
0108
0109 BOOST_CHECK_EQUAL(det012->name(), "Det012");
0110 BOOST_CHECK_EQUAL(det012->volumes().size(), 3u);
0111 BOOST_CHECK_EQUAL(det012->volumePtrs().size(), 3u);
0112
0113
0114 BOOST_CHECK_EQUAL(det012, unpackToShared<Experimental::Detector>(*det012));
0115 BOOST_CHECK_EQUAL(det012,
0116 unpackToShared<const Experimental::Detector>(*det012));
0117
0118
0119
0120 std::size_t nSurfaces = 0;
0121 det012->visitSurfaces([&nSurfaces](const auto* s) {
0122 if (s != nullptr) {
0123 nSurfaces++;
0124 }
0125 });
0126 BOOST_CHECK_EQUAL(nSurfaces, 11u);
0127
0128
0129 std::size_t nVolumes = 0;
0130 det012->visitVolumes([&nVolumes](const auto* v) {
0131 if (v != nullptr) {
0132 nVolumes++;
0133 }
0134 });
0135 BOOST_CHECK_EQUAL(nVolumes, 3u);
0136
0137
0138
0139 struct SetMaterial {
0140
0141 std::shared_ptr<const HomogeneousSurfaceMaterial> surfaceMaterial =
0142 std::make_shared<HomogeneousSurfaceMaterial>(
0143 MaterialSlab(Material::fromMolarDensity(1., 2., 3., 4., 5.), 1.));
0144
0145 std::shared_ptr<HomogeneousVolumeMaterial> volumeMaterial =
0146 std::make_shared<HomogeneousVolumeMaterial>(
0147 Material::fromMolarDensity(1., 2., 3., 4., 5.));
0148
0149
0150 void operator()(Surface* s) {
0151 if (s != nullptr) {
0152 s->assignSurfaceMaterial(surfaceMaterial);
0153 }
0154 }
0155
0156
0157 void operator()(Experimental::DetectorVolume* v) {
0158 if (v != nullptr) {
0159 v->assignVolumeMaterial(volumeMaterial);
0160 }
0161 }
0162 };
0163
0164 SetMaterial setMaterial;
0165 det012->visitMutableSurfaces(setMaterial);
0166 det012->visitMutableVolumes(setMaterial);
0167
0168
0169 std::size_t nSurfacesWithMaterial = 0;
0170 det012->visitSurfaces([&nSurfacesWithMaterial](const auto* s) {
0171 if (s != nullptr && s->surfaceMaterial() != nullptr) {
0172 nSurfacesWithMaterial++;
0173 }
0174 });
0175 BOOST_CHECK_EQUAL(nSurfacesWithMaterial, 11u);
0176
0177
0178 std::size_t nVolumesWithMaterial = 0;
0179
0180 det012->visitVolumes([&nVolumesWithMaterial](const auto* v) {
0181 if (v != nullptr && v->volumeMaterial() != nullptr) {
0182 nVolumesWithMaterial++;
0183 }
0184 });
0185 BOOST_CHECK_EQUAL(nVolumesWithMaterial, 3u);
0186
0187
0188 Experimental::NavigationState nState;
0189 nState.position = Vector3(5., 0., 0.);
0190 nState.currentDetector = det012.get();
0191 det012->updateDetectorVolume(tContext, nState);
0192 BOOST_CHECK_EQUAL(nState.currentVolume, cyl0.get());
0193
0194 auto find1 = det012->findDetectorVolume(tContext, Vector3(15., 0., 0.));
0195 BOOST_CHECK_EQUAL(find1, cyl1.get());
0196
0197 auto find2 = det012->findDetectorVolume(tContext, Vector3(150., 0., 0.));
0198 BOOST_CHECK_EQUAL(find2, cyl2.get());
0199
0200 auto findNull = det012->findDetectorVolume(tContext, Vector3(1500., 0., 0.));
0201 BOOST_CHECK_EQUAL(findNull, nullptr);
0202
0203
0204 auto find0 = det012->findDetectorVolume("Cyl0");
0205 BOOST_CHECK_EQUAL(find0, cyl0.get());
0206
0207 findNull = det012->findDetectorVolume("Null");
0208 BOOST_CHECK_EQUAL(findNull, nullptr);
0209
0210
0211 Experimental::ExternalNavigationDelegate unconnected;
0212 BOOST_CHECK_THROW(
0213 Experimental::Detector::makeShared("Det012_unconnected", volumes012,
0214 std::move(unconnected)),
0215 std::invalid_argument);
0216
0217 generator.assignGeometryId(cache, *cyl0nameDup);
0218
0219
0220 std::vector<std::shared_ptr<Experimental::DetectorVolume>> volumes002 = {
0221 cyl0, cyl0nameDup, cyl2};
0222 BOOST_CHECK_THROW(
0223 Experimental::Detector::makeShared("Det002_name_duplicate", volumes002,
0224 Experimental::tryRootVolumes()),
0225 std::invalid_argument);
0226 }
0227
0228 BOOST_AUTO_TEST_CASE(DetectorConstructionWithHierarchyMap) {
0229 auto portalGenerator = Experimental::defaultPortalGenerator();
0230
0231 std::vector<std::unique_ptr<DetectorElementStub>> detStore;
0232 std::vector<double> radii = {100, 102, 104, 106, 108, 110};
0233 auto cylinderVoumeBounds =
0234 std::make_unique<CylinderVolumeBounds>(80, 130, 200);
0235 std::vector<std::shared_ptr<Surface>> surfaces = {};
0236 for (auto [ir, r] : enumerate(radii)) {
0237 auto detElement = std::make_unique<DetectorElementStub>(
0238 Transform3::Identity(), std::make_shared<CylinderBounds>(r, 190.), 0.1);
0239 auto surface = detElement->surface().getSharedPtr();
0240 surface->assignGeometryId(GeometryIdentifier{}.withSensitive(ir + 1));
0241 surfaces.push_back(std::move(surface));
0242 detStore.push_back(std::move(detElement));
0243 }
0244
0245 auto cylVolume = Experimental::DetectorVolumeFactory::construct(
0246 portalGenerator, tContext, "CylinderVolume", Transform3::Identity(),
0247 std::move(cylinderVoumeBounds), surfaces, {},
0248 Experimental::tryNoVolumes(), Experimental::tryAllPortalsAndSurfaces());
0249
0250 Experimental::GeometryIdGenerator::Config generatorConfig;
0251 Experimental::GeometryIdGenerator generator(
0252 generatorConfig,
0253 getDefaultLogger("SequentialIdGenerator", Logging::VERBOSE));
0254
0255 auto cache = generator.generateCache();
0256 generator.assignGeometryId(cache, *cylVolume);
0257
0258 auto det = Experimental::Detector::makeShared("DetWithSurfaces", {cylVolume},
0259 Experimental::tryRootVolumes());
0260
0261 const auto& sensitiveHierarchyMap = det->sensitiveHierarchyMap();
0262
0263 const Surface* surface0 =
0264 det->findSurface(GeometryIdentifier{}.withSensitive(1));
0265
0266 BOOST_CHECK_EQUAL(sensitiveHierarchyMap.size(), 6u);
0267 BOOST_CHECK_NE(surface0, nullptr);
0268 }
0269
0270 BOOST_AUTO_TEST_SUITE_END()
0271
0272 }