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