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