File indexing completed on 2025-08-06 08:11:28
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010
0011 #include <boost/test/unit_test.hpp>
0012
0013 #include "Acts/Definitions/Algebra.hpp"
0014 #include "Acts/Definitions/Tolerance.hpp"
0015 #include "Acts/Geometry/Extent.hpp"
0016 #include "Acts/Geometry/GeometryContext.hpp"
0017 #include "Acts/Geometry/Polyhedron.hpp"
0018 #include "Acts/Surfaces/ConeBounds.hpp"
0019 #include "Acts/Surfaces/ConeSurface.hpp"
0020 #include "Acts/Surfaces/Surface.hpp"
0021 #include "Acts/Surfaces/SurfaceBounds.hpp"
0022 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0023 #include "Acts/Utilities/BinningType.hpp"
0024 #include "Acts/Utilities/Result.hpp"
0025
0026 #include <algorithm>
0027 #include <cmath>
0028 #include <memory>
0029 #include <string>
0030
0031
0032
0033 namespace Acts::Test {
0034
0035
0036 GeometryContext tgContext = GeometryContext();
0037
0038 BOOST_AUTO_TEST_SUITE(ConeSurfaces)
0039
0040
0041 BOOST_AUTO_TEST_CASE(ConeSurfaceConstruction) {
0042
0043
0044
0045
0046 double alpha{M_PI / 8.}, halfPhiSector{M_PI / 16.}, zMin{1.0}, zMax{10.};
0047 bool symmetric(false);
0048 Translation3 translation{0., 1., 2.};
0049 auto pTransform = Transform3(translation);
0050 BOOST_CHECK_EQUAL(
0051 Surface::makeShared<ConeSurface>(Transform3::Identity(), alpha, symmetric)
0052 ->type(),
0053 Surface::Cone);
0054 BOOST_CHECK_EQUAL(
0055 Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric)->type(),
0056 Surface::Cone);
0057
0058
0059 BOOST_CHECK_EQUAL(Surface::makeShared<ConeSurface>(pTransform, alpha, zMin,
0060 zMax, halfPhiSector)
0061 ->type(),
0062 Surface::Cone);
0063
0064
0065
0066
0067 auto pConeBounds =
0068 std::make_shared<const ConeBounds>(alpha, zMin, zMax, halfPhiSector, 0.);
0069 BOOST_CHECK_EQUAL(
0070 Surface::makeShared<ConeSurface>(pTransform, pConeBounds)->type(),
0071 Surface::Cone);
0072
0073
0074
0075 auto coneSurfaceObject =
0076 Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
0077 auto copiedConeSurface = Surface::makeShared<ConeSurface>(*coneSurfaceObject);
0078 BOOST_CHECK_EQUAL(copiedConeSurface->type(), Surface::Cone);
0079 BOOST_CHECK(*copiedConeSurface == *coneSurfaceObject);
0080
0081
0082 auto copiedTransformedConeSurface = Surface::makeShared<ConeSurface>(
0083 tgContext, *coneSurfaceObject, pTransform);
0084 BOOST_CHECK_EQUAL(copiedTransformedConeSurface->type(), Surface::Cone);
0085
0086
0087 BOOST_CHECK_THROW(auto nullBounds = Surface::makeShared<ConeSurface>(
0088 Transform3::Identity(), nullptr),
0089 AssertionFailureException);
0090 }
0091
0092
0093 BOOST_AUTO_TEST_CASE(ConeSurfaceProperties) {
0094
0095 double alpha{M_PI / 8.} ;
0096 bool symmetric(false);
0097 Translation3 translation{0., 1., 2.};
0098 auto pTransform = Transform3(translation);
0099 auto coneSurfaceObject =
0100 Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
0101
0102
0103 BOOST_CHECK_EQUAL(coneSurfaceObject->type(), Surface::Cone);
0104
0105
0106 Vector3 binningPosition{0., 1., 2.};
0107 CHECK_CLOSE_ABS(
0108 coneSurfaceObject->binningPosition(tgContext, BinningValue::binPhi),
0109 binningPosition, 1e-6);
0110
0111
0112 Vector3 globalPosition{2.0, 2.0, 2.0};
0113 Vector3 momentum{1.e6, 1.e6, 1.e6};
0114 double rootHalf = std::sqrt(0.5);
0115 RotationMatrix3 expectedFrame;
0116 expectedFrame << -rootHalf, 0., rootHalf, rootHalf, 0., rootHalf, 0., 1., 0.;
0117 CHECK_CLOSE_OR_SMALL(
0118 coneSurfaceObject->referenceFrame(tgContext, globalPosition, momentum),
0119 expectedFrame, 1e-6, 1e-9);
0120
0121
0122 Vector3 origin{0., 0., 0.};
0123 Vector3 normal3D = {0., -1., 0.};
0124 CHECK_CLOSE_ABS(coneSurfaceObject->normal(tgContext, origin), normal3D, 1e-6);
0125
0126
0127 Vector2 positionPiBy2(1.0, M_PI / 2.);
0128 Vector3 normalAtPiBy2{0.0312768, 0.92335, -0.382683};
0129
0130 CHECK_CLOSE_OR_SMALL(coneSurfaceObject->normal(tgContext, positionPiBy2),
0131 normalAtPiBy2, 1e-2, 1e-9);
0132
0133
0134 Vector3 symmetryAxis{0., 0., 1.};
0135 CHECK_CLOSE_ABS(coneSurfaceObject->rotSymmetryAxis(tgContext), symmetryAxis,
0136 1e-6);
0137
0138
0139 BOOST_CHECK_EQUAL(coneSurfaceObject->bounds().type(), SurfaceBounds::eCone);
0140
0141
0142 Vector2 localPosition{1.0, M_PI / 2.0};
0143 globalPosition =
0144 coneSurfaceObject->localToGlobal(tgContext, localPosition, momentum);
0145
0146 Vector3 expectedPosition{0.0220268, 1.65027, 3.5708};
0147
0148 CHECK_CLOSE_REL(globalPosition, expectedPosition, 1e-2);
0149
0150
0151 localPosition =
0152 coneSurfaceObject->globalToLocal(tgContext, globalPosition, momentum)
0153 .value();
0154
0155 Vector2 expectedLocalPosition{1.0, M_PI / 2.0};
0156
0157 CHECK_CLOSE_REL(localPosition, expectedLocalPosition, 1e-6);
0158
0159
0160 Vector3 offSurface{100, 1, 2};
0161 BOOST_CHECK(coneSurfaceObject->isOnSurface(tgContext, globalPosition,
0162 momentum, BoundaryCheck(true)));
0163 BOOST_CHECK(!coneSurfaceObject->isOnSurface(tgContext, offSurface, momentum,
0164 BoundaryCheck(true)));
0165
0166
0167 CHECK_CLOSE_REL(coneSurfaceObject->pathCorrection(tgContext, offSurface,
0168 momentum.normalized()),
0169 0.40218866453252877, 0.01);
0170
0171
0172 BOOST_CHECK_EQUAL(coneSurfaceObject->name(),
0173 std::string("Acts::ConeSurface"));
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 }
0189
0190 BOOST_AUTO_TEST_CASE(ConeSurfaceEqualityOperators) {
0191 double alpha{M_PI / 8.} ;
0192 bool symmetric(false);
0193 Translation3 translation{0., 1., 2.};
0194 auto pTransform = Transform3(translation);
0195 auto coneSurfaceObject =
0196 Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
0197
0198 auto coneSurfaceObject2 =
0199 Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
0200
0201
0202 BOOST_CHECK(*coneSurfaceObject == *coneSurfaceObject2);
0203
0204 BOOST_TEST_CHECKPOINT(
0205 "Create and then assign a ConeSurface object to the existing one");
0206
0207 auto assignedConeSurface =
0208 Surface::makeShared<ConeSurface>(Transform3::Identity(), 0.1, true);
0209 *assignedConeSurface = *coneSurfaceObject;
0210
0211 BOOST_CHECK(*assignedConeSurface == *coneSurfaceObject);
0212 }
0213
0214 BOOST_AUTO_TEST_CASE(ConeSurfaceExtent) {
0215 double alpha{M_PI / 8.}, zMin{0.}, zMax{10.};
0216
0217 Translation3 translation{0., 0., 0.};
0218
0219
0220 auto pTransform = Transform3(translation);
0221 auto pConeBounds = std::make_shared<const ConeBounds>(alpha, zMin, zMax);
0222 auto pCone = Surface::makeShared<ConeSurface>(pTransform, pConeBounds);
0223 auto pConeExtent = pCone->polyhedronRepresentation(tgContext, 1).extent();
0224
0225 double rMax = zMax * std::tan(alpha);
0226 CHECK_CLOSE_ABS(zMin, pConeExtent.min(binZ), s_onSurfaceTolerance);
0227 CHECK_CLOSE_ABS(zMax, pConeExtent.max(binZ), s_onSurfaceTolerance);
0228 CHECK_CLOSE_ABS(0., pConeExtent.min(binR), s_onSurfaceTolerance);
0229 CHECK_CLOSE_ABS(rMax, pConeExtent.max(binR), s_onSurfaceTolerance);
0230 CHECK_CLOSE_ABS(-rMax, pConeExtent.min(binX), s_onSurfaceTolerance);
0231 CHECK_CLOSE_ABS(rMax, pConeExtent.max(binX), s_onSurfaceTolerance);
0232 CHECK_CLOSE_ABS(-rMax, pConeExtent.min(binY), s_onSurfaceTolerance);
0233 CHECK_CLOSE_ABS(rMax, pConeExtent.max(binY), s_onSurfaceTolerance);
0234
0235
0236 double halfPhiSector = M_PI / 8.;
0237 pConeBounds =
0238 std::make_shared<const ConeBounds>(alpha, zMin, zMax, halfPhiSector, 0.);
0239 pCone = Surface::makeShared<ConeSurface>(pTransform, pConeBounds);
0240 pConeExtent = pCone->polyhedronRepresentation(tgContext, 1).extent();
0241
0242 CHECK_CLOSE_ABS(zMin, pConeExtent.min(binZ), s_onSurfaceTolerance);
0243 CHECK_CLOSE_ABS(zMax, pConeExtent.max(binZ), s_onSurfaceTolerance);
0244 CHECK_CLOSE_ABS(0., pConeExtent.min(binR), s_onSurfaceTolerance);
0245 CHECK_CLOSE_ABS(rMax, pConeExtent.max(binR), s_onSurfaceTolerance);
0246 }
0247
0248
0249 BOOST_AUTO_TEST_CASE(ConeSurfaceAlignment) {
0250 double alpha{M_PI / 8.};
0251 bool symmetric(false);
0252 Translation3 translation{0., 1., 2.};
0253 auto pTransform = Transform3(translation);
0254 auto coneSurfaceObject =
0255 Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
0256
0257 const auto& rotation = pTransform.rotation();
0258
0259 const Vector3 localZAxis = rotation.col(2);
0260
0261 CHECK_CLOSE_ABS(localZAxis, Vector3(0., 0., 1.), 1e-15);
0262
0263
0264 Vector3 globalPosition{0, 1. + std::tan(alpha), 3};
0265
0266
0267
0268 const auto& loc3DToLocBound =
0269 coneSurfaceObject->localCartesianToBoundLocalDerivative(tgContext,
0270 globalPosition);
0271
0272 ActsMatrix<2, 3> expLoc3DToLocBound = ActsMatrix<2, 3>::Zero();
0273 expLoc3DToLocBound << -1, 0, M_PI / 2. * std::tan(alpha), 0, 0, 1;
0274 CHECK_CLOSE_ABS(loc3DToLocBound, expLoc3DToLocBound, 1e-10);
0275 }
0276
0277 BOOST_AUTO_TEST_SUITE_END()
0278 }