Belle II Software  release-05-01-25
PerigeeCircle.test.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2014 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Oliver Frost <oliver.frost@desy.de> *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <tracking/trackFindingCDC/geometry/PerigeeCircle.h>
12 #include <tracking/trackFindingCDC/geometry/GeneralizedCircle.h>
13 #include <tracking/trackFindingCDC/geometry/Vector2D.h>
14 
15 #include <gtest/gtest.h>
16 
17 
18 using namespace Belle2;
19 using namespace TrackFindingCDC;
20 
21 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_inheritance)
22 {
23 
24  double curvature = 1.0;
25  double phi0 = M_PI / 4.0;
26  double impact = 1.0;
27 
28  // Checks if the normal parameters n follow the same sign convention
29  PerigeeCircle perigeeCircle(curvature, phi0, impact);
30 
31  const GeneralizedCircle generalizedCircle(perigeeCircle.n0(),
32  perigeeCircle.n12(),
33  perigeeCircle.n3());
34 
35  EXPECT_NEAR(curvature, generalizedCircle.curvature(), 10e-7);
36  EXPECT_NEAR(impact, generalizedCircle.impact(), 10e-7);
37  EXPECT_NEAR(perigeeCircle.tangential().x(), generalizedCircle.tangential().x(), 10e-7);
38  EXPECT_NEAR(perigeeCircle.tangential().y(), generalizedCircle.tangential().y(), 10e-7);
39 
40  PerigeeCircle roundTripCircle(generalizedCircle);
41 
42  EXPECT_NEAR(curvature, roundTripCircle.curvature(), 10e-7);
43  EXPECT_NEAR(impact, roundTripCircle.impact(), 10e-7);
44  EXPECT_NEAR(cos(phi0), roundTripCircle.phi0Vec().x(), 10e-7);
45  EXPECT_NEAR(sin(phi0), roundTripCircle.phi0Vec().y(), 10e-7);
46  EXPECT_NEAR(phi0, roundTripCircle.phi0(), 10e-7);
47 
48  PerigeeCircle roundTripCircle2;
49  roundTripCircle2.setN(generalizedCircle);
50 
51  EXPECT_NEAR(curvature, roundTripCircle2.curvature(), 10e-7);
52  EXPECT_NEAR(impact, roundTripCircle2.impact(), 10e-7);
53  EXPECT_NEAR(cos(phi0), roundTripCircle2.tangential().x(), 10e-7);
54  EXPECT_NEAR(sin(phi0), roundTripCircle2.tangential().y(), 10e-7);
55  EXPECT_NEAR(phi0, roundTripCircle2.phi0(), 10e-7);
56 }
57 
58 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_isLine)
59 {
60  double radius = 1;
61  Vector2D center = Vector2D(2.0, 0.0);
62  PerigeeCircle circle = PerigeeCircle::fromCenterAndRadius(center, radius);
63 
64  EXPECT_FALSE(circle.isLine());
65 
66  float curvature = 0;
67  float phi0 = M_PI / 2;
68  float impact = -1;
69  PerigeeCircle line = PerigeeCircle(curvature, phi0, impact);
70 
71  EXPECT_TRUE(line.isLine());
72 }
73 
74 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_isCircle)
75 {
76  double radius = 1;
77  Vector2D center = Vector2D(2.0, 0.0);
78  PerigeeCircle circle = PerigeeCircle::fromCenterAndRadius(center, radius);
79 
80  EXPECT_TRUE(circle.isCircle());
81 
82  float curvature = 0;
83  float phi0 = M_PI / 2;
84  float impact = -1;
85  PerigeeCircle line = PerigeeCircle(curvature, phi0, impact);
86 
87  EXPECT_FALSE(line.isCircle());
88 }
89 
90 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_orientation)
91 {
92  double curvature = 1;
93  Vector2D phi0 = Vector2D::Phi(1);
94  double impact = 1;
95 
96  PerigeeCircle circle(curvature, phi0, impact);
97  EXPECT_EQ(ERotation::c_CounterClockwise, circle.orientation());
98 
99  PerigeeCircle reversedCircle = circle.reversed();
100  EXPECT_EQ(ERotation::c_Clockwise, reversedCircle.orientation());
101 
102  curvature = 0;
103  PerigeeCircle line(curvature, phi0, impact);
104  EXPECT_EQ(ERotation::c_CounterClockwise, line.orientation());
105 
106  PerigeeCircle reversedLine = line.reversed();
107  EXPECT_EQ(ERotation::c_Clockwise, reversedLine.orientation());
108 }
109 
110 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_minimalCylindricalR)
111 {
112  double curvature = 1.0 / 2.0;
113  double tangtialPhi = M_PI / 4.0;
114  double impact = -1.0;
115 
116  // Checks if the normal parameters n follow the same sign convention
117  PerigeeCircle perigeeCircle(curvature, tangtialPhi, impact);
118 
119  EXPECT_EQ(1, perigeeCircle.minimalCylindricalR());
120 }
121 
122 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_maximalCylindricalR)
123 {
124  double curvature = 1.0 / 2.0;
125  double tangtialPhi = M_PI / 4.0;
126  double impact = -1.0;
127 
128  // Checks if the normal parameters n follow the same sign convention
129  PerigeeCircle perigeeCircle(curvature, tangtialPhi, impact);
130 
131  EXPECT_EQ(3, perigeeCircle.maximalCylindricalR());
132 }
133 
134 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_setCenterAndRadius)
135 {
136  PerigeeCircle circle;
137  Vector2D center(0.5, 0.0);
138  double radius = 1.5;
139  circle.setCenterAndRadius(center, radius, ERotation::c_CounterClockwise);
140 
141  EXPECT_TRUE(circle.isCircle());
142  EXPECT_FALSE(circle.isLine());
143 
144  EXPECT_NEAR(1.5, circle.radius(), 10e-7);
145  EXPECT_NEAR(0.5, circle.center().x(), 10e-7);
146  EXPECT_NEAR(0.0, circle.center().y(), 10e-7);
147 }
148 
149 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_distance)
150 {
151 
152  double curvature = -1.;
153  double phi0 = 3. * M_PI / 4.;
154  double impact = 1. - sqrt(2.);
155 
156  PerigeeCircle circle(curvature, phi0, impact);
157 
158  EXPECT_TRUE(circle.isCircle());
159  EXPECT_FALSE(circle.isLine());
160 
161  EXPECT_NEAR(-1.0, circle.radius(), 10e-7);
162  EXPECT_NEAR(1.0, circle.center().x(), 10e-7);
163  EXPECT_NEAR(1.0, circle.center().y(), 10e-7);
164 
165  EXPECT_NEAR(curvature, circle.curvature(), 10e-7);
166  EXPECT_NEAR(phi0, circle.phi0(), 10e-7);
167  EXPECT_NEAR(impact, circle.impact(), 10e-7);
168 
169  EXPECT_NEAR(0, circle.distance(Vector2D(1.0, 0.0)), 10e-7);
170  EXPECT_NEAR(0, circle.distance(Vector2D(0.0, 1.0)), 10e-7);
171  EXPECT_NEAR(impact, circle.distance(Vector2D(0.0, 0.0)), 10e-7);
172 
173  EXPECT_NEAR(0.5, circle.distance(Vector2D(1.0, 0.5)), 10e-7);
174 
175  EXPECT_NEAR(-0.5, circle.distance(Vector2D(1.0, 2.5)), 10e-7);
176  EXPECT_NEAR(-0.5, circle.distance(Vector2D(2.5, 1.0)), 10e-7);
177 }
178 
179 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_invalidate)
180 {
181  PerigeeCircle defaultCircle;
182  EXPECT_TRUE(defaultCircle.isInvalid());
183 
184  double curvature = -1.;
185  double phi0 = 3. * M_PI / 4.;
186  double impact = 1. - sqrt(2.0);
187 
188  PerigeeCircle circle(curvature, phi0, impact);
189 
190  circle.invalidate();
191  EXPECT_TRUE(circle.isInvalid());
192 
193  circle.reverse();
194  EXPECT_TRUE(circle.isInvalid());
195 
196  circle = circle.reversed();
197  EXPECT_TRUE(circle.isInvalid());
198 
199  GeneralizedCircle generalizedCircle;
200  generalizedCircle.invalidate();
201  circle.setN(generalizedCircle);
202 
203  EXPECT_TRUE(circle.isInvalid());
204 }
205 
206 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_passiveMoveBy)
207 {
208  Vector2D center(4.0, 2.0);
209  double radius = 5.0;
210  PerigeeCircle circle = PerigeeCircle::fromCenterAndRadius(center, radius);
211 
212  circle.passiveMoveBy(Vector2D(4.0, 0.0));
213 
214  EXPECT_NEAR(5.0, circle.radius(), 10e-7);
215  EXPECT_NEAR(0.0, circle.perigee().x(), 10e-7);
216  EXPECT_NEAR(-3.0, circle.perigee().y(), 10e-7);
217 }
218 
219 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_conformalTranform)
220 {
221  Vector2D center(1.0, 0.0);
222  double radius = 1.0;
223  PerigeeCircle circle = PerigeeCircle::fromCenterAndRadius(center, radius);
224 
225  // Get two points on the circle to check for the orientation to be correct
226  Vector2D firstPos = circle.atArcLength(1);
227  Vector2D secondPos = circle.atArcLength(2);
228 
229  EXPECT_NEAR(1.0, circle.curvature(), 10e-7);
230  EXPECT_NEAR(-M_PI / 2.0, circle.phi0(), 10e-7);
231  EXPECT_NEAR(0.0, circle.impact(), 10e-7);
232  EXPECT_NEAR(0.0, circle.distance(firstPos), 10e-7);
233  EXPECT_NEAR(0.0, circle.distance(secondPos), 10e-7);
234 
235  circle.conformalTransform();
236  firstPos.conformalTransform();
237  secondPos.conformalTransform();
238 
239  EXPECT_NEAR(0.0, circle.curvature(), 10e-7);
240  EXPECT_NEAR(M_PI / 2.0, circle.phi0(), 10e-7);
241  EXPECT_NEAR(-1.0 / 2.0, circle.impact(), 10e-7);
242 
243  double firstConformalArcLength = circle.arcLengthTo(firstPos);
244  double secondConformalArcLength = circle.arcLengthTo(secondPos);
245  EXPECT_LT(firstConformalArcLength, secondConformalArcLength);
246 
247  EXPECT_NEAR(0.0, circle.distance(firstPos), 10e-7);
248  EXPECT_NEAR(0.0, circle.distance(secondPos), 10e-7);
249 
250  // Another conformal transformation goes back to the original circle
251  PerigeeCircle conformalCopy = circle.conformalTransformed();
252  EXPECT_NEAR(1.0, conformalCopy.curvature(), 10e-7);
253  EXPECT_NEAR(-M_PI / 2.0, conformalCopy.phi0(), 10e-7);
254  EXPECT_NEAR(0.0, conformalCopy.impact(), 10e-7);
255 }
256 
257 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_closest)
258 {
259  PerigeeCircle circle(1.0, Vector2D(0.0, -1.0), 1.0);
260  Vector2D up(2.0, 2.0);
261  Vector2D far(5.0, 0.0);
262 
263  EXPECT_EQ(Vector2D(2.0, 1.0), circle.closest(up));
264  EXPECT_EQ(Vector2D(3.0, 0.0), circle.closest(far));
265 
266  // This tests for point which is on the circle
267  double smallAngle = M_PI / 100;
268  Vector2D near(2.0 - cos(smallAngle), sin(smallAngle));
269 
270  Vector2D closestOfNear = circle.closest(near);
271  EXPECT_NEAR(near.x(), closestOfNear.x(), 10e-7);
272  EXPECT_NEAR(near.y(), closestOfNear.y(), 10e-7);
273 }
274 
275 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_atArcLength)
276 {
277  double radius = 1;
278  Vector2D center = Vector2D(2.0, 0.0);
279 
280  PerigeeCircle circle = PerigeeCircle::fromCenterAndRadius(center, radius);
281 
282  double smallAngle = M_PI / 100;
283  Vector2D near(2.0 - cos(smallAngle), sin(smallAngle));
284 
285  double nearArcLength =
286  -smallAngle * radius; // Minus because of default counterclockwise orientation
287 
288  Vector2D atNear = circle.atArcLength(nearArcLength);
289 
290  EXPECT_NEAR(near.x(), atNear.x(), 10e-7);
291  EXPECT_NEAR(near.y(), atNear.y(), 10e-7);
292 
293  Vector2D down(2.0, -1.0);
294  double downArcLength =
295  +M_PI / 2.0 * radius; // Plus because of default counterclockwise orientation
296 
297  Vector2D atDown = circle.atArcLength(downArcLength);
298 
299  EXPECT_NEAR(down.x(), atDown.x(), 10e-7);
300  EXPECT_NEAR(down.y(), atDown.y(), 10e-7);
301 }
302 
303 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_arcLengthToCylindricalR)
304 {
305  double radius = 1;
306  Vector2D center = Vector2D(2.0, 0.0);
307 
308  PerigeeCircle circle = PerigeeCircle::fromCenterAndRadius(center, radius);
309  {
310  double closestArcLength = circle.arcLengthToCylindricalR(1);
311  EXPECT_NEAR(0, closestArcLength, 10e-7);
312 
313  double widestArcLength = circle.arcLengthToCylindricalR(3);
314  EXPECT_NEAR(M_PI, widestArcLength, 10e-7);
315 
316  double halfArcLength = circle.arcLengthToCylindricalR(sqrt(5.0));
317  EXPECT_NEAR(M_PI / 2, halfArcLength, 10e-7);
318 
319  double unreachableHighArcLength = circle.arcLengthToCylindricalR(4);
320  EXPECT_TRUE(std::isnan(unreachableHighArcLength));
321 
322  double unreachableLowArcLength = circle.arcLengthToCylindricalR(0.5);
323  EXPECT_TRUE(std::isnan(unreachableLowArcLength));
324  }
325 
326  PerigeeCircle reversedCircle = circle.reversed();
327  {
328  double closestArcLength = reversedCircle.arcLengthToCylindricalR(1);
329  EXPECT_NEAR(0, closestArcLength, 10e-7);
330 
331  double widestArcLength = reversedCircle.arcLengthToCylindricalR(3);
332  EXPECT_NEAR(M_PI, widestArcLength, 10e-7);
333 
334  double halfArcLength = reversedCircle.arcLengthToCylindricalR(sqrt(5.0));
335  EXPECT_NEAR(M_PI / 2, halfArcLength, 10e-7);
336 
337  double unreachableHighArcLength = reversedCircle.arcLengthToCylindricalR(4);
338  EXPECT_TRUE(std::isnan(unreachableHighArcLength));
339 
340  double unreachableLowArcLength = reversedCircle.arcLengthToCylindricalR(0.5);
341  EXPECT_TRUE(std::isnan(unreachableLowArcLength));
342  }
343 }
344 
345 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_atCylindricalR)
346 {
347  double radius = 1;
348  Vector2D center = Vector2D(2.0, 0.0);
349  PerigeeCircle circle = PerigeeCircle::fromCenterAndRadius(center, radius);
350 
351  std::pair<Vector2D, Vector2D> solutions = circle.atCylindricalR(sqrt(5.0));
352 
353  EXPECT_NEAR(2, solutions.first.x(), 10e-7);
354  EXPECT_NEAR(1, solutions.first.y(), 10e-7);
355 
356  EXPECT_NEAR(2, solutions.second.x(), 10e-7);
357  EXPECT_NEAR(-1, solutions.second.y(), 10e-7);
358 }
359 
360 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_atCylindricalR_opposite_orientation)
361 {
362  double radius = 1;
363  Vector2D center = Vector2D(2.0, 0.0);
364  PerigeeCircle circle = PerigeeCircle::fromCenterAndRadius(center, radius, ERotation::c_Clockwise);
365 
366  std::pair<Vector2D, Vector2D> solutions = circle.atCylindricalR(sqrt(5.0));
367 
368  EXPECT_NEAR(2, solutions.first.x(), 10e-7);
369  EXPECT_NEAR(-1, solutions.first.y(), 10e-7);
370 
371  EXPECT_NEAR(2, solutions.second.x(), 10e-7);
372  EXPECT_NEAR(1, solutions.second.y(), 10e-7);
373 }
374 
375 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_OriginCircleFromPointDirection)
376 {
377  double expectedCurvature = 1.0 / 2.0;
378  double expectedPhi0 = M_PI / 4.0;
379  double impact = 0;
380 
381  // Checks if the normal parameters n follow the same sign convention
382  const PerigeeCircle perigeeCircle(expectedCurvature, expectedPhi0, impact);
383  const Vector2D& expectedPhi0Vec = perigeeCircle.phi0Vec();
384 
385  double randomArcLength = 2.0;
386  Vector2D pos2D = perigeeCircle.atArcLength(randomArcLength);
387  Vector2D phiVec = perigeeCircle.tangential(pos2D);
388 
389  double curvature = 2 * pos2D.cross(phiVec) / pos2D.normSquared();
390  Vector2D phi0Vec = phiVec.flippedOver(pos2D);
391 
392  EXPECT_NEAR(expectedCurvature, curvature, 10e-7);
393  EXPECT_NEAR(expectedPhi0Vec.x(), phi0Vec.x(), 10e-7);
394  EXPECT_NEAR(expectedPhi0Vec.y(), phi0Vec.y(), 10e-7);
395  EXPECT_NEAR(expectedPhi0, phi0Vec.phi(), 10e-7);
396  EXPECT_NEAR(1, phi0Vec.norm(), 10e-7);
397 }
Belle2::TrackFindingCDC::Vector2D::Phi
static Vector2D Phi(const double phi)
Constucts a unit vector with azimuth angle equal to phi.
Definition: Vector2D.h:73
Belle2::TrackFindingCDC::PerigeeCircle::fromCenterAndRadius
static PerigeeCircle fromCenterAndRadius(const Vector2D &center, double absRadius, ERotation orientation=ERotation::c_CounterClockwise)
Constructor from center, radius and a optional orientation.
Definition: PerigeeCircle.cc:111
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TEST
TEST(TestgetDetectorRegion, TestgetDetectorRegion)
Test Constructors.
Definition: utilityFunctions.cc:18