Project
Loading...
Searching...
No Matches
HelixHelper.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
16#ifndef _ALICEO2_HELIX_HELPER_
17#define _ALICEO2_HELIX_HELPER_
18
20#include "MathUtils/Utils.h"
22
23namespace o2
24{
25namespace track
26{
27
29//< precalculated track radius, center, alpha sin,cos and their combinations
30struct TrackAuxPar : public o2::math_utils::CircleXYf_t {
31 float c, s, cc, ss, cs; // cos ans sin of track alpha and their products
32
33 TrackAuxPar() = default;
34
35 template <typename T>
36 TrackAuxPar(const T& trc, float bz)
37 {
38 set(trc, bz);
39 }
40 float cosDif(const TrackAuxPar& t) const { return c * t.c + s * t.s; } // cos(alpha_this - alha_t)
41 float sinDif(const TrackAuxPar& t) const { return s * t.c - c * t.s; } // sin(alpha_this - alha_t)
42
43 template <typename T>
44 void set(const T& trc, float bz)
45 {
46 trc.getCircleParams(bz, *this, s, c);
47 cc = c * c;
48 ss = s * s;
49 cs = c * s;
50 }
52};
53
54//__________________________________________________________
55//< crossing coordinates of 2 circles
56struct CrossInfo {
57 static constexpr float MaxDistXYDef = 10.;
58 float xDCA[2] = {};
59 float yDCA[2] = {};
60 int nDCA = 0;
61
63 {
64 const auto& trcA = trax0.rC > trax1.rC ? trax0 : trax1; // designate the largest circle as A
65 const auto& trcB = trax0.rC > trax1.rC ? trax1 : trax0;
66 float xDist = trcB.xC - trcA.xC, yDist = trcB.yC - trcA.yC;
67 float dist2 = xDist * xDist + yDist * yDist, dist = std::sqrt(dist2), rsum = trcA.rC + trcB.rC;
68 if (std::abs(dist) < 1e-12) {
69 return nDCA; // circles are concentric?
70 }
71 if (dist > rsum) { // circles don't touch, chose a point in between
72 // the parametric equation of lines connecting the centers is
73 // x = x0 + t/dist * (x1-x0), y = y0 + t/dist * (y1-y0)
74 if (dist - rsum > maxDistXY) { // too large distance
75 return nDCA;
76 }
77 notTouchingXY(dist, xDist, yDist, trcA, trcB.rC);
78 } else if (dist + trcB.rC < trcA.rC) { // the small circle is nestled into large one w/o touching
79 // select the point of closest approach of 2 circles
80 notTouchingXY(dist, xDist, yDist, trcA, -trcB.rC);
81 } else { // 2 intersection points
82 // to simplify calculations, we move to new frame x->x+Xc0, y->y+Yc0, so that
83 // the 1st one is centered in origin
84 if (std::abs(xDist) < std::abs(yDist)) {
85 float a = (trcA.rC * trcA.rC - trcB.rC * trcB.rC + dist2) / (2. * yDist), b = -xDist / yDist, ab = a * b, bb = b * b;
86 float det = ab * ab - (1. + bb) * (a * a - trcA.rC * trcA.rC);
87 if (det > 0.) {
88 det = std::sqrt(det);
89 xDCA[0] = (-ab + det) / (1. + b * b);
90 yDCA[0] = a + b * xDCA[0] + trcA.yC;
91 xDCA[0] += trcA.xC;
92 xDCA[1] = (-ab - det) / (1. + b * b);
93 yDCA[1] = a + b * xDCA[1] + trcA.yC;
94 xDCA[1] += trcA.xC;
95 nDCA = 2;
96 } else { // due to the finite precision the det<=0, i.e. the circles are barely touching, fall back to this special case
97 notTouchingXY(dist, xDist, yDist, trcA, trcB.rC);
98 }
99 } else {
100 float a = (trcA.rC * trcA.rC - trcB.rC * trcB.rC + dist2) / (2. * xDist), b = -yDist / xDist, ab = a * b, bb = b * b;
101 float det = ab * ab - (1. + bb) * (a * a - trcA.rC * trcA.rC);
102 if (det > 0.) {
103 det = std::sqrt(det);
104 yDCA[0] = (-ab + det) / (1. + bb);
105 xDCA[0] = a + b * yDCA[0] + trcA.xC;
106 yDCA[0] += trcA.yC;
107 yDCA[1] = (-ab - det) / (1. + bb);
108 xDCA[1] = a + b * yDCA[1] + trcA.xC;
109 yDCA[1] += trcA.yC;
110 nDCA = 2;
111 } else { // due to the finite precision the det<=0, i.e. the circles are barely touching, fall back to this special case
112 notTouchingXY(dist, xDist, yDist, trcA, trcB.rC);
113 }
114 }
115 }
116 return nDCA;
117 }
118
119 void notTouchingXY(float dist, float xDist, float yDist, const TrackAuxPar& trcA, float rBSign)
120 {
121 // fast method to calculate DCA between 2 circles, assuming that they don't touch each outer:
122 // the parametric equation of lines connecting the centers is x = xA + t/dist * xDist, y = yA + t/dist * yDist
123 // with xA,yY being the center of the circle A ( = trcA.xC, trcA.yC ), xDist = trcB.xC = trcA.xC ...
124 // There are 2 special cases:
125 // (a) small circle is inside the large one: provide rBSign as -trcB.rC
126 // (b) circle are side by side: provide rBSign as trcB.rC
127 nDCA = 1;
128 auto t2d = (dist + trcA.rC - rBSign) / dist;
129 xDCA[0] = trcA.xC + 0.5 * (xDist * t2d);
130 yDCA[0] = trcA.yC + 0.5 * (yDist * t2d);
131 }
132
133 template <typename T>
134 int linesCrossInfo(const TrackAuxPar& trax0, const T& tr0,
135 const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef)
136 {
150
151 float dx = trax1.xC - trax0.xC; // for straight line TrackAuxPar stores lab coordinates at referene point!!!
152 float dy = trax1.yC - trax0.yC; //
153 float dz = tr1.getZ() - tr0.getZ();
154 auto csp0i2 = 1. / tr0.getCsp2(); // 1 / csp^2
155 auto csp0i = std::sqrt(csp0i2);
156 auto tgp0 = tr0.getSnp() * csp0i;
157 float kx0 = trax0.c - trax0.s * tgp0;
158 float ky0 = trax0.s + trax0.c * tgp0;
159 float kz0 = tr0.getTgl() * csp0i;
160 auto csp1i2 = 1. / tr1.getCsp2(); // 1 / csp^2
161 auto csp1i = std::sqrt(csp1i2);
162 auto tgp1 = tr1.getSnp() * std::sqrt(csp1i2);
163 float kx1 = trax1.c - trax1.s * tgp1;
164 float ky1 = trax1.s + trax1.c * tgp1;
165 float kz1 = tr1.getTgl() * csp1i;
174 float a00 = (1.f + tr0.getTgl() * tr0.getTgl()) * csp0i2, a11 = (1.f + tr1.getTgl() * tr1.getTgl()) * csp1i2, a01 = -(kx0 * kx1 + ky0 * ky1 + kz0 * kz1);
175 float b0 = dx * kx0 + dy * ky0 + dz * kz0, b1 = -(dx * kx1 + dy * ky1 + dz * kz1);
176 float det = a00 * a11 - a01 * a01, det0 = b0 * a11 - b1 * a01, det1 = a00 * b1 - a01 * b0;
177 if (std::abs(det) > o2::constants::math::Almost0) {
178 auto detI = 1. / det;
179 auto t0 = det0 * detI;
180 auto t1 = det1 * detI;
181 float addx0 = kx0 * t0, addy0 = ky0 * t0, addx1 = kx1 * t1, addy1 = ky1 * t1;
182 dx += addx1 - addx0; // recalculate XY distance at DCA
183 dy += addy1 - addy0;
184 if (dx * dx + dy * dy > maxDistXY * maxDistXY) {
185 return nDCA;
186 }
187 xDCA[0] = (trax0.xC + addx0 + trax1.xC + addx1) * 0.5;
188 yDCA[0] = (trax0.yC + addy0 + trax1.yC + addy1) * 0.5;
189 nDCA = 1;
190 }
191 return nDCA;
192 }
193
194 template <typename T>
195 int circleLineCrossInfo(const TrackAuxPar& trax0, const T& tr0,
196 const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef)
197 {
211
212 const auto& traxH = trax0.rC > trax1.rC ? trax0 : trax1; // circle (for the line rC is set to 0)
213 const auto& traxL = trax0.rC > trax1.rC ? trax1 : trax0; // line
214 const auto& trcL = trax0.rC > trax1.rC ? tr1 : tr0; // track of the line
215
216 // solve quadratic equation of line crossing the circle
217 float dx = traxL.xC - traxH.xC; // X distance between the line lab reference and circle center
218 float dy = traxL.yC - traxH.yC; // Y...
219 // t^2(kx^2+ky^2) + 2t(dx*kx+dy*ky) + dx^2 + dy^2 - r^2 = 0
220 auto cspi2 = 1. / trcL.getCsp2(); // 1 / csp^2 == kx^2 + ky^2
221 auto cspi = std::sqrt(cspi2);
222 auto tgp = trcL.getSnp() * cspi;
223 float kx = traxL.c - traxL.s * tgp;
224 float ky = traxL.s + traxL.c * tgp;
225 double dk = dx * kx + dy * ky;
226 double det = dk * dk - cspi2 * (dx * dx + dy * dy - traxH.rC * traxH.rC);
227 if (det > 0) { // 2 crossings
228 det = std::sqrt(det);
229 float t0 = (-dk + det) * cspi2;
230 float t1 = (-dk - det) * cspi2;
231 xDCA[0] = traxL.xC + kx * t0;
232 yDCA[0] = traxL.yC + ky * t0;
233 xDCA[1] = traxL.xC + kx * t1;
234 yDCA[1] = traxL.yC + ky * t1;
235 nDCA = 2;
236 } else {
237 // there is no crossing, find the point of the closest approach on the line which is closest to the circle center
238 float t = -dk * cspi2;
239 float xL = traxL.xC + kx * t, yL = traxL.yC + ky * t; // point on the line, need to average with point on the circle
240 float dxc = xL - traxH.xC, dyc = yL - traxH.yC, dist = std::sqrt(dxc * dxc + dyc * dyc);
241 if (dist - traxH.rC > maxDistXY) { // too large distance
242 return nDCA;
243 }
244 float drcf = traxH.rC / dist; // radius / distance to circle center
245 float xH = traxH.xC + dxc * drcf, yH = traxH.yC + dyc * drcf;
246 xDCA[0] = (xL + xH) * 0.5;
247 yDCA[0] = (yL + yH) * 0.5;
248 nDCA = 1;
249 }
250 return nDCA;
251 }
252
253 template <typename T>
254 int set(const TrackAuxPar& trax0, const T& tr0, const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef)
255 {
256 // calculate up to 2 crossings between 2 circles
257 nDCA = 0;
258 if (trax0.rC > o2::constants::math::Almost0 && trax1.rC > o2::constants::math::Almost0) { // both are not straight lines
260 } else if (trax0.rC < o2::constants::math::Almost0 && trax1.rC < o2::constants::math::Almost0) { // both are straigt lines
262 } else {
264 }
265 //
266 return nDCA;
267 }
268
269 CrossInfo() = default;
270
271 template <typename T>
272 CrossInfo(const TrackAuxPar& trax0, const T& tr0, const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef)
273 {
274 set(trax0, tr0, trax1, tr1, maxDistXY);
275 }
277};
278
279} // namespace track
280} // namespace o2
281
282#endif
General auxilliary methods.
const GPUTPCGMMerger::trackCluster & b1
const int16_t bb
useful math constants
Declarations of 2D primitives.
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition glcorearb.h:5034
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition glcorearb.h:5034
constexpr float Almost0
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
int set(const TrackAuxPar &trax0, const T &tr0, const TrackAuxPar &trax1, const T &tr1, float maxDistXY=MaxDistXYDef)
int linesCrossInfo(const TrackAuxPar &trax0, const T &tr0, const TrackAuxPar &trax1, const T &tr1, float maxDistXY=MaxDistXYDef)
const TrackAuxPar & trax1
Definition HelixHelper.h:62
ClassDefNV(CrossInfo, 1)
CrossInfo(const TrackAuxPar &trax0, const T &tr0, const TrackAuxPar &trax1, const T &tr1, float maxDistXY=MaxDistXYDef)
const T const TrackAuxPar const T & tr1
int circlesCrossInfo(const TrackAuxPar &trax0, const TrackAuxPar &trax1, float maxDistXY=MaxDistXYDef)
Definition HelixHelper.h:62
const TrackAuxPar float maxDistXY
Definition HelixHelper.h:62
static constexpr float MaxDistXYDef
Definition HelixHelper.h:57
int circleLineCrossInfo(const TrackAuxPar &trax0, const T &tr0, const TrackAuxPar &trax1, const T &tr1, float maxDistXY=MaxDistXYDef)
void notTouchingXY(float dist, float xDist, float yDist, const TrackAuxPar &trcA, float rBSign)
TrackAuxPar(const T &trc, float bz)
Definition HelixHelper.h:36
float sinDif(const TrackAuxPar &t) const
Definition HelixHelper.h:41
ClassDefNV(TrackAuxPar, 1)
void set(const T &trc, float bz)
Definition HelixHelper.h:44
float cosDif(const TrackAuxPar &t) const
Definition HelixHelper.h:40