Project
Loading...
Searching...
No Matches
GPUTPCCompressionTrackModel.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
14
16#include "GPUConstantMem.h"
17#include "GPUParam.inc"
18
19using namespace o2::gpu;
20
21// ATTENTION! This track model is used for the data compression.
22// Changes to the propagation and fit will prevent the decompression of data
23// encoded with the old version!!!
24
25#ifdef GPUCA_COMPRESSION_TRACK_MODEL_MERGER
26GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float alpha, uint8_t qPt, const GPUParam& GPUrestrict() param)
27{
28 mProp.SetMaterialTPC();
29 mProp.SetMaxSinPhi(GPUCA_MAX_SIN_PHI);
30 mProp.SetSeedingErrors(true); // Larger errors for seeds, better since we don't start with good hypothesis
31 mProp.SetFitInProjections(true);
32 mProp.SetPropagateBzOnly(true);
33 mProp.SetPolynomialField(&param.polynomialField);
34 mTrk.X() = x;
35 mTrk.Y() = y;
36 mTrk.Z() = z;
37 mTrk.SinPhi() = 0;
38 mTrk.DzDs() = 0;
39 mTrk.QPt() = (qPt - 127.f) * (20.f / 127.f);
40 mTrk.ResetCovariance();
41 mProp.SetTrack(&mTrk, alpha);
42 mParam = &param;
43 // GPUInfo("Initialized: x %f y %f z %f alpha %f qPt %f", x, y, z, alpha, mTrk.QPt());
44}
45
46GPUd() int32_t GPUTPCCompressionTrackModel::Propagate(float x, float alpha)
47{
48 int32_t retVal = mProp.PropagateToXAlpha(x, alpha, true);
49 // GPUInfo("Propagated to: x %f y %f z %f alpha %f qPt %f", x, mTrk.Y(), mTrk.Z(), alpha, mTrk.QPt());
50 return retVal;
51}
52
53GPUd() int32_t GPUTPCCompressionTrackModel::Filter(float y, float z, int32_t iRow)
54{
55 mTrk.ConstrainSinPhi();
56 int32_t retVal = mProp.Update(y, z, iRow, *mParam, 0, 0, nullptr, false, false, 0.f);
57 // GPUInfo("Filtered with %f %f: y %f z %f qPt %f", y, z, mTrk.Y(), mTrk.Z(), mTrk.QPt());
58 return retVal;
59}
60
61GPUd() int32_t GPUTPCCompressionTrackModel::Mirror()
62{
63 mProp.Mirror(true);
64 // GPUInfo("Mirrored: y %f z %f qPt %f", mTrk.Y(), mTrk.Z(), mTrk.QPt());
65 return 0;
66}
67
68#elif defined(GPUCA_COMPRESSION_TRACK_MODEL_SECTORTRACKER)
69
71#include "GPUTPCTracker.h"
72
73GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float alpha, uint8_t qPt, const GPUParam& GPUrestrict() param)
74{
75 mTrk.InitParam();
76 mTrk.SetX(x);
77 mTrk.SetY(y);
78 mTrk.SetZ(z);
79 mTrk.SetSinPhi(0);
80 mTrk.SetDzDs(0);
81 mTrk.SetQPt((qPt - 127.f) * (20.f / 127.f));
82 mAlpha = alpha;
83 mParam = &param;
84 // GPUInfo("Initialized: x %f y %f z %f alpha %f qPt %f", x, y, z, alpha, mTrk.QPt());
85}
86
87GPUd() int32_t GPUTPCCompressionTrackModel::Propagate(float x, float alpha)
88{
90 if (alpha != mAlpha && !mTrk.Rotate(alpha, t0, GPUCA_MAX_SIN_PHI)) {
91 return 2;
92 }
93 int32_t retVal = !mTrk.TransportToX(x, t0, mParam->bzCLight, GPUCA_MAX_SIN_PHI);
94 // GPUInfo("Propagated to: x %f y %f z %f alpha %f qPt %f", x, mTrk.Y(), mTrk.Z(), alpha, mTrk.QPt());
95 return retVal;
96}
97
98GPUd() int32_t GPUTPCCompressionTrackModel::Filter(float y, float z, int32_t iRow)
99{
100 mTrk.ConstrainSinPhi();
101 float err2Y, err2Z;
102 GPUTPCTracker::GetErrors2Seeding(*mParam, iRow, mTrk, -1.f, err2Y, err2Z);
103 int32_t retVal = !mTrk.Filter(y, z, err2Y, err2Z, GPUCA_MAX_SIN_PHI, false);
104 // GPUInfo("Filtered with %f %f: y %f z %f qPt %f", y, z, mTrk.Y(), mTrk.Z(), mTrk.QPt());
105 return retVal;
106}
107
108GPUd() int32_t GPUTPCCompressionTrackModel::Mirror()
109{
110 return 1;
111}
112
113#else // Default internal track model for compression
114
115GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float alpha, uint8_t qPt, const GPUParam& GPUrestrict() param)
116{
117 // initialize track model
118 mX = x;
119 mAlpha = alpha;
120 CAMath::SinCos(alpha, mSinAlpha, mCosAlpha);
121 mP[0] = y;
122 mP[1] = z;
123 mP[2] = 0.f;
124 mP[3] = 0.f;
125 mP[4] = (qPt - 127.f) * (20.f / 127.f);
126 resetCovariance();
127 mNDF = -5;
128 mBz = param.bzCLight;
129 float pti = CAMath::Abs(mP[4]);
130 if (pti < 1.e-4f) {
131 pti = 1.e-4f; // set 10.000 GeV momentum for straight track
132 }
133 mTrk.x = x;
134 mTrk.y = y;
135 mTrk.z = z;
136 mTrk.q = (mP[4] >= 0) ? 1.f : -1.f;
137 mTrk.pt = 1.f / pti;
138 mTrk.p = mTrk.pt;
139 mTrk.px = mTrk.pt;
140 mTrk.py = 0.f;
141 mTrk.pz = 0.f;
142 mTrk.qpt = mTrk.q * pti;
143 calculateMaterialCorrection();
144}
145
146GPUd() int32_t GPUTPCCompressionTrackModel::Propagate(float x, float alpha)
147{
148 // constrain sin(phi)
149 if (mP[2] > MaxSinPhi) {
150 mP[2] = MaxSinPhi;
151 } else if (mP[2] < -MaxSinPhi) {
152 mP[2] = -MaxSinPhi;
153 }
154 // propagate track parameters to specified x
155 if (CAMath::Abs(alpha - mAlpha) > 1.e-4f) {
156 if (rotateToAlpha(alpha) != 0) {
157 return -2;
158 }
159 }
160 if (CAMath::Abs(x - mX) < 1.e-7f) {
161 mX = x;
162 return 0;
163 }
164
165 // propagate mTrk to t0e
166 PhysicalTrackModel t0e(mTrk);
167 float dLp = 0;
168 if (CAMath::Abs(x - t0e.x) < 1.e-8f) {
169 return 0;
170 }
171 if (propagateToXBzLightNoUpdate(t0e, x, mBz, dLp)) {
172 return 1;
173 }
174 updatePhysicalTrackValues(t0e);
175 if (CAMath::Abs(t0e.sinphi) >= MaxSinPhi) {
176 return -3;
177 }
178 return followLinearization(t0e, mBz, dLp);
179}
180
181GPUd() int32_t GPUTPCCompressionTrackModel::Filter(float y, float z, int32_t iRow)
182{
183 // apply kalman filter update with measurement y/z
184 float err2Y, err2Z;
185 getClusterErrors2(iRow, z, mTrk.sinphi, mTrk.dzds, err2Y, err2Z);
186 if (mNDF == -5) {
187 // first measurement: no need to filter, as the result is known in advance. so just set it
188 // ignore offline statistical errors for now (as is also done by default)
189 mP[0] = y;
190 mP[1] = z;
191 mC[0] = err2Y;
192 mC[2] = err2Z;
193 mNDF = -3;
194 return 0;
195 }
196
197 // constrain sin(phi)
198 if (mP[2] > MaxSinPhi) {
199 mP[2] = MaxSinPhi;
200 } else if (mP[2] < -MaxSinPhi) {
201 mP[2] = -MaxSinPhi;
202 }
203
204 const float d00 = mC[0], d01 = mC[1], d02 = mC[3], d03 = mC[6], d04 = mC[10];
205 const float d10 = mC[1], d11 = mC[2], d12 = mC[4], d13 = mC[7], d14 = mC[11];
206
207 const float z0 = y - mP[0];
208 const float z1 = z - mP[1];
209 float w0, w1, w2;
210 if (mNDF <= 0) {
211 w0 = 1.f / (err2Y + d00);
212 w1 = 0;
213 w2 = 1.f / (err2Z + d11);
214 } else {
215 w0 = d11 + err2Z, w1 = d10, w2 = d00 + err2Y;
216 { // Invert symmetric matrix
217 float det = w0 * w2 - w1 * w1;
218 if (CAMath::Abs(det) < 1.e-10f) {
219 return -1;
220 }
221 det = 1.f / det;
222 w0 = w0 * det;
223 w1 = -w1 * det;
224 w2 = w2 * det;
225 }
226 }
227 mNDF += 2;
228
229 if (mNDF <= 0) {
230 const float k00 = d00 * w0;
231 const float k20 = d02 * w0;
232 const float k40 = d04 * w0;
233 const float k11 = d11 * w2;
234 const float k31 = d13 * w2;
235 mP[0] += k00 * z0;
236 mP[1] += k11 * z1;
237 mP[2] += k20 * z0;
238 mP[3] += k31 * z1;
239 mP[4] += k40 * z0;
240
241 mC[0] -= k00 * d00;
242 mC[2] -= k11 * d11;
243 mC[3] -= k20 * d00;
244 mC[5] -= k20 * d02;
245 mC[7] -= k31 * d11;
246 mC[9] -= k31 * d13;
247 mC[10] -= k00 * d04;
248 mC[12] -= k40 * d02;
249 mC[14] -= k40 * d04;
250 } else {
251 const float k00 = d00 * w0 + d01 * w1;
252 const float k01 = d00 * w1 + d10 * w2;
253 const float k10 = d01 * w0 + d11 * w1;
254 const float k11 = d01 * w1 + d11 * w2;
255 const float k20 = d02 * w0 + d12 * w1;
256 const float k21 = d02 * w1 + d12 * w2;
257 const float k30 = d03 * w0 + d13 * w1;
258 const float k31 = d03 * w1 + d13 * w2;
259 const float k40 = d04 * w0 + d14 * w1;
260 const float k41 = d04 * w1 + d14 * w2;
261
262 mP[0] += k00 * z0 + k01 * z1;
263 mP[1] += k10 * z0 + k11 * z1;
264 mP[2] += k20 * z0 + k21 * z1;
265 mP[3] += k30 * z0 + k31 * z1;
266 mP[4] += k40 * z0 + k41 * z1;
267
268 mC[0] -= k00 * d00 + k01 * d10;
269
270 mC[2] -= k10 * d01 + k11 * d11;
271
272 mC[3] -= k20 * d00 + k21 * d10;
273 mC[5] -= k20 * d02 + k21 * d12;
274
275 mC[7] -= k30 * d01 + k31 * d11;
276 mC[9] -= k30 * d03 + k31 * d13;
277
278 mC[10] -= k40 * d00 + k41 * d10;
279 mC[12] -= k40 * d02 + k41 * d12;
280 mC[14] -= k40 * d04 + k41 * d14;
281
282 mC[1] -= k10 * d00 + k11 * d10;
283 mC[4] -= k20 * d01 + k21 * d11;
284 mC[6] -= k30 * d00 + k31 * d10;
285 mC[8] -= k30 * d02 + k31 * d12;
286 mC[11] -= k40 * d01 + k41 * d11;
287 mC[13] -= k40 * d03 + k41 * d13;
288 }
289 return 0;
290}
291
292GPUd() int32_t GPUTPCCompressionTrackModel::Mirror()
293{
294 float dy = -2.f * mTrk.q * mTrk.px / mBz;
295 float dS; // path in XY
296 {
297 float chord = dy; // chord to the extrapolated point == |dy|*sign(x direction)
298 float sa = -mTrk.cosphi; // sin( half of the rotation angle ) == (chord/2) / radius
299
300 // dS = (Pt/b)*2*arcsin( sa )
301 // = (Pt/b)*2*sa*(1 + 1/6 sa^2 + 3/40 sa^4 + 5/112 sa^6 +... )
302 // = chord*(1 + 1/6 sa^2 + 3/40 sa^4 + 5/112 sa^6 +... )
303
304 float sa2 = sa * sa;
305 const float k2 = 1.f / 6.f;
306 const float k4 = 3.f / 40.f;
307 // const float k6 = 5.f/112.f;
308 dS = chord + chord * sa2 * (k2 + k4 * sa2);
309 // dS = CAMath(pt2)/b*2.f*CAMath::ASin( sa );
310 }
311
312 if (mTrk.sinphi < 0.f) {
313 dS = -dS;
314 }
315
316 mTrk.y = mTrk.y + 2.f * dy; // TODO check why dy is added TWICE to the track position
317 mTrk.z = mTrk.z + 2.f * mTrk.dzds * dS;
318 changeDirection();
319
320 // Energy Loss
321
322 float dL = CAMath::Copysign(dS * mTrk.dlds, -1.f); // we are in flight direction
323
324 float& mC40 = mC[10];
325 float& mC41 = mC[11];
326 float& mC42 = mC[12];
327 float& mC43 = mC[13];
328 float& mC44 = mC[14];
329
330 float dLmask = 0.f;
331 bool maskMS = (CAMath::Abs(dL) < mMaterial.DLMax);
332 if (maskMS) {
333 dLmask = dL;
334 }
335 float dLabs = CAMath::Abs(dLmask);
336 float corr = 1.f - mMaterial.EP2 * dLmask;
337
338 float corrInv = 1.f / corr;
339 mTrk.px *= corrInv;
340 mTrk.py *= corrInv;
341 mTrk.pz *= corrInv;
342 mTrk.pt *= corrInv;
343 mTrk.p *= corrInv;
344 mTrk.qpt *= corr;
345
346 mP[4] *= corr;
347
348 mC40 *= corr;
349 mC41 *= corr;
350 mC42 *= corr;
351 mC43 *= corr;
352 mC44 = mC44 * corr * corr + dLabs * mMaterial.sigmadE2;
353
354 return 0;
355}
356
357GPUd() void GPUTPCCompressionTrackModel::updatePhysicalTrackValues(PhysicalTrackModel& trk)
358{
359 float px = trk.px;
360 if (CAMath::Abs(px) < 1.e-4f) {
361 px = CAMath::Copysign(1.e-4f, px);
362 }
363
364 trk.pt = CAMath::Sqrt(px * px + trk.py * trk.py);
365 float pti = 1.f / trk.pt;
366 trk.p = CAMath::Sqrt(px * px + trk.py * trk.py + trk.pz * trk.pz);
367 trk.sinphi = trk.py * pti;
368 trk.cosphi = px * pti;
369 trk.secphi = trk.pt / px;
370 trk.dzds = trk.pz * pti;
371 trk.dlds = trk.p * pti;
372 trk.qpt = trk.q * pti;
373}
374
375GPUd() void GPUTPCCompressionTrackModel::changeDirection()
376{
377 mTrk.py = -mTrk.py;
378 mTrk.pz = -mTrk.pz;
379 mTrk.q = -mTrk.q;
380 mTrk.sinphi = -mTrk.sinphi;
381 mTrk.dzds = -mTrk.dzds;
382 mTrk.qpt = -mTrk.qpt;
383 updatePhysicalTrackValues(mTrk);
384
385 mC[3] = -mC[3];
386 mC[4] = -mC[4];
387 mC[6] = -mC[6];
388 mC[7] = -mC[7];
389 mC[10] = -mC[10];
390 mC[11] = -mC[11];
391}
392
393GPUd() int32_t GPUTPCCompressionTrackModel::rotateToAlpha(float newAlpha)
394{
395 //
396 // Rotate the track coordinate system in XY to the angle newAlpha
397 // return value is error code (0==no error)
398 //
399
400 float newCosAlpha = 0, newSinAlpha = 0;
401 CAMath::SinCos(newAlpha, newSinAlpha, newCosAlpha);
402
403 float cc = newCosAlpha * mCosAlpha + newSinAlpha * mSinAlpha; // CAMath::Cos(newAlpha - mAlpha);
404 float ss = newSinAlpha * mCosAlpha - newCosAlpha * mSinAlpha; // CAMath::Sin(newAlpha - mAlpha);
405
406 PhysicalTrackModel t0 = mTrk;
407
408 float x0 = mTrk.x;
409 float y0 = mTrk.y;
410 float px0 = mTrk.px;
411 float py0 = mTrk.py;
412
413 if (CAMath::Abs(mP[2]) >= MaxSinPhi || CAMath::Abs(px0) < (1 - MaxSinPhi)) {
414 return -1;
415 }
416
417 // rotate t0 track
418 float px1 = px0 * cc + py0 * ss;
419 float py1 = -px0 * ss + py0 * cc;
420
421 {
422 t0.x = x0 * cc + y0 * ss;
423 t0.y = -x0 * ss + y0 * cc;
424 t0.px = px1;
425 t0.py = py1;
426 updatePhysicalTrackValues(t0);
427 }
428
429 if (CAMath::Abs(py1) > MaxSinPhi * mTrk.pt || CAMath::Abs(px1) < (1 - MaxSinPhi)) {
430 return -1;
431 }
432
433 // calculate X of rotated track:
434 float trackX = x0 * cc + ss * mP[0];
435
436 // transport t0 to trackX
437 float dLp = 0;
438 if (propagateToXBzLightNoUpdate(t0, trackX, mBz, dLp)) {
439 return -1;
440 }
441 updatePhysicalTrackValues(t0);
442
443 if (CAMath::Abs(t0.sinphi) >= MaxSinPhi) {
444 return -1;
445 }
446
447 // now t0 is rotated and propagated, all checks are passed
448
449 // Rotate track using mTrk for linearisation. After rotation X is not fixed, but has a covariance
450
451 // Y Z Sin DzDs q/p
452 // Jacobian J0 = { { j0, 0, 0, 0, 0 }, // Y
453 // { 0, 1, 0, 0, 0 }, // Z
454 // { 0, 0, j1, 0, 0 }, // SinPhi
455 // { 0, 0, 0, 1, 0 }, // DzDs
456 // { 0, 0, 0, 0, 1 }, // q/p
457 // { j2, 0, 0, 0, 0 } }// X (rotated )
458
459 float j0 = cc;
460 float j1 = px1 / px0;
461 float j2 = ss;
462 // float dy = mT->Y() - y0;
463 // float ds = mT->SinPhi() - mTrk.SinPhi();
464
465 mX = trackX; // == x0*cc + ss*mP[0] == t0.x + j0*dy;
466 mP[0] = -x0 * ss + cc * mP[0]; //== t0.y + j0*dy;
467 // mP[2] = py1/pt0 + j1*ds; // == t0.sinphi + j1*ds; // use py1, since t0.sinphi can have different sign
468 mP[2] = -CAMath::Sqrt(1.f - mP[2] * mP[2]) * ss + mP[2] * cc;
469
470 // Rotate cov. matrix Cr = J0 x C x J0T. Cr has one more row+column for X:
471 float* c = mC;
472
473 float c15 = c[0] * j0 * j2;
474 float c16 = c[1] * j2;
475 float c17 = c[3] * j1 * j2;
476 float c18 = c[6] * j2;
477 float c19 = c[10] * j2;
478 float c20 = c[0] * j2 * j2;
479
480 c[0] *= j0 * j0;
481 c[3] *= j0;
482 c[10] *= j0;
483
484 c[3] *= j1;
485 c[5] *= j1 * j1;
486 c[12] *= j1;
487
488 if (setDirectionAlongX(t0)) { // change direction if Px < 0
489 mP[2] = -mP[2];
490 mP[3] = -mP[3];
491 mP[4] = -mP[4];
492 c[3] = -c[3]; // covariances with SinPhi
493 c[4] = -c[4];
494 c17 = -c17;
495 c[6] = -c[6]; // covariances with DzDs
496 c[7] = -c[7];
497 c18 = -c18;
498 c[10] = -c[10]; // covariances with QPt
499 c[11] = -c[11];
500 c19 = -c19;
501 }
502
503 // Now fix the X coordinate: so to say, transport track T to fixed X = mX.
504 // only covariance changes. Use rotated and transported t0 for linearisation
505 float j3 = -t0.py / t0.px;
506 float j4 = -t0.pz / t0.px;
507 float j5 = t0.qpt * mBz;
508
509 // Y Z Sin DzDs q/p X
510 // Jacobian J1 = { { 1, 0, 0, 0, 0, j3 }, // Y
511 // { 0, 1, 0, 0, 0, j4 }, // Z
512 // { 0, 0, 1, 0, 0, j5 }, // SinPhi
513 // { 0, 0, 0, 1, 0, 0 }, // DzDs
514 // { 0, 0, 0, 0, 1, 0 } }; // q/p
515
516 float h15 = c15 + c20 * j3;
517 float h16 = c16 + c20 * j4;
518 float h17 = c17 + c20 * j5;
519
520 c[0] += j3 * (c15 + h15);
521
522 c[2] += j4 * (c16 + h16);
523
524 c[3] += c17 * j3 + h15 * j5;
525 c[5] += j5 * (c17 + h17);
526
527 c[7] += c18 * j4;
528 // c[ 9] = c[ 9];
529
530 c[10] += c19 * j3;
531 c[12] += c19 * j5;
532 // c[14] = c[14];
533
534 mAlpha = newAlpha;
535 mCosAlpha = newCosAlpha;
536 mSinAlpha = newSinAlpha;
537 mTrk = t0;
538
539 return 0;
540}
541
542GPUd() int32_t GPUTPCCompressionTrackModel::propagateToXBzLightNoUpdate(PhysicalTrackModel& t, float x, float Bz, float& dLp)
543{
544 //
545 // transport the track to X=x in magnetic field B = ( 0, 0, Bz[kG*0.000299792458] )
546 // dLp is a return value == path length / track momentum [cm/(GeV/c)]
547 // the method returns error code (0 == no error)
548 //
549 // Additional values are not recalculated, UpdateValues() has to be called afterwards!!
550 //
551 float b = t.q * Bz;
552 float pt2 = t.px * t.px + t.py * t.py;
553 float dx = x - t.x;
554 float pye = t.py - dx * b; // extrapolated py
555 float pxe2 = pt2 - pye * pye;
556
557 if (t.px < (1.f - MaxSinPhi) || pxe2 < (1.f - MaxSinPhi) * (1.f - MaxSinPhi)) {
558 return -1; // can not transport to x=x
559 }
560 float pxe = CAMath::Sqrt(pxe2); // extrapolated px
561 float pti = 1.f / CAMath::Sqrt(pt2);
562
563 float ty = (t.py + pye) / (t.px + pxe);
564 float dy = dx * ty;
565 float dS; // path in XY
566 {
567 float chord = dx * CAMath::Sqrt(1.f + ty * ty); // chord to the extrapolated point == sqrt(dx^2+dy^2)*sign(dx)
568 float sa = 0.5f * chord * b * pti; // sin( half of the rotation angle ) == (chord/2) / radius
569
570 // dS = (Pt/b)*2*arcsin( sa )
571 // = (Pt/b)*2*sa*(1 + 1/6 sa^2 + 3/40 sa^4 + 5/112 sa^6 +... )
572 // = chord*(1 + 1/6 sa^2 + 3/40 sa^4 + 5/112 sa^6 +... )
573
574 float sa2 = sa * sa;
575 const float k2 = 1.f / 6.f;
576 const float k4 = 3.f / 40.f;
577 // const float k6 = 5.f/112.f;
578 dS = chord + chord * sa2 * (k2 + k4 * sa2);
579 // dS = CAMath::Sqrt(pt2)/b*2.f*CAMath::ASin( sa );
580 }
581
582 dLp = pti * dS; // path in XYZ / p == path in XY / pt
583
584 float dz = t.pz * dLp;
585
586 t.x = x;
587 t.y += dy;
588 t.z += dz;
589 t.px = pxe;
590 t.py = pye;
591 return 0;
592}
593
594GPUd() bool GPUTPCCompressionTrackModel::setDirectionAlongX(PhysicalTrackModel& t)
595{
596 //
597 // set direction of movenment collinear to X axis
598 // return value is true when direction has been changed
599 //
600 if (t.px >= 0) {
601 return 0;
602 }
603
604 t.px = -t.px;
605 t.py = -t.py;
606 t.pz = -t.pz;
607 t.q = -t.q;
608 updatePhysicalTrackValues(t);
609 return 1;
610}
611
612GPUd() int32_t GPUTPCCompressionTrackModel::followLinearization(const PhysicalTrackModel& t0e, float Bz, float dLp)
613{
614 // t0e is alrerady extrapolated t0
615
616 // propagate track and cov matrix with derivatives for (0,0,Bz) field
617
618 float dS = dLp * t0e.pt;
619 float dL = CAMath::Abs(dLp * t0e.p);
620
621 dL = -dL; // we are always in flight direction
622
623 float ey = mTrk.sinphi;
624 float ex = mTrk.cosphi;
625 float exi = mTrk.secphi;
626 float ey1 = t0e.sinphi;
627 float ex1 = t0e.cosphi;
628 float ex1i = t0e.secphi;
629
630 float k = -mTrk.qpt * Bz;
631 float dx = t0e.x - mTrk.x;
632 float kdx = k * dx;
633 float cc = ex + ex1;
634 float cci = 1.f / cc;
635
636 float dxcci = dx * cci;
637 float hh = dxcci * ex1i * (1.f + ex * ex1 + ey * ey1);
638
639 float j02 = exi * hh;
640 float j04 = -Bz * dxcci * hh;
641 float j13 = dS;
642 float j24 = -dx * Bz;
643
644 float* p = mP;
645
646 float d0 = p[0] - mTrk.y;
647 float d1 = p[1] - mTrk.z;
648 float d2 = p[2] - mTrk.sinphi;
649 float d3 = p[3] - mTrk.dzds;
650 float d4 = p[4] - mTrk.qpt;
651
652 float newSinPhi = ey1 + d2 + j24 * d4;
653 if (mNDF >= 15 && CAMath::Abs(newSinPhi) > MaxSinPhi) {
654 return -4;
655 }
656
657 mTrk = t0e;
658 mX = t0e.x;
659 p[0] = t0e.y + d0 + j02 * d2 + j04 * d4;
660 p[1] = t0e.z + d1 + j13 * d3;
661 p[2] = newSinPhi;
662 p[3] = t0e.dzds + d3;
663 p[4] = t0e.qpt + d4;
664
665 float* c = mC;
666
667 float c20 = c[3];
668 float c21 = c[4];
669 float c22 = c[5];
670
671 float c30 = c[6];
672 float c31 = c[7];
673 float c32 = c[8];
674 float c33 = c[9];
675
676 float c40 = c[10];
677 float c41 = c[11];
678 float c42 = c[12];
679 float c43 = c[13];
680 float c44 = c[14];
681
682 if (mNDF <= 0) {
683 float c20ph04c42 = c20 + j04 * c42;
684 float j02c22 = j02 * c22;
685 float j04c44 = j04 * c44;
686
687 float n6 = c30 + j02 * c32 + j04 * c43;
688 float n7 = c31 + j13 * c33;
689 float n10 = c40 + j02 * c42 + j04c44;
690 float n11 = c41 + j13 * c43;
691 float n12 = c42 + j24 * c44;
692
693 c[0] += j02 * j02c22 + j04 * j04c44 + 2.f * (j02 * c20ph04c42 + j04 * c40);
694 c[1] += j02 * c21 + j04 * c41 + j13 * n6;
695 c[2] += j13 * (c31 + n7);
696 c[3] = c20ph04c42 + j02c22 + j24 * n10;
697 c[4] = c21 + j13 * c32 + j24 * n11;
698 c[5] = c22 + j24 * (c42 + n12);
699 c[6] = n6;
700 c[7] = n7;
701 c[8] = c32 + c43 * j24;
702 c[10] = n10;
703 c[11] = n11;
704 c[12] = n12;
705 } else {
706 float c00 = c[0];
707 float c10 = c[1];
708 float c11 = c[2];
709
710 float ss = ey + ey1;
711 float tg = ss * cci;
712 float xx = 1.f - 0.25f * kdx * kdx * (1.f + tg * tg);
713 if (xx < 1.e-8f) {
714 return -1;
715 }
716 xx = CAMath::Sqrt(xx);
717 float yy = CAMath::Sqrt(ss * ss + cc * cc);
718
719 float j12 = dx * mTrk.dzds * tg * (2.f + tg * (ey * exi + ey1 * ex1i)) / (xx * yy);
720 float j14 = 0;
721 if (CAMath::Abs(mTrk.qpt) > 1.e-6f) {
722 j14 = (2.f * xx * ex1i * dx / yy - dS) * mTrk.dzds / mTrk.qpt;
723 } else {
724 j14 = -mTrk.dzds * Bz * dx * dx * exi * exi * exi * (0.5f * ey + (1.f / 3.f) * kdx * (1 + 2.f * ey * ey) * exi * exi);
725 }
726
727 p[1] += j12 * d2 + j14 * d4;
728
729 float h00 = c00 + c20 * j02 + c40 * j04;
730 // float h01 = c10 + c21*j02 + c41*j04;
731 float h02 = c20 + c22 * j02 + c42 * j04;
732 // float h03 = c30 + c32*j02 + c43*j04;
733 float h04 = c40 + c42 * j02 + c44 * j04;
734
735 float h10 = c10 + c20 * j12 + c30 * j13 + c40 * j14;
736 float h11 = c11 + c21 * j12 + c31 * j13 + c41 * j14;
737 float h12 = c21 + c22 * j12 + c32 * j13 + c42 * j14;
738 float h13 = c31 + c32 * j12 + c33 * j13 + c43 * j14;
739 float h14 = c41 + c42 * j12 + c43 * j13 + c44 * j14;
740
741 float h20 = c20 + c40 * j24;
742 float h21 = c21 + c41 * j24;
743 float h22 = c22 + c42 * j24;
744 float h23 = c32 + c43 * j24;
745 float h24 = c42 + c44 * j24;
746
747 c[0] = h00 + h02 * j02 + h04 * j04;
748
749 c[1] = h10 + h12 * j02 + h14 * j04;
750 c[2] = h11 + h12 * j12 + h13 * j13 + h14 * j14;
751
752 c[3] = h20 + h22 * j02 + h24 * j04;
753 c[4] = h21 + h22 * j12 + h23 * j13 + h24 * j14;
754 c[5] = h22 + h24 * j24;
755
756 c[6] = c30 + c32 * j02 + c43 * j04;
757 c[7] = c31 + c32 * j12 + c33 * j13 + c43 * j14;
758 c[8] = c32 + c43 * j24;
759 // c[ 9] = c33;
760
761 c[10] = c40 + c42 * j02 + c44 * j04;
762 c[11] = c41 + c42 * j12 + c43 * j13 + c44 * j14;
763 c[12] = c42 + c44 * j24;
764 // c[13] = c43;
765 // c[14] = c44;
766 }
767
768 float& mC22 = c[5];
769 float& mC33 = c[9];
770 float& mC40 = c[10];
771 float& mC41 = c[11];
772 float& mC42 = c[12];
773 float& mC43 = c[13];
774 float& mC44 = c[14];
775
776 float dLmask = 0.f;
777 bool maskMS = (CAMath::Abs(dL) < mMaterial.DLMax);
778 if (maskMS) {
779 dLmask = dL;
780 }
781 float dLabs = CAMath::Abs(dLmask);
782
783 // Energy Loss
784 {
785 // std::cout<<"APPLY ENERGY LOSS!!!"<<std::endl;
786 float corr = 1.f - mMaterial.EP2 * dLmask;
787 float corrInv = 1.f / corr;
788 mTrk.px *= corrInv;
789 mTrk.py *= corrInv;
790 mTrk.pz *= corrInv;
791 mTrk.pt *= corrInv;
792 mTrk.p *= corrInv;
793 mTrk.qpt *= corr;
794
795 p[4] *= corr;
796
797 mC40 *= corr;
798 mC41 *= corr;
799 mC42 *= corr;
800 mC43 *= corr;
801 mC44 = mC44 * corr * corr + dLabs * mMaterial.sigmadE2;
802 }
803 // Multiple Scattering
804
805 {
806 mC22 += dLabs * mMaterial.k22 * mTrk.cosphi * mTrk.cosphi;
807 mC33 += dLabs * mMaterial.k33;
808 mC43 += dLabs * mMaterial.k43;
809 mC44 += dLabs * mMaterial.k44;
810 }
811
812 return 0;
813}
814
815GPUd() void GPUTPCCompressionTrackModel::calculateMaterialCorrection()
816{
817 const float mass = 0.13957f;
818
819 float qpt = mTrk.qpt;
820 if (CAMath::Abs(qpt) > 20) {
821 qpt = 20;
822 }
823
824 float w2 = (1.f + mTrk.dzds * mTrk.dzds); //==(P/pt)2
825 float pti2 = qpt * qpt;
826 if (pti2 < 1.e-4f) {
827 pti2 = 1.e-4f;
828 }
829
830 float mass2 = mass * mass;
831 float beta2 = w2 / (w2 + mass2 * pti2);
832
833 float p2 = w2 / pti2; // impuls 2
834 float betheRho = approximateBetheBloch(p2 / mass2) * mMaterial.rho;
835 float E = CAMath::Sqrt(p2 + mass2);
836 float theta2 = (14.1f * 14.1f / 1.e6f) / (beta2 * p2) * mMaterial.radLenInv;
837
838 mMaterial.EP2 = E / p2;
839
840 // Approximate energy loss fluctuation (M.Ivanov)
841
842 const float knst = 0.07f; // To be tuned.
843 mMaterial.sigmadE2 = knst * mMaterial.EP2 * qpt;
844 mMaterial.sigmadE2 = mMaterial.sigmadE2 * mMaterial.sigmadE2;
845
846 mMaterial.k22 = theta2 * w2;
847 mMaterial.k33 = mMaterial.k22 * w2;
848 mMaterial.k43 = 0.f;
849 mMaterial.k44 = theta2 * mTrk.dzds * mTrk.dzds * pti2;
850
851 float br = (betheRho > 1.e-8f) ? betheRho : 1.e-8f;
852 mMaterial.DLMax = 0.3f * E / br;
853 mMaterial.EP2 *= betheRho;
854 mMaterial.sigmadE2 = mMaterial.sigmadE2 * betheRho; // + mMaterial.fK44;
855}
856
857GPUd() float GPUTPCCompressionTrackModel::approximateBetheBloch(float beta2)
858{
859 //------------------------------------------------------------------
860 // This is an approximation of the Bethe-Bloch formula with
861 // the density effect taken into account at beta*gamma > 3.5
862 // (the approximation is reasonable only for solid materials)
863 //------------------------------------------------------------------
864
865 const float log0 = CAMath::Log(5940.f);
866 const float log1 = CAMath::Log(3.5f * 5940.f);
867
868 bool bad = (beta2 >= .999f) || (beta2 < 1.e-8f);
869
870 if (bad) {
871 return 0.f;
872 }
873
874 float a = beta2 / (1.f - beta2);
875 float b = 0.5f * CAMath::Log(a);
876 float d = 0.153e-3f / beta2;
877 float c = b - beta2;
878
879 float ret = d * (log0 + b + c);
880 float case1 = d * (log1 + c);
881
882 if (a > 3.5f * 3.5f) {
883 ret = case1;
884 }
885
886 return ret;
887}
888
889GPUd() void GPUTPCCompressionTrackModel::getClusterErrors2(int32_t iRow, float z, float sinPhi, float DzDs, float& ErrY2, float& ErrZ2) const
890{
891 int32_t rowType = iRow < 97 ? (iRow < 63 ? 0 : 1) : (iRow < 127 ? 2 : 3);
892 if (rowType > 2) {
893 rowType = 2; // TODO: Add type 3
894 }
895 constexpr float tpcLength = 250.f - 0.275f;
896 z = CAMath::Abs(tpcLength - CAMath::Abs(z));
897 float s2 = sinPhi * sinPhi;
898 if (s2 > 0.95f * 0.95f) {
899 s2 = 0.95f * 0.95f;
900 }
901 float sec2 = 1.f / (1.f - s2);
902 float angleY2 = s2 * sec2; // dy/dx
903 float angleZ2 = DzDs * DzDs * sec2; // dz/dx
904
905 const float* cY = mParamErrors0[0][rowType];
906 ErrY2 = cY[0] + cY[1] * z + cY[2] * angleY2;
907 ErrY2 *= ErrY2;
908
909 const float* cZ = mParamErrors0[1][rowType];
910 ErrZ2 = cZ[0] + cZ[1] * z + cZ[2] * angleZ2;
911 ErrZ2 *= ErrZ2;
912}
913
914GPUd() void GPUTPCCompressionTrackModel::resetCovariance()
915{
916 mC[0] = 100.f;
917 mC[1] = 0.f;
918 mC[2] = 100.f;
919 mC[3] = 0.f;
920 mC[4] = 0.f;
921 mC[5] = 1.f;
922 mC[6] = 0.f;
923 mC[7] = 0.f;
924 mC[8] = 0.f;
925 mC[9] = 10.f;
926 mC[10] = 0.f;
927 mC[11] = 0.f;
928 mC[12] = 0.f;
929 mC[13] = 0.f;
930 mC[14] = 10.f;
931}
932
933#endif
#define GPUrestrict()
#define GPUCA_MAX_SIN_PHI
int32_t retVal
GPUd() void GPUTPCCompressionTrackModel
constexpr int p2()
uint32_t c
Definition RawData.h:2
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLuint GLfloat x0
Definition glcorearb.h:5034
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition glcorearb.h:5034
GLenum GLfloat param
Definition glcorearb.h:271
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLuint GLfloat GLfloat y0
Definition glcorearb.h:5034
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
constexpr float MaxSinPhi
float float float float z1
Definition MathUtils.h:44
value_T d2
Definition TrackUtils.h:135
kp1 *kp2 *value_T beta2
Definition TrackUtils.h:131
std::vector< o2::mch::ChannelCode > cc