Belle II Software  release-08-01-10
ThreeHitFilters.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 
9 #pragma once
10 
11 #include <framework/geometry/B2Vector3.h>
12 #include "tracking/vxdCaTracking/TwoHitFilters.h"
13 #include "tracking/vxdCaTracking/FilterExceptions.h"
14 #include <framework/logging/Logger.h>
15 
16 namespace Belle2 {
24  public:
25 
29  m_radiusCalculated(false),
30  m_radius(0.),
31  m_x2(0.),
32  m_y2(0.),
33  m_z2(0.)
34  {
35  m_hitA.SetXYZ(0., 0., 0.);
36  m_hitB.SetXYZ(0., 0., 0.);
37  m_hitC.SetXYZ(0., 0., 0.);
38  m_vecAB.SetXYZ(0., 0., 0.);
39  m_vecBC.SetXYZ(0., 0., 0.);
40  resetMagneticField(1.5);
41  }
42 
44  ThreeHitFilters(const B2Vector3D& outerHit, const B2Vector3D& centerHit, const B2Vector3D& innerHit,
45  const double magneticFieldStrength = 1.5):
47  m_radiusCalculated(false),
48  m_radius(0.),
49  m_hitA(outerHit),
50  m_hitB(centerHit),
51  m_hitC(innerHit),
52  m_vecAB(outerHit - centerHit),
53  m_vecBC(centerHit - innerHit)
54  {
55  m_x2 = m_vecAB[0] * m_vecBC[0];
56  m_y2 = m_vecAB[1] * m_vecBC[1];
57  m_z2 = m_vecAB[2] * m_vecBC[2];
58  resetMagneticField(magneticFieldStrength);
59  }
60 
61 
64 
66  void resetValues(const B2Vector3D& outerHit, const B2Vector3D& centerHit, const B2Vector3D& innerHit)
67  {
68  m_radiusCalculated = false;
70  m_radius = 0.;
71  m_hitA = outerHit;
72  m_hitB = centerHit;
73  m_hitC = innerHit;
74  m_vecAB = outerHit - centerHit;
75  m_vecBC = centerHit - innerHit;
76 
77  m_x2 = m_vecAB[0] * m_vecBC[0];
78  m_y2 = m_vecAB[1] * m_vecBC[1];
79  m_z2 = m_vecAB[2] * m_vecBC[2];
80  }
81 
82 
83 
89  void resetMagneticField(const double magneticFieldStrength = 1.5) { m_magneticFieldFactor = magneticFieldStrength * 0.00299710; }
90 
91 
92 
94  double getMagneticField() { return m_magneticFieldFactor / 0.00299710; }
95 
96 
97 
99  double filterNan(double value) { return m_twoHitFilter.filterNan(value); }
100 
101 
102 
104  double calcAngle3D()
105  {
106  double angle = ((m_x2 + m_y2 + m_z2) / (m_vecAB.Mag2() *
107  m_vecBC.Mag2())); // fullCalc would be acos(m_vecAB.Dot(m_vecBC) / m_vecAB.Mag()*m_vecBC.Mag())
108  return filterNan(angle);
109  } // return unit: none (calculation for degrees is incomplete, if you want readable numbers, use fullAngle3D instead)
110 
111 
112 
114  double fullAngle3D()
115  {
116  double angle = acos(m_vecAB.Dot(m_vecBC) / (m_vecAB.Mag() * m_vecBC.Mag())); // 0-pi
117  angle = (angle * (180. / M_PI));
118  return filterNan(angle);
119  } // return unit: ° (0 - 180°)
120 
121 
122 
124  double calcAngleXY()
125  {
126  double angle = ((m_x2 + m_y2) / (m_vecAB.Perp2() * m_vecBC.Perp2())); // fullAngle:
127  return filterNan(angle);
128  } // return unit: none (calculation for degrees is incomplete, if you want readable numbers, use fullAngleXY instead)
129 
130 
131 
133  double fullAngleXY()
134  {
135  double angle = fullAngle2D(m_vecAB, m_vecBC); // 0-pi
136  angle = (angle * (180. / M_PI));
137  return filterNan(angle);
138  } // return unit: ° (0 - 180°)
139 
140 
141 
143  double calcAngleRZ()
144  {
145  B2Vector3D rzVecAB(m_vecAB.Perp(), m_vecAB[2], 0.);
146  B2Vector3D rzVecBC(m_vecBC.Perp(), m_vecBC[2], 0.);
147  return calcAngle2D(rzVecAB, rzVecBC);
148  } // return unit: none (calculation for degrees is incomplete, if you want readable numbers, use fullAngleRZ instead)
149 
150 
151 
153  double fullAngleRZ()
154  {
155  B2Vector3D rzVecAB(m_vecAB.Perp(), m_vecAB[2], 0.);
156  B2Vector3D rzVecBC(m_vecBC.Perp(), m_vecBC[2], 0.);
157  double angle = fullAngle2D(rzVecAB, rzVecBC); // 0-pi
158  angle = (angle * (180. / M_PI));
159  return filterNan(angle);
160  } // return unit: ° (0 - 180°)
161 
162 
163 
166  {
167  checkCalcRadius();
168 
169  return (fabs(m_centerABC.Perp() - m_radius)); // distance of closest approach of circle to the IP
170  } // return unit: cm
171 
172 
173 
175  double calcPt()
176  {
177  checkCalcRadius();
178 
179  return calcPt(m_radius);
180  } // return unit: GeV/c
181 
182 
183 
185  double calcPt(double radius)
186  {
187  sanityCheckRadius(radius);
188 
189  return (m_magneticFieldFactor * radius);
190  } // return unit: GeV/c
191 
192 
193 
196  {
198  double slopeAB = m_twoHitFilter.calcSlopeRZ();
200  double slopeBC = m_twoHitFilter.calcSlopeRZ();
201 
202  return filterNan(slopeBC - slopeAB);
203  } // return unit: none
204 
205 
206 
212  {
214 
215  B2Vector3D points2hitA = m_hitA - m_centerABC;
216  B2Vector3D points2hitB = m_hitB - m_centerABC;
217  B2Vector3D points2hitC = m_hitC - m_centerABC;
218  double alfaAB = fullAngle2D(points2hitA, points2hitB);
219  double alfaBC = fullAngle2D(points2hitB, points2hitC);
220  //return filterNan( (alfaAB * m_vecBC[2]) - (alfaBC *m_vecAB[2]) );
221  return (alfaAB * m_vecBC[2]) - (alfaBC *
222  m_vecAB[2]); // equals to alfaAB/dZAB and alfaBC/dZBC, but this solution here can not produce a division by zero
223  } // return unit: radians*cm
224 
225 
226 
229  {
230  checkCalcRadius();
231 
232  B2Vector3D points2hitA = m_hitA - m_centerABC;
233  B2Vector3D points2hitB = m_hitB - m_centerABC;
234  B2Vector3D points2hitC = m_hitC - m_centerABC;
235  double alfaABr = fullAngle2D(points2hitA, points2hitB) * m_radius;
236  double alfaBCr = fullAngle2D(points2hitB, points2hitC) * m_radius;
237 
238  return filterNan((asin(m_vecAB[2] / alfaABr)) - asin(m_vecBC[2] / alfaBCr)); // Beware of z>r!
239  }
240 
241 
242 
245  {
247  B2Vector3D points2hitA = m_hitA - m_centerABC;
248  B2Vector3D points2hitB = m_hitB - m_centerABC;
249  B2Vector3D points2hitC = m_hitC - m_centerABC;
250  double alfaAB = calcAngle2D(points2hitA, points2hitB);
251  double alfaBC = calcAngle2D(points2hitB, points2hitC);
252  // real calculation: ratio is (m_vecij[2] = deltaZ): alfaAB/deltaZab : alfaBC/deltaZbc, the following equation saves two times '/'
253  return filterNan((alfaAB * m_vecBC[2]) / (alfaBC * m_vecAB[2]));
254  } // return unit: none
255 
256 
257 
259  double calcHelixFit() { return calcHelixParameterFit(); }
260 
261 
262 
264  double calcAngle2D(const B2Vector3D& vecA, const B2Vector3D& vecB)
265  {
266  double angle = ((vecA[0] * vecB[0] + vecA[1] * vecB[1]) / sqrt(vecA.Perp2() * vecB.Perp2()));
267  return filterNan(angle);
268  }
269 
273  double fullAngle2D(const B2Vector3D& vecA, const B2Vector3D& vecB)
274  {
275  return acos(calcAngle2D(vecA, vecB));
276  //return filterNan(angle);
277  }
278 
279 
280 
282  double calcRadius(const B2Vector3D& a, const B2Vector3D& b, const B2Vector3D& c, const B2Vector3D& circleCenter)
283  {
284  return ((circleCenter - a).Perp() + (circleCenter - b).Perp() + (circleCenter - c).Perp()) /
285  3.; // = radius in [cm], sign here not needed. normally: signKappaAB/normAB1
286  } // used by calcPt() and calcCircleDist2IP()
287 
288 
289 
291  void calcCircleCenter(const B2Vector3D& a, const B2Vector3D& b, const B2Vector3D& c, B2Vector3D& circleCenter)
292  {
293  // calculates the intersection point using Cramer's rule.
294  // 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
295  double inX = b[0] - c[0]; // x value of the normal vector of the inner segment (b-c)
296  double inY = b[1] - c[1]; // y value of the normal vector of the inner segment (b-c)
297  double outX = a[0] - b[0]; // x value of the normal vector of the outer segment (a-b)
298  double outY = a[1] - b[1]; // y value of the normal vector of the outer segment (a-b)
299 
300  //searching solution for Ax = b, aij are the matrix elements of A, bi are elements of b
301  double a11 = inY;
302  double a12 = -inX;
303  double a21 = -outY;
304  double a22 = outX;
305  double b1 = b[0] + outX * 0.5 - (c[0] + inX * 0.5);
306  double b2 = b[1] + outY * 0.5 - (c[1] + inY * 0.5);
307 
308  if (a11 * a22 == a12 * a21) { throw FilterExceptions::Straight_Line(); }
309 
310  double s = (b1 * a22 - b2 * a21) / (a11 * a22 - a12 * a21); //the determinant is zero iff the three hits are on a line in (x,y).
311 
312  circleCenter.SetXYZ(c[0] + inX * 0.5 + s * inY, c[1] + inY * 0.5 - s * inX, 0.);
313  }
314 
315 
316 
318  int calcSign(const B2Vector3D& a, const B2Vector3D& b, const B2Vector3D& c);
319 
320 
321 
323  int calcSign(const B2Vector3D& a, const B2Vector3D& b, const B2Vector3D& c, const B2Vector3D& sigma_a, const B2Vector3D& sigma_b,
324  const B2Vector3D& sigma_c)
325  {
326  B2Vector3D c2b = b - c; c2b.SetZ(0.);
327  B2Vector3D b2a = a - b; b2a.SetZ(0.);
328  double angle = atan2(b2a[0], b2a[1]) - atan2(c2b[0], c2b[1]);
329  double sigmaan = (sigma_a.Mag() + sigma_b.Mag() + sigma_c.Mag()) / (3.*(c2b.Mag() +
330  b2a.Mag())); //TODO 1/3...mean of the sigmas. Possible improvement: Use a parameter instead, and determine with simulated events.
331  if (angle < (-sigmaan)) { return -1; }
332  else if (angle > sigmaan) {return 1; }
333  else { return 0; }
334  }
335 
336 
337 
338  protected:
339 
340 
343  {
344  if (m_circleCenterCalculated == false) {
347  }
348  }
349 
350 
353  {
355  if (m_radiusCalculated == false) {
358  m_radiusCalculated = true;
359  }
360  }
361 
362 
364  void sanityCheckRadius(double radius)
365  {
366  if (fabs(radius) <
367  0.0000001) { // WARNING hardcoded value, is there a quasi-global value for such cases (this case, minimal accepted radius)
368  m_radiusCalculated = false;
369  m_circleCenterCalculated = false;
370  m_radius = 0.;
371  B2ERROR("sanityCheckRadius: given radius is " << radius << ", which is below threshold of " << 0.0000001 << ", throwing exception");
372  throw FilterExceptions::Circle_too_small();
373  }
374  }
375 
376 
377 
382  double m_radius;
383  double m_x2;
384  double m_y2;
385  double m_z2;
394  }; //end class ThreeHitFilters
396 } //end namespace Belle2
DataType Perp2() const
The transverse component squared (R^2 in cylindrical coordinate system).
Definition: B2Vector3.h:196
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
void SetZ(DataType z)
set Z/3rd-coordinate
Definition: B2Vector3.h:461
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
void SetXYZ(DataType x, DataType y, DataType z)
set all coordinates using data type
Definition: B2Vector3.h:464
The class 'ThreeHitFilters' bundles filter methods using 3 hits which are stored in B2Vector3Ds.
~ThreeHitFilters()
Destructor.
double calcAngle3D()
calculates the angle between the hits/vectors (3D), returning unit: none (calculation for degrees is ...
double calcDeltaSOverZ()
calculates the helixparameter describing the deviation in arc length per unit in z.
double fullAngle3D()
calculates the angle between the hits/vectors (3D), returning unit: angle in degrees
bool m_circleCenterCalculated
initially set to false, will be set true if calcCircleCenter() is used at least once
ThreeHitFilters(const B2Vector3D &outerHit, const B2Vector3D &centerHit, const B2Vector3D &innerHit, const double magneticFieldStrength=1.5)
Constructor.
double m_radius
radius[cm] of a circle in r-phi-plane formed by the 3 hits
void resetValues(const B2Vector3D &outerHit, const B2Vector3D &centerHit, const B2Vector3D &innerHit)
Overrides Constructor-Setup.
double calcPt()
calculates the estimation of the transverse momentum of the 3-hit-tracklet, returning unit: GeV/c
double calcHelixFit()
reverse compatibility, calls calcHelixParameterFit
double fullAngleRZ()
calculates the angle between the hits/vectors (RZ), returning unit: angle in degrees
double m_x2
internal intermediate value storing x^2, no enduser-relevance
bool m_radiusCalculated
initially set to false, will be set true if calcInvCurvature() is used at least once
void checkCalcCircleCenter()
checks whether the calcCircleCenter()-Member has been executed already and executes it if not
B2Vector3D m_centerABC
center position of a circle in r-phi-plane formed by the 3 hits
void calcCircleCenter(const B2Vector3D &a, const B2Vector3D &b, const B2Vector3D &c, B2Vector3D &circleCenter)
calculates an estimation of circleCenter position, result is written into the 4th input-parameter
B2Vector3D m_vecAB
vector pointing from center hit to outer hit (outer segment)
double calcRadius(const B2Vector3D &a, const B2Vector3D &b, const B2Vector3D &c, const B2Vector3D &circleCenter)
calculates an estimation of the radius of given hits and existing estimation of circleCenter,...
double filterNan(double value)
returns zero if value is nan or inf
double calcDeltaSlopeRZ()
calculates deviations in the slope of the inner segment and the outer segment, returning unit: none
B2Vector3D m_hitB
center hit (position relevant for useful filter calculation) used for the filter calculation
B2Vector3D m_vecBC
vector pointing from inner hit to center hit (inner segment)
double getMagneticField()
returns the set value of the magnetic field in Tesla
double m_y2
internal intermediate value storing y^2, no enduser-relevance
double calcAngleRZ()
calculates the angle between the hits/vectors (RZ), returning unit: none (calculation for degrees is ...
double fullAngleXY()
calculates the angle between the hits/vectors (XY), returning unit: angle in degrees
void sanityCheckRadius(double radius)
check Radius for bad values and throw exception if the value is bad
double calcDeltaSlopeZOverS()
compares the "slopes" z over arc length.
double calcCircleDist2IP()
calculates the distance of the point of closest approach of circle to the IP, returning unit: cm
double fullAngle2D(const B2Vector3D &vecA, const B2Vector3D &vecB)
calculates the angle between the hits/vectors (2D), generalized, returning unit: angle in radians WAR...
void resetMagneticField(const double magneticFieldStrength=1.5)
Overrides Constructor-Setup for magnetic field.
double m_z2
internal intermediate value storing z^2, no enduser-relevance
double calcPt(double radius)
calculates the estimation of the transverse momentum of given radius using defined strength of magnet...
int calcSign(const B2Vector3D &a, const B2Vector3D &b, const B2Vector3D &c, const B2Vector3D &sigma_a, const B2Vector3D &sigma_b, const B2Vector3D &sigma_c)
calculates calculates the sign of the curvature of given 3-hit-tracklet.
TwoHitFilters m_twoHitFilter
instance of TwoHitFilters-class used for some internal calculations
B2Vector3D m_hitC
inner hit (position relevant for useful filter calculation) used for the filter calculation
double calcHelixParameterFit()
calculates the helixparameter describing the deviation in z per unit angle, returning unit: none
void checkCalcRadius()
checks whether the calcRadius()-Member has been executed already and executes it if not
double m_magneticFieldFactor
is factor containing speed of light (c), the magnetic field (b) and the scaling factor s for conversi...
double calcAngle2D(const B2Vector3D &vecA, const B2Vector3D &vecB)
calculates the angle between the hits/vectors (2D), generalized, returning unit: none.
double calcAngleXY()
calculates the angle between the hits/vectors (XY), returning unit: none (calculation for degrees is ...
int calcSign(const B2Vector3D &a, const B2Vector3D &b, const B2Vector3D &c)
calculates calculates the sign of the curvature of given 3-hit-tracklet.
ThreeHitFilters()
Empty constructor.
B2Vector3D m_hitA
outer hit (position relevant for useful filter calculation) used for the filter calculation
The class 'TwoHitFilters' bundles filter methods using 2 hits which are stored in B2Vector3Ds.
Definition: TwoHitFilters.h:22
double filterNan(double value) const
nice little nanChecker returns 0 if value was nan or inf, else returns value itself
double calcSlopeRZ() const
calculates the angle of the slope of the hits in RZ, returnValue = theta = atan(r/z)
Definition: TwoHitFilters.h:70
void resetValues(const B2Vector3D &outerHit, const B2Vector3D &innerHit)
Overrides Constructor-Setup.
Definition: TwoHitFilters.h:46
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.