File indexing completed on 2025-01-18 09:12:41
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/Definitions/Units.hpp"
0013 #include "Acts/Geometry/DetectorElementBase.hpp"
0014 #include "Acts/Geometry/Extent.hpp"
0015 #include "Acts/Geometry/GeometryContext.hpp"
0016 #include "Acts/Geometry/ProtoLayer.hpp"
0017 #include "Acts/Surfaces/PlaneSurface.hpp"
0018 #include "Acts/Surfaces/RectangleBounds.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "Acts/Tests/CommonHelpers/DetectorElementStub.hpp"
0021 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0022 #include "Acts/Utilities/BinningType.hpp"
0023 #include "Acts/Utilities/RangeXD.hpp"
0024
0025 #include <cmath>
0026 #include <memory>
0027 #include <numbers>
0028 #include <sstream>
0029 #include <string>
0030 #include <vector>
0031
0032 namespace Acts::Test::Layers {
0033
0034 GeometryContext tgContext = GeometryContext();
0035
0036 BOOST_AUTO_TEST_SUITE(Geometry)
0037
0038 BOOST_AUTO_TEST_CASE(ProtoLayerTests) {
0039 using enum AxisDirection;
0040
0041
0042 auto recBounds = std::make_shared<RectangleBounds>(3., 6.);
0043
0044
0045 static const Transform3 planeYZ =
0046 AngleAxis3(std::numbers::pi / 2., Vector3::UnitY()) *
0047 AngleAxis3(std::numbers::pi / 2., Vector3::UnitZ()) *
0048 Transform3::Identity();
0049 static const Transform3 planeZX =
0050 AngleAxis3(-std::numbers::pi / 2., Vector3::UnitX()) *
0051 AngleAxis3(-std::numbers::pi / 2., Vector3::UnitZ()) *
0052 Transform3::Identity();
0053
0054 std::vector<std::shared_ptr<const Surface>> surfaceStore;
0055 surfaceStore.reserve(100);
0056
0057 auto createProtoLayer = [&](const Transform3& trf,
0058 bool shared = false) -> ProtoLayer {
0059 auto atNegX = Surface::makeShared<PlaneSurface>(
0060 Transform3(trf * Translation3(Vector3(-3., 0., 0.)) * planeYZ),
0061 recBounds);
0062
0063 auto atPosX = Surface::makeShared<PlaneSurface>(
0064 Transform3(trf * Translation3(Vector3(3., 0., 0.)) * planeYZ),
0065 recBounds);
0066
0067 auto atNegY = Surface::makeShared<PlaneSurface>(
0068 Transform3(trf * Translation3(Vector3(0., -3, 0.)) * planeZX),
0069 recBounds);
0070
0071 auto atPosY = Surface::makeShared<PlaneSurface>(
0072 Transform3(trf * Translation3(Vector3(0., 3., 0.)) * planeZX),
0073 recBounds);
0074
0075 std::vector<std::shared_ptr<const Surface>> sharedSurfaces = {
0076 atNegX, atNegY, atPosX, atPosY};
0077 surfaceStore.insert(surfaceStore.begin(), sharedSurfaces.begin(),
0078 sharedSurfaces.end());
0079 if (!shared) {
0080 std::vector<const Surface*> surfaces = {atNegX.get(), atNegY.get(),
0081 atPosX.get(), atPosY.get()};
0082
0083 return ProtoLayer(tgContext, surfaces);
0084 }
0085 return ProtoLayer(tgContext, sharedSurfaces);
0086 };
0087
0088
0089 auto pLayerSf = createProtoLayer(Transform3::Identity());
0090 auto pLayerSfShared = createProtoLayer(Transform3::Identity());
0091
0092 BOOST_CHECK(pLayerSf.extent.range() == pLayerSfShared.extent.range());
0093 BOOST_CHECK(pLayerSf.envelope == pLayerSfShared.envelope);
0094
0095
0096 BOOST_CHECK_EQUAL(pLayerSf.surfaces().size(), 4);
0097
0098 auto rB = std::make_shared<RectangleBounds>(30., 60.);
0099
0100
0101 auto addSurface =
0102 Surface::makeShared<PlaneSurface>(Transform3::Identity(), rB);
0103
0104 pLayerSf.add(tgContext, *addSurface.get());
0105
0106 BOOST_CHECK_EQUAL(pLayerSf.surfaces().size(), 5);
0107
0108
0109 BOOST_CHECK(!(pLayerSf.extent.range() == pLayerSfShared.extent.range()));
0110
0111
0112 auto protoLayer = createProtoLayer(Transform3::Identity());
0113
0114 CHECK_CLOSE_ABS(protoLayer.range(AxisX), 12., 1e-8);
0115 CHECK_CLOSE_ABS(protoLayer.medium(AxisX), 0., 1e-8);
0116 CHECK_CLOSE_ABS(protoLayer.min(AxisX), -6., 1e-8);
0117 CHECK_CLOSE_ABS(protoLayer.max(AxisX), 6., 1e-8);
0118 CHECK_CLOSE_ABS(protoLayer.range(AxisY), 6., 1e-8);
0119 CHECK_CLOSE_ABS(protoLayer.medium(AxisY), 0., 1e-8);
0120 CHECK_CLOSE_ABS(protoLayer.min(AxisY), -3., 1e-8);
0121 CHECK_CLOSE_ABS(protoLayer.max(AxisY), 3., 1e-8);
0122 CHECK_CLOSE_ABS(protoLayer.range(AxisZ), 12., 1e-8);
0123 CHECK_CLOSE_ABS(protoLayer.medium(AxisZ), 0., 1e-8);
0124 CHECK_CLOSE_ABS(protoLayer.min(AxisZ), -6., 1e-8);
0125 CHECK_CLOSE_ABS(protoLayer.max(AxisZ), 6., 1e-8);
0126 CHECK_CLOSE_ABS(protoLayer.max(AxisR), std::hypot(3, 6), 1e-8);
0127 CHECK_CLOSE_ABS(protoLayer.min(AxisR), 3., 1e-8);
0128
0129
0130
0131
0132
0133 auto protoLayerRot = createProtoLayer(AngleAxis3(-0.345, Vector3::UnitZ()) *
0134 Transform3::Identity());
0135
0136 BOOST_CHECK_NE(protoLayer.min(AxisX), -6.);
0137 CHECK_CLOSE_ABS(protoLayerRot.medium(AxisX), 0., 1e-8);
0138 CHECK_CLOSE_ABS(protoLayerRot.medium(AxisY), 0., 1e-8);
0139 CHECK_CLOSE_ABS(protoLayerRot.range(AxisZ), 12., 1e-8);
0140 CHECK_CLOSE_ABS(protoLayerRot.medium(AxisZ), 0., 1e-8);
0141 CHECK_CLOSE_ABS(protoLayerRot.min(AxisZ), -6., 1e-8);
0142 CHECK_CLOSE_ABS(protoLayerRot.max(AxisZ), 6., 1e-8);
0143 CHECK_CLOSE_ABS(protoLayerRot.min(AxisR), 3., 1e-8);
0144 CHECK_CLOSE_ABS(protoLayerRot.max(AxisR), std::hypot(3, 6), 1e-8);
0145
0146 std::stringstream sstream;
0147 protoLayerRot.toStream(sstream);
0148 std::string oString = R"(ProtoLayer with dimensions (min/max)
0149 Extent in space :
0150 - value : AxisX | range = [-6.66104, 6.66104]
0151 - value : AxisY | range = [-4.85241, 4.85241]
0152 - value : AxisZ | range = [-6, 6]
0153 - value : AxisR | range = [3, 6.7082]
0154 - value : AxisPhi | range = [-3.02295, 2.33295]
0155 - value : AxisRPhi | range = [-20.2785, 15.6499]
0156 - value : AxisTheta | range = [0.61548, 2.52611]
0157 - value : AxisEta | range = [-1.14622, 1.14622]
0158 - value : AxisMag | range = [7.34847, 7.34847]
0159 )";
0160 BOOST_CHECK_EQUAL(sstream.str(), oString);
0161 }
0162
0163 BOOST_AUTO_TEST_CASE(OrientedLayer) {
0164 using enum AxisDirection;
0165 using namespace Acts::UnitLiterals;
0166
0167 Transform3 base = Transform3::Identity();
0168
0169 auto recBounds = std::make_shared<RectangleBounds>(3_mm, 6_mm);
0170
0171 std::vector<std::unique_ptr<DetectorElementBase>> detectorElements;
0172
0173 auto makeFan = [&](double yrot, double thickness = 0) {
0174 detectorElements.clear();
0175
0176 std::size_t nSensors = 8;
0177 double deltaPhi = 2 * std::numbers::pi / nSensors;
0178 double r = 20_mm;
0179 std::vector<std::shared_ptr<const Surface>> surfaces;
0180 for (std::size_t i = 0; i < nSensors; i++) {
0181
0182
0183 Transform3 trf = base * AngleAxis3{yrot, Vector3::UnitY()} *
0184 AngleAxis3{deltaPhi * i, Vector3::UnitZ()} *
0185 Translation3(Vector3::UnitX() * r);
0186
0187 auto& element = detectorElements.emplace_back(
0188 std::make_unique<DetectorElementStub>(trf, recBounds, thickness));
0189
0190 surfaces.push_back(element->surface().getSharedPtr());
0191 }
0192 return surfaces;
0193 };
0194
0195 std::vector<std::shared_ptr<const Surface>> surfaces = makeFan(0_degree);
0196
0197 ProtoLayer protoLayer(tgContext, surfaces);
0198
0199 BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8);
0200 BOOST_CHECK_CLOSE(protoLayer.min(AxisX), -23_mm, 1e-8);
0201 BOOST_CHECK_CLOSE(protoLayer.max(AxisX), 23_mm, 1e-8);
0202 BOOST_CHECK_CLOSE(protoLayer.min(AxisY), -23_mm, 1e-8);
0203 BOOST_CHECK_CLOSE(protoLayer.max(AxisY), 23_mm, 1e-8);
0204 BOOST_CHECK_CLOSE(protoLayer.min(AxisZ), 0_mm, 1e-8);
0205 BOOST_CHECK_CLOSE(protoLayer.max(AxisZ), 0_mm, 1e-8);
0206 BOOST_CHECK_CLOSE(protoLayer.min(AxisR), 17_mm, 1e-8);
0207 BOOST_CHECK_CLOSE(protoLayer.max(AxisR), 23.769728648_mm, 1e-8);
0208
0209 surfaces = makeFan(45_degree);
0210
0211
0212 protoLayer = {tgContext, surfaces};
0213
0214 BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8);
0215 BOOST_CHECK_CLOSE(protoLayer.min(AxisX), -16.26345596_mm, 1e-4);
0216 BOOST_CHECK_CLOSE(protoLayer.max(AxisX), 16.26345596_mm, 1e-4);
0217 BOOST_CHECK_CLOSE(protoLayer.min(AxisY), -23_mm, 1e-8);
0218 BOOST_CHECK_CLOSE(protoLayer.max(AxisY), 23_mm, 1e-8);
0219 BOOST_CHECK_CLOSE(protoLayer.min(AxisZ), -16.26345596_mm, 1e-4);
0220 BOOST_CHECK_CLOSE(protoLayer.max(AxisZ), 16.26345596_mm, 1e-4);
0221
0222 protoLayer = {tgContext, surfaces,
0223 Transform3{AngleAxis3{45_degree, Vector3::UnitY()}}.inverse()};
0224
0225 BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8);
0226 BOOST_CHECK_CLOSE(protoLayer.range(AxisX), 46_mm, 1e-8);
0227 BOOST_CHECK_CLOSE(protoLayer.min(AxisX), -23_mm, 1e-8);
0228 BOOST_CHECK_CLOSE(protoLayer.max(AxisX), 23_mm, 1e-8);
0229 BOOST_CHECK_CLOSE(protoLayer.range(AxisY), 46_mm, 1e-8);
0230 BOOST_CHECK_CLOSE(protoLayer.min(AxisY), -23_mm, 1e-8);
0231 BOOST_CHECK_CLOSE(protoLayer.max(AxisY), 23_mm, 1e-8);
0232 CHECK_SMALL(protoLayer.range(AxisZ), 1e-14);
0233 CHECK_SMALL(protoLayer.min(AxisZ), 1e-14);
0234 CHECK_SMALL(protoLayer.max(AxisZ), 1e-14);
0235
0236 surfaces = makeFan(0_degree, 10_mm);
0237
0238 protoLayer = {tgContext, surfaces};
0239
0240 BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8);
0241 BOOST_CHECK_CLOSE(protoLayer.range(AxisX), 46_mm, 1e-8);
0242 BOOST_CHECK_CLOSE(protoLayer.min(AxisX), -23_mm, 1e-8);
0243 BOOST_CHECK_CLOSE(protoLayer.max(AxisX), 23_mm, 1e-8);
0244 BOOST_CHECK_CLOSE(protoLayer.range(AxisY), 46_mm, 1e-8);
0245 BOOST_CHECK_CLOSE(protoLayer.min(AxisY), -23_mm, 1e-8);
0246 BOOST_CHECK_CLOSE(protoLayer.max(AxisY), 23_mm, 1e-8);
0247 BOOST_CHECK_CLOSE(protoLayer.range(AxisZ), 10_mm, 1e-8);
0248 BOOST_CHECK_CLOSE(protoLayer.min(AxisZ), -5_mm, 1e-8);
0249 BOOST_CHECK_CLOSE(protoLayer.max(AxisZ), 5_mm, 1e-8);
0250
0251 surfaces = makeFan(45_degree, 10_mm);
0252
0253 protoLayer = {tgContext, surfaces,
0254 Transform3{AngleAxis3{45_degree, Vector3::UnitY()}}.inverse()};
0255
0256 BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8);
0257 BOOST_CHECK_CLOSE(protoLayer.range(AxisX), 46_mm, 1e-8);
0258 BOOST_CHECK_CLOSE(protoLayer.min(AxisX), -23_mm, 1e-8);
0259 BOOST_CHECK_CLOSE(protoLayer.max(AxisX), 23_mm, 1e-8);
0260 BOOST_CHECK_CLOSE(protoLayer.range(AxisY), 46_mm, 1e-8);
0261 BOOST_CHECK_CLOSE(protoLayer.min(AxisY), -23_mm, 1e-8);
0262 BOOST_CHECK_CLOSE(protoLayer.max(AxisY), 23_mm, 1e-8);
0263 BOOST_CHECK_CLOSE(protoLayer.range(AxisZ), 10_mm, 1e-8);
0264 BOOST_CHECK_CLOSE(protoLayer.min(AxisZ), -5_mm, 1e-8);
0265 BOOST_CHECK_CLOSE(protoLayer.max(AxisZ), 5_mm, 1e-8);
0266 }
0267
0268 BOOST_AUTO_TEST_SUITE_END()
0269
0270 }