Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ConeSurfaceTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ConeSurfaceTests.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 
15 #include "Acts/Geometry/Extent.hpp"
25 
26 #include <algorithm>
27 #include <cmath>
28 #include <memory>
29 #include <string>
30 
31 namespace tt = boost::test_tools;
32 using boost::test_tools::output_test_stream;
33 namespace utf = boost::unit_test;
34 
35 namespace Acts {
36 
37 namespace Test {
38 
39 // Create a test context
41 
42 BOOST_AUTO_TEST_SUITE(ConeSurfaces)
43 
44 
45 BOOST_AUTO_TEST_CASE(ConeSurfaceConstruction) {
46  // ConeSurface default constructor is deleted
47  //
50  double alpha{M_PI / 8.}, halfPhiSector{M_PI / 16.}, zMin{1.0}, zMax{10.};
51  bool symmetric(false);
52  Translation3 translation{0., 1., 2.};
53  auto pTransform = Transform3(translation);
54  BOOST_CHECK_EQUAL(
55  Surface::makeShared<ConeSurface>(Transform3::Identity(), alpha, symmetric)
56  ->type(),
58  BOOST_CHECK_EQUAL(
59  Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric)->type(),
61  //
63  BOOST_CHECK_EQUAL(Surface::makeShared<ConeSurface>(pTransform, alpha, zMin,
64  zMax, halfPhiSector)
65  ->type(),
67 
69  // ConeBounds (double alpha, double zmin, double zmax, double halfphi=M_PI,
70  // double avphi=0.)
71  auto pConeBounds =
72  std::make_shared<const ConeBounds>(alpha, zMin, zMax, halfPhiSector, 0.);
73  BOOST_CHECK_EQUAL(
74  Surface::makeShared<ConeSurface>(pTransform, pConeBounds)->type(),
76  //
77  //
79  auto coneSurfaceObject =
80  Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
81  auto copiedConeSurface = Surface::makeShared<ConeSurface>(*coneSurfaceObject);
82  BOOST_CHECK_EQUAL(copiedConeSurface->type(), Surface::Cone);
83  BOOST_CHECK(*copiedConeSurface == *coneSurfaceObject);
84  //
86  auto copiedTransformedConeSurface = Surface::makeShared<ConeSurface>(
87  tgContext, *coneSurfaceObject, pTransform);
88  BOOST_CHECK_EQUAL(copiedTransformedConeSurface->type(), Surface::Cone);
89 
91  BOOST_CHECK_THROW(auto nullBounds = Surface::makeShared<ConeSurface>(
92  Transform3::Identity(), nullptr),
94 }
95 //
97 BOOST_AUTO_TEST_CASE(ConeSurfaceProperties) {
99  double alpha{M_PI / 8.} /*,halfPhiSector{M_PI/16.}, zMin{1.0}, zMax{10.}*/;
100  bool symmetric(false);
101  Translation3 translation{0., 1., 2.};
102  auto pTransform = Transform3(translation);
103  auto coneSurfaceObject =
104  Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
105  //
107  BOOST_CHECK_EQUAL(coneSurfaceObject->type(), Surface::Cone);
108  //
110  Vector3 binningPosition{0., 1., 2.};
112  coneSurfaceObject->binningPosition(tgContext, BinningValue::binPhi),
113  binningPosition, 1e-6);
114  //
116  Vector3 globalPosition{2.0, 2.0, 2.0};
117  Vector3 momentum{1.e6, 1.e6, 1.e6};
118  double rootHalf = std::sqrt(0.5);
119  RotationMatrix3 expectedFrame;
120  expectedFrame << -rootHalf, 0., rootHalf, rootHalf, 0., rootHalf, 0., 1., 0.;
122  coneSurfaceObject->referenceFrame(tgContext, globalPosition, momentum),
123  expectedFrame, 1e-6, 1e-9);
124  //
126  Vector3 origin{0., 0., 0.};
127  Vector3 normal3D = {0., -1., 0.};
128  CHECK_CLOSE_ABS(coneSurfaceObject->normal(tgContext, origin), normal3D, 1e-6);
129  //
131  Vector2 positionPiBy2(1.0, M_PI / 2.);
132  Vector3 normalAtPiBy2{0.0312768, 0.92335, -0.382683};
133 
134  CHECK_CLOSE_OR_SMALL(coneSurfaceObject->normal(tgContext, positionPiBy2),
135  normalAtPiBy2, 1e-2, 1e-9);
136  //
138  Vector3 symmetryAxis{0., 0., 1.};
139  CHECK_CLOSE_ABS(coneSurfaceObject->rotSymmetryAxis(tgContext), symmetryAxis,
140  1e-6);
141  //
143  BOOST_CHECK_EQUAL(coneSurfaceObject->bounds().type(), SurfaceBounds::eCone);
144  //
146  Vector2 localPosition{1.0, M_PI / 2.0};
147  globalPosition =
148  coneSurfaceObject->localToGlobal(tgContext, localPosition, momentum);
149  // std::cout<<globalPosition<<std::endl;
150  Vector3 expectedPosition{0.0220268, 1.65027, 3.5708};
151 
152  CHECK_CLOSE_REL(globalPosition, expectedPosition, 1e-2);
153  //
155  localPosition =
156  coneSurfaceObject->globalToLocal(tgContext, globalPosition, momentum)
157  .value();
158  // std::cout<<localPosition<<std::endl;
159  Vector2 expectedLocalPosition{1.0, M_PI / 2.0};
160 
161  CHECK_CLOSE_REL(localPosition, expectedLocalPosition, 1e-6);
162  //
164  Vector3 offSurface{100, 1, 2};
165  BOOST_CHECK(coneSurfaceObject->isOnSurface(tgContext, globalPosition,
166  momentum, true));
167  BOOST_CHECK(
168  !coneSurfaceObject->isOnSurface(tgContext, offSurface, momentum, true));
169 
171  CHECK_CLOSE_REL(coneSurfaceObject->pathCorrection(tgContext, offSurface,
172  momentum.normalized()),
173  0.40218866453252877, 0.01);
174  //
176  BOOST_CHECK_EQUAL(coneSurfaceObject->name(),
177  std::string("Acts::ConeSurface"));
178  //
180  // TODO 2017-04-12 msmk: check how to correctly check output
181  // boost::test_tools::output_test_stream dumpOuput;
182  // coneSurfaceObject.toStream(dumpOuput);
183  // BOOST_CHECK(dumpOuput.is_equal(
184  // "Acts::ConeSurface\n"
185  // " Center position (x, y, z) = (0.0000, 1.0000, 2.0000)\n"
186  // " Rotation: colX = (1.000000, 0.000000, 0.000000)\n"
187  // " colY = (0.000000, 1.000000, 0.000000)\n"
188  // " colZ = (0.000000, 0.000000, 1.000000)\n"
189  // " Bounds : Acts::ConeBounds: (tanAlpha, minZ, maxZ, averagePhi,
190  // halfPhiSector) = (0.4142136, 0.0000000, inf, 0.0000000,
191  // 3.1415927)"));
192 }
193 
194 BOOST_AUTO_TEST_CASE(ConeSurfaceEqualityOperators) {
195  double alpha{M_PI / 8.} /*, halfPhiSector{M_PI/16.}, zMin{1.0}, zMax{10.}*/;
196  bool symmetric(false);
197  Translation3 translation{0., 1., 2.};
198  auto pTransform = Transform3(translation);
199  auto coneSurfaceObject =
200  Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
201  //
202  auto coneSurfaceObject2 =
203  Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
204  //
206  BOOST_CHECK(*coneSurfaceObject == *coneSurfaceObject2);
207  //
208  BOOST_TEST_CHECKPOINT(
209  "Create and then assign a ConeSurface object to the existing one");
211  auto assignedConeSurface =
212  Surface::makeShared<ConeSurface>(Transform3::Identity(), 0.1, true);
213  *assignedConeSurface = *coneSurfaceObject;
215  BOOST_CHECK(*assignedConeSurface == *coneSurfaceObject);
216 }
217 
218 BOOST_AUTO_TEST_CASE(ConeSurfaceExtent) {
219  double alpha{M_PI / 8.}, zMin{0.}, zMax{10.};
220 
221  Translation3 translation{0., 0., 0.};
222 
223  // Testing a Full cone
224  auto pTransform = Transform3(translation);
225  auto pConeBounds = std::make_shared<const ConeBounds>(alpha, zMin, zMax);
226  auto pCone = Surface::makeShared<ConeSurface>(pTransform, pConeBounds);
227  auto pConeExtent = pCone->polyhedronRepresentation(tgContext, 1).extent();
228 
229  double rMax = zMax * std::tan(alpha);
230  CHECK_CLOSE_ABS(zMin, pConeExtent.min(binZ), s_onSurfaceTolerance);
231  CHECK_CLOSE_ABS(zMax, pConeExtent.max(binZ), s_onSurfaceTolerance);
232  CHECK_CLOSE_ABS(0., pConeExtent.min(binR), s_onSurfaceTolerance);
233  CHECK_CLOSE_ABS(rMax, pConeExtent.max(binR), s_onSurfaceTolerance);
234  CHECK_CLOSE_ABS(-rMax, pConeExtent.min(binX), s_onSurfaceTolerance);
235  CHECK_CLOSE_ABS(rMax, pConeExtent.max(binX), s_onSurfaceTolerance);
236  CHECK_CLOSE_ABS(-rMax, pConeExtent.min(binY), s_onSurfaceTolerance);
237  CHECK_CLOSE_ABS(rMax, pConeExtent.max(binY), s_onSurfaceTolerance);
238 
239  // Now a sector
240  double halfPhiSector = M_PI / 8.;
241  pConeBounds =
242  std::make_shared<const ConeBounds>(alpha, zMin, zMax, halfPhiSector, 0.);
243  pCone = Surface::makeShared<ConeSurface>(pTransform, pConeBounds);
244  pConeExtent = pCone->polyhedronRepresentation(tgContext, 1).extent();
245 
246  CHECK_CLOSE_ABS(zMin, pConeExtent.min(binZ), s_onSurfaceTolerance);
247  CHECK_CLOSE_ABS(zMax, pConeExtent.max(binZ), s_onSurfaceTolerance);
248  CHECK_CLOSE_ABS(0., pConeExtent.min(binR), s_onSurfaceTolerance);
249  CHECK_CLOSE_ABS(rMax, pConeExtent.max(binR), s_onSurfaceTolerance);
250 }
251 
253 BOOST_AUTO_TEST_CASE(ConeSurfaceAlignment) {
254  double alpha{M_PI / 8.};
255  bool symmetric(false);
256  Translation3 translation{0., 1., 2.};
257  auto pTransform = Transform3(translation);
258  auto coneSurfaceObject =
259  Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
260 
261  const auto& rotation = pTransform.rotation();
262  // The local frame z axis
263  const Vector3 localZAxis = rotation.col(2);
264  // Check the local z axis is aligned to global z axis
265  CHECK_CLOSE_ABS(localZAxis, Vector3(0., 0., 1.), 1e-15);
266 
268  Vector3 globalPosition{0, 1. + std::tan(alpha), 3};
269 
270  // Test the derivative of bound track parameters local position w.r.t.
271  // position in local 3D Cartesian coordinates
272  const auto& loc3DToLocBound =
273  coneSurfaceObject->localCartesianToBoundLocalDerivative(tgContext,
274  globalPosition);
275  // Check if the result is as expected
276  ActsMatrix<2, 3> expLoc3DToLocBound = ActsMatrix<2, 3>::Zero();
277  expLoc3DToLocBound << -1, 0, M_PI / 2. * std::tan(alpha), 0, 0, 1;
278  CHECK_CLOSE_ABS(loc3DToLocBound, expLoc3DToLocBound, 1e-10);
279 }
280 
281 BOOST_AUTO_TEST_SUITE_END()
282 
283 } // namespace Test
284 
285 } // namespace Acts