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