Project
Loading...
Searching...
No Matches
TrackFwd.cxx
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
13#include "Math/MatrixFunctions.h"
14#include <GPUCommonLogger.h>
15
16namespace o2
17{
18namespace track
19{
20using namespace std;
21
22//_________________________________________________________________________
23TrackParCovFwd::TrackParCovFwd(const Double_t z, const SMatrix5& parameters, const SMatrix55Sym& covariances, const Double_t chi2)
24{
25 setZ(z);
26 setParameters(parameters);
27 setCovariances(covariances);
28 setTrackChi2(chi2);
29}
30
31//__________________________________________________________________________
33{
34 // Track parameters linearly extrapolated to the plane at "zEnd".
35
36 if (getZ() == zEnd) {
37 return; // nothing to be done if same z
38 }
39
40 // Compute track parameters
41 auto dZ = (zEnd - getZ());
42 auto phi0 = getPhi();
43 auto [sinphi0, cosphi0] = o2::math_utils::sincosd(phi0);
44 auto invtanl0 = 1.0 / getTanl();
45 auto n = dZ * invtanl0;
46 mParameters(0) += n * cosphi0;
47 mParameters(1) += n * sinphi0;
48 mZ = zEnd;
49}
50
51//__________________________________________________________________________
53{
54 // Track parameters and their covariances linearly extrapolated to the plane at "zEnd".
55
56 // Calculate the jacobian related to the track parameters extrapolated to "zEnd"
57 auto dZ = (zEnd - getZ());
58 auto phi0 = getPhi();
59 auto tanl0 = getTanl();
60 auto invtanl0 = 1.0 / tanl0;
61 auto [sinphi0, cosphi0] = o2::math_utils::sincosd(phi0);
62 auto n = dZ * invtanl0;
63 auto m = n * invtanl0;
64
65 // Extrapolate track parameters to "zEnd"
66 mParameters(0) += n * cosphi0;
67 mParameters(1) += n * sinphi0;
68 setZ(zEnd);
69
70 // Calculate Jacobian
71 SMatrix55Std jacob = ROOT::Math::SMatrixIdentity();
72 jacob(0, 2) = -n * sinphi0;
73 jacob(0, 3) = -m * cosphi0;
74 jacob(1, 2) = n * cosphi0;
75 jacob(1, 3) = -m * sinphi0;
76
77 // Extrapolate track parameter covariances to "zEnd"
78 setCovariances(ROOT::Math::Similarity(jacob, mCovariances));
79}
80
81//__________________________________________________________________________
82void TrackParFwd::propagateParamToZquadratic(double zEnd, double zField)
83{
84 // Track parameters extrapolated to the plane at "zEnd" considering a helix
85
86 if (getZ() == zEnd) {
87 return; // nothing to be done if same z
88 }
89
90 // Compute track parameters
91 auto dZ = (zEnd - getZ());
92 auto phi0 = getPhi();
93 auto [sinphi0, cosphi0] = o2::math_utils::sincosd(phi0);
94 auto invtanl0 = 1.0 / getTanl();
95 auto invqpt0 = getInvQPt();
96 auto Hz = std::copysign(1, zField);
97 auto k = TMath::Abs(o2::constants::math::B2C * zField);
98 auto n = dZ * invtanl0;
99 auto theta = -invqpt0 * dZ * k * invtanl0;
100
101 mParameters(0) += n * cosphi0 - 0.5 * n * theta * Hz * sinphi0;
102 mParameters(1) += n * sinphi0 + 0.5 * n * theta * Hz * cosphi0;
103 mParameters(2) += Hz * theta;
104 setZ(zEnd);
105}
106
107//__________________________________________________________________________
108void TrackParCovFwd::propagateToZquadratic(double zEnd, double zField)
109{
110 // Extrapolate track parameters and covariances matrix to "zEnd"
111 // using quadratic track model
112
113 if (getZ() == zEnd) {
114 return; // nothing to be done if same z
115 }
116
117 // Compute track parameters
118 auto dZ = (zEnd - getZ());
119 auto phi0 = getPhi();
120 auto [sinphi0, cosphi0] = o2::math_utils::sincosd(phi0);
121 auto invtanl0 = 1.0 / getTanl();
122 auto invqpt0 = getInvQPt();
123 auto Hz = std::copysign(1, zField);
124 auto k = TMath::Abs(o2::constants::math::B2C * zField);
125 auto n = dZ * invtanl0;
126 auto m = n * invtanl0;
127 auto theta = -invqpt0 * dZ * k * invtanl0;
128
129 // Extrapolate track parameters to "zEnd"
130 mParameters(0) += n * cosphi0 - 0.5 * n * theta * Hz * sinphi0;
131 mParameters(1) += n * sinphi0 + 0.5 * n * theta * Hz * cosphi0;
132 mParameters(2) += Hz * theta;
133 mZ = zEnd;
134
135 // Calculate Jacobian
136 SMatrix55Std jacob = ROOT::Math::SMatrixIdentity();
137 jacob(0, 2) = -n * theta * 0.5 * Hz * cosphi0 - n * sinphi0;
138 jacob(0, 3) = Hz * m * theta * sinphi0 - m * cosphi0;
139 jacob(0, 4) = k * m * 0.5 * Hz * dZ * sinphi0;
140 jacob(1, 2) = -n * theta * 0.5 * Hz * sinphi0 + n * cosphi0;
141 jacob(1, 3) = -Hz * m * theta * cosphi0 - m * sinphi0;
142 jacob(1, 4) = -k * m * 0.5 * Hz * dZ * cosphi0;
143 jacob(2, 3) = -Hz * theta * invtanl0;
144 jacob(2, 4) = -Hz * k * n;
145
146 // Extrapolate track parameter covariances to "zEnd"
147 setCovariances(ROOT::Math::Similarity(jacob, mCovariances));
148}
149
150//__________________________________________________________________________
151void TrackParFwd::propagateParamToZhelix(double zEnd, double zField)
152{
153 // Track parameters extrapolated to the plane at "zEnd"
154 // using helix track model
155
156 if (getZ() == zEnd) {
157 return; // nothing to be done if same z
158 }
159
160 // Compute track parameters
161 auto dZ = (zEnd - getZ());
162 auto phi0 = getPhi();
163 auto tanl0 = getTanl();
164 auto invtanl0 = 1.0 / tanl0;
165 auto invqpt0 = getInvQPt();
166 auto qpt0 = 1.0 / invqpt0;
167 auto [sinphi0, cosphi0] = o2::math_utils::sincosd(phi0);
168
169 auto k = TMath::Abs(o2::constants::math::B2C * zField);
170 auto invk = 1.0 / k;
171 auto theta = -invqpt0 * dZ * k * invtanl0;
172 auto [sintheta, costheta] = o2::math_utils::sincosd(theta);
173 auto Hz = std::copysign(1, zField);
174 auto Y = sinphi0 * qpt0 * invk;
175 auto X = cosphi0 * qpt0 * invk;
176 auto YC = Y * costheta;
177 auto YS = Y * sintheta;
178 auto XC = X * costheta;
179 auto XS = X * sintheta;
180
181 // Extrapolate track parameters to "zEnd"
182 mParameters(0) += Hz * (Y - YC) - XS;
183 mParameters(1) += Hz * (-X + XC) - YS;
184 mParameters(2) += Hz * theta;
185 mZ = zEnd;
186}
187
188//__________________________________________________________________________
189void TrackParCovFwd::propagateToZhelix(double zEnd, double zField)
190{
191 // Extrapolate track parameters and covariances matrix to "zEnd"
192 // using helix track model
193
194 auto dZ = (zEnd - getZ());
195 auto phi0 = getPhi();
196 auto tanl0 = getTanl();
197 auto invtanl0 = 1.0 / tanl0;
198 auto invqpt0 = getInvQPt();
199 auto qpt0 = 1.0 / invqpt0;
200 auto [sinphi0, cosphi0] = o2::math_utils::sincosd(phi0);
201 auto k = TMath::Abs(o2::constants::math::B2C * zField);
202 auto invk = 1.0 / k;
203 auto theta = -invqpt0 * dZ * k * invtanl0;
204 auto [sintheta, costheta] = o2::math_utils::sincosd(theta);
205 auto Hz = std::copysign(1, zField);
206 auto L = qpt0 * qpt0 * invk;
207 auto N = dZ * invtanl0 * qpt0;
208 auto O = sintheta * cosphi0;
209 auto P = sinphi0 * costheta;
210 auto R = sinphi0 * sintheta;
211 auto S = cosphi0 * costheta;
212 auto Y = sinphi0 * qpt0 * invk;
213 auto X = cosphi0 * qpt0 * invk;
214 auto YC = Y * costheta;
215 auto YS = Y * sintheta;
216 auto XC = X * costheta;
217 auto XS = X * sintheta;
218 auto T = qpt0 * costheta;
219 auto U = qpt0 * sintheta;
220 auto V = qpt0;
221 auto n = dZ * invtanl0;
222 auto m = n * invtanl0;
223
224 // Extrapolate track parameters to "zEnd"
225 mParameters(0) += Hz * (Y - YC) - XS;
226 mParameters(1) += Hz * (-X + XC) - YS;
227 mParameters(2) += Hz * theta;
228 mZ = zEnd;
229
230 // Calculate Jacobian
231 SMatrix55Std jacob = ROOT::Math::SMatrixIdentity();
232 jacob(0, 2) = Hz * X - Hz * XC + YS;
233 jacob(0, 3) = Hz * R * m - S * m;
234 jacob(0, 4) = -Hz * N * R + Hz * T * Y - Hz * V * Y + N * S + U * X;
235 jacob(1, 2) = Hz * Y - Hz * YC - XS;
236 jacob(1, 3) = -Hz * O * m - P * m;
237 jacob(1, 4) = Hz * N * O - Hz * T * X + Hz * V * X + N * P + U * Y;
238 jacob(2, 3) = -Hz * theta * invtanl0;
239 jacob(2, 4) = -Hz * k * n;
240
241 // Extrapolate track parameter covariances to "zEnd"
242 setCovariances(ROOT::Math::Similarity(jacob, mCovariances));
243}
244
245//__________________________________________________________________________
246void TrackParCovFwd::propagateToZ(double zEnd, double zField)
247{
248 // Security for zero B field
249 if (zField == 0.0) {
250 propagateToZlinear(zEnd);
251 return;
252 }
253
254 // Extrapolate track parameters and covariances matrix to "zEnd"
255 // Parameters: helix track model; Error propagation: Quadratic
256
257 auto dZ = (zEnd - getZ());
258 auto phi0 = getPhi();
259 auto tanl0 = getTanl();
260 auto invtanl0 = 1.0 / tanl0;
261 auto invqpt0 = getInvQPt();
262 auto qpt0 = 1.0 / invqpt0;
263 auto [sinphi0, cosphi0] = o2::math_utils::sincosd(phi0);
264 auto k = TMath::Abs(o2::constants::math::B2C * zField);
265 auto invk = 1.0 / k;
266 auto theta = -invqpt0 * dZ * k * invtanl0;
267 auto [sintheta, costheta] = o2::math_utils::sincosd(theta);
268 auto Hz = std::copysign(1, zField);
269 auto Y = sinphi0 * qpt0 * invk;
270 auto X = cosphi0 * qpt0 * invk;
271 auto YC = Y * costheta;
272 auto YS = Y * sintheta;
273 auto XC = X * costheta;
274 auto XS = X * sintheta;
275 auto n = dZ * invtanl0;
276 auto m = n * invtanl0;
277
278 // Extrapolate track parameters to "zEnd"
279 // Helix
280 mParameters(0) += Hz * (Y - YC) - XS;
281 mParameters(1) += Hz * (-X + XC) - YS;
282 mParameters(2) += Hz * theta;
283 mZ = zEnd;
284
285 // Jacobian (quadratic)
286 SMatrix55Std jacob = ROOT::Math::SMatrixIdentity();
287 jacob(0, 2) = -n * theta * 0.5 * Hz * cosphi0 - n * sinphi0;
288 jacob(0, 3) = Hz * m * theta * sinphi0 - m * cosphi0;
289 jacob(0, 4) = k * m * 0.5 * Hz * dZ * sinphi0;
290 jacob(1, 2) = -n * theta * 0.5 * Hz * sinphi0 + n * cosphi0;
291 jacob(1, 3) = -Hz * m * theta * cosphi0 - m * sinphi0;
292 jacob(1, 4) = -k * m * 0.5 * Hz * dZ * cosphi0;
293 jacob(2, 3) = -Hz * theta * invtanl0;
294 jacob(2, 4) = -Hz * k * n;
295
296 // Extrapolate track parameter covariances to "zEnd"
297 setCovariances(ROOT::Math::Similarity(jacob, mCovariances));
298}
299
300//__________________________________________________________________________
301bool TrackParCovFwd::update(const std::array<float, 2>& p, const std::array<float, 2>& cov)
302{
305
306 using SVector2 = ROOT::Math::SVector<double, 2>;
307 using SMatrix22 = ROOT::Math::SMatrix<double, 2>;
308 using SMatrix25 = ROOT::Math::SMatrix<double, 2, 5>;
309 using SMatrix52 = ROOT::Math::SMatrix<double, 5, 2>;
310
311 SMatrix55Sym I = ROOT::Math::SMatrixIdentity();
312 SMatrix25 H_k;
313 SMatrix22 V_k;
314 SVector2 m_k(p[0], p[1]), r_k_kminus1;
315 V_k(0, 0) = cov[0];
316 V_k(1, 1) = cov[1];
317 H_k(0, 0) = 1.0;
318 H_k(1, 1) = 1.0;
319
320 // Covariance of residuals
321 SMatrix22 invResCov = (V_k + ROOT::Math::Similarity(H_k, mCovariances));
322 invResCov.Invert();
323
324 // Kalman Gain Matrix
325 SMatrix52 K_k = mCovariances * ROOT::Math::Transpose(H_k) * invResCov;
326
327 // Update Parameters
328 r_k_kminus1 = m_k - H_k * mParameters; // Residuals of prediction
329 mParameters = mParameters + K_k * r_k_kminus1;
330
331 // Update covariances Matrix
332 SMatrix55Std updatedCov;
333 auto& CP = mCovariances;
334 auto& sigmax2 = cov[0];
335 auto& sigmay2 = cov[1];
336 auto A = 1. / (sigmax2 * sigmay2 + sigmax2 * CP(1, 1) + sigmay2 * CP(0, 0) + CP(0, 0) * CP(1, 1) - CP(0, 1) * CP(0, 1));
337 auto AX = A * sigmax2;
338 auto AY = A * sigmay2;
339 auto B = sigmax2 * sigmay2;
340 auto C = (sigmax2 + CP(0, 0)) * (sigmay2 + CP(1, 1));
341 auto D = 1 / (-C + CP(0, 1) * CP(0, 1));
342 auto E = sigmax2 + CP(0, 0);
343 auto F = sigmay2 + CP(1, 1);
344 auto G = -C + CP(0, 1) * CP(0, 1);
345
346 // Explicit evaluation of "updatedCov = (I - K_k * H_k) * mCovariances"
347 updatedCov(0, 0) = AX * (sigmay2 * CP(0, 0) + CP(0, 0) * CP(1, 1) - CP(0, 1) * CP(0, 1));
348 updatedCov(0, 1) = AX * sigmay2 * CP(0, 1);
349 updatedCov(0, 2) = AX * (sigmay2 * CP(0, 2) - CP(0, 1) * CP(1, 2) + CP(0, 2) * CP(1, 1));
350 updatedCov(0, 3) = AX * (sigmay2 * CP(0, 3) - CP(0, 1) * CP(1, 3) + CP(0, 3) * CP(1, 1));
351 updatedCov(0, 4) = AX * (sigmay2 * CP(0, 4) - CP(0, 1) * CP(1, 4) + CP(0, 4) * CP(1, 1));
352 updatedCov(1, 1) = AY * (sigmax2 * CP(1, 1) + CP(0, 0) * CP(1, 1) - CP(0, 1) * CP(0, 1));
353 updatedCov(1, 2) = AY * (sigmax2 * CP(1, 2) + CP(0, 0) * CP(1, 2) - CP(0, 1) * CP(0, 2));
354 updatedCov(1, 3) = AY * (sigmax2 * CP(1, 3) + CP(0, 0) * CP(1, 3) - CP(0, 1) * CP(0, 3));
355 updatedCov(1, 4) = AY * (sigmax2 * CP(1, 4) + CP(0, 0) * CP(1, 4) - CP(0, 1) * CP(0, 4));
356 updatedCov(2, 2) = D * (G * CP(2, 2) - CP(0, 2) * (-F * CP(0, 2) + CP(0, 1) * CP(1, 2)) - CP(1, 2) * (-E * CP(1, 2) + CP(0, 1) * CP(0, 2)));
357 updatedCov(2, 3) = D * (G * CP(2, 3) - CP(0, 2) * (-F * CP(0, 3) + CP(0, 1) * CP(1, 3)) - CP(1, 2) * (-E * CP(1, 3) + CP(0, 1) * CP(0, 3)));
358 updatedCov(2, 4) = D * (G * CP(2, 4) - CP(0, 2) * (-F * CP(0, 4) + CP(0, 1) * CP(1, 4)) - CP(1, 2) * (-E * CP(1, 4) + CP(0, 1) * CP(0, 4)));
359 updatedCov(3, 3) = D * (G * CP(3, 3) - CP(0, 3) * (-F * CP(0, 3) + CP(0, 1) * CP(1, 3)) - CP(1, 3) * (-E * CP(1, 3) + CP(0, 1) * CP(0, 3)));
360 updatedCov(3, 4) = D * (G * CP(3, 4) - CP(0, 3) * (-F * CP(0, 4) + CP(0, 1) * CP(1, 4)) - CP(1, 3) * (-E * CP(1, 4) + CP(0, 1) * CP(0, 4)));
361 updatedCov(4, 4) = D * (G * CP(4, 4) - CP(0, 4) * (-F * CP(0, 4) + CP(0, 1) * CP(1, 4)) - CP(1, 4) * (-E * CP(1, 4) + CP(0, 1) * CP(0, 4)));
362
363 mCovariances(0, 0) = updatedCov(0, 0);
364 mCovariances(0, 1) = updatedCov(0, 1);
365 mCovariances(0, 2) = updatedCov(0, 2);
366 mCovariances(0, 3) = updatedCov(0, 3);
367 mCovariances(0, 4) = updatedCov(0, 4);
368 mCovariances(1, 1) = updatedCov(1, 1);
369 mCovariances(1, 2) = updatedCov(1, 2);
370 mCovariances(1, 3) = updatedCov(1, 3);
371 mCovariances(1, 4) = updatedCov(1, 4);
372 mCovariances(2, 2) = updatedCov(2, 2);
373 mCovariances(2, 3) = updatedCov(2, 3);
374 mCovariances(2, 4) = updatedCov(2, 4);
375 mCovariances(3, 3) = updatedCov(3, 3);
376 mCovariances(3, 4) = updatedCov(3, 4);
377 mCovariances(4, 4) = updatedCov(4, 4);
378
379 auto addChi2Track = ROOT::Math::Similarity(r_k_kminus1, invResCov);
380 mTrackChi2 += addChi2Track;
381
382 return true;
383}
384
385//__________________________________________________________________________
386void TrackParCovFwd::addMCSEffect(double x_over_X0)
387{
392
393 if (x_over_X0 == 0) { // Nothing to do
394 return;
395 }
396
397 auto phi0 = getPhi();
398 auto tanl0 = getTanl();
399 auto invtanl0 = 1.0 / tanl0;
400 auto invqpt0 = getInvQPt();
401
402 auto [sinphi0, cosphi0] = o2::math_utils::sincosd(phi0);
403
404 auto csclambda = TMath::Abs(TMath::Sqrt(1 + tanl0 * tanl0) * invtanl0);
405 auto pathLengthOverX0 = x_over_X0 * csclambda; //
406
407 // Angular dispersion square of the track (variance) in a plane perpendicular to the trajectory
408 auto sigmathetasq = 0.0136 * getInverseMomentum();
409 sigmathetasq *= sigmathetasq * pathLengthOverX0;
410
411 // Get covariance matrix
412 SMatrix55Sym newParamCov(getCovariances());
413
414 auto A = tanl0 * tanl0 + 1;
415
416 newParamCov(2, 2) += sigmathetasq * A;
417
418 newParamCov(3, 3) += sigmathetasq * A * A;
419
420 newParamCov(4, 4) += sigmathetasq * tanl0 * tanl0 * invqpt0 * invqpt0;
421
422 // Set new covariances
423 setCovariances(newParamCov);
424}
425
426//_______________________________________________________
427void TrackParFwd::getCircleParams(float bz, o2::math_utils::CircleXY<float>& c, float& sna, float& csa) const
428{
429 c.rC = getCurvature(bz);
430 constexpr double MinCurv = 1e-6;
431 if (std::abs(c.rC) > MinCurv) {
432 c.rC = 1.f / getCurvature(bz);
433 double sn = getSnp(), cs = std::sqrt((1.f - sn) * (1.f + sn));
434 c.xC = getX() - sn * c.rC; // center in tracking
435 c.yC = getY() + cs * c.rC; // frame. Note: r is signed!!!
436 c.rC = std::abs(c.rC);
437 } else {
438 c.rC = 0.f; // signal straight line
439 c.xC = getX();
440 c.yC = getY();
441 }
442}
443//________________________________________________________________
444bool TrackParCovFwd::propagateToVtxhelixWithMCS(double z, const std::array<float, 2>& p, const std::array<float, 2>& cov, double field, double x_over_X0)
445{
446 // Propagate fwd track to vertex using helix model, adding MCS effects
447 addMCSEffect(x_over_X0);
448 propagateToZhelix(z, field);
449 return update(p, cov);
450}
451//________________________________________________________________
452bool TrackParCovFwd::propagateToVtxlinearWithMCS(double z, const std::array<float, 2>& p, const std::array<float, 2>& cov, double x_over_X0)
453{
454 // Propagate fwd track to vertex using linear model, adding MCS effects
455 addMCSEffect(x_over_X0);
457 return update(p, cov);
458}
459
460bool TrackParCovFwd::getCovXYZPxPyPzGlo(std::array<float, 21>& cv) const
461{
462 //---------------------------------------------------------------------
463 // This function returns the global covariance matrix of the fwdtrack params
464 //
465 // Cov(x,x) ... : cv[0]
466 // Cov(y,x) ... : cv[1] cv[2]
467 // Cov(z,x) ... : cv[3] cv[4] cv[5]
468 // Cov(px,x)... : cv[6] cv[7] cv[8] cv[9]
469 // Cov(py,x)... : cv[10] cv[11] cv[12] cv[13] cv[14]
470 // Cov(pz,x)... : cv[15] cv[16] cv[17] cv[18] cv[19] cv[20]
471 //---------------------------------------------------------------------
472 auto pt = getPt();
473 auto cp = std::sqrt((1. - getSnp()) * (1. + getSnp()));
474 auto sp = getSnp();
475 auto tgl = getTgl();
476
477 auto px = pt * std::sqrt((1. - getSnp()) * (1. + getSnp()));
478 auto py = pt * getSnp();
479 auto pz = pt * getTgl();
480 auto q = getCharge();
481
482 cv[0] = mCovariances(0, 0);
483 cv[1] = mCovariances(1, 0);
484 cv[2] = mCovariances(1, 1);
485 cv[3] = 0;
486 cv[4] = 0;
487 cv[5] = 0;
488 cv[6] = -mCovariances(0, 2) * py - mCovariances(0, 4) * px * pt * q;
489 cv[7] = -mCovariances(1, 2) * py - mCovariances(1, 4) * px * pt * q;
490 cv[8] = 0;
491 cv[9] = 2 * mCovariances(2, 4) * px * py * q * pt + mCovariances(2, 2) * py * py + mCovariances(4, 4) * px * px * pt * pt;
492 cv[10] = mCovariances(0, 2) * px - mCovariances(0, 4) * py * pt * q;
493 cv[11] = mCovariances(1, 2) * px - mCovariances(1, 4) * py * pt * q;
494 cv[12] = 0;
495 cv[13] = mCovariances(2, 4) * (py * py - px * px) * q * pt - mCovariances(2, 2) * px * py + mCovariances(4, 4) * px * py * pt * pt;
496 cv[14] = -2 * mCovariances(2, 4) * px * py * q * pt + mCovariances(2, 2) * px * px + mCovariances(4, 4) * py * py * pt * pt;
497 cv[15] = mCovariances(0, 3) * pt - mCovariances(0, 4) * pt * pz * q;
498 cv[16] = mCovariances(1, 3) * pt - mCovariances(1, 4) * pt * pz * q;
499 cv[17] = 0;
500 cv[18] = -mCovariances(2, 3) * py * pt - mCovariances(3, 4) * px * q * pt * pt + mCovariances(2, 4) * py * pz * q * pt + mCovariances(4, 4) * px * pz * pt * pt;
501 cv[19] = mCovariances(2, 3) * px * pt - mCovariances(3, 4) * q * pt * pt * py - mCovariances(2, 4) * px * pz * q * pt + mCovariances(4, 4) * py * pz * pt * pt;
502 cv[20] = -2 * mCovariances(3, 4) * pz * q * pt * pt + mCovariances(3, 3) * pt * pt + mCovariances(4, 4) * pz * pz * pt * pt;
503
504 return true;
505}
506
507//________________________________________________________________
508
509void TrackParCovFwd::propagateToDCAhelix(double zField, const std::array<double, 3>& p, std::array<double, 3>& dca)
510{
511 // Computing DCA of fwd track w.r.t vertex in helix track model, using Newton-Raphson minimization
512
513 auto x0 = mParameters(0);
514 auto y0 = mParameters(1);
515 auto z0 = mZ;
516 auto phi0 = mParameters(2);
517 auto tanl = mParameters(3);
518 auto qOverPt = mParameters(4);
519 auto k = TMath::Abs(o2::constants::math::B2C * zField);
520 auto qpt = 1.0 / qOverPt;
521 auto qR = qpt / std::fabs(k);
522 auto invtanl = 1.0 / tanl;
523 auto Hz = std::copysign(1, zField);
524
525 auto xPV = p[0];
526 auto yPV = p[1];
527 auto zPV = p[2];
528
529 auto qRtanl = qR * tanl;
530 auto invqRtanl = 1.0 / qRtanl;
531 auto [sinp, cosp] = o2::math_utils::sincosd(phi0);
532
533 auto z = zPV;
534 double tol = 1e-4;
535 int max_iter = 10;
536 int iter = 0;
537
538 while (iter++ < max_iter) {
539 double theta = (z0 - z) * invqRtanl;
540 double phi_theta = phi0 + Hz * theta;
541 double sin_phi_theta = sin(phi_theta);
542 double cos_phi_theta = cos(phi_theta);
543
544 double DX = x0 - Hz * qR * (sin_phi_theta - sinp) - xPV;
545 double DY = y0 + Hz * qR * (cos_phi_theta - cosp) - yPV;
546 double DZ = z - zPV;
547
548 double dD2_dZ =
549 2 * DX * cos_phi_theta * invtanl +
550 2 * DY * sin_phi_theta * invtanl +
551 2 * DZ;
552
553 double d2D2_dZ2 =
554 2 * invtanl * invtanl +
555 2 * invtanl * (DX * Hz * sin_phi_theta - DY * Hz * cos_phi_theta) * invqRtanl +
556 2;
557
558 double z_new = z - dD2_dZ / d2D2_dZ2;
559
560 if (std::abs(z_new - z) < tol) {
561 z = z_new;
562 this->propagateToZhelix(z, zField);
563 dca[0] = this->getX() - xPV;
564 dca[1] = this->getY() - yPV;
565 dca[2] = this->getZ() - zPV;
566 LOG(debug) << "Converged after " << iter << " iterations for vertex X=" << p[0] << ", Y=" << p[1] << ", Z = " << p[2];
567 return;
568 }
569 z = z_new;
570 }
571 LOG(debug) << "Failed to converge after " << iter << " iterations for vertex X=" << p[0] << ", Y=" << p[1] << ", Z = " << p[2];
572 return;
573}
574
575} // namespace track
576} // namespace o2
uint32_t c
Definition RawData.h:2
Base forward track model, params only, w/o covariance.
std::ostringstream debug
Definition A.h:16
Definition B.h:16
void setCovariances(const SMatrix55Sym &covariances)
Definition TrackFwd.h:149
void propagateToZquadratic(double zEnd, double zField)
Definition TrackFwd.cxx:108
void propagateToZ(double zEnd, double zField)
Definition TrackFwd.cxx:246
bool propagateToVtxhelixWithMCS(double z, const std::array< float, 2 > &p, const std::array< float, 2 > &cov, double field, double x_over_X0)
Definition TrackFwd.cxx:444
void propagateToZhelix(double zEnd, double zField)
Definition TrackFwd.cxx:189
bool getCovXYZPxPyPzGlo(std::array< float, 21 > &cv) const
Definition TrackFwd.cxx:460
bool update(const std::array< float, 2 > &p, const std::array< float, 2 > &cov)
Definition TrackFwd.cxx:301
const SMatrix55Sym & getCovariances() const
Definition TrackFwd.h:148
void addMCSEffect(double x2X0)
Definition TrackFwd.cxx:386
bool propagateToVtxlinearWithMCS(double z, const std::array< float, 2 > &p, const std::array< float, 2 > &cov, double x_over_X0)
Definition TrackFwd.cxx:452
void propagateToZlinear(double zEnd)
Definition TrackFwd.cxx:52
void propagateToDCAhelix(double zField, const std::array< double, 3 > &p, std::array< double, 3 > &dca)
Definition TrackFwd.cxx:509
void propagateParamToZlinear(double zEnd)
Definition TrackFwd.cxx:32
void propagateParamToZquadratic(double zEnd, double zField)
Definition TrackFwd.cxx:82
void propagateParamToZhelix(double zEnd, double zField)
Definition TrackFwd.cxx:151
Double_t getTanl() const
Definition TrackFwd.h:72
Double_t getInverseMomentum() const
Definition TrackFwd.h:84
Double_t getPt() const
Definition TrackFwd.h:78
SMatrix5 mParameters
Track parameters.
Definition TrackFwd.h:132
Double_t mTrackChi2
Chi2 of the track when the associated cluster was attached.
Definition TrackFwd.h:133
Double_t getTgl() const
Definition TrackFwd.h:74
Double_t getPhi() const
Definition TrackFwd.h:56
void setParameters(const SMatrix5 &parameters)
set track parameters
Definition TrackFwd.h:108
Double_t getZ() const
return Z coordinate (cm)
Definition TrackFwd.h:46
Double_t mZ
Z coordinate (cm)
Definition TrackFwd.h:124
Double_t getCurvature(double b) const
Definition TrackFwd.h:89
Double_t getY() const
Definition TrackFwd.h:52
void getCircleParams(float bz, o2::math_utils::CircleXY< float > &c, float &sna, float &csa) const
Definition TrackFwd.cxx:427
Double_t getCharge() const
return the charge (assumed forward motion)
Definition TrackFwd.h:96
Double_t getX() const
Definition TrackFwd.h:49
void setZ(Double_t z)
set Z coordinate (cm)
Definition TrackFwd.h:48
Double_t getSnp() const
Definition TrackFwd.h:58
void setTrackChi2(Double_t chi2)
set the chi2 of the track when the associated cluster was attached
Definition TrackFwd.h:115
Double_t getInvQPt() const
Definition TrackFwd.h:77
GLdouble n
Definition glcorearb.h:1982
const GLfloat * m
Definition glcorearb.h:4066
GLuint GLfloat x0
Definition glcorearb.h:5034
GLuint GLfloat GLfloat y0
Definition glcorearb.h:5034
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
constexpr float B2C
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"