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