8 #include <framework/dataobjects/Helix.h>
13 #include <framework/utilities/TestHelpers.h>
15 #include <gtest/gtest.h>
19 using namespace HelixParameterIndex;
22 std::ostream&
operator<<(::std::ostream& output,
const TVector3& tVector3)
26 << tVector3.X() <<
", "
27 << tVector3.Y() <<
", "
28 << tVector3.Z() <<
")";
42 bool d0Near = fabs(expected.getD0() - actual.getD0()) < tolerance;
43 bool phi0Near =
angleNear(expected.getPhi0(), actual.getPhi0(), tolerance);
44 bool omegaNear = fabs(expected.getOmega() - actual.getOmega()) < tolerance;
45 bool z0Near = fabs(expected.getZ0() - actual.getZ0()) < tolerance;
46 bool tanLambdaNear = fabs(expected.getTanLambda() - actual.getTanLambda()) < tolerance;
48 return d0Near and phi0Near and omegaNear and z0Near and tanLambdaNear;
53 Belle2::Helix helixFromCenter(
const TVector3& center,
const float& radius,
const float& tanLambda)
55 double omega = 1 / radius;
56 double phi0 = center.Phi() + copysign(M_PI / 2.0, radius);
57 double d0 = copysign(center.Perp(), radius) - radius;
58 double z0 = center.Z();
64 vector<float> linspace(
const float& start,
const float& end,
const int n)
66 std::vector<float> result(n);
70 for (
int i = 1; i < n - 1; ++i) {
71 float start_weight = (float)(n - 1 - i) / (n - 1);
72 float end_weight = 1 - start_weight;
73 result[i] = start * start_weight + end * end_weight;
80 class HelixTest :
public ::testing::Test {
84 double absError = 1e-6;
85 double nominalBz = 1.5;
87 std::vector<float> omegas { -1, 0, 1};
89 std::vector<float> phi0s = linspace(-M_PI, M_PI, 11);
90 std::vector<float> d0s { -0.5, -0.2, 0, 0.2, 0.5};
92 std::vector<float> chis = linspace(-5 * M_PI / 6, 5 * M_PI / 6, 11);
94 std::vector<TVector3> bys = {
95 TVector3(-2.0, 0.5, 0.0),
96 TVector3(-1.0, 0.5, 0.0),
97 TVector3(0.0, 0.5, 0.0),
98 TVector3(1.0, 0.5, 0.0),
99 TVector3(2.0, 0.5, 0.0),
101 TVector3(-2.0, 0.0, 0.0),
102 TVector3(-1.0, 0.0, 0.0),
103 TVector3(0.0, 0.0, 0.0),
104 TVector3(1.0, 0.0, 0.0),
105 TVector3(2.0, 0.0, 0.0),
107 TVector3(-2.0, -1.0, 0.0),
108 TVector3(-1.0, -1.0, 0.0),
109 TVector3(0.0, -1.0, 0.0),
110 TVector3(1.0, -1.0, 0.0),
111 TVector3(2.0, -1.0, 0.0),
117 TEST_F(HelixTest, Getters)
120 unsigned int nCases = 1;
121 double bField = nominalBz;
123 for (
unsigned int i = 0; i < nCases; ++i) {
125 short int charge = generator.Uniform(-1, 1) > 0 ? 1 : -1;
128 TVector2 d(generator.Uniform(-1, 1), generator.Uniform(-1, 1));
129 TVector2 pt(generator.Uniform(-1, 1), generator.Uniform(-1, 1));
130 d.Set(d.X(), -d.X() * pt.Px() / pt.Py());
133 TVector3 position(d.X(), d.Y(), generator.Uniform(-1, 1));
134 TVector3 momentum(pt.Px(), pt.Py(), generator.Uniform(-1, 1));
137 Helix helix(position, momentum, charge, bField);
140 EXPECT_ALL_NEAR(position, helix.getPerigee(), absError);
141 EXPECT_ALL_NEAR(momentum, helix.getMomentum(bField), absError);
144 EXPECT_NEAR(momentum.Perp(), helix.getTransverseMomentum(bField), absError);
147 EXPECT_NEAR(charge / momentum.Perp(), helix.getKappa(bField), absError);
151 EXPECT_NEAR(position.Perp(), fabs(helix.getD0()), absError);
154 EXPECT_SAME_SIGN(position.Cross(momentum).Z(), helix.getD0());
157 EXPECT_NEAR(momentum.Phi(), helix.getPhi0(), absError);
160 EXPECT_NEAR(position.Z(), helix.getZ0(), absError);
163 EXPECT_NEAR(1 / tan(momentum.Theta()), helix.getTanLambda(), absError);
166 EXPECT_NEAR(1 / tan(momentum.Theta()), helix.getCotTheta(), absError);
169 EXPECT_EQ(charge, helix.getChargeSign());
174 TEST_F(HelixTest, SignOfD0)
178 const TVector3 position(1, 0, 0);
179 const TVector3 momentum(0, 1, 0);
180 const TVector3 oppositeMomentum(0, -1, 0);
182 const float bField = nominalBz;
184 Helix helix(position, momentum, charge, bField);
185 EXPECT_NEAR(1, helix.getD0(), absError);
188 Helix helix2(position, momentum, -charge, bField);
189 EXPECT_NEAR(1, helix2.getD0(), absError);
192 Helix oppositeMomentumHelix(position, oppositeMomentum, charge, bField);
193 EXPECT_NEAR(-1, oppositeMomentumHelix.getD0(), absError);
195 Helix oppositeMomentumHelix2(position, oppositeMomentum, -charge, bField);
196 EXPECT_NEAR(-1, oppositeMomentumHelix2.getD0(), absError);
208 TVector3 center(0.0, -2.0, 0.0);
213 Helix helix = helixFromCenter(center, radius, tanLambda);
215 TVector3 actualCenter = helix.getPerigee() * ((1 / helix.getOmega() + helix.getD0()) / helix.getD0());
216 EXPECT_NEAR(center.X(), actualCenter.X(), absError);
217 EXPECT_NEAR(center.Y(), actualCenter.Y(), absError);
220 TEST_F(HelixTest, Explicit)
228 TVector3 center(0.0, -2.0, 0.0);
233 Helix helix = helixFromCenter(center, radius, tanLambda);
234 EXPECT_NEAR(-1, helix.getD0(), absError);
235 EXPECT_ANGLE_NEAR(-M_PI, helix.getPhi0(), absError);
236 EXPECT_NEAR(-1, helix.getOmega(), absError);
241 float arcLength2D = 0;
242 TVector3 position = helix.getPositionAtArcLength2D(arcLength2D);
243 TVector3 tangential = helix.getUnitTangentialAtArcLength2D(arcLength2D);
245 EXPECT_ALL_NEAR(TVector3(0.0, -1.0, 0.0), position, absError);
246 EXPECT_ANGLE_NEAR(-M_PI, tangential.Phi(), absError);
250 float arcLength2D = M_PI / 2;
251 TVector3 position = helix.getPositionAtArcLength2D(arcLength2D);
252 TVector3 tangential = helix.getUnitTangentialAtArcLength2D(arcLength2D);
253 EXPECT_ALL_NEAR(TVector3(-1.0, -2.0, 0.0), position, absError);
254 EXPECT_ANGLE_NEAR(-M_PI / 2, tangential.Phi(), absError);
258 float arcLength2D = M_PI;
259 TVector3 position = helix.getPositionAtArcLength2D(arcLength2D);
260 TVector3 tangential = helix.getUnitTangentialAtArcLength2D(arcLength2D);
261 EXPECT_ALL_NEAR(TVector3(0.0, -3.0, 0.0), position, absError);
262 EXPECT_ANGLE_NEAR(0, tangential.Phi(), absError);
266 float arcLength2D = 3 * M_PI / 2 ;
267 TVector3 position = helix.getPositionAtArcLength2D(arcLength2D);
268 TVector3 tangential = helix.getUnitTangentialAtArcLength2D(arcLength2D);
269 EXPECT_ALL_NEAR(TVector3(1.0, -2.0, 0.0), position, absError);
270 EXPECT_ANGLE_NEAR(M_PI / 2, tangential.Phi(), absError);
274 TEST_F(HelixTest, Tangential)
279 for (
const float d0 : d0s) {
280 for (
const float phi0 : phi0s) {
281 for (
const float omega : omegas) {
283 Helix helix(d0, phi0, omega, z0, tanLambda);
284 TEST_CONTEXT(
"Failed for " << helix);
286 TVector3 tangentialAtPerigee = helix.getUnitTangentialAtArcLength2D(0.0);
288 EXPECT_ANGLE_NEAR(phi0, tangentialAtPerigee.Phi(), absError);
289 EXPECT_FLOAT_EQ(1.0, tangentialAtPerigee.Mag());
290 EXPECT_FLOAT_EQ(tanLambda, 1 / tan(tangentialAtPerigee.Theta()));
292 for (
const float chi : chis) {
296 float arcLength2D = chi;
299 TVector3 tangential = helix.getUnitTangentialAtArcLength2D(arcLength2D);
300 EXPECT_ALL_NEAR(tangentialAtPerigee, tangential, absError);
303 float arcLength2D = -chi / omega;
304 TVector3 tangential = helix.getUnitTangentialAtArcLength2D(arcLength2D);
306 float actualChi = tangential.DeltaPhi(tangentialAtPerigee);
307 EXPECT_ANGLE_NEAR(chi, actualChi, absError);
308 EXPECT_FLOAT_EQ(tangentialAtPerigee.Theta(), tangential.Theta());
309 EXPECT_FLOAT_EQ(1, tangential.Mag());
320 TEST_F(HelixTest, MomentumExtrapolation)
323 float tanLambda = -2;
325 for (
const float d0 : d0s) {
326 for (
const float phi0 : phi0s) {
327 for (
const float omega : omegas) {
330 Helix helix(d0, phi0, omega, z0, tanLambda);
331 TVector3 momentumAtPerigee = helix.getMomentum(nominalBz);
332 for (
const float chi : chis) {
334 float arcLength2D = -chi / omega;
335 TVector3 extrapolatedMomentum = helix.getMomentumAtArcLength2D(arcLength2D, nominalBz);
337 float actualChi = extrapolatedMomentum.DeltaPhi(momentumAtPerigee);
338 EXPECT_ANGLE_NEAR(chi, actualChi, absError);
339 EXPECT_FLOAT_EQ(momentumAtPerigee.Theta(), extrapolatedMomentum.Theta());
340 EXPECT_FLOAT_EQ(momentumAtPerigee.Mag(), extrapolatedMomentum.Mag());
350 TEST_F(HelixTest, Extrapolation)
357 for (
const float d0 : d0s) {
358 for (
const float phi0 : phi0s) {
359 for (
const float omega : omegas) {
361 Helix helix(d0, phi0, omega, z0, tanLambda);
362 TVector3 perigee = helix.getPerigee();
364 TVector3 tangentialAtPerigee = helix.getUnitTangentialAtArcLength2D(0.0);
365 TEST_CONTEXT(
"Failed for " << helix);
369 for (
const float chi : chis) {
370 TEST_CONTEXT(
"Failed for chi = " << chi);
374 float expectedArcLength2D = omega != 0 ? -chi / omega : chi;
375 TVector3 pointOnHelix = helix.getPositionAtArcLength2D(expectedArcLength2D);
377 float cylindricalR = pointOnHelix.Perp();
378 float arcLength2D = helix.getArcLength2DAtCylindricalR(cylindricalR);
381 EXPECT_NEAR(fabs(expectedArcLength2D), arcLength2D, absError);
384 TVector3 secantVector = pointOnHelix - perigee;
386 if (expectedArcLength2D == 0) {
387 EXPECT_NEAR(0, secantVector.Mag(), absError);
389 TVector2 secantVectorXY = secantVector.XYvector();
391 TVector2 tangentialXY = tangentialAtPerigee.XYvector();
392 float coalignment = secantVectorXY * tangentialXY ;
394 bool extrapolationIsForward = coalignment > 0;
395 bool expectedIsForward = expectedArcLength2D > 0;
396 EXPECT_EQ(expectedIsForward, extrapolationIsForward);
405 TEST_F(HelixTest, ExtrapolationToNormalPlane)
408 TVector3 center(0.0, 2.0, 0.0);
412 Helix helix = helixFromCenter(center, radius, tanLambda);
419 double arcLength2D = helix.getArcLength2DAtNormalPlane(x, y, nx, ny);
420 EXPECT_NEAR(-M_PI / 2, arcLength2D, absError);
424 TVector3 center(0.0, 2.0, 0.0);
428 Helix helix = helixFromCenter(center, radius, tanLambda);
435 double arcLength2D = helix.getArcLength2DAtNormalPlane(x, y, nx, ny);
436 EXPECT_NEAR(M_PI / 2, arcLength2D, absError);
440 TVector3 center(0.0, 2.0, 0.0);
444 Helix helix = helixFromCenter(center, radius, tanLambda);
451 double arcLength2D = helix.getArcLength2DAtNormalPlane(x, y, nx, ny);
452 EXPECT_NEAR(M_PI / 2, arcLength2D, absError);
456 TVector3 center(0.0, 2.0, 0.0);
460 Helix helix = helixFromCenter(center, radius, tanLambda);
467 double arcLength2D = helix.getArcLength2DAtNormalPlane(x, y, nx, ny);
468 EXPECT_NEAR(-M_PI / 2, arcLength2D, absError);
475 TEST_F(HelixTest, PerigeeExtrapolateRoundTrip)
478 float tanLambda = -2;
480 for (
const float d0 : d0s) {
481 for (
const float phi0 : phi0s) {
482 for (
const float omega : omegas) {
486 Helix expectedHelix(d0, phi0, omega, z0, tanLambda);
488 for (
const float chi : chis) {
489 float arcLength2D = -chi / omega;
490 TVector3 position = expectedHelix.getPositionAtArcLength2D(arcLength2D);
491 TVector3 momentum = expectedHelix.getMomentumAtArcLength2D(arcLength2D, nominalBz);
492 int chargeSign = expectedHelix.getChargeSign();
494 EXPECT_NEAR(tanLambda, 1 / tan(momentum.Theta()), absError);
495 EXPECT_ANGLE_NEAR(phi0 + chi, momentum.Phi(), absError);
496 EXPECT_NEAR(z0 + tanLambda * arcLength2D, position.Z(), absError);
499 Helix helix(position, momentum, chargeSign, nominalBz);
501 EXPECT_NEAR(expectedHelix.getOmega(), helix.getOmega(), absError);
502 EXPECT_ANGLE_NEAR(expectedHelix.getPhi0(), helix.getPhi0(), absError);
503 EXPECT_NEAR(expectedHelix.getD0(), helix.getD0(), absError);
504 EXPECT_NEAR(expectedHelix.getTanLambda(), helix.getTanLambda(), absError);
505 EXPECT_NEAR(expectedHelix.getZ0(), helix.getZ0(), absError);
599 TEST_F(HelixTest, PassiveMoveExplicit)
601 TVector3 center(0.0, 1.0, 0.0);
605 Helix helix = helixFromCenter(center, radius, tanLambda);
607 ASSERT_NEAR(0, helix.getD0(), absError);
608 ASSERT_ANGLE_NEAR(0, helix.getPhi0(), absError);
609 ASSERT_NEAR(-1, helix.getOmega(), absError);
612 Helix expectedHelix(helix);
616 TVector3 by(1.0, 1.0, 0.0);
618 float arcLength2D = helix.passiveMoveBy(by);
622 ASSERT_NEAR(M_PI / 2, arcLength2D, absError);
624 ASSERT_NEAR(0, helix.getD0(), absError);
625 ASSERT_ANGLE_NEAR(M_PI / 2, helix.getPhi0(), absError);
626 ASSERT_NEAR(-1, helix.getOmega(), absError);
628 ASSERT_NEAR(3 * M_PI / 2, helix.getZ0(), absError);
629 ASSERT_NEAR(3, helix.getTanLambda(), absError);
632 float arcLength2DBackward = helix.passiveMoveBy(-by);
634 ASSERT_NEAR(arcLength2D, -arcLength2DBackward, absError);
635 ASSERT_ALL_NEAR(expectedHelix, helix, absError);
639 TEST_F(HelixTest, PassiveMove)
644 for (
const float phi0 : phi0s) {
645 for (
const float omega : omegas) {
646 for (
const float d0 : d0s) {
647 for (
const float chi : chis) {
648 for (
const float newD0 : d0s) {
649 Helix helix(d0, phi0, omega, z0, tanLambda);
650 TEST_CONTEXT(
"Failed for " << helix);
654 float expectedArcLength2D = omega == 0 ? chi : -chi / omega;
655 TVector3 positionOnHelix = helix.getPositionAtArcLength2D(expectedArcLength2D);
656 TVector3 tangentialToHelix = helix.getUnitTangentialAtArcLength2D(expectedArcLength2D);
658 TVector3 perpendicularToHelix = tangentialToHelix;
659 perpendicularToHelix.RotateZ(M_PI / 2.0);
661 perpendicularToHelix *= 1 / perpendicularToHelix.Perp();
663 TVector3 displacementFromHelix = -perpendicularToHelix * newD0;
664 TVector3 testPosition = positionOnHelix + displacementFromHelix;
666 TVector3 expectedPerigee = -displacementFromHelix;
668 TEST_CONTEXT(
"Failed for chi " << chi);
669 TEST_CONTEXT(
"Failed for position on helix " << positionOnHelix);
670 TEST_CONTEXT(
"Failed for tangential to helix " << tangentialToHelix);
671 TEST_CONTEXT(
"Failed for perpendicular to helix " << perpendicularToHelix);
672 TEST_CONTEXT(
"Failed for test position " << testPosition);
674 float arcLength2D = helix.passiveMoveBy(testPosition);
676 ASSERT_NEAR(expectedArcLength2D, arcLength2D, absError);
678 ASSERT_ALL_NEAR(expectedPerigee, helix.getPerigee(), absError);
687 TEST_F(HelixTest, calcPassiveMoveByJacobian_identity)
689 TVector3 center(0.0, 1.0, 0.0);
693 Helix helix = helixFromCenter(center, radius, tanLambda);
695 TMatrixD noMoveJacobian = helix.calcPassiveMoveByJacobian(TVector3(0.0, 0.0, 0.0));
697 EXPECT_NEAR(1.0, noMoveJacobian(0, 0), 1e-7);
698 EXPECT_NEAR(0.0, noMoveJacobian(0, 1), 1e-7);
699 EXPECT_NEAR(0.0, noMoveJacobian(0, 2), 1e-7);
701 EXPECT_NEAR(0.0, noMoveJacobian(1, 0), 1e-7);
702 EXPECT_NEAR(1.0, noMoveJacobian(1, 1), 1e-7);
703 EXPECT_NEAR(0.0, noMoveJacobian(1, 2), 1e-7);
705 EXPECT_NEAR(0.0, noMoveJacobian(2, 0), 1e-7);
706 EXPECT_NEAR(0.0, noMoveJacobian(2, 1), 1e-7);
707 EXPECT_NEAR(1.0, noMoveJacobian(2, 2), 1e-7);
710 TEST_F(HelixTest, calcPassiveMoveByJacobian_orthogonalToPhi0)
712 TVector3 center(0.0, 1.0, 0.0);
716 Helix helix = helixFromCenter(center, radius, tanLambda);
718 TMatrixD moveByOneJacobian = helix.calcPassiveMoveByJacobian(TVector3(0.0, -1.0, 0.0));
720 EXPECT_NEAR(1.0, moveByOneJacobian(iD0, iD0), 1e-7);
721 EXPECT_NEAR(0.0, moveByOneJacobian(iD0, iPhi0), 1e-7);
722 EXPECT_NEAR(0.0, moveByOneJacobian(iD0, iOmega), 1e-7);
724 EXPECT_NEAR(0.0, moveByOneJacobian(iPhi0, iD0), 1e-7);
725 EXPECT_NEAR(1.0 / 2.0, moveByOneJacobian(iPhi0, iPhi0), 1e-7);
726 EXPECT_NEAR(0.0, moveByOneJacobian(iPhi0, iOmega), 1e-7);
728 EXPECT_NEAR(0.0, moveByOneJacobian(iOmega, iD0), 1e-7);
729 EXPECT_NEAR(0.0, moveByOneJacobian(iOmega, iPhi0), 1e-7);
730 EXPECT_NEAR(1.0, moveByOneJacobian(iOmega, iOmega), 1e-7);
734 TEST_F(HelixTest, calcPassiveMoveByJacobian_parallelToPhi0_compare_opposite_transformation)
736 TVector3 center(0.0, 1.0, 0.0);
740 Helix helix = helixFromCenter(center, radius, tanLambda);
742 TMatrixD moveByPlusTwoXJacobian = helix.calcPassiveMoveByJacobian(TVector3(2.0, 0.0, 0.0));
743 TMatrixD moveByMinusTwoXJacobian = helix.calcPassiveMoveByJacobian(TVector3(-2.0, 0.0, 0.0));
745 EXPECT_NEAR(1.0, moveByPlusTwoXJacobian(iOmega, iOmega), 1e-7);
746 EXPECT_NEAR(0.0, moveByPlusTwoXJacobian(iOmega, iPhi0), 1e-7);
747 EXPECT_NEAR(0.0, moveByPlusTwoXJacobian(iOmega, iD0), 1e-7);
749 EXPECT_NEAR(1.0, moveByMinusTwoXJacobian(iOmega, iOmega), 1e-7);
750 EXPECT_NEAR(0.0, moveByMinusTwoXJacobian(iOmega, iPhi0), 1e-7);
751 EXPECT_NEAR(0.0, moveByMinusTwoXJacobian(iOmega, iD0), 1e-7);
754 EXPECT_NEAR(moveByMinusTwoXJacobian(iD0, iOmega), moveByPlusTwoXJacobian(iD0, iOmega), 1e-7);
755 EXPECT_NEAR(moveByMinusTwoXJacobian(iPhi0, iPhi0), moveByPlusTwoXJacobian(iPhi0, iPhi0), 1e-7);
756 EXPECT_NEAR(moveByMinusTwoXJacobian(iD0, iD0), moveByPlusTwoXJacobian(iD0, iD0), 1e-7);
759 EXPECT_NEAR(moveByMinusTwoXJacobian(iD0, iPhi0), -moveByPlusTwoXJacobian(iD0, iPhi0), 1e-7);
760 EXPECT_NEAR(moveByMinusTwoXJacobian(iPhi0, iD0), -moveByPlusTwoXJacobian(iPhi0, iD0), 1e-7);
761 EXPECT_NEAR(moveByMinusTwoXJacobian(iPhi0, iOmega), -moveByPlusTwoXJacobian(iPhi0, iOmega), 1e-7);
764 EXPECT_NEGATIVE(moveByPlusTwoXJacobian(iD0, iPhi0));
765 EXPECT_POSITIVE(moveByPlusTwoXJacobian(iD0, iOmega));
766 EXPECT_POSITIVE(moveByPlusTwoXJacobian(iPhi0, iD0));
767 EXPECT_NEGATIVE(moveByPlusTwoXJacobian(iPhi0, iOmega));
769 EXPECT_NEGATIVE(moveByPlusTwoXJacobian(iD0, iD0) - 1);
770 EXPECT_NEGATIVE(moveByPlusTwoXJacobian(iPhi0, iPhi0) - 1);
773 TEST_F(HelixTest, calcPassiveMoveByJacobian_roundtrip)
775 for (
const TVector3& by : bys) {
776 TVector3 center(0.0, 1.0, 0.0);
780 Helix helix = helixFromCenter(center, radius, tanLambda);
782 TMatrixD jacobian = helix.calcPassiveMoveByJacobian(by);
783 helix.passiveMoveBy(by);
785 TMatrixD reverseJacobian = helix.calcPassiveMoveByJacobian(-by);
787 TMatrixD unitMatrix = reverseJacobian * jacobian;
789 for (
int i = 0; i < 5; ++i) {
790 for (
int j = 0; j < 5; ++j) {
793 EXPECT_NEAR(1, unitMatrix(i, j), 1e-7);
796 EXPECT_NEAR(0, unitMatrix(i, j), 1e-7);
805 TEST_F(HelixTest, calcPassiveMoveByJacobian_parallelToPhi0)
807 TVector3 center(1.0, 0.0, 0.0);
811 Helix helix = helixFromCenter(center, radius, tanLambda);
813 TMatrixD moveByTwoYJacobian = helix.calcPassiveMoveByJacobian(TVector3(0.0, 2.0, 0.0));
816 double deltaParallel = 2;
822 double lambda = 1.0 / (5.0 + 3.0 * sqrt(5.0));
823 double mu = sqrt(5.0) / 10.0;
826 EXPECT_NEAR(1.0, moveByTwoYJacobian(iOmega, iOmega), 1e-7);
827 EXPECT_NEAR(0.0, moveByTwoYJacobian(iOmega, iPhi0), 1e-7);
828 EXPECT_NEAR(0.0, moveByTwoYJacobian(iOmega, iD0), 1e-7);
830 EXPECT_NEAR(2.0 / 5.0, moveByTwoYJacobian(iPhi0, iOmega), 1e-7);
831 EXPECT_NEAR(1.0 / 5.0, moveByTwoYJacobian(iPhi0, iPhi0), 1e-7);
832 EXPECT_NEAR(-2.0 / 5.0, moveByTwoYJacobian(iPhi0, iD0), 1e-7);
834 EXPECT_NEAR(mu * zeta - A * lambda, moveByTwoYJacobian(iD0, iOmega), 1e-7);
835 EXPECT_NEAR(2.0 * mu * u * deltaParallel, moveByTwoYJacobian(iD0, iPhi0), 1e-7);
836 EXPECT_NEAR(2.0 * mu * nu, moveByTwoYJacobian(iD0, iD0), 1e-7);
841 TEST_F(HelixTest, calcPassiveMoveByJacobian_consistency_of_expansion)
843 TVector3 center(0.0, 1.0, 0.0);
847 Helix helix = helixFromCenter(center, radius, tanLambda);
849 for (
const TVector3& by : bys) {
850 TMatrixD jacobian = helix.calcPassiveMoveByJacobian(by);
851 TMatrixD jacobianWithExpansion = helix.calcPassiveMoveByJacobian(by, 10000);
853 EXPECT_NEAR(1.0, jacobian(iOmega, iOmega), 1e-7);
854 EXPECT_NEAR(0.0, jacobian(iOmega, iPhi0), 1e-7);
855 EXPECT_NEAR(0.0, jacobian(iOmega, iD0), 1e-7);
857 EXPECT_NEAR(1.0, jacobianWithExpansion(iOmega, iOmega), 1e-7);
858 EXPECT_NEAR(0.0, jacobianWithExpansion(iOmega, iPhi0), 1e-7);
859 EXPECT_NEAR(0.0, jacobianWithExpansion(iOmega, iD0), 1e-7);
861 EXPECT_NEAR(jacobianWithExpansion(iD0, iD0), jacobian(iD0, iD0), 1e-7);
862 EXPECT_NEAR(jacobianWithExpansion(iD0, iPhi0), jacobian(iD0, iPhi0), 1e-7);
863 EXPECT_NEAR(jacobianWithExpansion(iD0, iOmega), jacobian(iD0, iOmega), 1e-7);
865 EXPECT_NEAR(jacobianWithExpansion(iPhi0, iD0), jacobian(iPhi0, iD0), 1e-7);
866 EXPECT_NEAR(jacobianWithExpansion(iPhi0, iPhi0), jacobian(iPhi0, iPhi0), 1e-7);
867 EXPECT_NEAR(jacobianWithExpansion(iPhi0, iOmega), jacobian(iPhi0, iOmega), 1e-7);
871 TEST_F(HelixTest, realExample)
874 std::vector<double> helixParams(5);
875 helixParams[0] = 3.82384;
876 helixParams[1] = std::remainder(3.575595, 2 * M_PI);
877 helixParams[2] = 0.00530726;
878 helixParams[3] = -0.000317335;
879 helixParams[4] = 1.34536;
881 TVector3 momentum(-0.768755, -0.356297, 1.13994);
882 TVector3 position(-1.60794, 3.46933, -0.000317335);
888 const double bZ = 1.5;
891 EXPECT_NEAR(0.0, momentum.XYvector() * position.XYvector(), 1e-6);
893 Helix helix(helixParams[0], helixParams[1], helixParams[2], helixParams[3], helixParams[4]);
895 EXPECT_ALL_NEAR(momentum, helix.getMomentum(bZ), 1e-5);
896 EXPECT_ALL_NEAR(position, helix.getPerigee(), 1e-5);
900 TEST_F(HelixTest, omegaForUnitMomentum)
902 TVector3 expectedMomentum(1.0, 0.0, 0.0);
903 TVector3 expectedPosition(0.0, 1.0, 0.0);
904 const double expectedCharge = 1;
905 const double bZ = 1.5;
907 Helix helix(expectedPosition, expectedMomentum, expectedCharge, bZ);
909 double expectedOmega = 0.0044968868700000003;
910 EXPECT_ALL_NEAR(expectedOmega, helix.getOmega(), 1e-7);
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
std::ostream & operator<<(std::ostream &output, const Helix &helix)
Output operator for debugging and the generation of unittest error messages.
double charge(int pdgCode)
Returns electric charge of a particle with given pdg code.
Some utilities to help with writing unit tests.
bool angleNear(double expected, double actual, double tolerance)
Predicate checking that two angular values are close to each other modulus a 2 * PI difference.
Abstract base class for different kinds of events.