10 #include <tracking/trackFindingCDC/fitting/KarimakisMethod.h>
12 #include <tracking/trackFindingCDC/fitting/EigenObservationMatrix.h>
13 #include <tracking/trackFindingCDC/fitting/CDCObservations2D.h>
15 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
17 #include <tracking/trackFindingCDC/geometry/UncertainPerigeeCircle.h>
18 #include <tracking/trackFindingCDC/geometry/PerigeeParameters.h>
19 #include <tracking/trackFindingCDC/geometry/Vector2D.h>
24 using namespace TrackFindingCDC;
27 : m_lineConstrained(false)
34 size_t nObservations = observations2D.
size();
36 if (not nObservations)
return;
43 double frontX = observations2D.
getX(0);
44 double frontY = observations2D.
getY(0);
47 double backX = observations2D.
getX(nObservations - 1);
48 double backY = observations2D.
getY(nObservations - 1);
68 constexpr
size_t iW = 0;
69 constexpr
size_t iX = 1;
70 constexpr
size_t iY = 2;
71 constexpr
size_t iR2 = 3;
75 const Eigen::Matrix< double, 4, 1 >& a,
76 const Eigen::Matrix< double, 4, 4 >& c,
77 bool lineConstrained =
false)
80 if (lineConstrained) {
82 q2 = c(iX, iX) - c(iY, iY);
84 q1 = c(iX, iY) * c(iR2, iR2) - c(iX, iR2) * c(iY, iR2);
85 q2 = (c(iX, iX) - c(iY, iY)) * c(iR2, iR2) - c(iX, iR2) * c(iX, iR2) + c(iY, iR2) * c(iY, iR2);
88 double phi = 0.5 * atan2(2. * q1, q2);
90 double sinphi = sin(phi);
91 double cosphi = cos(phi);
94 if (lineConstrained) {
96 I = sinphi * a(iX) - cosphi * a(iY);
99 double kappa = (sinphi * c(iX, iR2) - cosphi * c(iY, iR2)) / c(iR2, iR2);
100 double delta = -kappa * a(iR2) + sinphi * a(iX) - cosphi * a(iY);
101 curv = 2. * kappa / sqrt(1. - 4. * delta * kappa);
102 I = 2. * delta / (1. + sqrt(1. - 4. * delta * kappa));
107 phi += phi > 0 ? -M_PI : M_PI;
108 return UncertainPerigeeCircle(curv, phi, I);
117 double calcChi2Karimaki(
const PerigeeCircle& parameters,
119 const Eigen::Matrix< double, 4, 4 >& c,
120 bool lineConstrained =
false)
123 const Vector2D vecPhi = -parameters.tangential();
125 const double cosphi = vecPhi.x();
126 const double sinphi = vecPhi.y();
128 if (lineConstrained) {
129 double chi2 = sw * (sinphi * sinphi * c(iX, iX) - 2. * sinphi * cosphi * c(iX, iY) + cosphi * cosphi * c(iY, iY));
133 const double rho = parameters.curvature();
134 const double d = parameters.impact();
136 const double u = 1 + d * rho;
137 const double kappa = 0.5 * rho /
u;
139 double chi2 = sw *
u *
u * (sinphi * sinphi * c(iX, iX) - 2. * sinphi * cosphi * c(iX, iY) + cosphi * cosphi * c(iY,
140 iY) - kappa * kappa * c(iR2, iR2));
148 PerigeePrecision calcPrecisionKarimaki(
const PerigeeCircle& parameters,
149 const Eigen::Matrix< double, 4, 4 >& s,
150 bool lineConstrained =
false)
152 PerigeePrecision perigeePrecision;
154 const double curv = parameters.curvature();
155 const double I = parameters.impact();
158 const Vector2D vecPhi = -parameters.tangential();
161 const double cosphi = vecPhi.x();
162 const double sinphi = vecPhi.y();
164 const double ssphi = sinphi * sinphi;
165 const double scphi = sinphi * cosphi;
166 const double ccphi = cosphi * cosphi;
168 const double rho = curv;
171 const double u = 1. + rho * d;
173 using namespace NPerigeeParameterIndices;
174 if (lineConstrained) {
181 perigeePrecision(
c_Phi0,
c_Phi0) = ccphi * s(iX, iX) + 2. * scphi * s(iX, iY) + ssphi * s(iY, iY);
182 perigeePrecision(
c_Phi0,
c_I) = -(cosphi * s(iX) + sinphi * s(iY));
184 perigeePrecision(
c_I,
c_I) = s(iW);
187 double sa = sinphi * s(iX) - cosphi * s(iY);
188 double sb = cosphi * s(iX) + sinphi * s(iY);
189 double sc = (ssphi - ccphi) * s(iX, iY) + scphi * (s(iX, iX) - s(iY, iY));
191 double sd = sinphi * s(iX, iR2) - cosphi * s(iY, iR2);
193 double saa = ssphi * s(iX, iX) - 2. * scphi * s(iX, iY) + ccphi * s(iY, iY);
196 double se = cosphi * s(iX, iR2) + sinphi * s(iY, iR2);
197 double sbb = ccphi * s(iX, iX) + 2. * scphi * s(iX, iY) + ssphi * s(iY, iY);
199 perigeePrecision(
c_Curv,
c_Curv) = 0.25 * s(iR2, iR2) - d * (sd - d * (saa + 0.5 * s(iR2) - d * (sa - 0.25 * d * s(iW))));
200 perigeePrecision(
c_Curv,
c_Phi0) = -
u * (0.5 * se - d * (sc - 0.5 * d * sb));
204 perigeePrecision(
c_Curv,
c_I) = rho * (-0.5 * sd + d * saa) + 0.5 * u * s(iR2) - 0.5 * d * ((2 *
u + rho * d) * sa - u * d * s(iW));
206 perigeePrecision(
c_Phi0,
c_I) =
u * (rho * sc -
u * sb);
208 perigeePrecision(
c_I,
c_I) = rho * (rho * saa - 2 *
u * sa) + u * u * s(iW);
210 return perigeePrecision;
219 Eigen::Matrix< double, 4, 4> sNoL = getWXYRSumMatrix(observations2D);
222 Eigen::Matrix<double, 4, 4> aNoL = sNoL / sNoL(iW);
225 Eigen::Matrix<double, 4, 1> meansNoL = aNoL.row(iW);
228 Eigen::Matrix<double, 4, 4> cNoL = aNoL - meansNoL * meansNoL.transpose();
231 size_t ndf = observations2D.
size() - 2;
239 double chi2 = calcChi2Karimaki(resultCircle, sNoL(iW), cNoL);