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/DetectorVolume.hpp"
0013 #include "Acts/Detector/Portal.hpp"
0014 #include "Acts/Detector/PortalGenerators.hpp"
0015 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0016 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0017 #include "Acts/Geometry/Extent.hpp"
0018 #include "Acts/Geometry/GeometryContext.hpp"
0019 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0020 #include "Acts/Material/HomogeneousVolumeMaterial.hpp"
0021 #include "Acts/Material/Material.hpp"
0022 #include "Acts/Material/MaterialSlab.hpp"
0023 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0024 #include "Acts/Navigation/InternalNavigation.hpp"
0025 #include "Acts/Navigation/NavigationState.hpp"
0026 #include "Acts/Surfaces/CylinderBounds.hpp"
0027 #include "Acts/Surfaces/CylinderSurface.hpp"
0028 #include "Acts/Surfaces/PlaneSurface.hpp"
0029 #include "Acts/Surfaces/RectangleBounds.hpp"
0030 #include "Acts/Surfaces/Surface.hpp"
0031 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0032 #include "Acts/Utilities/BinningType.hpp"
0033
0034 #include <cstddef>
0035 #include <memory>
0036 #include <stdexcept>
0037 #include <utility>
0038 #include <vector>
0039
0040
0041
0042
0043
0044
0045
0046
0047 template <typename referenced_type>
0048 std::shared_ptr<referenced_type> unpackToShared(referenced_type& rt) {
0049 return rt.getSharedPtr();
0050 }
0051
0052 using namespace Acts::Experimental;
0053
0054 Acts::GeometryContext tContext;
0055
0056 BOOST_AUTO_TEST_SUITE(Detector)
0057
0058 BOOST_AUTO_TEST_CASE(SurfaceVolumeContainment) {
0059
0060 auto surfaceOutOfBounds = Acts::Surface::makeShared<Acts::CylinderSurface>(
0061 Acts::Transform3::Identity() * Acts::Translation3(-1000, 0., 0.),
0062 std::make_shared<Acts::CylinderBounds>(1, 1));
0063
0064 auto vBounds = Acts::CuboidVolumeBounds(10.0, 10.0, 10.0);
0065 auto portalGenerator =
0066 Acts::Experimental::defaultPortalAndSubPortalGenerator();
0067 BOOST_CHECK_THROW(
0068 Acts::Experimental::DetectorVolumeFactory::construct(
0069 portalGenerator, Acts::GeometryContext(),
0070 "CubeWithOutofBoundsSurface", Acts::Transform3::Identity(),
0071 std::make_shared<Acts::CuboidVolumeBounds>(vBounds),
0072 {surfaceOutOfBounds}, {}, Acts::Experimental::tryAllSubVolumes(),
0073 Acts::Experimental::tryAllPortalsAndSurfaces(), 1000),
0074 std::invalid_argument);
0075
0076
0077 auto surfaceTooBig = Acts::Surface::makeShared<Acts::PlaneSurface>(
0078 Acts::Transform3::Identity() * Acts::Translation3(0, 0., 0.),
0079 std::make_shared<Acts::RectangleBounds>(1, 100));
0080
0081 BOOST_CHECK_THROW(
0082 Acts::Experimental::DetectorVolumeFactory::construct(
0083 portalGenerator, Acts::GeometryContext(), "CubeWithSurfaceTooBig",
0084 Acts::Transform3::Identity(),
0085 std::make_shared<Acts::CuboidVolumeBounds>(vBounds), {surfaceTooBig},
0086 {}, Acts::Experimental::tryAllSubVolumes(),
0087 Acts::Experimental::tryAllPortalsAndSurfaces(), 1000),
0088 std::invalid_argument);
0089
0090
0091 auto bigVolume = Acts::Experimental::DetectorVolumeFactory::construct(
0092 portalGenerator, Acts::GeometryContext(), "BigCube",
0093 Acts::Transform3::Identity(),
0094 std::make_shared<Acts::CuboidVolumeBounds>(vBounds), {}, {},
0095 Acts::Experimental::tryAllSubVolumes(),
0096 Acts::Experimental::tryAllPortalsAndSurfaces(), 1000);
0097
0098 auto smallBounds = Acts::CuboidVolumeBounds(1.0, 1.0, 1.0);
0099 BOOST_CHECK_THROW(
0100 Acts::Experimental::DetectorVolumeFactory::construct(
0101 portalGenerator, Acts::GeometryContext(),
0102 "SmallCubeWithBigCubeInside", Acts::Transform3::Identity(),
0103 std::make_shared<Acts::CuboidVolumeBounds>(smallBounds), {},
0104 {bigVolume}, Acts::Experimental::tryAllSubVolumes(),
0105 Acts::Experimental::tryAllPortalsAndSurfaces(), 1000),
0106 std::invalid_argument);
0107
0108
0109 auto smallVolumeMisaligned =
0110 Acts::Experimental::DetectorVolumeFactory::construct(
0111 portalGenerator, Acts::GeometryContext(), "SmallCubeMisaligned",
0112 Acts::Transform3::Identity() * Acts::Translation3(9.5, 0., 0.),
0113 std::make_shared<Acts::CuboidVolumeBounds>(smallBounds), {}, {},
0114 Acts::Experimental::tryAllSubVolumes(),
0115 Acts::Experimental::tryAllPortalsAndSurfaces(), 1000);
0116
0117 BOOST_CHECK_THROW(
0118 Acts::Experimental::DetectorVolumeFactory::construct(
0119 portalGenerator, Acts::GeometryContext(), "CubeWithMisalignedVolume",
0120 Acts::Transform3::Identity(),
0121 std::make_shared<Acts::CuboidVolumeBounds>(vBounds), {},
0122 {smallVolumeMisaligned}, Acts::Experimental::tryAllSubVolumes(),
0123 Acts::Experimental::tryAllPortalsAndSurfaces(), 1000),
0124 std::invalid_argument);
0125 }
0126
0127 BOOST_AUTO_TEST_CASE(CylindricalDetectorVolumePortals) {
0128 double rInner = 10.;
0129 double rOuter = 100.;
0130 double zHalfL = 200.;
0131
0132 Acts::Transform3 nominal = Acts::Transform3::Identity();
0133
0134 auto fullCylinderBounds =
0135 std::make_unique<Acts::CylinderVolumeBounds>(0., rOuter, zHalfL);
0136
0137 auto portalGenerator = defaultPortalGenerator();
0138
0139
0140 BOOST_CHECK_THROW(
0141 DetectorVolumeFactory::construct(portalGenerator, tContext,
0142 "MisconfiguredFullCylinderVolume",
0143 nominal, nullptr, tryAllPortals()),
0144 std::invalid_argument);
0145
0146
0147 PortalGenerator unconnected;
0148 BOOST_CHECK_THROW(
0149 DetectorVolumeFactory::construct(unconnected, tContext,
0150 "MisconfiguredFullCylinderVolume",
0151 nominal, nullptr, tryAllPortals()),
0152 std::invalid_argument);
0153
0154
0155 auto fullCylinderVolume = DetectorVolumeFactory::construct(
0156 portalGenerator, tContext, "FullCylinderVolume", nominal,
0157 std::move(fullCylinderBounds), tryAllPortals());
0158
0159 BOOST_CHECK_EQUAL(fullCylinderVolume,
0160 unpackToShared<DetectorVolume>(*fullCylinderVolume));
0161 BOOST_CHECK_EQUAL(fullCylinderVolume,
0162 unpackToShared<const DetectorVolume>(*fullCylinderVolume));
0163
0164 BOOST_CHECK(fullCylinderVolume->surfaces().empty());
0165 BOOST_CHECK(fullCylinderVolume->volumes().empty());
0166 BOOST_CHECK_EQUAL(fullCylinderVolume->portals().size(), 3u);
0167
0168
0169 auto tubeCylinderBounds =
0170 std::make_unique<Acts::CylinderVolumeBounds>(rInner, rOuter, zHalfL);
0171
0172 auto tubeCylinderVolume = DetectorVolumeFactory::construct(
0173 portalGenerator, tContext, "TubeCylinderVolume", nominal,
0174 std::move(tubeCylinderBounds), tryAllPortals());
0175
0176 BOOST_CHECK(tubeCylinderVolume->surfaces().empty());
0177 BOOST_CHECK(tubeCylinderVolume->volumes().empty());
0178 BOOST_CHECK_EQUAL(tubeCylinderVolume->portals().size(), 4u);
0179
0180
0181 BOOST_CHECK(tubeCylinderVolume->inside(tContext, Acts::Vector3(50., 0., 0.)));
0182
0183 BOOST_CHECK(
0184 !tubeCylinderVolume->inside(tContext, Acts::Vector3(150., 0., 0.)));
0185
0186
0187 auto volumeExtent = tubeCylinderVolume->extent(tContext, 1);
0188 CHECK_CLOSE_ABS(volumeExtent.min(Acts::AxisDirection::AxisR), 10., 10e-5);
0189 CHECK_CLOSE_ABS(volumeExtent.max(Acts::AxisDirection::AxisR), 100., 10e-5);
0190 CHECK_CLOSE_ABS(volumeExtent.min(Acts::AxisDirection::AxisZ), -200., 10e-5);
0191 CHECK_CLOSE_ABS(volumeExtent.max(Acts::AxisDirection::AxisZ), 200., 10e-5);
0192 }
0193
0194 BOOST_AUTO_TEST_CASE(UpdatePortal) {
0195 Acts::Transform3 nominal = Acts::Transform3::Identity();
0196
0197 auto fullCylinderBounds =
0198 std::make_unique<Acts::CylinderVolumeBounds>(0., 10., 100.);
0199
0200 auto portalGenerator = defaultPortalGenerator();
0201
0202 auto fullCylinderVolume = DetectorVolumeFactory::construct(
0203 portalGenerator, tContext, "FullCylinderVolume", nominal,
0204 std::move(fullCylinderBounds), tryAllPortals());
0205
0206 auto cylinderSurface =
0207 Acts::Surface::makeShared<Acts::CylinderSurface>(nominal, 10., 100.);
0208
0209 auto cylinderPortal =
0210 std::make_shared<Acts::Experimental::Portal>(cylinderSurface);
0211
0212 fullCylinderVolume->updatePortal(cylinderPortal, 2u);
0213
0214 BOOST_CHECK_EQUAL(fullCylinderVolume->portals()[2u], cylinderPortal.get());
0215 }
0216
0217 BOOST_AUTO_TEST_CASE(CuboidWithCuboid) {
0218 double bigBox = 100.;
0219 double smallBox = 10.;
0220
0221 Acts::Transform3 nominal = Acts::Transform3::Identity();
0222
0223 auto bigBoxBounds =
0224 std::make_unique<Acts::CuboidVolumeBounds>(bigBox, bigBox, bigBox);
0225
0226 auto smallBoxBounds =
0227 std::make_unique<Acts::CuboidVolumeBounds>(smallBox, smallBox, smallBox);
0228
0229 auto portals = defaultPortalGenerator();
0230 auto generatePortalsUpdateInternals = defaultPortalAndSubPortalGenerator();
0231
0232
0233 auto innerBox = DetectorVolumeFactory::construct(
0234 portals, tContext, "InnerBox", nominal, std::move(smallBoxBounds),
0235 tryAllPortals());
0236
0237 std::vector<std::shared_ptr<Acts::Surface>> surfaces = {};
0238 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>> volumes = {
0239 innerBox};
0240
0241
0242
0243 auto outerBox = DetectorVolumeFactory::construct(
0244 generatePortalsUpdateInternals, tContext, "OuterBox", nominal,
0245 std::move(bigBoxBounds), surfaces, volumes, tryAllSubVolumes(),
0246 tryAllPortals());
0247
0248
0249 Acts::Experimental::NavigationState nState;
0250 nState.position = Acts::Vector3(-50., 5., 0.);
0251 nState.direction = Acts::Vector3(1., 0., 0.);
0252
0253 BOOST_CHECK(outerBox->inside(tContext, nState.position));
0254 nState.currentVolume = outerBox.get();
0255
0256 outerBox->updateNavigationState(tContext, nState);
0257
0258
0259
0260 BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 3u);
0261
0262
0263
0264 std::size_t nSurfaces = 0;
0265 outerBox->visitSurfaces([&nSurfaces](const auto* s) {
0266 if (s != nullptr) {
0267 nSurfaces++;
0268 }
0269 });
0270
0271 BOOST_CHECK_EQUAL(nSurfaces, 12u);
0272
0273
0274 std::size_t nVolumes = 0;
0275 outerBox->visitVolumes([&nVolumes](const auto* v) {
0276 if (v != nullptr) {
0277 nVolumes++;
0278 }
0279 });
0280 BOOST_CHECK_EQUAL(nVolumes, 2u);
0281
0282
0283
0284 struct SetMaterial {
0285
0286 std::shared_ptr<const Acts::HomogeneousSurfaceMaterial> surfaceMaterial =
0287 std::make_shared<Acts::HomogeneousSurfaceMaterial>(Acts::MaterialSlab(
0288 Acts::Material::fromMolarDensity(1., 2., 3., 4., 5.), 1.));
0289
0290 std::shared_ptr<Acts::HomogeneousVolumeMaterial> volumeMaterial =
0291 std::make_shared<Acts::HomogeneousVolumeMaterial>(
0292 Acts::Material::fromMolarDensity(1., 2., 3., 4., 5.));
0293
0294
0295 void operator()(Acts::Surface* s) {
0296 if (s != nullptr) {
0297 s->assignSurfaceMaterial(surfaceMaterial);
0298 }
0299 }
0300
0301
0302 void operator()(DetectorVolume* v) {
0303 if (v != nullptr) {
0304 v->assignVolumeMaterial(volumeMaterial);
0305 }
0306 }
0307 };
0308
0309 SetMaterial setMaterial;
0310 outerBox->visitMutableSurfaces(setMaterial);
0311 outerBox->visitMutableVolumes(setMaterial);
0312
0313
0314 std::size_t nSurfacesWithMaterial = 0;
0315 outerBox->visitSurfaces([&nSurfacesWithMaterial](const auto* s) {
0316 if (s != nullptr && s->surfaceMaterial() != nullptr) {
0317 nSurfacesWithMaterial++;
0318 }
0319 });
0320 BOOST_CHECK_EQUAL(nSurfacesWithMaterial, 12u);
0321
0322
0323 std::size_t nVolumesWithMaterial = 0;
0324 outerBox->visitVolumes([&nVolumesWithMaterial](const auto* v) {
0325 if (v != nullptr && v->volumeMaterial() != nullptr) {
0326 nVolumesWithMaterial++;
0327 }
0328 });
0329 BOOST_CHECK_EQUAL(nVolumesWithMaterial, 2u);
0330 }
0331
0332 BOOST_AUTO_TEST_CASE(CylinderWithSurfacesTestExtractors) {
0333 auto portalGenerator = defaultPortalGenerator();
0334
0335 std::vector<double> radii = {100, 102, 104, 106, 108, 110};
0336 auto cylinderVoumeBounds =
0337 std::make_unique<Acts::CylinderVolumeBounds>(80, 130, 200);
0338 std::vector<std::shared_ptr<Acts::Surface>> surfaces = {};
0339 for (const auto& r : radii) {
0340 surfaces.push_back(Acts::Surface::makeShared<Acts::CylinderSurface>(
0341 Acts::Transform3::Identity(),
0342 std::make_shared<Acts::CylinderBounds>(r, 190)));
0343 }
0344
0345
0346 auto cylinderVolume = DetectorVolumeFactory::construct(
0347 portalGenerator, tContext, "CylinderVolume", Acts::Transform3::Identity(),
0348 std::move(cylinderVoumeBounds), surfaces, {}, tryNoVolumes(),
0349 tryAllPortalsAndSurfaces());
0350
0351
0352 NavigationState nState;
0353 AllPortalsExtractor allPortals;
0354 AllSurfacesExtractor allSurfaces;
0355 IndexedSurfacesExtractor indexedSurfaces;
0356
0357
0358 BOOST_CHECK_THROW(allPortals.extract(tContext, nState), std::runtime_error);
0359 BOOST_CHECK_THROW(allSurfaces.extract(tContext, nState), std::runtime_error);
0360 BOOST_CHECK_THROW(indexedSurfaces.extract(tContext, nState, {0u, 1u}),
0361 std::runtime_error);
0362
0363
0364 nState.currentVolume = cylinderVolume.get();
0365
0366
0367 auto eportals = allPortals.extract(tContext, nState);
0368 BOOST_CHECK_EQUAL(eportals.size(), 4u);
0369
0370 auto esurfaces = allSurfaces.extract(tContext, nState);
0371 BOOST_CHECK_EQUAL(esurfaces.size(), 6u);
0372
0373 esurfaces = indexedSurfaces.extract(tContext, nState, {2u, 4u});
0374 BOOST_CHECK_EQUAL(esurfaces.size(), 2u);
0375 BOOST_CHECK_EQUAL(esurfaces[0u], surfaces[2u].get());
0376 BOOST_CHECK_EQUAL(esurfaces[1u], surfaces[4u].get());
0377
0378
0379 struct CountSurfaces {
0380 unsigned int counter = 0;
0381
0382 void operator()(const Acts::Surface* s) {
0383 if (s != nullptr) {
0384 counter++;
0385 }
0386 }
0387 };
0388
0389 CountSurfaces countSurfaces;
0390 cylinderVolume->visitSurfaces(countSurfaces);
0391
0392
0393 BOOST_CHECK_EQUAL(countSurfaces.counter, 10u);
0394 }
0395
0396 BOOST_AUTO_TEST_SUITE_END()