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