EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DiscSurfaceTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DiscSurfaceTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2018 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/data/test_case.hpp>
10 #include <boost/test/tools/output_test_stream.hpp>
11 #include <boost/test/unit_test.hpp>
12 
20 
21 #include <limits>
22 
23 namespace utf = boost::unit_test;
24 namespace tt = boost::test_tools;
25 
26 namespace Acts {
27 
28 namespace Test {
29 // using boost::test_tools::output_test_stream;
30 // Create a test context
32 
33 BOOST_AUTO_TEST_SUITE(Surfaces)
35 BOOST_AUTO_TEST_CASE(DiscSurfaceConstruction) {
36  // default constructor is deleted
37  // scaffolding...
38  double rMin(1.0), rMax(5.0), halfPhiSector(M_PI / 8.);
39  //
41  BOOST_CHECK_NO_THROW(
42  Surface::makeShared<DiscSurface>(Transform3D::Identity(), rMin, rMax));
43  //
45  Translation3D translation{0., 1., 2.};
46  auto pTransform = Transform3D(translation);
47  BOOST_CHECK_NO_THROW(
48  Surface::makeShared<DiscSurface>(pTransform, rMin, rMax, halfPhiSector));
49  //
51  auto anotherDiscSurface =
52  Surface::makeShared<DiscSurface>(pTransform, rMin, rMax, halfPhiSector);
53  // N.B. Just using
54  // BOOST_CHECK_NO_THROW(Surface::makeShared<DiscSurface>(anotherDiscSurface))
55  // tries to call
56  // the (deleted) default constructor.
57  auto copiedSurface = Surface::makeShared<DiscSurface>(*anotherDiscSurface);
58  BOOST_TEST_MESSAGE("Copy constructed DiscSurface ok");
59  //
61  BOOST_CHECK_NO_THROW(Surface::makeShared<DiscSurface>(
62  tgContext, *anotherDiscSurface, pTransform));
63 
65  DetectorElementStub detElem;
66  BOOST_CHECK_THROW(
67  auto nullBounds = Surface::makeShared<DiscSurface>(nullptr, detElem),
69 }
70 
72 BOOST_AUTO_TEST_CASE(DiscSurfaceProperties, *utf::expected_failures(2)) {
73  Vector3D origin3D{0, 0, 0};
74  double rMin(1.0), rMax(5.0), halfPhiSector(M_PI / 8.);
75  auto discSurfaceObject = Surface::makeShared<DiscSurface>(
76  Transform3D::Identity(), rMin, rMax, halfPhiSector);
77  //
79  BOOST_CHECK_EQUAL(discSurfaceObject->type(), Surface::Disc);
80  //
82  Vector3D zAxis{0, 0, 1};
83  BOOST_CHECK_EQUAL(discSurfaceObject->normal(tgContext), zAxis);
84  //
86  Vector2D lpos(2.0, 0.05);
87  BOOST_CHECK_EQUAL(discSurfaceObject->normal(tgContext, lpos), zAxis);
88  //
90  // auto binningPosition=
91  // discSurfaceObject.binningPosition(BinningValue::binRPhi );
92  // std::cout<<binningPosition<<std::endl;
93  BOOST_CHECK_EQUAL(
94  discSurfaceObject->binningPosition(tgContext, BinningValue::binRPhi),
95  origin3D);
96  //
98  BOOST_CHECK_EQUAL(discSurfaceObject->bounds().type(), SurfaceBounds::eDisc);
99  //
100  Vector3D ignoredMomentum{0., 0., 0.};
102  Vector3D point3DNotInSector{0.0, 1.2, 0};
103  Vector3D point3DOnSurface{1.2, 0.0, 0};
104  BOOST_CHECK(!discSurfaceObject->isOnSurface(
105  tgContext, point3DNotInSector, ignoredMomentum, true)); // passes
106  BOOST_CHECK(discSurfaceObject->isOnSurface(tgContext, point3DOnSurface,
107  ignoredMomentum, true)); // passes
108  //
110  Vector3D returnedPosition{10.9, 8.7, 6.5};
111  Vector3D expectedPosition{1.2, 0, 0};
112  Vector2D rPhiOnDisc{1.2, 0.0};
113  Vector2D rPhiNotInSector{1.2, M_PI}; // outside sector at Phi=0, +/- pi/8
114  returnedPosition =
115  discSurfaceObject->localToGlobal(tgContext, rPhiOnDisc, ignoredMomentum);
116  CHECK_CLOSE_ABS(returnedPosition, expectedPosition, 1e-6);
117  //
118  returnedPosition = discSurfaceObject->localToGlobal(
119  tgContext, rPhiNotInSector, ignoredMomentum);
120  Vector3D expectedNonPosition{-1.2, 0, 0};
121  CHECK_CLOSE_ABS(returnedPosition, expectedNonPosition, 1e-6);
122  //
124  Vector2D returnedLocalPosition{33., 44.};
125  Vector2D expectedLocalPosition{1.2, 0.0};
126  returnedLocalPosition =
127  discSurfaceObject
128  ->globalToLocal(tgContext, point3DOnSurface, ignoredMomentum)
129  .value();
130  CHECK_CLOSE_ABS(returnedLocalPosition, expectedLocalPosition, 1e-6);
131 
132  // Global to local does not check inside bounds
133  returnedLocalPosition =
134  discSurfaceObject
135  ->globalToLocal(tgContext, point3DNotInSector, ignoredMomentum)
136  .value();
137  //
138  Vector3D pointOutsideR{0.0, 100., 0};
139  returnedLocalPosition =
140  discSurfaceObject
141  ->globalToLocal(tgContext, pointOutsideR, ignoredMomentum)
142  .value();
143  //
145  Vector2D rPhi1_1{std::sqrt(2.), M_PI / 4.};
146  Vector2D cartesian1_1{1., 1.};
147  CHECK_CLOSE_REL(discSurfaceObject->localPolarToCartesian(rPhi1_1),
148  cartesian1_1, 1e-6);
149  //
151  CHECK_CLOSE_REL(discSurfaceObject->localCartesianToPolar(cartesian1_1),
152  rPhi1_1, 1e-6);
153  //
155  CHECK_CLOSE_REL(discSurfaceObject->localPolarToLocalCartesian(rPhi1_1),
156  cartesian1_1, 1e-6);
157  //
159  Vector3D cartesian3D1_1{1., 1., 0.};
161  discSurfaceObject->localCartesianToGlobal(tgContext, cartesian1_1),
162  cartesian3D1_1, 1e-6);
163  //
166  discSurfaceObject->globalToLocalCartesian(tgContext, cartesian3D1_1),
167  cartesian1_1, 1e-6);
168  //
170  double projected3DMomentum = std::sqrt(3.) * 1.e6;
171  Vector3D momentum{projected3DMomentum, projected3DMomentum,
172  projected3DMomentum};
173  Vector3D ignoredPosition{1.1, 2.2, 3.3};
174  CHECK_CLOSE_REL(discSurfaceObject->pathCorrection(tgContext, ignoredPosition,
175  momentum.normalized()),
176  std::sqrt(3), 0.01);
177  //
179  Vector3D globalPosition{1.2, 0.0, -10.};
180  Vector3D direction{0., 0., 1.}; // must be normalised
181  Vector3D expected{1.2, 0.0, 0.0};
182 
183  // intersect is a struct of (Vector3D) position, pathLength, distance and
184  // (bool) valid, it's contained in a Surface intersection
185  auto sfIntersection =
186  discSurfaceObject->intersect(tgContext, globalPosition, direction, false);
187  Intersection3D expectedIntersect{Vector3D{1.2, 0., 0.}, 10.,
188  Intersection3D::Status::reachable};
189  BOOST_CHECK(bool(sfIntersection));
190  CHECK_CLOSE_ABS(sfIntersection.intersection.position,
191  expectedIntersect.position, 1e-9);
192  CHECK_CLOSE_ABS(sfIntersection.intersection.pathLength,
193  expectedIntersect.pathLength, 1e-9);
194  BOOST_CHECK_EQUAL(sfIntersection.object, discSurfaceObject.get());
195 
196  //
198  boost::test_tools::output_test_stream nameOuput;
199  nameOuput << discSurfaceObject->name();
200  BOOST_CHECK(nameOuput.is_equal("Acts::DiscSurface"));
201 }
202 //
204 BOOST_AUTO_TEST_CASE(DiscSurfaceAssignment) {
205  Vector3D origin3D{0, 0, 0};
206  double rMin(1.0), rMax(5.0), halfPhiSector(M_PI / 8.);
207  auto discSurfaceObject = Surface::makeShared<DiscSurface>(
208  Transform3D::Identity(), rMin, rMax, halfPhiSector);
209  auto assignedDisc =
210  Surface::makeShared<DiscSurface>(Transform3D::Identity(), 2.2, 4.4, 0.07);
211  //
212  BOOST_CHECK_NO_THROW(*assignedDisc = *discSurfaceObject);
213  BOOST_CHECK((*assignedDisc) == (*discSurfaceObject));
214 }
215 
217 BOOST_AUTO_TEST_CASE(DiscSurfaceExtent) {
218  double rMin(1.0), rMax(5.0);
219 
220  auto pDisc =
221  Surface::makeShared<DiscSurface>(Transform3D::Identity(), 0., rMax);
222  auto pDiscExtent = pDisc->polyhedronRepresentation(tgContext, 1).extent();
223 
224  CHECK_CLOSE_ABS(0., pDiscExtent.min(binZ), s_onSurfaceTolerance);
225  CHECK_CLOSE_ABS(0., pDiscExtent.max(binZ), s_onSurfaceTolerance);
226  CHECK_CLOSE_ABS(0., pDiscExtent.min(binR), s_onSurfaceTolerance);
227  CHECK_CLOSE_ABS(rMax, pDiscExtent.max(binR), s_onSurfaceTolerance);
228  CHECK_CLOSE_ABS(-rMax, pDiscExtent.min(binX), s_onSurfaceTolerance);
229  CHECK_CLOSE_ABS(rMax, pDiscExtent.max(binX), s_onSurfaceTolerance);
230  CHECK_CLOSE_ABS(-rMax, pDiscExtent.min(binY), s_onSurfaceTolerance);
231  CHECK_CLOSE_ABS(rMax, pDiscExtent.max(binY), s_onSurfaceTolerance);
232  CHECK_CLOSE_ABS(-M_PI, pDiscExtent.min(binPhi), s_onSurfaceTolerance);
233  CHECK_CLOSE_ABS(M_PI, pDiscExtent.max(binPhi), s_onSurfaceTolerance);
234 
235  auto pRing =
236  Surface::makeShared<DiscSurface>(Transform3D::Identity(), rMin, rMax);
237  auto pRingExtent = pRing->polyhedronRepresentation(tgContext, 1).extent();
238 
239  CHECK_CLOSE_ABS(0., pRingExtent.min(binZ), s_onSurfaceTolerance);
240  CHECK_CLOSE_ABS(0., pRingExtent.max(binZ), s_onSurfaceTolerance);
241  CHECK_CLOSE_ABS(rMin, pRingExtent.min(binR), s_onSurfaceTolerance);
242  CHECK_CLOSE_ABS(rMax, pRingExtent.max(binR), s_onSurfaceTolerance);
243  CHECK_CLOSE_ABS(-rMax, pRingExtent.min(binX), s_onSurfaceTolerance);
244  CHECK_CLOSE_ABS(rMax, pRingExtent.max(binX), s_onSurfaceTolerance);
245  CHECK_CLOSE_ABS(-rMax, pRingExtent.min(binY), s_onSurfaceTolerance);
246  CHECK_CLOSE_ABS(rMax, pRingExtent.max(binY), s_onSurfaceTolerance);
247 }
248 
250 BOOST_AUTO_TEST_CASE(DiscSurfaceAlignment) {
251  Translation3D translation{0., 1., 2.};
252  Transform3D transform(translation);
253  double rMin(1.0), rMax(5.0), halfPhiSector(M_PI / 8.);
254  auto discSurfaceObject =
255  Surface::makeShared<DiscSurface>(transform, rMin, rMax, halfPhiSector);
256 
257  const auto& rotation = transform.rotation();
258  // The local frame z axis
259  const Vector3D localZAxis = rotation.col(2);
260  // Check the local z axis is aligned to global z axis
261  CHECK_CLOSE_ABS(localZAxis, Vector3D(0., 0., 1.), 1e-15);
262 
264  Vector3D globalPosition{0, 4, 2};
265  Vector3D momentum{0, 0, 1};
266  Vector3D direction = momentum.normalized();
267 
268  // Call the function to calculate the derivative of local frame axes w.r.t its
269  // rotation
270  const auto& [rotToLocalXAxis, rotToLocalYAxis, rotToLocalZAxis] =
272 
273  // (a) Test the derivative of path length w.r.t. alignment parameters
274  const AlignmentRowVector& alignToPath =
275  discSurfaceObject->alignmentToPathDerivative(tgContext, rotToLocalZAxis,
276  globalPosition, direction);
277  // The expected results
278  AlignmentRowVector expAlignToPath = AlignmentRowVector::Zero();
279  expAlignToPath << 0, 0, 1, 3, 0, 0;
280  // Check if the calculated derivative is as expected
281  CHECK_CLOSE_ABS(alignToPath, expAlignToPath, 1e-10);
282 
283  // (b) Test the derivative of bound track parameters local position w.r.t.
284  // position in local 3D Cartesian coordinates
285  const auto& loc3DToLocBound =
286  discSurfaceObject->localCartesianToBoundLocalDerivative(tgContext,
287  globalPosition);
288  // Check if the result is as expected
289  LocalCartesianToBoundLocalMatrix expLoc3DToLocBound =
290  LocalCartesianToBoundLocalMatrix::Zero();
291  expLoc3DToLocBound << 0, 1, 0, -1.0 / 3, 0, 0;
292  CHECK_CLOSE_ABS(loc3DToLocBound, expLoc3DToLocBound, 1e-10);
293 }
294 
295 BOOST_AUTO_TEST_SUITE_END()
296 
297 } // namespace Test
298 
299 } // namespace Acts