8#include <tracking/trackFindingCDC/fitting/KarimakisMethod.h>
10#include <tracking/trackFindingCDC/fitting/EigenObservationMatrix.h>
11#include <tracking/trackFindingCDC/fitting/CDCObservations2D.h>
13#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectory2D.h>
15#include <tracking/trackingUtilities/geometry/UncertainPerigeeCircle.h>
16#include <tracking/trackingUtilities/geometry/PerigeeParameters.h>
17#include <tracking/trackingUtilities/geometry/Vector2D.h>
22using namespace TrackFindingCDC;
23using namespace TrackingUtilities;
33 size_t nObservations = observations2D.
size();
35 if (not nObservations)
return;
42 double frontX = observations2D.
getX(0);
43 double frontY = observations2D.
getY(0);
46 double backX = observations2D.
getX(nObservations - 1);
47 double backY = observations2D.
getY(nObservations - 1);
67 constexpr size_t iW = 0;
68 constexpr size_t iX = 1;
69 constexpr size_t iY = 2;
70 constexpr size_t iR2 = 3;
74 const Eigen::Matrix< double, 4, 1 >& a,
75 const Eigen::Matrix< double, 4, 4 >& c,
76 bool lineConstrained =
false)
79 if (lineConstrained) {
81 q2 = c(iX, iX) - c(iY, iY);
83 q1 = c(iX, iY) * c(iR2, iR2) - c(iX, iR2) * c(iY, iR2);
84 q2 = (c(iX, iX) - c(iY, iY)) * c(iR2, iR2) - c(iX, iR2) * c(iX, iR2) + c(iY, iR2) * c(iY, iR2);
87 double phi = 0.5 * atan2(2. * q1, q2);
89 double sinphi = sin(phi);
90 double cosphi = cos(phi);
93 if (lineConstrained) {
95 I = sinphi * a(iX) - cosphi * a(iY);
98 double kappa = (sinphi * c(iX, iR2) - cosphi * c(iY, iR2)) / c(iR2, iR2);
99 double delta = -kappa * a(iR2) + sinphi * a(iX) - cosphi * a(iY);
100 curv = 2. * kappa /
sqrt(1. - 4. * delta * kappa);
101 I = 2. * delta / (1. +
sqrt(1. - 4. * delta * kappa));
106 phi += phi > 0 ? -M_PI : M_PI;
107 return UncertainPerigeeCircle(curv, phi, I);
116 double calcChi2Karimaki(
const PerigeeCircle& parameters,
118 const Eigen::Matrix< double, 4, 4 >& c,
119 bool lineConstrained =
false)
122 const Vector2D vecPhi = -parameters.tangential();
124 const double cosphi = vecPhi.
x();
125 const double sinphi = vecPhi.
y();
127 if (lineConstrained) {
128 double chi2 = sw * (sinphi * sinphi * c(iX, iX) - 2. * sinphi * cosphi * c(iX, iY) + cosphi * cosphi * c(iY, iY));
132 const double rho = parameters.curvature();
133 const double d = parameters.impact();
135 const double u = 1 + d * rho;
136 const double kappa = 0.5 * rho / u;
138 double chi2 = sw * u * u * (sinphi * sinphi * c(iX, iX) - 2. * sinphi * cosphi * c(iX, iY) + cosphi * cosphi * c(iY,
139 iY) - kappa * kappa * c(iR2, iR2));
147 PerigeePrecision calcPrecisionKarimaki(
const PerigeeCircle& parameters,
148 const Eigen::Matrix< double, 4, 4 >& s,
149 bool lineConstrained =
false)
151 PerigeePrecision perigeePrecision;
153 const double curv = parameters.curvature();
154 const double I = parameters.impact();
157 const Vector2D vecPhi = -parameters.tangential();
160 const double cosphi = vecPhi.
x();
161 const double sinphi = vecPhi.
y();
163 const double ssphi = sinphi * sinphi;
164 const double scphi = sinphi * cosphi;
165 const double ccphi = cosphi * cosphi;
167 const double rho = curv;
170 const double u = 1. + rho * d;
172 using namespace NPerigeeParameterIndices;
173 if (lineConstrained) {
174 perigeePrecision(c_Curv, c_Curv) = 0.;
175 perigeePrecision(c_Curv, c_Phi0) = 0.;
176 perigeePrecision(c_Curv, c_I) = 0.;
177 perigeePrecision(c_Phi0, c_Curv) = 0.;
178 perigeePrecision(c_I, c_Curv) = 0.;
180 perigeePrecision(c_Phi0, c_Phi0) = ccphi * s(iX, iX) + 2. * scphi * s(iX, iY) + ssphi * s(iY, iY);
181 perigeePrecision(c_Phi0, c_I) = -(cosphi * s(iX) + sinphi * s(iY));
182 perigeePrecision(c_I, c_Phi0) = perigeePrecision(c_Phi0, c_I);
183 perigeePrecision(c_I, c_I) = s(iW);
186 double sa = sinphi * s(iX) - cosphi * s(iY);
187 double sb = cosphi * s(iX) + sinphi * s(iY);
188 double sc = (ssphi - ccphi) * s(iX, iY) + scphi * (s(iX, iX) - s(iY, iY));
190 double sd = sinphi * s(iX, iR2) - cosphi * s(iY, iR2);
192 double saa = ssphi * s(iX, iX) - 2. * scphi * s(iX, iY) + ccphi * s(iY, iY);
195 double se = cosphi * s(iX, iR2) + sinphi * s(iY, iR2);
196 double sbb = ccphi * s(iX, iX) + 2. * scphi * s(iX, iY) + ssphi * s(iY, iY);
198 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))));
199 perigeePrecision(c_Curv, c_Phi0) = - u * (0.5 * se - d * (sc - 0.5 * d * sb));
200 perigeePrecision(c_Phi0, c_Curv) = perigeePrecision(c_Curv, c_Phi0);
201 perigeePrecision(c_Phi0, c_Phi0) = u * u * sbb;
203 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));
204 perigeePrecision(c_I, c_Curv) = perigeePrecision(c_Curv, c_I);
205 perigeePrecision(c_Phi0, c_I) = u * (rho * sc - u * sb);
206 perigeePrecision(c_I, c_Phi0) = perigeePrecision(c_Phi0, c_I);
207 perigeePrecision(c_I, c_I) = rho * (rho * saa - 2 * u * sa) + u * u * s(iW);
209 return perigeePrecision;
218 Eigen::Matrix< double, 4, 4> sNoL = getWXYRSumMatrix(observations2D);
221 Eigen::Matrix<double, 4, 4> aNoL = sNoL / sNoL(iW);
224 Eigen::Matrix<double, 4, 1> meansNoL = aNoL.row(iW);
227 Eigen::Matrix<double, 4, 4> cNoL = aNoL - meansNoL * meansNoL.transpose();
230 size_t ndf = observations2D.
size() - 2;
238 double chi2 = calcChi2Karimaki(resultCircle, sNoL(iW), cNoL);
240 PerigeePrecision perigeePrecision = calcPrecisionKarimaki(resultCircle, sNoL,
isLineConstrained());
243 PerigeeCovariance perigeeCovariance = PerigeeUtil::covarianceFromPrecision(perigeePrecision);
Class serving as a storage of observed drift circles to present to the Riemann fitter.
double getX(int iObservation) const
Getter for the x value of the observation at the given index.
double getY(int iObservation) const
Getter for the y value of the observation at the given index.
TrackingUtilities::Vector2D getCentralPoint() const
Extracts the observation center that is at the index in the middle.
void passiveMoveBy(const TrackingUtilities::Vector2D &origin)
Moves all observations passively such that the given vector becomes to origin of the new coordinate s...
std::size_t size() const
Returns the number of observations stored.
KarimakisMethod()
Constructor setting the default constraints.
void update(TrackingUtilities::CDCTrajectory2D &trajectory2D, CDCObservations2D &observations2D) const
Executes the fit and updates the trajectory parameters. This may render the information in the observ...
bool isLineConstrained() const
Getter for the indicator that lines should be fitted by this fitter.
TrackingUtilities::UncertainPerigeeCircle fitInternal(CDCObservations2D &observations2D) const
Internal method doing the heavy work.
bool m_lineConstrained
Memory for the flag indicating that lines should be fitted.
Particle trajectory as it is seen in xy projection represented as a circle.
double setLocalOrigin(const Vector2D &localOrigin)
Setter for the origin of the local coordinate system.
void setLocalCircle(const UncertainPerigeeCircle &localPerigeeCircle)
Setter for the generalized circle that describes the trajectory.
void clear()
Clears all information from this trajectory.
double arcLengthBetween(const Vector2D &from, const Vector2D &to) const
Calculates the arc length between two points of closest approach on the circle.
Adds an uncertainty matrix to the circle in perigee parameterisation.
void reverse()
Flips the orientation of the circle in place.
void setPerigeeCovariance(const PerigeeCovariance &perigeeCovariance)
Setter for the whole covariance matrix of the perigee parameters.
void setNDF(std::size_t ndf)
Setter for the number of degrees of freediom used in the circle fit.
void setChi2(const double chi2)
Setter for the chi square value of the circle fit.
A two dimensional vector which is equipped with functions for correct handling of orientation relate...
double x() const
Getter for the x coordinate.
double y() const
Getter for the y coordinate.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.