Belle II Software  release-06-02-00
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 
16 namespace Belle2 {
21  namespace vxdHoughTracking {
22 
25  public:
27  ThreeHitVariables() : m_oHit(0., 0., 0.), m_cHit(0., 0., 0.), m_iHit(0., 0., 0.),
28  m_outerDifferenceVector(0., 0., 0.), m_innerDifferenceVector(0., 0., 0.)
29  {};
30 
35  ThreeHitVariables(const B2Vector3D& oHit, const B2Vector3D& cHit, const B2Vector3D& iHit) :
36  m_oHit(oHit), m_cHit(cHit), m_iHit(iHit)
37  {
38  m_outerDifferenceVector = oHit - cHit;
39  m_innerDifferenceVector = cHit - iHit;
40  };
41 
46  void setHits(const B2Vector3D& oHit, const B2Vector3D& cHit, const B2Vector3D& iHit)
47  {
48  m_oHit = oHit;
49  m_oHit = oHit;
50  m_iHit = iHit;
51  m_outerDifferenceVector = oHit - cHit;
52  m_innerDifferenceVector = cHit - iHit;
53  }
54 
58  double calcAvgDistanceXY(const B2Vector3D& circleCenter)
59  {
60  return (sqrt(std::pow(circleCenter.X() - m_oHit.X(), 2) + std::pow(circleCenter.Y() - m_oHit.Y(), 2)) +
61  sqrt(std::pow(circleCenter.X() - m_cHit.X(), 2) + std::pow(circleCenter.Y() - m_cHit.Y(), 2)) +
62  sqrt(std::pow(circleCenter.X() - m_iHit.X(), 2) + std::pow(circleCenter.Y() - m_iHit.Y(), 2))) / 3.;
63  }
64 
65 
67  double getAngle3D()
68  {
71  return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
72  }
73 
74 
77  {
78  // fullCalc would be acos(m_vecAB.Dot(m_vecBC) / m_vecAB.Mag()*m_vecBC.Mag()), but here time-consuming parts have been neglected
81  return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
82  }
83 
84 
86  double getAngleRZ()
87  {
90  TwoHitVariables twoHitVariables(rzVecAB, rzVecBC);
91 
92  double result = acos(twoHitVariables.getCosXY()); // 0-pi
93  return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
94  } // return unit: rad (0 - pi)
95 
96 
99  {
102  TwoHitVariables twoHitVariables(rzVecAB, rzVecBC);
103 
104  return twoHitVariables.getCosXY();
105  }
106 
109  double getAngleXY()
110  {
112  double result = acos(twoHitVariables.getCosXY()); // 0-pi
113  return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
114  }
115 
116 
119  {
120  // calculates the intersection point using Cramer's rule.
121  // 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
122  double inX = m_cHit.X() - m_iHit.X(); // x value of the normal vector of the inner segment (m_cHit-m_iHit)
123  double inY = m_cHit.Y() - m_iHit.Y(); // y value of the normal vector of the inner segment (m_cHit-m_iHit)
124  double outX = m_oHit.X() - m_cHit.X(); // x value of the normal vector of the outer segment (m_oHit-m_cHit)
125  double outY = m_oHit.Y() - m_cHit.Y(); // y value of the normal vector of the outer segment (m_oHit-m_cHit)
126 
127  // searching solution for Ax = b, aij are the matrix elements of A, bi are elements of b
128  double a11 = inY;
129  double a12 = -inX;
130  double a21 = -outY;
131  double a22 = outX;
132  double b1 = m_cHit.X() + outX * 0.5 - (m_iHit.X() + inX * 0.5);
133  double b2 = m_cHit.Y() + outY * 0.5 - (m_iHit.Y() + inY * 0.5);
134 
135  // protect against the determinant being zero
136  if (a11 * a22 == a12 * a21) {
137  return B2Vector3D(1e30, 1e30, 1e30);
138  }
139 
140  // the determinant is zero if the three hits are on a line in (x,y), which is checked above.
141  double s = (b1 * a22 - b2 * a21) / (a11 * a22 - a12 * a21);
142 
143  return B2Vector3D(m_iHit.X() + inX * 0.5 + s * inY, m_iHit.Y() + inY * 0.5 - s * inX, 0.);
144  }
145 
146 
149  {
150  B2Vector3D circleCenter = getCircleCenterXY();
151  if (circleCenter.Perp2() > 1e30) {
152  return NAN;
153  }
154  double circleRadius = calcAvgDistanceXY(circleCenter);
155 
156  // distance of closest approach of circle to the IP :
157  // WARNING only valid for IP=0,0,X
158  return (fabs(circleCenter.Perp() - circleRadius));
159  }
160 
161 
164  {
165  B2Vector3D circleCenter = getCircleCenterXY();
166  if (circleCenter.Perp2() > 1e30) {
167  return NAN;
168  }
169  return calcAvgDistanceXY(circleCenter);
170  }
171 
172 
175  double getCosAngleXY()
176  {
177  double result = (m_outerDifferenceVector.X() * m_innerDifferenceVector.X() +
180 
181  return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
182  }
183 
184 
187  {
188  TwoHitVariables outerTwoHitVariables(m_oHit, m_cHit);
189  TwoHitVariables innerTwoHitVariables(m_cHit, m_iHit);
190  double slopeOC = outerTwoHitVariables.getRZSlope();
191  double slopeCI = innerTwoHitVariables.getRZSlope();
192 
193  return slopeCI - slopeOC;
194  }
195 
196 
199  {
200  B2Vector3D circleCenter = getCircleCenterXY();
201  if (circleCenter.Perp2() > 1e30) {
202  return NAN;
203  }
204  double circleRadius = calcAvgDistanceXY(circleCenter);
205  B2Vector3D vecOuter2cC = m_oHit - circleCenter;
206  B2Vector3D vecCenter2cC = m_cHit - circleCenter;
207  B2Vector3D vecInner2cC = m_iHit - circleCenter;
208 
209  TwoHitVariables outerTwoHitVariables(vecOuter2cC, vecCenter2cC);
210  TwoHitVariables innerTwoHitVariables(vecCenter2cC, vecInner2cC);
211 
212  // WARNING: this is only approximately S (valid in the limit of small angles) but might be OK for this use!!!
213  // want to replace id with 2*sin ( alfa ) * circleRadius
214  double alfaOCr = acos(outerTwoHitVariables.getCosXY()) * circleRadius ;
215  double alfaCIr = acos(innerTwoHitVariables.getCosXY()) * circleRadius ;
216 
217  // Beware of z>r!:
218  double result = (asin(double(m_oHit.Z() - m_cHit.Z()) / alfaOCr)) - asin(double(m_cHit.Z() - m_iHit.Z()) / alfaCIr);
219 
220  return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
221  }
222 
223 
225  double getDeltaSoverZ()
226  {
227  B2Vector3D circleCenter = getCircleCenterXY();
228  if (circleCenter.Perp2() > 1e30) {
229  return NAN;
230  }
231  B2Vector3D vecOuter2cC = m_oHit - circleCenter;
232  B2Vector3D vecCenter2cC = m_cHit - circleCenter;
233  B2Vector3D vecInner2cC = m_iHit - circleCenter;
234 
235  TwoHitVariables outerTwoHitVariables(vecOuter2cC, vecCenter2cC);
236  TwoHitVariables innerTwoHitVariables(vecCenter2cC, vecInner2cC);
237  double alfaOC = acos(outerTwoHitVariables.getCosXY());
238  double alfaCI = acos(innerTwoHitVariables.getCosXY());
239 
240  // equals to alfaAB/dZAB and alfaBC/dZBC, but this solution here can not produce a division by zero:
241  return (alfaOC * double(m_cHit.Z() - m_iHit.Z())) - (alfaCI * double(m_oHit.Z() - m_cHit.Z()));
242  }
243 
244 
247  {
248  B2Vector3D circleCenter = getCircleCenterXY();
249  if (circleCenter.Perp2() > 1e30) {
250  return NAN;
251  }
252 
253  B2Vector3D vecOuter2cC = m_oHit - circleCenter;
254  B2Vector3D vecCenter2cC = m_cHit - circleCenter;
255  B2Vector3D vecInner2cC = m_iHit - circleCenter;
256  TwoHitVariables outerTwoHitVariables(vecOuter2cC, vecCenter2cC);
257  TwoHitVariables innerTwoHitVariables(vecCenter2cC, vecInner2cC);
258 
259  double alfaAB = outerTwoHitVariables.getCosXY();
260  double alfaBC = innerTwoHitVariables.getCosXY();
261 
262  // real calculation: ratio is (m_vecij[2] = deltaZ): alfaAB/deltaZab : alfaBC/deltaZbc, the following equation saves two times '/'
263  double result = (alfaAB * double(m_cHit.Z() - m_iHit.Z())) / (alfaBC * double(m_oHit.Z() - m_cHit.Z()));
264 
265  return (std::isnan(result) || std::isinf(result)) ? double(0) : result;
266  }
267 
268 
271  {
272  B2Vector3D circleCenter = getCircleCenterXY();
273  if (circleCenter.Perp2() > 1e30) {
274  return NAN;
275  }
276  double circleRadius = calcAvgDistanceXY(circleCenter);
277 
278  return 0.00299792458 * m_BFieldZ * circleRadius;
279  }
280 
281 
286  {
287  using boost::math::sign;
288  B2Vector3D ba(m_oHit.X() - m_cHit.X(), m_oHit.Y() - m_cHit.Y(), 0.0);
289  B2Vector3D bc(m_cHit.X() - m_iHit.X(), m_cHit.Y() - m_iHit.Y(), 0.0);
290  return sign(bc.Orthogonal() * ba); //normal vector of m_vecBC times segment of ba
291  }
292 
296  int getCurvatureSign(const B2Vector3D& oHit, const B2Vector3D& cHit, const B2Vector3D& iHit)
297  {
298  using boost::math::sign;
299  B2Vector3D ba(oHit.X() - cHit.X(), oHit.Y() - cHit.Y(), 0.0);
300  B2Vector3D bc(cHit.X() - iHit.X(), cHit.Y() - iHit.Y(), 0.0);
301  return sign(bc.Orthogonal() * ba); //normal vector of m_vecBC times segment of ba
302  }
303 
306  void setBFieldZ(const double bfieldZ = 1.5) { m_BFieldZ = bfieldZ; }
307 
308  private:
310  double m_BFieldZ = 1.5;
322 
323  };
324  }
326 }
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:420
DataType Perp2() const
The transverse component squared (R^2 in cylindrical coordinate system).
Definition: B2Vector3.h:181
DataType X() const
access variable X (= .at(0) without boundary check)
Definition: B2Vector3.h:416
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:418
DataType Mag() const
The magnitude (rho in spherical coordinate system).
Definition: B2Vector3.h:144
DataType Mag2() const
The magnitude squared (rho^2 in spherical coordinate system).
Definition: B2Vector3.h:142
DataType Dot(const B2Vector3< DataType > &p) const
Scalar product.
Definition: B2Vector3.h:275
B2Vector3< DataType > Orthogonal() const
Vector orthogonal to this one.
Definition: B2Vector3.h:262
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
Definition: B2Vector3.h:185
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:493
Abstract base class for different kinds of events.