9#include <framework/dataobjects/UncertainHelix.h>
11#include <framework/utilities/TestHelpers.h>
12#include <gtest/gtest.h>
19 TEST(UncertainHelixTest, CartesianCovarianceRoundtripWithPerigeeOnOrigin)
21 ROOT::Math::XYZVector expectedMomentum(1.0, 0.0, 0.0);
22 ROOT::Math::XYZVector expectedPosition(0.0, 0.0, 0.0);
23 const double expectedCharge = -1;
25 const double pValue = 0.5;
27 TMatrixDSym expectedCov6(6);
29 expectedCov6(0, 0) = 0;
30 expectedCov6(1, 1) = 2;
31 expectedCov6(2, 2) = 3;
32 expectedCov6(3, 3) = 4;
33 expectedCov6(4, 4) = 5;
34 expectedCov6(5, 5) = 6;
43 const ROOT::Math::XYZVector position = uncertainHelix.getPerigee();
44 const ROOT::Math::XYZVector momentum = uncertainHelix.getMomentum(bZ);
45 const double charge = uncertainHelix.getChargeSign();
46 const TMatrixDSym cov6 = uncertainHelix.getCartesianCovariance(bZ);
48 EXPECT_NEAR(expectedPosition.X(), position.X(), 1e-7);
49 EXPECT_NEAR(expectedPosition.Y(), position.Y(), 1e-7);
50 EXPECT_NEAR(expectedPosition.Z(), position.Z(), 1e-7);
52 EXPECT_NEAR(expectedMomentum.X(), momentum.X(), 1e-7);
53 EXPECT_NEAR(expectedMomentum.Y(), momentum.Y(), 1e-7);
54 EXPECT_NEAR(expectedMomentum.Z(), momentum.Z(), 1e-7);
56 EXPECT_EQ(expectedCharge, charge);
58 for (
int i = 0; i < 6; ++i) {
59 for (
int j = 0; j < 6; ++j) {
60 EXPECT_NEAR(expectedCov6(i, j), cov6(i, j), 1e-7);
66 TEST(UncertainHelixTest, CartesianCovarianceRoundtripAtPerigeeBesidesOrigin)
68 ROOT::Math::XYZVector expectedMomentum(1.0, 0.0, 0.0);
69 ROOT::Math::XYZVector expectedPosition(0.0, 1.0, 0.0);
70 const double expectedCharge = -1;
72 const double pValue = 0.5;
74 TMatrixDSym expectedCov6(6);
76 expectedCov6(0, 0) = 0;
77 for (
int i = 1; i < 6; ++i) {
78 for (
int j = 1; j < 6; ++j) {
80 expectedCov6(i, j) = 1;
84 expectedCov6(1, 1) = 2;
85 expectedCov6(2, 2) = 3;
86 expectedCov6(3, 3) = 4;
87 expectedCov6(4, 4) = 5;
88 expectedCov6(5, 5) = 6;
97 const ROOT::Math::XYZVector position = uncertainHelix.getPerigee();
98 const ROOT::Math::XYZVector momentum = uncertainHelix.getMomentum(bZ);
99 const double charge = uncertainHelix.getChargeSign();
100 const TMatrixDSym cov6 = uncertainHelix.getCartesianCovariance(bZ);
102 EXPECT_NEAR(expectedPosition.X(), position.X(), 1e-7);
103 EXPECT_NEAR(expectedPosition.Y(), position.Y(), 1e-7);
104 EXPECT_NEAR(expectedPosition.Z(), position.Z(), 1e-7);
106 EXPECT_NEAR(expectedMomentum.X(), momentum.X(), 1e-7);
107 EXPECT_NEAR(expectedMomentum.Y(), momentum.Y(), 1e-7);
108 EXPECT_NEAR(expectedMomentum.Z(), momentum.Z(), 1e-7);
110 EXPECT_EQ(expectedCharge, charge);
113 TVectorD nullSpace(6);
114 const double factor =
115 (expectedPosition.X() * expectedMomentum.Y() - expectedPosition.Y() * expectedMomentum.X()) / expectedMomentum.Perp2();
116 nullSpace[0] = expectedMomentum.X();
117 nullSpace[1] = expectedMomentum.Y();
119 nullSpace[3] = factor * expectedMomentum.Y();
120 nullSpace[4] = - factor * expectedMomentum.X();
123 TVectorD nullVector = cov6 * nullSpace;
124 for (
int j = 0; j < 6; ++j) {
125 EXPECT_NEAR(0, nullVector(j), 1e-7);
137 const TMatrixDSym cov6_2 = uncertainHelix2.getCartesianCovariance(bZ);
138 for (
int i = 0; i < 6; ++i) {
139 for (
int j = 0; j < 6; ++j) {
140 EXPECT_NEAR(cov6(i, j), cov6_2(i, j), 1e-7);
145 TEST(UncertainHelixTest, CartesianCovarianceRoundtripAtPerigeeBesidesOriginIndividualCoordinates)
147 ROOT::Math::XYZVector expectedMomentum(1.0, 0.0, 0.0);
148 ROOT::Math::XYZVector expectedPosition(0.0, 1.0, 0.0);
149 const double expectedCharge = -1;
151 const double pValue = 0.5;
153 for (
int i = 1; i < 6; ++i) {
155 TMatrixDSym expectedCov6(6);
157 expectedCov6(0, 0) = 0;
159 expectedCov6(i, i) = 1;
168 const ROOT::Math::XYZVector position = uncertainHelix.getPerigee();
169 const ROOT::Math::XYZVector momentum = uncertainHelix.getMomentum(bZ);
170 const double charge = uncertainHelix.getChargeSign();
171 const TMatrixDSym cov6 = uncertainHelix.getCartesianCovariance(bZ);
173 EXPECT_NEAR(expectedPosition.X(), position.X(), 1e-7);
174 EXPECT_NEAR(expectedPosition.Y(), position.Y(), 1e-7);
175 EXPECT_NEAR(expectedPosition.Z(), position.Z(), 1e-7);
177 EXPECT_NEAR(expectedMomentum.X(), momentum.X(), 1e-7);
178 EXPECT_NEAR(expectedMomentum.Y(), momentum.Y(), 1e-7);
179 EXPECT_NEAR(expectedMomentum.Z(), momentum.Z(), 1e-7);
181 EXPECT_EQ(expectedCharge, charge);
184 TVectorD nullSpace(6);
185 const double factor =
186 (expectedPosition.X() * expectedMomentum.Y() - expectedPosition.Y() * expectedMomentum.X()) / expectedMomentum.Perp2();
187 nullSpace[0] = expectedMomentum.X();
188 nullSpace[1] = expectedMomentum.Y();
190 nullSpace[3] = factor * expectedMomentum.Y();
191 nullSpace[4] = - factor * expectedMomentum.X();
194 TVectorD nullVector = cov6 * nullSpace;
195 for (
int j = 0; j < 6; ++j) {
196 EXPECT_NEAR(0, nullVector(j), 1e-7);
208 const TMatrixDSym cov6_2 = uncertainHelix2.getCartesianCovariance(bZ);
209 for (
int j = 0; j < 6; ++j) {
210 for (
int k = 0; k < 6; ++k) {
211 EXPECT_NEAR(cov6(j, k), cov6_2(j, k), 1e-7);
217 TEST(UncertainHelixTest, PerigeeCovarianceRoundtripAtPerigeeBesidesOriginIndividualCoordinates)
221 double omega = -0.005;
222 double tanLambda = 1;
226 const double pValue = 0.5;
228 for (
int i = 0; i < 5; ++i) {
230 TMatrixDSym expectedCov5(5);
232 expectedCov5(i, i) = 1;
234 UncertainHelix uncertainHelix(d0, phi0, omega, z0, tanLambda, expectedCov5, pValue);
236 const ROOT::Math::XYZVector position = uncertainHelix.getPerigee();
237 const ROOT::Math::XYZVector momentum = uncertainHelix.getMomentum(bZ);
238 const double charge = uncertainHelix.getChargeSign();
239 const TMatrixDSym cov6 = uncertainHelix.getCartesianCovariance(bZ);
248 EXPECT_NEAR(d0, uncertainHelix2.getD0(), 1e-7);
249 EXPECT_NEAR(phi0, uncertainHelix2.getPhi0(), 1e-7);
250 EXPECT_NEAR(omega, uncertainHelix2.getOmega(), 1e-7);
252 EXPECT_NEAR(z0, uncertainHelix2.getZ0(), 1e-7);
253 EXPECT_NEAR(tanLambda, uncertainHelix2.getTanLambda(), 1e-7);
255 const TMatrixDSym& cov5 = uncertainHelix2.getCovariance();
256 EXPECT_EQ(-1, charge);
258 for (
int j = 0; j < 5; ++j) {
259 for (
int k = 0; k < 5; ++k) {
260 EXPECT_NEAR(expectedCov5(j, k), cov5(j, k), 1e-7);
266 TEST(UncertainHelixTest, RealPerigeeCovarianceRoundTrip)
268 const double bZ = 1.5;
269 const double pValue = 0.5;
271 std::vector<float> helixParams(5);
272 std::vector<float> helixCovariance(15);
274 helixParams[0] = 3.82384;
275 helixParams[1] = std::remainder(3.57559, 2 * M_PI);
276 helixParams[2] = 0.00530726;
277 helixParams[3] = -0.000317335;
278 helixParams[4] = 1.34536;
280 helixCovariance[0] = 0.000648818;
281 helixCovariance[1] = 6.357e-05;
282 helixCovariance[2] = 2.04344e-07;
283 helixCovariance[3] = -0.00101879;
284 helixCovariance[4] = 2.29407e-05;
286 helixCovariance[5] = 1.02934e-05;
287 helixCovariance[6] = 1.39609e-08;
288 helixCovariance[7] = 9.57685e-07;
289 helixCovariance[8] = 1.19863e-06;
291 helixCovariance[9] = 4.96093e-10;
292 helixCovariance[10] = -8.41612e-07;
293 helixCovariance[11] = 6.50684e-08;
295 helixCovariance[12] = 0.0317385;
296 helixCovariance[13] = -0.00065476;
298 helixCovariance[14] = 3.6521e-05;
300 TMatrixDSym expectedCov5(5);
301 unsigned int counter = 0;
302 for (
unsigned int i = 0; i < 5; ++i) {
303 for (
unsigned int j = i; j < 5; ++j) {
304 expectedCov5(i, j) = expectedCov5(j, i) = helixCovariance[counter];
317 const ROOT::Math::XYZVector position = uncertainHelix.getPerigee();
318 const ROOT::Math::XYZVector momentum = uncertainHelix.getMomentum(bZ);
319 const double charge = uncertainHelix.getChargeSign();
320 const TMatrixDSym cov6 = uncertainHelix.getCartesianCovariance(bZ);
329 EXPECT_NEAR(helixParams[0], uncertainHelix2.getD0(), 1e-7);
330 EXPECT_NEAR(helixParams[1], uncertainHelix2.getPhi0(), 1e-7);
331 EXPECT_NEAR(helixParams[2], uncertainHelix2.getOmega(), 1e-7);
333 EXPECT_NEAR(helixParams[3], uncertainHelix2.getZ0(), 1e-7);
334 EXPECT_NEAR(helixParams[4], uncertainHelix2.getTanLambda(), 1e-7);
336 const TMatrixDSym& cov5 = uncertainHelix2.getCovariance();
337 EXPECT_EQ(1, charge);
339 for (
int i = 0; i < 5; ++i) {
340 for (
int j = 0; j < 5; ++j) {
341 EXPECT_NEAR(expectedCov5(i, j), cov5(i, j), 1e-7);
347 TEST(UncertainHelixTest, Explicit_D0)
351 double omega = -0.005;
352 double tanLambda = 1;
356 const double pValue = 0.5;
358 TMatrixDSym expectedCov5(5);
360 expectedCov5(0, 0) = 1;
362 TMatrixDSym expectedCov6(6);
364 expectedCov6(1, 1) = 1;
366 UncertainHelix uncertainHelix(d0, phi0, omega, z0, tanLambda, expectedCov5, pValue);
368 const TMatrixDSym cov6 = uncertainHelix.getCartesianCovariance(bZ);
370 for (
int i = 0; i < 6; ++i) {
371 for (
int j = 0; j < 6; ++j) {
372 TEST_CONTEXT(
"Failed for index (" << i <<
", " << j <<
")");
373 EXPECT_NEAR(expectedCov6(i, j), cov6(i, j), 1e-7);
378 TEST(UncertainHelixTest, Explicit_Phi0)
382 double omega = -0.006;
383 double tanLambda = 0;
386 const double bZ = 1.5;
387 const double pValue = 0.5;
389 TMatrixDSym expectedCov5(5);
391 expectedCov5(1, 1) = 1;
393 UncertainHelix uncertainHelix(d0, phi0, omega, z0, tanLambda, expectedCov5, pValue);
395 const ROOT::Math::XYZVector position = uncertainHelix.getPerigee();
396 const ROOT::Math::XYZVector momentum = uncertainHelix.getMomentum(bZ);
397 const double charge = uncertainHelix.getChargeSign();
398 const TMatrixDSym cov6 = uncertainHelix.getCartesianCovariance(bZ);
400 double absMom2D = uncertainHelix.getTransverseMomentum(1.5);
402 TMatrixDSym expectedCov6(6);
404 expectedCov6(4, 4) = absMom2D * absMom2D;
406 for (
int i = 0; i < 6; ++i) {
407 for (
int j = 0; j < 6; ++j) {
408 TEST_CONTEXT(
"Failed for index (" << i <<
", " << j <<
")");
409 EXPECT_NEAR(expectedCov6(i, j), cov6(i, j), 1e-7);
420 EXPECT_NEAR(d0, uncertainHelix2.getD0(), 1e-7);
421 EXPECT_NEAR(phi0, uncertainHelix2.getPhi0(), 1e-7);
422 EXPECT_NEAR(omega, uncertainHelix2.getOmega(), 1e-7);
424 EXPECT_NEAR(z0, uncertainHelix2.getZ0(), 1e-7);
425 EXPECT_NEAR(tanLambda, uncertainHelix2.getTanLambda(), 1e-7);
427 const TMatrixDSym& cov5 = uncertainHelix2.getCovariance();
428 EXPECT_EQ(-1, charge);
430 for (
int i = 0; i < 5; ++i) {
431 for (
int j = 0; j < 5; ++j) {
432 TEST_CONTEXT(
"Failed for index (" << i <<
", " << j <<
")");
433 EXPECT_NEAR(expectedCov5(i, j), cov5(i, j), 1e-7);
438 TEST(UncertainHelixTest, MoveInCartesianVersusMoveInPerigeeCoordinates)
441 ROOT::Math::XYZVector moveBy(0.5, -1, 0.5);
445 double omega = -0.005;
446 double tanLambda = 1;
450 const double pValue = 0.5;
452 TMatrixDSym initialCov5(5);
454 for (
int i = 0; i < 5; ++i) {
455 for (
int j = 0; j < 5; ++j) {
456 initialCov5(i, j) = i + j;
460 UncertainHelix uncertainHelix(d0, phi0, omega, z0, tanLambda, initialCov5, pValue);
462 const ROOT::Math::XYZVector position = uncertainHelix.getPerigee();
463 const ROOT::Math::XYZVector momentum = uncertainHelix.getMomentum(bZ);
464 const double charge = uncertainHelix.getChargeSign();
465 const TMatrixDSym cov6 = uncertainHelix.getCartesianCovariance(bZ);
468 const ROOT::Math::XYZVector movedPosition = position - moveBy;
476 const TMatrixDSym& cov5 = movedUncertainHelix.getCovariance();
481 const TMatrixDSym expectedCov5 = expectedMovedUncertainHelix.
getCovariance();
484 EXPECT_NEAR(expectedMovedUncertainHelix.getD0(), movedUncertainHelix.getD0(), 1e-7);
485 EXPECT_NEAR(expectedMovedUncertainHelix.getPhi0(), movedUncertainHelix.getPhi0(), 1e-7);
486 EXPECT_NEAR(expectedMovedUncertainHelix.getOmega(), movedUncertainHelix.getOmega(), 1e-7);
487 EXPECT_NEAR(expectedMovedUncertainHelix.getZ0(), movedUncertainHelix.getZ0(), 1e-7);
488 EXPECT_NEAR(expectedMovedUncertainHelix.getTanLambda(), movedUncertainHelix.getTanLambda(), 1e-7);
490 for (
int i = 0; i < 5; ++i) {
491 for (
int j = 0; j < 5; ++j) {
492 TEST_CONTEXT(
"Failed for index (" << i <<
", " << j <<
")");
493 EXPECT_NEAR(expectedCov5(i, j), cov5(i, j), 1e-7);
This class represents an ideal helix in perigee parameterization including the covariance matrix of t...
double passiveMoveBy(const ROOT::Math::XYZVector &by)
Moves origin of the coordinate system (passive transformation) by the given vector.
const TMatrixDSym & getCovariance() const
Getter for covariance matrix of perigee parameters in matrix form.
double charge(int pdgCode)
Returns electric charge of a particle with given pdg code.
Abstract base class for different kinds of events.