Belle II Software  release-05-01-25
GeneralizedCircle.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/GeneralizedCircle.h>
12 #include <tracking/trackFindingCDC/geometry/Vector2D.h>
13 
14 #include <gtest/gtest.h>
15 
16 using namespace Belle2;
17 using namespace TrackFindingCDC;
18 
19 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_Getters)
20 {
21  float absError = 10e-6;
22 
23  float n0 = 0.0;
24  float n1 = 1.0;
25  float n2 = 0.0;
26  float n3 = 1.0;
27 
28  GeneralizedCircle circle(n0, n1, n2, n3);
29 
30  EXPECT_NEAR(n0, circle.n0(), absError);
31  EXPECT_NEAR(n1, circle.n1(), absError);
32  EXPECT_NEAR(n2, circle.n2(), absError);
33  EXPECT_NEAR(n3, circle.n3(), absError);
34 
35  EXPECT_NEAR(2.0 * n3, circle.curvature(), absError);
36  EXPECT_NEAR(1.0 / (2.0 * n3), circle.radius(), absError);
37 
38  EXPECT_NEAR(M_PI / 2.0, circle.tangentialPhi(), absError);
39 
40  EXPECT_NEAR(0, circle.impact(), absError);
41 }
42 
43 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_orientation)
44 {
45  GeneralizedCircle circle(1.0, 0.0, 0.0, 1.0);
46  EXPECT_EQ(ERotation::c_CounterClockwise, circle.orientation());
47 
48  GeneralizedCircle reversedCircle(1.0, 0.0, 0.0, -1.0);
49  EXPECT_EQ(ERotation::c_Clockwise, reversedCircle.orientation());
50 
51  GeneralizedCircle line(1.0, 0.0, 0.0, 0.0);
52  EXPECT_EQ(ERotation::c_CounterClockwise, line.orientation());
53 
54  GeneralizedCircle reversedLine(1.0, 0.0, 0.0, -0.0);
55  EXPECT_EQ(ERotation::c_Clockwise, reversedLine.orientation());
56 }
57 
58 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_conformalTranform)
59 {
60  Vector2D center(1.0, 0.0);
61  double radius = 1.0;
62  GeneralizedCircle circle = GeneralizedCircle::fromCenterAndRadius(center, radius);
63 
64  // Get two points on the circle to check for the orientation to be correct
65  Vector2D firstPos = circle.atArcLength(1);
66  Vector2D secondPos = circle.atArcLength(2);
67 
68  EXPECT_NEAR(1.0, circle.curvature(), 10e-7);
69  EXPECT_NEAR(-M_PI / 2.0, circle.tangentialPhi(), 10e-7);
70  EXPECT_NEAR(0.0, circle.impact(), 10e-7);
71  EXPECT_NEAR(0.0, circle.distance(firstPos), 10e-7);
72  EXPECT_NEAR(0.0, circle.distance(secondPos), 10e-7);
73 
74  circle.conformalTransform();
75  firstPos.conformalTransform();
76  secondPos.conformalTransform();
77 
78  EXPECT_NEAR(0.0, circle.curvature(), 10e-7);
79  EXPECT_NEAR(M_PI / 2.0, circle.tangentialPhi(), 10e-7);
80  EXPECT_NEAR(-1.0 / 2.0, circle.impact(), 10e-7);
81 
82  double firstConformalArcLength = circle.arcLengthTo(firstPos);
83  double secondConformalArcLength = circle.arcLengthTo(secondPos);
84  EXPECT_TRUE(firstConformalArcLength < secondConformalArcLength);
85  EXPECT_LT(firstConformalArcLength, secondConformalArcLength);
86 
87  EXPECT_NEAR(0.0, circle.distance(firstPos), 10e-7);
88  EXPECT_NEAR(0.0, circle.distance(secondPos), 10e-7);
89 
90  // Another conformal transformation goes back to the original circle
91  GeneralizedCircle conformalCopy = circle.conformalTransformed();
92  EXPECT_NEAR(1.0, conformalCopy.curvature(), 10e-7);
93  EXPECT_NEAR(-M_PI / 2.0, conformalCopy.tangentialPhi(), 10e-7);
94  EXPECT_NEAR(0.0, conformalCopy.impact(), 10e-7);
95 }
96 
97 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_closest)
98 {
99  GeneralizedCircle circle(0.0, -1.0, 0.0, 1.0 / 2.0);
100  Vector2D up(1.0, 2.0);
101  Vector2D far(4.0, 0.0);
102 
103  EXPECT_EQ(Vector2D(1.0, 1.0), circle.closest(up));
104  EXPECT_EQ(Vector2D(2.0, 0.0), circle.closest(far));
105 
106  // This tests for point which is on the circle
107  double smallAngle = M_PI / 100;
108  Vector2D near(1.0 - cos(smallAngle), sin(smallAngle));
109 
110  Vector2D closestOfNear = circle.closest(near);
111  EXPECT_NEAR(near.x(), closestOfNear.x(), 10e-7);
112  EXPECT_NEAR(near.y(), closestOfNear.y(), 10e-7);
113 }
114 
115 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_arcLengthFactor)
116 {
117  GeneralizedCircle circle(0.0, -1.0, 0.0, 1.0 / 2.0);
118  double smallAngle = M_PI / 100;
119  Vector2D near(1.0 - cos(smallAngle), sin(smallAngle));
120 
121  double expectedArcLengthFactor = smallAngle / near.cylindricalR();
122  EXPECT_NEAR(expectedArcLengthFactor, circle.arcLengthFactor(near.cylindricalR()), 10e-7);
123 }
124 
125 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_arcLengthBetween)
126 {
127  GeneralizedCircle circle(0.0, -1.0, 0.0, 1.0 / 2.0);
128  Vector2D origin(0.0, 0.0);
129  Vector2D up(1.0, 2.0);
130  Vector2D down(1.0, -2.0);
131  Vector2D far(4.0, 0.0);
132 
133  double smallAngle = M_PI / 100;
134  Vector2D close(1.0 - cos(smallAngle), sin(smallAngle));
135 
136  EXPECT_NEAR(-M_PI / 2.0, circle.arcLengthBetween(origin, up), 10e-7);
137  EXPECT_NEAR(M_PI / 2.0, circle.arcLengthBetween(origin, down), 10e-7);
138 
139  EXPECT_NEAR(M_PI / 2.0, circle.arcLengthBetween(up, origin), 10e-7);
140  EXPECT_NEAR(-M_PI / 2.0, circle.arcLengthBetween(down, origin), 10e-7);
141 
142  // Sign of the length at the far end is unstable, which is why fabs is taken here
143  EXPECT_NEAR(M_PI, fabs(circle.arcLengthBetween(origin, far)), 10e-7);
144 
145  EXPECT_NEAR(-smallAngle, circle.arcLengthBetween(origin, close), 10e-7);
146 
147  GeneralizedCircle line(0.0, -1.0, 0.0, 0.0);
148  EXPECT_NEAR(-2, line.arcLengthBetween(origin, up), 10e-7);
149  EXPECT_NEAR(2, line.arcLengthBetween(origin, down), 10e-7);
150  EXPECT_NEAR(0, line.arcLengthBetween(origin, far), 10e-7);
151 
152  GeneralizedCircle reverseLine(0.0, 1.0, 0.0, -0.0);
153  EXPECT_NEAR(2, reverseLine.arcLengthBetween(origin, up), 10e-7);
154  EXPECT_NEAR(-2, reverseLine.arcLengthBetween(origin, down), 10e-7);
155  EXPECT_NEAR(0, reverseLine.arcLengthBetween(origin, far), 10e-7);
156 }
157 
158 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_passiveMoveBy)
159 {
160  Vector2D center(4.0, 2.0);
161  double radius = 5.0;
162  GeneralizedCircle circle = GeneralizedCircle::fromCenterAndRadius(center, radius);
163 
164  circle.passiveMoveBy(Vector2D(3.0, 3.0));
165 
166  EXPECT_NEAR(5.0, circle.radius(), 10e-7);
167  EXPECT_NEAR(1.0, circle.center().x(), 10e-7);
168  EXPECT_NEAR(-1.0, circle.center().y(), 10e-7);
169 }
170 
171 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_intersections)
172 {
173 
174  GeneralizedCircle circle = GeneralizedCircle::fromCenterAndRadius(Vector2D(1.0, 1.0), 1);
175  GeneralizedCircle line = GeneralizedCircle(sqrt(2.0), -Vector2D(1.0, 1.0).unit());
176 
177  std::pair<Vector2D, Vector2D> intersections = circle.intersections(line);
178 
179  const Vector2D& intersection1 = intersections.first;
180  const Vector2D& intersection2 = intersections.second;
181 
182  EXPECT_NEAR(1 - sqrt(2.0) / 2.0, intersection1.x(), 10e-7);
183  EXPECT_NEAR(1 + sqrt(2.0) / 2.0, intersection1.y(), 10e-7);
184 
185  EXPECT_NEAR(1 + sqrt(2.0) / 2.0, intersection2.x(), 10e-7);
186  EXPECT_NEAR(1 - sqrt(2.0) / 2.0, intersection2.y(), 10e-7);
187 }
188 
189 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_atArcLength)
190 {
191  double radius = 1;
192  Vector2D center = Vector2D(2.0, 0.0);
193 
194  GeneralizedCircle circle = GeneralizedCircle::fromCenterAndRadius(center, radius);
195 
196  double smallAngle = M_PI / 100;
197  Vector2D near(2.0 - cos(smallAngle), sin(smallAngle));
198 
199  double nearArcLength =
200  -smallAngle * radius; // Minus because of default counterclockwise orientation
201 
202  Vector2D atNear = circle.atArcLength(nearArcLength);
203 
204  EXPECT_NEAR(near.x(), atNear.x(), 10e-7);
205  EXPECT_NEAR(near.y(), atNear.y(), 10e-7);
206 
207  Vector2D down(2.0, -1.0);
208  double downArcLength =
209  +M_PI / 2.0 * radius; // Plus because of default counterclockwise orientation
210 
211  Vector2D atDown = circle.atArcLength(downArcLength);
212 
213  EXPECT_NEAR(down.x(), atDown.x(), 10e-7);
214  EXPECT_NEAR(down.y(), atDown.y(), 10e-7);
215 }
216 
217 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_arcLengthToCylindricalR)
218 {
219  double radius = 1;
220  Vector2D center = Vector2D(2.0, 0.0);
221 
222  GeneralizedCircle circle = GeneralizedCircle::fromCenterAndRadius(center, radius);
223  {
224  double closestArcLength = circle.arcLengthToCylindricalR(1);
225  EXPECT_NEAR(0, closestArcLength, 10e-7);
226 
227  double widestArcLength = circle.arcLengthToCylindricalR(3);
228  EXPECT_NEAR(M_PI, widestArcLength, 10e-7);
229 
230  double halfArcLength = circle.arcLengthToCylindricalR(sqrt(5.0));
231  EXPECT_NEAR(M_PI / 2, halfArcLength, 10e-7);
232 
233  double unreachableHighArcLength = circle.arcLengthToCylindricalR(4);
234  EXPECT_TRUE(std::isnan(unreachableHighArcLength));
235 
236  double unreachableLowArcLength = circle.arcLengthToCylindricalR(0.5);
237  EXPECT_TRUE(std::isnan(unreachableLowArcLength));
238  }
239 
240  GeneralizedCircle reversedCircle = circle.reversed();
241  {
242  double closestArcLength = reversedCircle.arcLengthToCylindricalR(1);
243  EXPECT_NEAR(0, closestArcLength, 10e-7);
244 
245  double widestArcLength = reversedCircle.arcLengthToCylindricalR(3);
246  EXPECT_NEAR(M_PI, widestArcLength, 10e-7);
247 
248  double halfArcLength = reversedCircle.arcLengthToCylindricalR(sqrt(5.0));
249  EXPECT_NEAR(M_PI / 2, halfArcLength, 10e-7);
250 
251  double unreachableHighArcLength = reversedCircle.arcLengthToCylindricalR(4);
252  EXPECT_TRUE(std::isnan(unreachableHighArcLength));
253 
254  double unreachableLowArcLength = reversedCircle.arcLengthToCylindricalR(0.5);
255  EXPECT_TRUE(std::isnan(unreachableLowArcLength));
256  }
257 }
258 
259 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_atCylindricalR)
260 {
261  double radius = 1;
262  Vector2D center = Vector2D(2.0, 0.0);
263  GeneralizedCircle circle = GeneralizedCircle::fromCenterAndRadius(center, radius);
264 
265  std::pair<Vector2D, Vector2D> solutions = circle.atCylindricalR(sqrt(5.0));
266 
267  EXPECT_NEAR(2, solutions.first.x(), 10e-7);
268  EXPECT_NEAR(1, solutions.first.y(), 10e-7);
269 
270  EXPECT_NEAR(2, solutions.second.x(), 10e-7);
271  EXPECT_NEAR(-1, solutions.second.y(), 10e-7);
272 }
273 
274 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_isLine)
275 {
276  double radius = 1;
277  Vector2D center = Vector2D(2.0, 0.0);
278  GeneralizedCircle circle = GeneralizedCircle::fromCenterAndRadius(center, radius);
279 
280  EXPECT_FALSE(circle.isLine());
281 
282  float curvature = 0;
283  float phi0 = M_PI / 2;
284  float impact = -1;
285  GeneralizedCircle line = GeneralizedCircle::fromPerigeeParameters(curvature, phi0, impact);
286 
287  EXPECT_TRUE(line.isLine());
288 }
289 
290 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_isCircle)
291 {
292  double radius = 1;
293  Vector2D center = Vector2D(2.0, 0.0);
294  GeneralizedCircle circle = GeneralizedCircle::fromCenterAndRadius(center, radius);
295 
296  EXPECT_TRUE(circle.isCircle());
297 
298  float curvature = 0;
299  float phi0 = M_PI / 2;
300  float impact = -1;
301  GeneralizedCircle line = GeneralizedCircle::fromPerigeeParameters(curvature, phi0, impact);
302 
303  EXPECT_FALSE(line.isCircle());
304 }
305 
306 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_perigeeConversion)
307 {
308  float curvature = -0.5;
309  float phi0 = M_PI / 2;
310  float impact = -1;
311  GeneralizedCircle circle = GeneralizedCircle::fromPerigeeParameters(curvature, phi0, impact);
312 
313  EXPECT_NEAR(impact, circle.impact(), 10e-7);
314  EXPECT_NEAR(phi0, circle.tangentialPhi(), 10e-7);
315  EXPECT_NEAR(curvature, circle.curvature(), 10e-7);
316 }
317 
318 TEST(TrackFindingCDCTest, geometry_GeneralizedCircle_distance)
319 {
320  float absError = 10e-6;
321 
322  float radius = 1.5;
323  Vector2D center = Vector2D(0.5, 0.0);
324 
325  GeneralizedCircle circle = GeneralizedCircle::fromCenterAndRadius(center, radius);
326 
327  Vector2D testPoint(3, 0);
328 
329  EXPECT_NEAR(1, circle.distance(testPoint), absError);
330  EXPECT_NEAR(1, circle.absDistance(testPoint), absError);
331  // Approximated distance is already quite far of since the circle radius is of the order of the
332  // distance
333  EXPECT_NEAR(1.33333, circle.fastDistance(testPoint), absError);
334 
335  // Now clockwise orientation. All points outside the circle have negative distance
336  circle.reverse();
337 
338  EXPECT_NEAR(-1, circle.distance(testPoint), absError);
339  EXPECT_NEAR(1, circle.absDistance(testPoint), absError);
340  EXPECT_NEAR(-1.33333, circle.fastDistance(testPoint), absError);
341 }
prepareAsicCrosstalkSimDB.e
e
aux.
Definition: prepareAsicCrosstalkSimDB.py:53
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TrackFindingCDC::GeneralizedCircle::fromPerigeeParameters
static GeneralizedCircle fromPerigeeParameters(double curvature, const Vector2D &tangential, double impact)
Constructor of a generalized circle from perigee parameters.
Belle2::TrackFindingCDC::GeneralizedCircle::fromCenterAndRadius
static GeneralizedCircle fromCenterAndRadius(const Vector2D &center, double absRadius, ERotation orientation=ERotation::c_CounterClockwise)
Constructor from center, radius and a optional orientation.
Definition: GeneralizedCircle.cc:69
Belle2::TEST
TEST(TestgetDetectorRegion, TestgetDetectorRegion)
Test Constructors.
Definition: utilityFunctions.cc:18