8#include <tracking/trackFindingCDC/fitting/ExtendedRiemannsMethod.h>
10#include <tracking/trackFindingCDC/fitting/EigenObservationMatrix.h>
11#include <tracking/trackFindingCDC/fitting/CDCObservations2D.h>
13#include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
15#include <tracking/trackFindingCDC/geometry/UncertainPerigeeCircle.h>
16#include <tracking/trackFindingCDC/geometry/PerigeeParameters.h>
17#include <tracking/trackFindingCDC/geometry/Vector2D.h>
19#include <tracking/trackFindingCDC/numerics/EigenView.h>
21#include <framework/logging/Logger.h>
26using namespace Belle2::TrackFindingCDC;
29 : m_lineConstrained(false)
30 , m_originConstrained(false)
37 size_t nObservations = observations2D.
size();
39 if (not nObservations)
return;
49 double frontX = observations2D.
getX(0);
50 double frontY = observations2D.
getY(0);
53 double backX = observations2D.
getX(nObservations - 1);
54 double backY = observations2D.
getY(nObservations - 1);
73 enum EParabolicIndices {
82 PerigeeCircle fit(
const Eigen::Matrix< double, 5, 5 >& sumMatrix,
83 bool lineConstrained =
false,
84 bool originConstrained =
false)
88 if (lineConstrained) {
89 if (originConstrained) {
90 Eigen::Matrix< double, 2, 2> X = sumMatrix.block<2, 2>(1, 1);
91 Eigen::Matrix< double, 2, 1> y = sumMatrix.block<2, 1>(1, iL);
92 Eigen::Matrix< double, 2, 1> n = X.ldlt().solve(y);
96 Eigen::Matrix< double, 3, 3> X = sumMatrix.block<3, 3>(0, 0);
97 Eigen::Matrix< double, 3, 1> y = sumMatrix.block<3, 1>(0, iL);
98 Eigen::Matrix< double, 3, 1> n = X.ldlt().solve(y);
104 if (originConstrained) {
105 Eigen::Matrix< double, 3, 3> X = sumMatrix.block<3, 3>(1, 1);
106 Eigen::Matrix< double, 3, 1> y = sumMatrix.block<3, 1>(1, iL);
107 Eigen::Matrix< double, 3, 1> n = X.ldlt().solve(y);
111 Eigen::Matrix< double, 4, 4> X = sumMatrix.block<4, 4>(0, 0);
112 Eigen::Matrix< double, 4, 1> y = sumMatrix.block<4, 1>(0, iL);
113 Eigen::Matrix< double, 4, 1> n = X.ldlt().solve(y);
123 bool lineConstrained =
false,
124 bool originConstrained =
false)
130 if (lineConstrained) {
131 if (originConstrained) {
132 Eigen::Matrix< double, 2, 2> X = sumMatrix.block<2, 2>(1, 1);
133 Eigen::SelfAdjointEigenSolver< Eigen::Matrix<double, 2, 2> > eigensolver(X);
134 Eigen::Matrix<double, 2, 1> n = eigensolver.eigenvectors().col(0);
135 if (eigensolver.info() != Eigen::Success) {
136 B2WARNING(
"SelfAdjointEigenSolver could not compute the eigen values of the observation matrix");
141 Eigen::Matrix< double, 3, 3> X = sumMatrix.block<3, 3>(0, 0);
142 Eigen::SelfAdjointEigenSolver< Eigen::Matrix<double, 3, 3> > eigensolver(X);
143 Eigen::Matrix<double, 3, 1> n = eigensolver.eigenvectors().col(0);
144 if (eigensolver.info() != Eigen::Success) {
145 B2WARNING(
"Eigen::SelfAdjointEigenSolver could not compute the eigen values of the observation matrix");
151 if (originConstrained) {
152 Eigen::Matrix< double, 3, 3> X = sumMatrix.block<3, 3>(1, 1);
153 Eigen::SelfAdjointEigenSolver< Eigen::Matrix<double, 3, 3> > eigensolver(X);
154 Eigen::Matrix<double, 3, 1> n = eigensolver.eigenvectors().col(0);
155 if (eigensolver.info() != Eigen::Success) {
156 B2WARNING(
"Eigen::SelfAdjointEigenSolver could not compute the eigen values of the observation matrix");
161 Eigen::Matrix< double, 4, 4 > X = sumMatrix.block<4, 4>(0, 0);
162 Eigen::SelfAdjointEigenSolver< Eigen::Matrix<double, 4, 4> > eigensolver(X);
163 Eigen::Matrix<double, 4, 1> n = eigensolver.eigenvectors().col(0);
164 if (eigensolver.info() != Eigen::Success) {
165 B2WARNING(
"Eigen::SelfAdjointEigenSolver could not compute the eigen values of the observation matrix");
174 PerigeeCircle fitSeperateOffset(Eigen::Matrix< double, 4, 1 > means,
175 Eigen::Matrix< double, 4, 4 > c,
176 bool lineConstrained =
false)
182 if (lineConstrained) {
183 Eigen::Matrix< double, 2, 2> X = c.block<2, 2>(1, 1);
184 Eigen::SelfAdjointEigenSolver< Eigen::Matrix<double, 2, 2> > eigensolver(X);
185 if (eigensolver.info() != Eigen::Success) {
186 B2WARNING(
"Eigen::SelfAdjointEigenSolver could not compute the eigen values of the observation matrix");
191 Eigen::Matrix<double, 4, 1> n;
192 n.middleRows<2>(iX) = eigensolver.eigenvectors().col(0);
193 n(iW) = -means.middleRows<2>(iX).transpose() * n.middleRows<2>(iX);
198 Eigen::Matrix< double, 3, 3> X = c.block<3, 3>(1, 1);
199 Eigen::SelfAdjointEigenSolver< Eigen::Matrix<double, 3, 3> > eigensolver(X);
200 if (eigensolver.info() != Eigen::Success) {
201 B2WARNING(
"Eigen::SelfAdjointEigenSolver could not compute the eigen values of the observation matrix");
206 Eigen::Matrix<double, 4, 1> n;
207 n.middleRows<3>(iX) = eigensolver.eigenvectors().col(0);
208 n(iW) = -means.middleRows<3>(iX).transpose() * n.middleRows<3>(iX);
217 const Eigen::Matrix< double, 5, 5 >& s)
219 Eigen::Matrix<double, 5, 1> n;
220 n(0) = parameters.n0();
221 n(1) = parameters.n1();
222 n(2) = parameters.n2();
223 n(3) = parameters.n3();
226 double chi2 = n.transpose() * s * n;
233 const Eigen::Matrix< double, 4, 4 >& s)
235 Eigen::Matrix<double, 4, 1> n;
236 n(0) = parameters.n0();
237 n(1) = parameters.n1();
238 n(2) = parameters.n2();
239 n(3) = parameters.n3();
241 double chi2 = n.transpose() * s * n;
247 const Eigen::Matrix< double, 4, 4 >& s,
248 bool lineConstrained =
false,
249 bool originConstrained =
false)
251 const double impact = parameters.impact();
252 const Vector2D& phi0Vec = parameters.tangential();
253 const double curvature = parameters.curvature();
255 using namespace NPerigeeParameterIndices;
256 Eigen::Matrix<double, 4, 3> ambiguity = Eigen::Matrix<double, 4, 3> ::Zero();
258 ambiguity(0, c_Curv) = impact * impact / 2;
259 ambiguity(1, c_Curv) = phi0Vec.
y() * impact;
260 ambiguity(2, c_Curv) = -phi0Vec.
x() * impact;
261 ambiguity(3, c_Curv) = 1.0 / 2.0;
263 ambiguity(0, c_Phi0) = 0;
264 ambiguity(1, c_Phi0) = phi0Vec.
x() * (1 + curvature * impact);
265 ambiguity(2, c_Phi0) = phi0Vec.
y() * (1 + curvature * impact);
266 ambiguity(3, c_Phi0) = 0;
268 ambiguity(0, c_I) = 1 + curvature * impact;
269 ambiguity(1, c_I) = phi0Vec.
y() * curvature;
270 ambiguity(2, c_I) = -phi0Vec.
x() * curvature;
271 ambiguity(3, c_I) = 0;
273 Eigen::Matrix<double, 3, 3> perigeePrecision = ambiguity.transpose() * s * ambiguity;
275 if (lineConstrained) {
276 perigeePrecision.row(c_Curv) = Eigen::Matrix<double, 1, 3>::Zero();
277 perigeePrecision.col(c_Curv) = Eigen::Matrix<double, 3, 1>::Zero();
280 if (originConstrained) {
281 perigeePrecision.row(c_I) = Eigen::Matrix<double, 1, 3>::Zero();
282 perigeePrecision.col(c_I) = Eigen::Matrix<double, 3, 1>::Zero();
286 mapToEigen(result) = perigeePrecision;
299 Eigen::Matrix< double, 5, 5 > s = getWXYRLSumMatrix(observations2D);
302 Eigen::Matrix<double, 4, 4> sNoL = s.block<4, 4>(0, 0);
305 size_t ndf = observations2D.
size() - 1;
320 if (nObservationsWithDriftRadius > 0) {
322 chi2 = calcChi2(resultCircle, s);
328 Eigen::Matrix< double, 4, 4> aNoL = sNoL / sNoL(iW);
331 Eigen::Matrix< double, 4, 1> meansNoL = aNoL.row(iW);
334 Eigen::Matrix< double, 4, 4> cNoL = aNoL - meansNoL * meansNoL.transpose();
342 chi2 = calcChi2(resultCircle, sNoL);
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.
Vector2D getCentralPoint() const
Extracts the observation center that is at the index in the middle.
void passiveMoveBy(const 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.
std::size_t getNObservationsWithDriftRadius() const
Returns the number of observations having a drift radius radius.
Particle trajectory as it is seen in xy projection represented as a circle.
void clear()
Clears all information from this trajectory.
bool isLineConstrained() const
Getter for the indicator that lines should be fitted by this fitter.
UncertainPerigeeCircle fitInternal(CDCObservations2D &observations2D) const
Internal method doing the heavy work.
ExtendedRiemannsMethod()
Constructor setting the default constraints.
void update(CDCTrajectory2D &trajectory2D, CDCObservations2D &observations2D) const
Executes the fit and updates the trajectory parameters This may render the information in the observa...
bool isOriginConstrained() const
Getter for the indicator that curves through the origin should be fitted by this fitter.
Extension of the generalized circle also caching the perigee coordinates.
double arcLengthBetween(const Vector2D &from, const Vector2D &to) const
Calculates the arc length between two points of closest approach on the circle.
static PerigeeCircle fromN(double n0, double n1, double n2, double n3=0)
Constructor with the four parameters of the generalized circle.
A matrix implementation to be used as an interface typ through out the track finder.
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.
Namespace to hide the contained enum constants.
static CovarianceMatrix covarianceFromPrecision(const PrecisionMatrix &prec)
Convert the precision matrix to the corresponding covariance matrix.