Belle II Software development
QualityEstimatorRiemannHelixFit Class Reference

Based on R. More...

#include <QualityEstimatorRiemannHelixFit.h>

Inheritance diagram for QualityEstimatorRiemannHelixFit:
QualityEstimatorBase

Public Member Functions

virtual double estimateQuality (std::vector< SpacePoint const * > const &measurements) final
 Minimal implementation of the quality estimation Calculates quality indicator in range [0,1].
 
void setMagneticFieldStrength (double magneticFieldZ=1.5)
 Setter for z component of magnetic field.
 
virtual QualityEstimationResults estimateQualityAndProperties (std::vector< SpacePoint const * > const &measurements)
 Quality estimation providing additional quantities Calculates quality indicator in range [0,1] Optionally returns chi2 and additional informations.
 

Protected Member Functions

double calcPt (double const radius) const
 Returns a value for the transverse momentum in GeV calculated from a provided radius.
 

Protected Attributes

double m_magneticFieldZ = 1.5
 Member storing the z component of the magnetic field.
 
QualityEstimationResults m_results
 Result of the quality estimation This is stored as a member variable, because some values may be calculated by 'estimateQuality' anyways.
 

Detailed Description

Based on R.

Fruehwirth, A. Strandlie, W. Waltenberger, Nuclear instruments and Methods in Physics Research A 490 (2002) 366-378

Definition at line 22 of file QualityEstimatorRiemannHelixFit.h.

Member Function Documentation

◆ calcPt()

double calcPt ( double const  radius) const
inlineprotectedinherited

Returns a value for the transverse momentum in GeV calculated from a provided radius.

Utilizing m_magneticFieldZ and hard coded speed of light

Definition at line 80 of file QualityEstimatorBase.h.

80{ return m_magneticFieldZ * radius * 0.00299792458; }
double m_magneticFieldZ
Member storing the z component of the magnetic field.

◆ estimateQuality()

double estimateQuality ( std::vector< SpacePoint const * > const &  measurements)
finalvirtual

Minimal implementation of the quality estimation Calculates quality indicator in range [0,1].

measurements - std::vector<SpacePoint const*> ordered from innermost to outermost measurement

Implements QualityEstimatorBase.

Definition at line 20 of file QualityEstimatorRiemannHelixFit.cc.

