Belle II Software development
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
16namespace 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.);
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.),
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.;
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 {
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 {
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 {
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;
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
B2Vector3D outerHit(0, 0, 0)
testing out of range behavior
Abstract base class for different kinds of events.