Belle II Software development
ThreeHitVariables.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#pragma once
9
10#include <tracking/vxdHoughTracking/filters/pathFilters/TwoHitVariables.h>
11#include <tracking/spacePointCreation/SpacePoint.h>
12#include <framework/geometry/B2Vector3.h>
13
14#include <cmath>
15#include <boost/math/special_functions/sign.hpp>
16
17namespace Belle2 {
22 namespace vxdHoughTracking {
23
26 public:
28 ThreeHitVariables() : m_oHit(0., 0., 0.), m_cHit(0., 0., 0.), m_iHit(0., 0., 0.),
30 {};
31
36 ThreeHitVariables(const B2Vector3D& oHit, const B2Vector3D& cHit, const B2Vector3D& iHit) :
37 m_oHit(oHit), m_cHit(cHit), m_iHit(iHit)
38 {
39 m_outerDifferenceVector = oHit - cHit;
40 m_innerDifferenceVector = cHit - iHit;
41 };
42
47 void setHits(const B2Vector3D& oHit, const B2Vector3D& cHit, const B2Vector3D& iHit)
48 {
49 m_oHit = oHit;
50 m_oHit = oHit;
51 m_iHit = iHit;
52 m_outerDifferenceVector = oHit - cHit;
53 m_innerDifferenceVector = cHit - iHit;
54 }
55
59 double calcAvgDistanceXY(const B2Vector3D& circleCenter)
60 {
61 return (sqrt(std::pow(circleCenter.X() - m_oHit.X(), 2) + std::pow(circleCenter.Y() - m_oHit.Y(), 2)) +
62 sqrt(std::pow(circleCenter.X() - m_cHit.X(), 2) + std::pow(circleCenter.Y() - m_cHit.Y(), 2)) +
63 sqrt(std::pow(circleCenter.X() - m_iHit.X(), 2) + std::pow(circleCenter.Y() - m_iHit.Y(), 2))) / 3.;
64 }
65
66
68 double getAngle3D()
69 {
72 return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
73 }
74
75
78 {
79 // fullCalc would be acos(m_vecAB.Dot(m_vecBC) / m_vecAB.Mag()*m_vecBC.Mag()), but here time-consuming parts have been neglected
82 return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
83 }
84
85
87 double getAngleRZ()
88 {
91 TwoHitVariables twoHitVariables(rzVecAB, rzVecBC);
92
93 double result = acos(twoHitVariables.getCosXY()); // 0-pi
94 return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
95 } // return unit: rad (0 - pi)
96
97
100 {
103 TwoHitVariables twoHitVariables(rzVecAB, rzVecBC);
104
105 return twoHitVariables.getCosXY();
106 }
107
110 double getAngleXY()
111 {
113 double result = acos(twoHitVariables.getCosXY()); // 0-pi
114 return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
115 }
116
117
120 {
121 // calculates the intersection point using Cramer's rule.
122 // x_1+s*n_1==x_2+t*n_2 --> n_1 *s - n_2 *t == x_2 - x_1 --> http://en.wikipedia.org/wiki/Cramer%27s_rule
123 double inX = m_cHit.X() - m_iHit.X(); // x value of the normal vector of the inner segment (m_cHit-m_iHit)
124 double inY = m_cHit.Y() - m_iHit.Y(); // y value of the normal vector of the inner segment (m_cHit-m_iHit)
125 double outX = m_oHit.X() - m_cHit.X(); // x value of the normal vector of the outer segment (m_oHit-m_cHit)
126 double outY = m_oHit.Y() - m_cHit.Y(); // y value of the normal vector of the outer segment (m_oHit-m_cHit)
127
128 // searching solution for Ax = b, aij are the matrix elements of A, bi are elements of b
129 double a11 = inY;
130 double a12 = -inX;
131 double a21 = -outY;
132 double a22 = outX;
133 double b1 = m_cHit.X() + outX * 0.5 - (m_iHit.X() + inX * 0.5);
134 double b2 = m_cHit.Y() + outY * 0.5 - (m_iHit.Y() + inY * 0.5);
135
136 // protect against the determinant being zero
137 if (a11 * a22 == a12 * a21) {
138 return B2Vector3D(1e30, 1e30, 1e30);
139 }
140
141 // the determinant is zero if the three hits are on a line in (x,y), which is checked above.
142 double s = (b1 * a22 - b2 * a21) / (a11 * a22 - a12 * a21);
143
144 return B2Vector3D(m_iHit.X() + inX * 0.5 + s * inY, m_iHit.Y() + inY * 0.5 - s * inX, 0.);
145 }
146
147
150 {
151 B2Vector3D circleCenter = getCircleCenterXY();
152 if (circleCenter.Perp2() > 1e30) {
153 return NAN;
154 }
155 double circleRadius = calcAvgDistanceXY(circleCenter);
156
157 // distance of closest approach of circle to the IP :
158 // WARNING only valid for IP=0,0,X
159 return (fabs(circleCenter.Perp() - circleRadius));
160 }
161
162
165 {
166 B2Vector3D circleCenter = getCircleCenterXY();
167 if (circleCenter.Perp2() > 1e30) {
168 return NAN;
169 }
170 return calcAvgDistanceXY(circleCenter);
171 }
172
173
177 {
178 double result = (m_outerDifferenceVector.X() * m_innerDifferenceVector.X() +
181
182 return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
183 }
184
185
188 {
189 TwoHitVariables outerTwoHitVariables(m_oHit, m_cHit);
190 TwoHitVariables innerTwoHitVariables(m_cHit, m_iHit);
191 double slopeOC = outerTwoHitVariables.getRZSlope();
192 double slopeCI = innerTwoHitVariables.getRZSlope();
193
194 return slopeCI - slopeOC;
195 }
196
197
200 {
201 B2Vector3D circleCenter = getCircleCenterXY();
202 if (circleCenter.Perp2() > 1e30) {
203 return NAN;
204 }
205 double circleRadius = calcAvgDistanceXY(circleCenter);
206 B2Vector3D vecOuter2cC = m_oHit - circleCenter;
207 B2Vector3D vecCenter2cC = m_cHit - circleCenter;
208 B2Vector3D vecInner2cC = m_iHit - circleCenter;
209
210 TwoHitVariables outerTwoHitVariables(vecOuter2cC, vecCenter2cC);
211 TwoHitVariables innerTwoHitVariables(vecCenter2cC, vecInner2cC);
212
213 // WARNING: this is only approximately S (valid in the limit of small angles) but might be OK for this use!!!
214 // want to replace id with 2*sin ( alfa ) * circleRadius
215 double alfaOCr = acos(outerTwoHitVariables.getCosXY()) * circleRadius ;
216 double alfaCIr = acos(innerTwoHitVariables.getCosXY()) * circleRadius ;
217
218 // Beware of z>r!:
219 double result = (asin(double(m_oHit.Z() - m_cHit.Z()) / alfaOCr)) - asin(double(m_cHit.Z() - m_iHit.Z()) / alfaCIr);
220
221 return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
222 }
223
224
227 {
228 B2Vector3D circleCenter = getCircleCenterXY();
229 if (circleCenter.Perp2() > 1e30) {
230 return NAN;
231 }
232 B2Vector3D vecOuter2cC = m_oHit - circleCenter;
233 B2Vector3D vecCenter2cC = m_cHit - circleCenter;
234 B2Vector3D vecInner2cC = m_iHit - circleCenter;
235
236 TwoHitVariables outerTwoHitVariables(vecOuter2cC, vecCenter2cC);
237 TwoHitVariables innerTwoHitVariables(vecCenter2cC, vecInner2cC);
238 double alfaOC = acos(outerTwoHitVariables.getCosXY());
239 double alfaCI = acos(innerTwoHitVariables.getCosXY());
240
241 // equals to alfaAB/dZAB and alfaBC/dZBC, but this solution here can not produce a division by zero:
242 return (alfaOC * double(m_cHit.Z() - m_iHit.Z())) - (alfaCI * double(m_oHit.Z() - m_cHit.Z()));
243 }
244
245
248 {
249 B2Vector3D circleCenter = getCircleCenterXY();
250 if (circleCenter.Perp2() > 1e30) {
251 return NAN;
252 }
253
254 B2Vector3D vecOuter2cC = m_oHit - circleCenter;
255 B2Vector3D vecCenter2cC = m_cHit - circleCenter;
256 B2Vector3D vecInner2cC = m_iHit - circleCenter;
257 TwoHitVariables outerTwoHitVariables(vecOuter2cC, vecCenter2cC);
258 TwoHitVariables innerTwoHitVariables(vecCenter2cC, vecInner2cC);
259
260 double alfaAB = outerTwoHitVariables.getCosXY();
261 double alfaBC = innerTwoHitVariables.getCosXY();
262
263 // real calculation: ratio is (m_vecij[2] = deltaZ): alfaAB/deltaZab : alfaBC/deltaZbc, the following equation saves two times '/'
264 double result = (alfaAB * double(m_cHit.Z() - m_iHit.Z())) / (alfaBC * double(m_oHit.Z() - m_cHit.Z()));
265
266 return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
267 }
268
269
272 {
273 B2Vector3D circleCenter = getCircleCenterXY();
274 if (circleCenter.Perp2() > 1e30) {
275 return NAN;
276 }
277 double circleRadius = calcAvgDistanceXY(circleCenter);
278
279 return 0.00299792458 * m_BFieldZ * circleRadius;
280 }
281
282
287 {
288 using boost::math::sign;
289 B2Vector3D ba(m_oHit.X() - m_cHit.X(), m_oHit.Y() - m_cHit.Y(), 0.0);
290 B2Vector3D bc(m_cHit.X() - m_iHit.X(), m_cHit.Y() - m_iHit.Y(), 0.0);
291 return sign(bc.Orthogonal() * ba); //normal vector of m_vecBC times segment of ba
292 }
293
297 int getCurvatureSign(const B2Vector3D& oHit, const B2Vector3D& cHit, const B2Vector3D& iHit)
298 {
299 using boost::math::sign;
300 B2Vector3D ba(oHit.X() - cHit.X(), oHit.Y() - cHit.Y(), 0.0);
301 B2Vector3D bc(cHit.X() - iHit.X(), cHit.Y() - iHit.Y(), 0.0);
302 return sign(bc.Orthogonal() * ba); //normal vector of m_vecBC times segment of ba
303 }
304
307 void setBFieldZ(const double bfieldZ = 1.5) { m_BFieldZ = bfieldZ; }
308
309 private:
311 double m_BFieldZ = 1.5;
323
324 };
325 }
327}
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:435
DataType Perp2() const
The transverse component squared (R^2 in cylindrical coordinate system).
Definition: B2Vector3.h:196
DataType X() const
access variable X (= .at(0) without boundary check)
Definition: B2Vector3.h:431
B2Vector3< DataType > Orthogonal() const
Vector orthogonal to this one.
Definition: B2Vector3.h:277
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:433
DataType Mag() const
The magnitude (rho in spherical coordinate system).
Definition: B2Vector3.h:159
DataType Mag2() const
The magnitude squared (rho^2 in spherical coordinate system).
Definition: B2Vector3.h:157
DataType Dot(const B2Vector3< DataType > &p) const
Scalar product.
Definition: B2Vector3.h:290
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
Definition: B2Vector3.h:200
Class that allows the calculation of simple variables to estimate the quality of a triplet of hits.
double getCosAngleRZSimple()
calculates the cosine of the angle between the hits/vectors (RZ), returning unit: none (calculation f...
double getDeltaSlopeZoverS()
compares the "slopes" z over arc length. calcDeltaSlopeZOverS is invariant under rotations in the r-z...
int getCurvatureSign(const B2Vector3D &oHit, const B2Vector3D &cHit, const B2Vector3D &iHit)
calculates calculates the sign of the curvature of 3-hit-tracklet given as arguments.
B2Vector3D getCircleCenterXY()
calculates an estimation of circleCenter position, result is returned as the x and y value of the B2V...
int getCurvatureSign()
calculates calculates the sign of the curvature of given 3-hit-tracklet.
void setBFieldZ(const double bfieldZ=1.5)
Set the B-Field value used for pT calculations.
double getDeltaSoverZ()
calculates the helixparameter describing the deviation in arc length per unit in z....
B2Vector3D m_outerDifferenceVector
The following two differences are used very often, so calculate once on construction vector containin...
double calcAvgDistanceXY(const B2Vector3D &circleCenter)
helper function which calculates the average distance in XY from the given center
double getAngle3D()
calculates the angle between the hits/vectors (3D), returning unit: angle in radian
ThreeHitVariables(const B2Vector3D &oHit, const B2Vector3D &cHit, const B2Vector3D &iHit)
actual useful constructor
void setHits(const B2Vector3D &oHit, const B2Vector3D &cHit, const B2Vector3D &iHit)
Set hits if not given in constructor of if they need to be changed.
double getCosAngleXY()
calculates the angle between the hits/vectors (XY), returning unit: none (calculation for degrees is ...
double m_BFieldZ
BField along z to estimate pT.
double getCircleDistanceIP()
calculates the distance of the point of closest approach of circle to the IP, returning unit: cm
B2Vector3D m_oHit
outermost hit position
B2Vector3D m_iHit
innermost hit position
double getSimplePTEstimate()
calculates the estimation of the transverse momentum of the 3-hit-tracklet, returning unit: GeV/c
double performHelixParamterFit()
calculates the helixparameter describing the deviation in z per unit angle, returning unit: none
B2Vector3D m_innerDifferenceVector
vector containing the difference m_cHit - m_iHit
double getAngleRZ()
calculates the angle between the hits/vectors (RZ), returning unit: angle in radian
double getAngle3DSimple()
calculates the angle between the hits/vectors (3D), returning unit: none (calculation for degrees is ...
double getCircleRadius()
calculates the estimation of the circle radius of the 3-hit-tracklet, returning unit: cm.
double getDeltaSlopeRZ()
calculates deviations in the slope of the inner segment and the outer segment, returning unit: none
double getAngleXY()
Calculates the angle in x-y between two vectors return unit: rad (0 - pi)
Class that allows the calculation of simple variables to check whether a combination of two hits shou...
double getCosXY()
calculate the cosine of the angle between two vectors in x-y
double getRZSlope()
get an estimate for the slope in R-z, similar to theta
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:516
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.