Belle II Software  release-08-01-10
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 
17 namespace Belle2 {
22  namespace vxdHoughTracking {
23 
26  public:
28  ThreeHitVariables() : m_oHit(0., 0., 0.), m_cHit(0., 0., 0.), m_iHit(0., 0., 0.),
29  m_outerDifferenceVector(0., 0., 0.), m_innerDifferenceVector(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 
176  double getCosAngleXY()
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 
226  double getDeltaSoverZ()
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
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
B2Vector3< DataType > Orthogonal() const
Vector orthogonal to this one.
Definition: B2Vector3.h:277
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.