Belle II Software  release-05-01-25
KarimakisMethod.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2014 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Oliver Frost *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 #include <tracking/trackFindingCDC/fitting/KarimakisMethod.h>
11 
12 #include <tracking/trackFindingCDC/fitting/EigenObservationMatrix.h>
13 #include <tracking/trackFindingCDC/fitting/CDCObservations2D.h>
14 
15 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
16 
17 #include <tracking/trackFindingCDC/geometry/UncertainPerigeeCircle.h>
18 #include <tracking/trackFindingCDC/geometry/PerigeeParameters.h>
19 #include <tracking/trackFindingCDC/geometry/Vector2D.h>
20 
21 #include <Eigen/Core>
22 
23 using namespace Belle2;
24 using namespace TrackFindingCDC;
25 
27  : m_lineConstrained(false)
28 {
29 }
30 
32  CDCObservations2D& observations2D) const
33 {
34  size_t nObservations = observations2D.size();
35  trajectory2D.clear();
36  if (not nObservations) return;
37 
38  Vector2D ref = observations2D.getCentralPoint();
39  observations2D.passiveMoveBy(ref);
40 
41  UncertainPerigeeCircle perigeeCircle = fitInternal(observations2D);
42 
43  double frontX = observations2D.getX(0);
44  double frontY = observations2D.getY(0);
45  Vector2D frontPos(frontX, frontY);
46 
47  double backX = observations2D.getX(nObservations - 1);
48  double backY = observations2D.getY(nObservations - 1);
49  Vector2D backPos(backX, backY);
50 
51  Vector2D overPos(0, 0);
52  double totalPerps = (perigeeCircle->arcLengthBetween(frontPos, overPos) +
53  perigeeCircle->arcLengthBetween(overPos, backPos));
54 
55  if (totalPerps < 0) {
56  perigeeCircle.reverse();
57  }
58 
59  trajectory2D.setLocalOrigin(ref);
60  trajectory2D.setLocalCircle(perigeeCircle);
61 }
62 
63 
64 
65 
66 namespace {
68  constexpr size_t iW = 0;
69  constexpr size_t iX = 1;
70  constexpr size_t iY = 2;
71  constexpr size_t iR2 = 3;
72 
74  UncertainPerigeeCircle fitKarimaki(const double /*sw*/,
75  const Eigen::Matrix< double, 4, 1 >& a,
76  const Eigen::Matrix< double, 4, 4 >& c,
77  bool lineConstrained = false)
78  {
79  double q1, q2 = 0.0;
80  if (lineConstrained) {
81  q1 = c(iX, iY);
82  q2 = c(iX, iX) - c(iY, iY);
83  } else {
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);
86  }
87 
88  double phi = 0.5 * atan2(2. * q1, q2);
89 
90  double sinphi = sin(phi);
91  double cosphi = cos(phi);
92 
93  double curv, I = 0.0;
94  if (lineConstrained) {
95  curv = 0.0; //line
96  I = sinphi * a(iX) - cosphi * a(iY);
97 
98  } else {
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));
103 
104  }
105 
106  // Karimaki uses the opposite sign for phi in contrast to the convention of this framework !!!
107  phi += phi > 0 ? -M_PI : M_PI;
108  return UncertainPerigeeCircle(curv, phi, I);
109 
110  }
111 
112 
113 
114 
115 
117  double calcChi2Karimaki(const PerigeeCircle& parameters,
118  const double sw,
119  const Eigen::Matrix< double, 4, 4 >& c,
120  bool lineConstrained = false)
121  {
122  // Karimaki uses the opposite sign for phi in contrast to the convention of this framework !!!
123  const Vector2D vecPhi = -parameters.tangential();
124 
125  const double cosphi = vecPhi.x();
126  const double sinphi = vecPhi.y();
127 
128  if (lineConstrained) {
129  double chi2 = sw * (sinphi * sinphi * c(iX, iX) - 2. * sinphi * cosphi * c(iX, iY) + cosphi * cosphi * c(iY, iY));
130  return chi2;
131  } else {
132  // Terminology Karimaki used in the paper
133  const double rho = parameters.curvature();
134  const double d = parameters.impact();
135 
136  const double u = 1 + d * rho;
137  const double kappa = 0.5 * rho / u;
138 
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));
141  return chi2;
142  }
143 
144  }
145 
146 
147 
148  PerigeePrecision calcPrecisionKarimaki(const PerigeeCircle& parameters,
149  const Eigen::Matrix< double, 4, 4 >& s,
150  bool lineConstrained = false)
151  {
152  PerigeePrecision perigeePrecision;
153 
154  const double curv = parameters.curvature();
155  const double I = parameters.impact();
156 
157  // Karimaki uses the opposite sign for phi in contrast to the convention of this framework !!!
158  const Vector2D vecPhi = -parameters.tangential();
159 
160  // Ternminology Karimaki using in the paper
161  const double cosphi = vecPhi.x();
162  const double sinphi = vecPhi.y();
163 
164  const double ssphi = sinphi * sinphi;
165  const double scphi = sinphi * cosphi;
166  const double ccphi = cosphi * cosphi;
167 
168  const double rho = curv;
169  const double d = I;
170 
171  const double u = 1. + rho * d;
172 
173  using namespace NPerigeeParameterIndices;
174  if (lineConstrained) {
175  perigeePrecision(c_Curv, c_Curv) = 0.;
176  perigeePrecision(c_Curv, c_Phi0) = 0.;
177  perigeePrecision(c_Curv, c_I) = 0.;
178  perigeePrecision(c_Phi0, c_Curv) = 0.;
179  perigeePrecision(c_I, c_Curv) = 0.;
180 
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));
183  perigeePrecision(c_I, c_Phi0) = perigeePrecision(c_Phi0, c_I);
184  perigeePrecision(c_I, c_I) = s(iW);
185 
186  } else {
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));
190 
191  double sd = sinphi * s(iX, iR2) - cosphi * s(iY, iR2);
192 
193  double saa = ssphi * s(iX, iX) - 2. * scphi * s(iX, iY) + ccphi * s(iY, iY);
194 
195  // Not in the Karimaki paper, but factors a similar term.
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);
198 
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));
201  perigeePrecision(c_Phi0, c_Curv) = perigeePrecision(c_Curv, c_Phi0);
202  perigeePrecision(c_Phi0, c_Phi0) = u * u * sbb;
203 
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));
205  perigeePrecision(c_I, c_Curv) = perigeePrecision(c_Curv, c_I);
206  perigeePrecision(c_Phi0, c_I) = u * (rho * sc - u * sb);
207  perigeePrecision(c_I, c_Phi0) = perigeePrecision(c_Phi0, c_I);
208  perigeePrecision(c_I, c_I) = rho * (rho * saa - 2 * u * sa) + u * u * s(iW);
209  }
210  return perigeePrecision;
211  }
212 }
213 
214 
215 
217 {
218  // Matrix of weighted sums
219  Eigen::Matrix< double, 4, 4> sNoL = getWXYRSumMatrix(observations2D);
220 
221  // Matrix of averages
222  Eigen::Matrix<double, 4, 4> aNoL = sNoL / sNoL(iW);
223 
224  // Measurement means
225  Eigen::Matrix<double, 4, 1> meansNoL = aNoL.row(iW);
226 
227  // Covariance matrix
228  Eigen::Matrix<double, 4, 4> cNoL = aNoL - meansNoL * meansNoL.transpose();
229 
230  // Determine NDF : Circle fit eats up to 3 degrees of freedom debpending on the constraints
231  size_t ndf = observations2D.size() - 2;
232 
233  if (not isLineConstrained()) {
234  --ndf;
235  }
236 
237  // Parameters to be fitted
238  UncertainPerigeeCircle resultCircle = fitKarimaki(sNoL(iW), meansNoL, cNoL, isLineConstrained());
239  double chi2 = calcChi2Karimaki(resultCircle, sNoL(iW), cNoL);
240 
241  PerigeePrecision perigeePrecision = calcPrecisionKarimaki(resultCircle, sNoL, isLineConstrained());
242 
243  // Use in pivotingin caset the matrix is not full rank as is for the constrained cases-
244  PerigeeCovariance perigeeCovariance = PerigeeUtil::covarianceFromPrecision(perigeePrecision);
245 
246  resultCircle.setChi2(chi2);
247  resultCircle.setNDF(ndf);
248  resultCircle.setPerigeeCovariance(perigeeCovariance);
249  return resultCircle;
250 }
Belle2::TrackFindingCDC::CDCObservations2D::size
std::size_t size() const
Returns the number of observations stored.
Definition: CDCObservations2D.h:88
Belle2::TrackFindingCDC::UncertainPerigeeCircle::setChi2
void setChi2(const double chi2)
Setter for the chi square value of the circle fit.
Definition: UncertainPerigeeCircle.h:190
Belle2::TrackFindingCDC::CDCObservations2D::getX
double getX(int iObservation) const
Getter for the x value of the observation at the given index.
Definition: CDCObservations2D.h:118
Belle2::TrackFindingCDC::Vector2D
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:37
Belle2::TrackFindingCDC::UncertainPerigeeCircle::setPerigeeCovariance
void setPerigeeCovariance(const PerigeeCovariance &perigeeCovariance)
Setter for the whole covariance matrix of the perigee parameters.
Definition: UncertainPerigeeCircle.h:160
Belle2::TrackFindingCDC::CDCObservations2D::passiveMoveBy
void passiveMoveBy(const Vector2D &origin)
Moves all observations passively such that the given vector becomes to origin of the new coordinate s...
Definition: CDCObservations2D.cc:347
Belle2::TrackFindingCDC::KarimakisMethod::fitInternal
UncertainPerigeeCircle fitInternal(CDCObservations2D &observations2D) const
Internal method doing the heavy work.
Definition: KarimakisMethod.cc:216
Belle2::TrackFindingCDC::CDCTrajectory2D::setLocalOrigin
double setLocalOrigin(const Vector2D &localOrigin)
Setter for the origin of the local coordinate system.
Definition: CDCTrajectory2D.cc:357
Belle2::TrackFindingCDC::PerigeeCircle::arcLengthBetween
double arcLengthBetween(const Vector2D &from, const Vector2D &to) const
Calculates the arc length between two points of closest approach on the circle.
Definition: PerigeeCircle.cc:246
Belle2::TrackFindingCDC::NPerigeeParameterIndices::c_I
@ c_I
Constant to address the impact parameter.
Definition: PerigeeParameters.h:42
Belle2::TrackFindingCDC::CDCTrajectory2D
Particle trajectory as it is seen in xy projection represented as a circle.
Definition: CDCTrajectory2D.h:46
Belle2::TrackFindingCDC::CDCObservations2D::getY
double getY(int iObservation) const
Getter for the y value of the observation at the given index.
Definition: CDCObservations2D.h:124
Belle2::TrackFindingCDC::CDCTrajectory2D::setLocalCircle
void setLocalCircle(const UncertainPerigeeCircle &localPerigeeCircle)
Setter for the generalized circle that describes the trajectory.
Definition: CDCTrajectory2D.h:502
Belle2::TrackFindingCDC::NPerigeeParameterIndices::c_Phi0
@ c_Phi0
Constant to address the azimuth angle of the direction of flight at the perigee.
Definition: PerigeeParameters.h:39
Belle2::TrackFindingCDC::UncertainPerigeeCircle
Adds an uncertainty matrix to the circle in perigee parameterisation.
Definition: UncertainPerigeeCircle.h:39
Belle2::TrackFindingCDC::CDCObservations2D
Class serving as a storage of observed drift circles to present to the Riemann fitter.
Definition: CDCObservations2D.h:53
Belle2::TrackFindingCDC::KarimakisMethod::update
void update(CDCTrajectory2D &trajectory2D, CDCObservations2D &observations2D) const
Executes the fit and updates the trajectory parameters. This may render the information in the observ...
Definition: KarimakisMethod.cc:31
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TrackFindingCDC::UncertainPerigeeCircle::reverse
void reverse()
Flips the orientation of the circle in place.
Definition: UncertainPerigeeCircle.h:217
Belle2::TrackFindingCDC::UncertainPerigeeCircle::setNDF
void setNDF(std::size_t ndf)
Setter for the number of degrees of freediom used in the circle fit.
Definition: UncertainPerigeeCircle.h:202
Belle2::TrackFindingCDC::UncertainParametersUtil< PerigeeUtil, EPerigeeParameter >::covarianceFromPrecision
static CovarianceMatrix covarianceFromPrecision(const PrecisionMatrix &prec)
Convert the precision matrix to the corresponding covariance matrix.
Definition: UncertainParameters.icc.h:87
prepareAsicCrosstalkSimDB.u
u
merged u1 and u2
Definition: prepareAsicCrosstalkSimDB.py:46
Belle2::TrackFindingCDC::PlainMatrix
A matrix implementation to be used as an interface typ through out the track finder.
Definition: PlainMatrix.h:50
Belle2::TrackFindingCDC::CDCTrajectory2D::clear
void clear()
Clears all information from this trajectoy.
Definition: CDCTrajectory2D.cc:90
Belle2::TrackFindingCDC::NPerigeeParameterIndices::c_Curv
@ c_Curv
Constant to address the curvature.
Definition: PerigeeParameters.h:36
Belle2::TrackFindingCDC::CDCObservations2D::getCentralPoint
Vector2D getCentralPoint() const
Extracts the observation center that is at the index in the middle.
Definition: CDCObservations2D.cc:330
Belle2::TrackFindingCDC::KarimakisMethod::isLineConstrained
bool isLineConstrained() const
Getter for the indictor that lines should be fitted by this fitter.
Definition: KarimakisMethod.h:46
Belle2::TrackFindingCDC::KarimakisMethod::KarimakisMethod
KarimakisMethod()
Constructor setting the default constraints.
Definition: KarimakisMethod.cc:26