File indexing completed on 2026-09-30 08:04:28
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Geometry/Blueprint.hpp"
0012 #include "Acts/Geometry/ContainerBlueprintNode.hpp"
0013 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0014
0015 #include <cmath>
0016 #include <stdexcept>
0017
0018 #include "NavigatorTelescope.hpp"
0019
0020 using namespace Acts;
0021 using namespace Acts::UnitLiterals;
0022 using namespace ActsTests::NavigatorTelescope;
0023
0024 namespace ActsTests {
0025
0026
0027
0028 BOOST_AUTO_TEST_SUITE(NavigatorExtendedSurface)
0029
0030
0031
0032 BOOST_AUTO_TEST_CASE(BaselineGen1) {
0033 ACTS_LOCAL_LOGGER(getDefaultLogger("Gen1", logLevel));
0034 Telescope telescope = makeTelescopeGen1();
0035 BOOST_REQUIRE(telescope.geometry->geometryVersion() ==
0036 TrackingGeometry::GeometryVersion::Gen1);
0037 Navigator navigator = makeNavigator(telescope.geometry, logger());
0038
0039 Navigator::Options options(gctx);
0040 NavigationTarget target = firstTarget(navigator, options, Vector3::Zero());
0041
0042 BOOST_CHECK_NE(&target.surface(), telescope.top);
0043 BOOST_CHECK_NE(&target.surface(), telescope.bottom);
0044 }
0045
0046 BOOST_AUTO_TEST_CASE(BaselineGen3) {
0047 ACTS_LOCAL_LOGGER(getDefaultLogger("Gen3", logLevel));
0048 Telescope telescope = makeTelescopeGen3(logger());
0049 BOOST_REQUIRE(telescope.geometry->geometryVersion() ==
0050 TrackingGeometry::GeometryVersion::Gen3);
0051 Navigator navigator = makeNavigator(telescope.geometry, logger());
0052
0053 Navigator::Options options(gctx);
0054 NavigationTarget target = firstTarget(navigator, options, Vector3::Zero());
0055
0056 BOOST_CHECK_NE(&target.surface(), telescope.top);
0057 BOOST_CHECK_NE(&target.surface(), telescope.bottom);
0058 }
0059
0060
0061
0062 BOOST_AUTO_TEST_CASE(BoundsExtensionGen1) {
0063 ACTS_LOCAL_LOGGER(getDefaultLogger("Gen1", logLevel));
0064 Telescope telescope = makeTelescopeGen1();
0065 Navigator navigator = makeNavigator(telescope.geometry, logger());
0066
0067 Navigator::Options options(gctx);
0068 options.registerExtendedSurface(*telescope.top);
0069 NavigationTarget target = firstTarget(navigator, options, Vector3::Zero());
0070
0071 BOOST_REQUIRE(!target.isNone());
0072 BOOST_CHECK_EQUAL(&target.surface(), telescope.top);
0073 }
0074
0075
0076 BOOST_AUTO_TEST_CASE(BoundsExtensionGen3) {
0077 ACTS_LOCAL_LOGGER(getDefaultLogger("Gen3", logLevel));
0078 Telescope telescope = makeTelescopeGen3(logger());
0079 Navigator navigator = makeNavigator(telescope.geometry, logger());
0080
0081 Navigator::Options options(gctx);
0082 options.registerExtendedSurface(*telescope.top);
0083 NavigationTarget target = firstTarget(navigator, options, Vector3::Zero());
0084
0085 BOOST_REQUIRE(!target.isNone());
0086 BOOST_CHECK_EQUAL(&target.surface(), telescope.top);
0087 BOOST_CHECK(!target.isPortalTarget());
0088 }
0089
0090
0091
0092 BOOST_AUTO_TEST_CASE(BoundsCheckedGen1) {
0093 ACTS_LOCAL_LOGGER(getDefaultLogger("Gen1", logLevel));
0094 Telescope telescope = makeTelescopeGen1();
0095 Navigator navigator = makeNavigator(telescope.geometry, logger());
0096
0097 Navigator::Options options(gctx);
0098 options.registerExtendedSurface(*telescope.top, BoundaryTolerance::None());
0099 NavigationTarget target = firstTarget(navigator, options, Vector3::Zero());
0100
0101 BOOST_CHECK_NE(&target.surface(), telescope.top);
0102 }
0103
0104 BOOST_AUTO_TEST_CASE(BoundsCheckedGen3) {
0105 ACTS_LOCAL_LOGGER(getDefaultLogger("Gen3", logLevel));
0106 Telescope telescope = makeTelescopeGen3(logger());
0107 Navigator navigator = makeNavigator(telescope.geometry, logger());
0108
0109 Navigator::Options options(gctx);
0110 options.registerExtendedSurface(*telescope.top, BoundaryTolerance::None());
0111 NavigationTarget target = firstTarget(navigator, options, Vector3::Zero());
0112
0113 BOOST_CHECK_NE(&target.surface(), telescope.top);
0114 }
0115
0116
0117
0118 BOOST_AUTO_TEST_CASE(SurfaceOutsideTheGeometryThrows) {
0119 ACTS_LOCAL_LOGGER(getDefaultLogger("Gen3", logLevel));
0120 Telescope telescope = makeTelescopeGen3(logger());
0121 Navigator navigator = makeNavigator(telescope.geometry, logger());
0122
0123 auto outOfGeometry = makeOutOfGeometrySurface({0, 0, 0.25_m});
0124 BOOST_REQUIRE(outOfGeometry->geometryId() == GeometryIdentifier{});
0125
0126 Navigator::Options options(gctx);
0127 options.registerExtendedSurface(*outOfGeometry);
0128 Navigator::State state = navigator.makeState(options);
0129 Vector3 position = Vector3::Zero();
0130 const Vector3 direction = Vector3::UnitZ();
0131 BOOST_CHECK_THROW(static_cast<void>(navigator.initialize(
0132 state, {.position = position, .direction = direction})),
0133 std::invalid_argument);
0134 }
0135
0136
0137
0138
0139 namespace {
0140 const Vector3 pokeStart{0, 0.9_m, 0};
0141 const Vector3 pokeDir = Vector3{0, 0.6, 1}.normalized();
0142 }
0143
0144
0145 BOOST_AUTO_TEST_CASE(CrossingOutsideTheVolumeIsDroppedGen1) {
0146 ACTS_LOCAL_LOGGER(getDefaultLogger("Gen1", logLevel));
0147 Telescope telescope = makeTelescopeGen1();
0148 Navigator navigator = makeNavigator(telescope.geometry, logger());
0149
0150 Navigator::Options options(gctx);
0151 options.registerExtendedSurface(*telescope.top);
0152 Navigator::State state = navigator.makeState(options);
0153 Vector3 position = pokeStart;
0154 BOOST_REQUIRE(
0155 navigator.initialize(state, {.position = position, .direction = pokeDir})
0156 .ok());
0157
0158 NavigationTarget target = navigator.nextTarget(state, position, pokeDir);
0159 BOOST_REQUIRE(!target.isNone());
0160 BOOST_CHECK(target.surface().geometryId().boundary() != 0);
0161 }
0162
0163
0164 BOOST_AUTO_TEST_CASE(CrossingOutsideTheVolumeIsDroppedGen3) {
0165 ACTS_LOCAL_LOGGER(getDefaultLogger("Gen3", logLevel));
0166 Telescope telescope = makeTelescopeGen3(logger());
0167 Navigator navigator = makeNavigator(telescope.geometry, logger());
0168
0169 Navigator::Options options(gctx);
0170 options.registerExtendedSurface(*telescope.top);
0171 Navigator::State state = navigator.makeState(options);
0172 Vector3 position = pokeStart;
0173 BOOST_REQUIRE(
0174 navigator.initialize(state, {.position = position, .direction = pokeDir})
0175 .ok());
0176
0177 NavigationTarget target = navigator.nextTarget(state, position, pokeDir);
0178 BOOST_REQUIRE(!target.isNone());
0179 BOOST_CHECK(target.isPortalTarget());
0180 }
0181
0182
0183
0184 BOOST_AUTO_TEST_CASE(ScopedToItsVolumeGen3) {
0185 auto logger = getDefaultLogger("Gen3", logLevel);
0186
0187 Blueprint::Config cfg;
0188 cfg.envelope = ExtentEnvelope{{
0189 .x = {20_mm, 20_mm},
0190 .y = {20_mm, 20_mm},
0191 .z = {20_mm, 20_mm},
0192 }};
0193 Blueprint root{cfg};
0194
0195
0196 const Surface* extended = nullptr;
0197 root.addCuboidContainer("Stack", AxisDirection::AxisZ, [&](auto& stack) {
0198 stack.addChild(
0199 std::make_shared<StaticBlueprintNode>(std::make_unique<TrackingVolume>(
0200 Transform3{Translation3{Vector3{0, 0, -0.5_m}}},
0201 std::make_shared<CuboidVolumeBounds>(0.5_m, 0.5_m, 0.5_m),
0202 "near")));
0203
0204 auto farVolume = std::make_unique<TrackingVolume>(
0205 Transform3{Translation3{Vector3{0, 0, 0.5_m}}},
0206 std::make_shared<CuboidVolumeBounds>(0.5_m, 0.5_m, 0.5_m), "far");
0207 auto surface = Surface::makeShared<PlaneSurface>(
0208 Transform3{Translation3{Vector3{0, 0.4_m, 0.5_m}}},
0209 std::make_shared<const RectangleBounds>(0.05_m, 0.05_m));
0210 extended = surface.get();
0211 farVolume->addSurface(std::move(surface));
0212 stack.addChild(std::make_shared<StaticBlueprintNode>(std::move(farVolume)));
0213 });
0214
0215 auto geometry = root.construct({}, gctx, *logger);
0216 BOOST_REQUIRE(extended != nullptr);
0217 Navigator navigator = makeNavigator(
0218 std::shared_ptr<const TrackingGeometry>(std::move(geometry)), *logger);
0219
0220 Navigator::Options options(gctx);
0221 options.registerExtendedSurface(*extended);
0222 Navigator::State state = navigator.makeState(options);
0223
0224 Vector3 position{0, 0, -0.9_m};
0225 const Vector3 dir = Vector3::UnitZ();
0226 BOOST_REQUIRE(
0227 navigator.initialize(state, {.position = position, .direction = dir})
0228 .ok());
0229
0230
0231 BOOST_REQUIRE_EQUAL(state.extendedSurfaces.size(), 1u);
0232 BOOST_REQUIRE(state.extendedSurfaces.front().volume != nullptr);
0233 BOOST_CHECK_EQUAL(state.extendedSurfaces.front().volume->volumeName(), "far");
0234
0235
0236 NavigationTarget target = navigator.nextTarget(state, position, dir);
0237 BOOST_REQUIRE(!target.isNone());
0238 BOOST_CHECK(target.isPortalTarget());
0239 stepOnto(position, dir, target.surface());
0240 navigator.handleSurfaceReached(state, position, dir, target.surface());
0241 BOOST_REQUIRE_EQUAL(state.currentVolume->volumeName(), "far");
0242
0243
0244 target = navigator.nextTarget(state, position, dir);
0245 BOOST_REQUIRE(!target.isNone());
0246 BOOST_CHECK_EQUAL(&target.surface(), extended);
0247 }
0248
0249 BOOST_AUTO_TEST_CASE(ScopedToItsLayerGen1) {
0250 ACTS_LOCAL_LOGGER(getDefaultLogger("Gen1", logLevel));
0251
0252 CuboidVolumeBuilder::Config conf;
0253 conf.position = {0., 0., 0.};
0254 conf.length = {2_m, 2_m, 2_m};
0255
0256
0257 CuboidVolumeBuilder::SurfaceConfig onAxis;
0258 onAxis.position = {0, 0, -0.3_m};
0259 onAxis.rBounds = std::make_shared<RectangleBounds>(0.1_m, 0.1_m);
0260 CuboidVolumeBuilder::LayerConfig nearLayer;
0261 nearLayer.binningDimension = AxisDirection::AxisZ;
0262 nearLayer.surfaceCfg.push_back(onAxis);
0263
0264 CuboidVolumeBuilder::SurfaceConfig offAxis;
0265 offAxis.position = {0, 0.4_m, 0.3_m};
0266 offAxis.rBounds = std::make_shared<RectangleBounds>(0.05_m, 0.05_m);
0267 CuboidVolumeBuilder::LayerConfig farLayer;
0268 farLayer.binningDimension = AxisDirection::AxisZ;
0269 farLayer.surfaceCfg.push_back(offAxis);
0270
0271 CuboidVolumeBuilder::VolumeConfig volume;
0272 volume.binningDimension = AxisDirection::AxisZ;
0273 volume.position = {0, 0, 0};
0274 volume.length = {1.9_m, 1.9_m, 1.9_m};
0275 volume.name = "telescope";
0276 volume.layerCfg.push_back(nearLayer);
0277 volume.layerCfg.push_back(farLayer);
0278 conf.volumeCfg.push_back(volume);
0279
0280 CuboidVolumeBuilder cvb(conf);
0281 TrackingGeometryBuilder::Config tgbCfg;
0282 tgbCfg.trackingVolumeBuilders.push_back(
0283 [=](const auto& context, const auto& inner, const auto&) {
0284 return cvb.trackingVolume(context, inner, nullptr);
0285 });
0286 auto geometry = TrackingGeometryBuilder(tgbCfg).trackingGeometry(gctx);
0287
0288 std::vector<const Surface*> surfaces;
0289 geometry->visitSurfaces([&](const Surface* sf) { surfaces.push_back(sf); });
0290 BOOST_REQUIRE_EQUAL(surfaces.size(), 2u);
0291 const Surface* extended = surfaces.at(1);
0292 BOOST_REQUIRE_EQUAL(extended->center(gctx).y(), 0.4_m);
0293
0294 Navigator navigator = makeNavigator(
0295 std::shared_ptr<const TrackingGeometry>(std::move(geometry)), logger());
0296
0297 Navigator::Options options(gctx);
0298 options.registerExtendedSurface(*extended);
0299 std::vector<const Surface*> reached =
0300 walk(navigator, options, Vector3{0, 0, -0.8_m}, Vector3::UnitZ());
0301
0302
0303
0304 BOOST_REQUIRE(!reached.empty());
0305 BOOST_CHECK_NE(reached.front(), extended);
0306 BOOST_CHECK_LT(
0307 std::abs(reached.front()->center(gctx).z() - onAxis.position.z()), 1_um);
0308 }
0309
0310 BOOST_AUTO_TEST_SUITE_END()
0311
0312 }