File indexing completed on 2025-11-01 07:55: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/MultiWireStructureBuilder.hpp"
0015 #include "Acts/Geometry/MultiWireVolumeBuilder.hpp"
0016 #include "Acts/Geometry/TrapezoidPortalShell.hpp"
0017 #include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
0018 #include "Acts/Navigation/NavigationState.hpp"
0019 #include "Acts/Navigation/NavigationStateFillers.hpp"
0020 #include "Acts/Surfaces/StrawSurface.hpp"
0021 #include "Acts/Surfaces/Surface.hpp"
0022 #include "ActsTests/CommonHelpers/DetectorElementStub.hpp"
0023
0024 #include <memory>
0025 #include <numbers>
0026 #include <string>
0027 #include <vector>
0028
0029 using namespace Acts;
0030 using namespace Acts::Experimental;
0031 using namespace Acts::detail;
0032
0033 GeometryContext tContext;
0034 constexpr std::size_t nSurfacesX = 15;
0035 constexpr std::size_t nSurfacesY = 4;
0036 constexpr double radius = 15.0;
0037 constexpr double halfZ = 250.0;
0038
0039 namespace ActsTests {
0040
0041 BOOST_AUTO_TEST_SUITE(NavigationSuite)
0042 auto logger = getDefaultLogger("MultiWireNavigationTests", Logging::VERBOSE);
0043
0044
0045 void generateStrawSurfaces(
0046 std::size_t nStraws, std::size_t nLayers, double radius, double halfZ,
0047 std::vector<std::shared_ptr<Surface>>& strawSurfaces,
0048 std::vector<std::unique_ptr<DetectorElementStub>>& elements) {
0049
0050 Vector3 ipos = {-0.5 * nStraws * 2 * radius + radius,
0051 -0.5 * nLayers * 2 * radius + radius, 0.};
0052
0053 Vector3 pos = ipos;
0054 auto lineBounds = std::make_shared<LineBounds>(radius, halfZ);
0055 int id = 1;
0056
0057
0058 for (std::size_t i = 0; i < nLayers; i++) {
0059 for (std::size_t j = 0; j < nStraws; j++) {
0060 pos.x() = ipos.x() + 2 * j * radius;
0061
0062 auto& element =
0063 elements.emplace_back(std::make_unique<DetectorElementStub>(
0064 Transform3(Translation3(pos)), lineBounds, 0));
0065
0066 element->surface().assignGeometryId(GeometryIdentifier(id++));
0067
0068 element->surface().assignDetectorElement(*element);
0069
0070 strawSurfaces.push_back(element->surface().getSharedPtr());
0071 }
0072
0073 pos.y() = ipos.y() + 2 * (i + 1) * radius;
0074 }
0075 }
0076
0077 BOOST_AUTO_TEST_CASE(Navigation_in_Indexed_Surfaces) {
0078 std::vector<std::shared_ptr<Surface>> strawSurfaces = {};
0079 std::vector<std::unique_ptr<DetectorElementStub>> detElements = {};
0080
0081 generateStrawSurfaces(nSurfacesX, nSurfacesY, radius, halfZ, strawSurfaces,
0082 detElements);
0083
0084 std::vector<double> vBounds = {0.5 * nSurfacesX * 2 * radius,
0085 0.5 * nSurfacesX * 2 * radius,
0086 0.5 * nSurfacesY * 2 * radius, halfZ};
0087
0088 MultiWireStructureBuilder::Config mlCfg;
0089 mlCfg.name = "Multi_Layer_With_Wires";
0090 mlCfg.mlSurfaces = strawSurfaces;
0091
0092 mlCfg.mlBinning = {
0093 {DirectedProtoAxis(AxisDirection::AxisX, AxisBoundaryType::Bound,
0094 -vBounds[0], vBounds[0], nSurfacesX),
0095 1u},
0096 {DirectedProtoAxis(AxisDirection::AxisY, AxisBoundaryType::Bound,
0097 -vBounds[2], vBounds[2], nSurfacesY),
0098 0u}};
0099 auto boundsPtr = std::make_unique<TrapezoidVolumeBounds>(
0100 vBounds[0], vBounds[1], vBounds[2], vBounds[3]);
0101 mlCfg.mlBounds = boundsPtr->values();
0102
0103 MultiWireStructureBuilder mlBuilder(mlCfg);
0104 auto [volumes, portals, roots] = mlBuilder.construct(tContext);
0105
0106 Acts::Experimental::NavigationState nState;
0107 nState.position = Acts::Vector3(0., -59., 0.);
0108 nState.direction = Acts::Vector3(0., 1., 0.);
0109
0110 nState.currentVolume = volumes.front().get();
0111 nState.currentVolume->updateNavigationState(tContext, nState);
0112
0113
0114
0115 BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 5u);
0116 }
0117
0118
0119 BOOST_AUTO_TEST_CASE(MultiLayer_NavigationPolicy) {
0120
0121 std::vector<std::shared_ptr<Surface>> strawSurfaces = {};
0122 std::vector<std::unique_ptr<DetectorElementStub>> detElements = {};
0123
0124 generateStrawSurfaces(nSurfacesX, nSurfacesY, radius, halfZ, strawSurfaces,
0125 detElements);
0126
0127 std::vector<double> vBounds = {0.5 * nSurfacesX * 2 * radius,
0128 0.5 * nSurfacesX * 2 * radius,
0129 0.5 * nSurfacesY * 2 * radius, halfZ};
0130
0131 MultiWireVolumeBuilder::Config mwCfg;
0132 mwCfg.name = "MultiWireVolume";
0133 mwCfg.mlSurfaces = strawSurfaces;
0134 mwCfg.binning = {
0135 {DirectedProtoAxis(AxisDirection::AxisX, AxisBoundaryType::Bound,
0136 -vBounds[0], vBounds[0], nSurfacesX),
0137 1u},
0138 {DirectedProtoAxis(AxisDirection::AxisY, AxisBoundaryType::Bound,
0139 -vBounds[2], vBounds[2], nSurfacesY),
0140 0u}};
0141 auto boundsPtr = std::make_shared<Acts::TrapezoidVolumeBounds>(
0142 vBounds[0], vBounds[1], vBounds[2], vBounds[3]);
0143 mwCfg.bounds = boundsPtr;
0144 mwCfg.transform = Transform3(Translation3(Vector3(0., 0., 0.)));
0145
0146
0147 MultiWireVolumeBuilder mwBuilder(mwCfg);
0148 std::unique_ptr<Acts::TrackingVolume> volume = mwBuilder.buildVolume();
0149
0150 SingleTrapezoidPortalShell portalShell(*volume);
0151 portalShell.applyToVolume();
0152
0153
0154
0155 BOOST_CHECK(volume->volumes().empty());
0156
0157
0158 BOOST_CHECK(volume->surfaces().size() == 60u);
0159
0160 BOOST_CHECK(volume->portals().size() == 6u);
0161
0162
0163 NavigationStream main;
0164 AppendOnlyNavigationStream stream{main};
0165 Vector3 startPos = {0., -59., 0.};
0166 Vector3 startDir = {0., 1., 0.};
0167 NavigationArguments args{startPos, startDir};
0168
0169 auto navFactory = mwBuilder.createNavigationPolicyFactory();
0170 volume->setNavigationPolicy(navFactory->build(tContext, *volume, *logger));
0171
0172 volume->initializeNavigationCandidates(args, stream, *logger);
0173
0174
0175 BOOST_CHECK_EQUAL(main.candidates().size(), 18u);
0176
0177
0178 auto it = std::unique(main.candidates().begin(), main.candidates().end(),
0179 [](const auto& lhs, const auto& rhs) {
0180 return lhs.surface() == rhs.surface();
0181 });
0182 BOOST_CHECK(it == main.candidates().end());
0183
0184
0185 double angle = std::numbers::pi / 4.;
0186 startDir = {std::cos(angle), std::sin(angle), 0.};
0187 args.direction = startDir;
0188
0189 main.candidates().clear();
0190 volume->initializeNavigationCandidates(args, stream, *logger);
0191
0192 BOOST_CHECK_EQUAL(main.candidates().size(), 18u);
0193 }
0194
0195 BOOST_AUTO_TEST_SUITE_END()
0196
0197 }