21{
22 const int nHits = measurements.size();
23 if (nHits < 3) return 0;
24
25 // Circle Fit
26
27 Eigen::Matrix<Precision, Eigen::Dynamic, Eigen::Dynamic> W = Eigen::Matrix<Precision, Eigen::Dynamic, Eigen::Dynamic>::Zero(nHits,
28 nHits);
29 Eigen::Matrix<Precision, Eigen::Dynamic, Eigen::Dynamic> Wz = Eigen::Matrix<Precision, Eigen::Dynamic, Eigen::Dynamic>::Zero(nHits,
30 nHits);
31 Eigen::Matrix<Precision, Eigen::Dynamic, 3> X = Eigen::Matrix<Precision, Eigen::Dynamic, 3>::Zero(nHits, 3);
32 Eigen::Matrix<Precision, Eigen::Dynamic, 1> Z = Eigen::Matrix<Precision, Eigen::Dynamic, 1>::Zero(nHits, 1);
33 Precision traceOfW = 0.;
34
35 short index = 0;
36 for (SpacePoint const* hit : measurements) {
37 auto position = hit->getPosition();
38 auto positionError = hit->getPositionError();
39 double x = position.X();
40 double y = position.Y();
41 double z = position.Z();
42 double sigmaX = positionError.X();
43 double sigmaY = positionError.Y();
44 double sigmaZ = positionError.Z();
45
46 double r2 = x * x + y * y;
47 double inverseVarianceXY = 1. / sqrt(sigmaX * sigmaX + sigmaY * sigmaY);
48
49 // The following weight matrix W can be improved for cases with multiple scattering
50 // by adding a correction term which will make the matrix non-diagonal.
51 // However, this requires prior knowledge of the curvature of the track and thus a
52 // second iteration (see page 368 of above mentioned source).
53 W(index, index) = inverseVarianceXY;
54 traceOfW += inverseVarianceXY;
55
56 X(index, 0) = x;
57 X(index, 1) = y;
58 X(index, 2) = r2;
59
60 // Values for z line fit for extrended Riemann fit
61 Wz(index, index) = 1. / sigmaZ;
62 Z(index, 0) = z;
63
64 index++;
65 }
66
67 Eigen::Matrix<Precision, 1, 3> xBar = Eigen::Matrix<Precision, Eigen::Dynamic, 1>::Ones(nHits, 1).transpose() * W * X / traceOfW;
68 Eigen::Matrix<Precision, 3, 3> Vx = X.transpose() * W * X - xBar.transpose() * xBar * traceOfW;
69
70 // Find eigenvector to smallest eigenvalue
71 Eigen::EigenSolver<Eigen::Matrix<Precision, 3, 3>> eigencollection(Vx);
72 Eigen::Matrix<Precision, 3, 1> eigenvalues = eigencollection.eigenvalues().real();
73 Eigen::Matrix<std::complex<Precision>, 3, 3> eigenvectors = eigencollection.eigenvectors();
74 Eigen::Matrix<Precision, 3, 1>::Index minRow, minCol;
75 eigenvalues.minCoeff(&minRow, &minCol);
76
77 Eigen::Matrix<Precision, 3, 1> n = eigenvectors.col(minRow).real();
78
79 // Calculate results with this eigenvector
80 Precision c = - xBar * n;
81 Precision x0 = - 0.5 * n(0) / n(2);
82 Precision y0 = - 0.5 * n(1) / n(2);
83 Precision rho2 = (1 - n(2) * (n(2) + 4 * c)) / (4 * n(2) * n(2));
84 Precision rho = sqrt(rho2);
85
86 // calculation of chi2 for circle fit using Karimaeki circle fit
87 Precision divisor = 1. / traceOfW;
88 Eigen::Matrix<Precision, Eigen::Dynamic, 1> unitvec = Eigen::Matrix<Precision, Eigen::Dynamic, 1>::Ones(nHits, 1);
89 Precision meanX = unitvec.transpose() * W * X.col(0);
90 meanX *= divisor;
91 Precision meanY = unitvec.transpose() * W * X.col(1);
92 meanY *= divisor;
93 Precision meanXY = unitvec.transpose() * W * (X.col(0).cwiseProduct(X.col(1)));
94 meanXY *= divisor;
95 Precision meanX2 = unitvec.transpose() * W * (X.col(0).cwiseProduct(X.col(0)));
96 meanX2 *= divisor;
97 Precision meanY2 = unitvec.transpose() * W * (X.col(1).cwiseProduct(X.col(1)));
98 meanY2 *= divisor;
99 Precision meanXR2 = unitvec.transpose() * W * (X.col(0).cwiseProduct(X.col(2)));
100 meanXR2 *= divisor;
101 Precision meanYR2 = unitvec.transpose() * W * (X.col(1).cwiseProduct(X.col(2)));
102 meanYR2 *= divisor;
103 Precision meanR2 = unitvec.transpose() * W * X.col(2);
104 meanR2 *= divisor;
105 Precision meanR4 = unitvec.transpose() * W * (X.col(2).cwiseProduct(X.col(2)));
106 meanR4 *= divisor;
107
108 // covariances:
109 Precision covXX = meanX2 - meanX * meanX;
110 Precision covXY = meanXY - meanX * meanY;
111 Precision covYY = meanY2 - meanY * meanY;
112 Precision covXR2 = meanXR2 - meanX * meanR2;
113 Precision covYR2 = meanYR2 - meanY * meanR2;
114 Precision covR2R2 = meanR4 - meanR2 * meanR2;
115
116 // q1, q2: helping variables, to make the code more readable
117 Precision q1 = covR2R2 * covXY - covXR2 * covYR2;
118 Precision q2 = covR2R2 * (covXX - covYY) - covXR2 * covXR2 + covYR2 * covYR2;
119
120 Precision pocaPhi = 0.5 * atan2(2. * q1, q2);
121
122 Precision sinPhi = sin(pocaPhi);
123 Precision cosPhi = cos(pocaPhi);
124 Precision kappa = (sinPhi * covXR2 - cosPhi * covYR2) / covR2R2;
125 Precision delta = -kappa * meanR2 + sinPhi * meanX - cosPhi * meanY;
126 Precision rootTerm = sqrt(1. - 4.*delta * kappa);
127 Precision curvature = 2.*kappa / (rootTerm);
128 Precision pocaD = 2.*delta / (1. + rootTerm);
129 short curvatureSign = calcCurvatureSignum(measurements);
130
131 if ((curvature < 0 && curvatureSign >= 0) || (curvature > 0 && curvatureSign < 0)) {
132 curvature = -curvature;
133 // pocaPhi = pocaPhi + M_PI; //
134 pocaD = -pocaD;
135 }
136
137 Precision chi2 = traceOfW * (1. + pocaD / rho) * (1. + curvature * pocaD) *
138 (sinPhi * sinPhi * covXX - 2.*sinPhi * cosPhi * covXY + cosPhi * cosPhi * covYY - kappa * kappa * covR2R2);
139
140 // Arc length calculation
141 Precision x_first = X.col(0)(0) - x0;
142 Precision y_first = X.col(1)(0) - y0;
143 Precision r_mag_first = sqrt(x_first * x_first + y_first * y_first);
144 Eigen::Matrix<Precision, Eigen::Dynamic, 1> x0s = Eigen::Matrix<Precision, Eigen::Dynamic, 1>::Ones(nHits, 1) * x0;
145 Eigen::Matrix<Precision, Eigen::Dynamic, 1> y0s = Eigen::Matrix<Precision, Eigen::Dynamic, 1>::Ones(nHits, 1) * y0;
146 Eigen::Matrix<Precision, Eigen::Dynamic, 1> r_mags = ((X.col(0) - x0s).cwiseProduct(X.col(0) - x0s) + (X.col(1) - y0s).cwiseProduct(
147 X.col(1) - y0s)).cwiseSqrt();
148
149 Eigen::Matrix<Precision, Eigen::Dynamic, 1> arc_angles = (x_first * (X.col(0) - x0s) + y_first * (X.col(1) - y0s)).cwiseQuotient(
150 r_mags) / r_mag_first;
151 Eigen::Matrix<Precision, Eigen::Dynamic, 1> arc_lengths = rho * arc_angles.array().acos().matrix();
152
153 Eigen::Matrix<Precision, Eigen::Dynamic, 2> A = Eigen::Matrix<Precision, Eigen::Dynamic, 2>::Ones(nHits, 2);
154 arc_lengths(0) = 0.;
155 A.col(1) = arc_lengths;
156
157 // Linear regression of z on arg_lengths with weight matrix Wz
158 Eigen::Matrix<Precision, 2, 1> p = (A.transpose() * Wz * A).inverse() * A.transpose() * Wz * Z;
159
160 // Construction of momentum vector with innermost hit and reconstructed circle center
161 Eigen::Matrix<Precision, 3, 1> momVec = Eigen::Matrix<Precision, 3, 1>::Zero();
162 momVec(0) = y0 - X.col(1)(0);
163 momVec(1) = - (x0 - X.col(0)(0));
164
165 Precision pT = Precision(calcPt(rho));
166 momVec = pT * momVec.normalized();
167
168 Eigen::Matrix<Precision, 3, 1> vec01 = X.row(1) - X.row(0);
169 vec01(2) = Z(1) - Z(0);
170 Precision angle01 = std::acos(vec01.dot(momVec) / momVec.norm() / vec01.norm());
171 if (angle01 > 0.5 * M_PI) { momVec *= -1.; }
172
173 // Calculation of a chi2 distributed quantity for the quality of fit of the z component fit.
174 Eigen::Matrix<Precision, Eigen::Dynamic, 1> ones = Eigen::Matrix<Precision, Eigen::Dynamic, 1>::Ones(nHits, 1);
175 Precision chi2_z = ((Z - p(0) * ones - p(1) * arc_lengths).cwiseQuotient(Wz * ones)).transpose() * ((Z - p(0) * ones - p(
176 1) * arc_lengths).cwiseQuotient(Wz * ones));
177
178 // Adding chi2 and chi2_z, thus creating a chi2 distribution with (n-3) + (n-2) = 2n-5 degrees of freedom
179 m_results.chiSquared = chi2 + chi2_z;
180 B2DEBUG(25, "Chi Squared of extended Riemann = " << * (m_results.chiSquared) << std::endl);
181
182 Precision pZ = pT * p(1);
183 momVec(2) = pZ;
184 m_results.pt = pT;
185 m_results.p = B2Vector3D(momVec(0), momVec(1), momVec(2));
186 m_results.curvatureSign = curvatureSign;
187 m_results.pocaD = pocaD;
188
189 return TMath::Prob(*(m_results.chiSquared), 2 * measurements.size() - 5);
190}
QualityEstimationResults m_results
Result of the quality estimation This is stored as a member variable, because some values may be calc...
double calcPt(double const radius) const
Returns a value for the transverse momentum in GeV calculated from a provided radius.
SpacePoint typically is build from 1 PXDCluster or 1-2 SVDClusters.
Definition: SpacePoint.h:42
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:516
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
short calcCurvatureSignum(std::vector< SpacePoint const * > const &measurements)
Calculate curvature based on triplets of measurements.
std::optional< double > pt
transverse momentum estimate from the QE
std::optional< short > curvatureSign
direction of curvature as obtained by the QE
std::optional< double > pocaD
distance to the z-axis of the POCA
std::optional< double > chiSquared
chi squared value obtained by the fit of the QE
std::optional< B2Vector3D > p
momentum vector estimate from the QE

◆ estimateQualityAndProperties()

virtual QualityEstimationResults estimateQualityAndProperties ( std::vector< SpacePoint const * > const &  measurements)
inlinevirtualinherited

Quality estimation providing additional quantities Calculates quality indicator in range [0,1] Optionally returns chi2 and additional informations.

Eg. momentum estimation.

measurements - std::vector<SpacePoint const*> ordered from innermost to outermost measurement

Reimplemented in QualityEstimatorTripletFit, and QualityEstimatorMC.

Definition at line 68 of file QualityEstimatorBase.h.

69 {
70 m_results = QualityEstimationResults();
72 return m_results;
73 }
virtual double estimateQuality(std::vector< SpacePoint const * > const &measurements)=0
Minimal implementation of the quality estimation Calculates quality indicator in range [0,...
double qualityIndicator
return value of the quality estimator

◆ setMagneticFieldStrength()

void setMagneticFieldStrength ( double  magneticFieldZ = 1.5)
inlineinherited

Setter for z component of magnetic field.

Parameters
magneticFieldZ: value to set it to

Definition at line 53 of file QualityEstimatorBase.h.

53{m_magneticFieldZ = magneticFieldZ;}

Member Data Documentation

◆ m_magneticFieldZ

double m_magneticFieldZ = 1.5
protectedinherited

Member storing the z component of the magnetic field.

Definition at line 84 of file QualityEstimatorBase.h.

◆ m_results

QualityEstimationResults m_results
protectedinherited

Result of the quality estimation This is stored as a member variable, because some values may be calculated by 'estimateQuality' anyways.

Therefore they don't need to be calculated explicitly in 'estimateQualityAndProperties'.

Definition at line 90 of file QualityEstimatorBase.h.


The documentation for this class was generated from the following files: