Project
Loading...
Searching...
No Matches
GPUTPCTrackletConstructor.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
15#define GPUCA_CADEBUG 0
16
17#include "GPUTPCDef.h"
18#include "GPUTPCGrid.h"
19#include "GPUTPCHit.h"
20#include "GPUTPCTrackParam.h"
21#include "GPUTPCTracker.h"
22#include "GPUTPCTracklet.h"
26#include "CalibdEdxContainer.h"
27#include "GPUParam.inc"
28#include "GPUCommonMath.h"
29
30using namespace o2::gpu;
31
33{
34 // Initialize Tracklet Parameters using default values
35 tParam.InitParam();
36}
37
39{
40 bool ok = 1;
41 const float* c = tParam.Cov();
42 for (int32_t i = 0; i < 15; i++) {
43 ok = ok && CAMath::Finite(c[i]);
44 }
45 for (int32_t i = 0; i < 5; i++) {
46 ok = ok && CAMath::Finite(tParam.Par()[i]);
47 }
48 ok = ok && (tParam.X() > 50);
49 if (c[0] <= 0 || c[2] <= 0 || c[5] <= 0 || c[9] <= 0 || c[14] <= 0) {
50 ok = 0;
51 }
52 return (ok);
53}
54
55GPUd() void GPUTPCTrackletConstructor::StoreTracklet(int32_t /*nBlocks*/, int32_t /*nThreads*/, int32_t /*iBlock*/, int32_t /*iThread*/, GPUsharedref() GPUSharedMemory& s, GPUTPCThreadMemory& GPUrestrict() r, GPUconstantref() GPUTPCTracker& GPUrestrict() tracker, GPUTPCTrackParam& GPUrestrict() tParam, calink* rowHits)
56{
57 // reconstruction of tracklets, tracklet store step
58 const uint32_t nHits = r.mLastRow + 1 - r.mFirstRow;
59 if (nHits == 0 || r.mNHits == 0 || (r.mNHits < GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(tParam.QPt() * tracker.Param().qptB5Scaler) || !CheckCov(tParam) || CAMath::Abs(tParam.GetQPt() * tracker.Param().qptB5Scaler) > tracker.Param().rec.maxTrackQPtB5)) {
60 CADEBUG(printf(" Rejected: nHits %d QPt %f MinHits %d MaxQPt %f CheckCov %d\n", r.mNHits, tParam.QPt(), GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(tParam.QPt() * tracker.Param().qptB5Scaler), tracker.Param().rec.maxTrackQPtB5, (int32_t)CheckCov(tParam)));
61 return;
62 }
63
64 /*GPUInfo("Tracklet %d: Hits %3d NDF %3d Chi %8.4f Sign %f Cov: %2.4f %2.4f %2.4f %2.4f %2.4f %2.4f %2.4f %2.4f %2.4f %2.4f %2.4f %2.4f %2.4f %2.4f %2.4f", r.mISH, r.mNHits, tParam.GetNDF(), tParam.GetChi2(), tParam.GetSignCosPhi(),
65 tParam.Cov()[0], tParam.Cov()[1], tParam.Cov()[2], tParam.Cov()[3], tParam.Cov()[4], tParam.Cov()[5], tParam.Cov()[6], tParam.Cov()[7], tParam.Cov()[8], tParam.Cov()[9],
66 tParam.Cov()[10], tParam.Cov()[11], tParam.Cov()[12], tParam.Cov()[13], tParam.Cov()[14]);*/
67
68 uint32_t hitout = CAMath::AtomicAdd(tracker.NRowHits(), nHits);
69 if (hitout + nHits > tracker.NMaxRowHits()) {
70 tracker.raiseError(GPUErrors::ERROR_TRACKLET_HIT_OVERFLOW, tracker.ISector(), hitout + nHits, tracker.NMaxRowHits());
71 CAMath::AtomicExch(tracker.NRowHits(), tracker.NMaxRowHits());
72 return;
73 }
74 uint32_t itrout = CAMath::AtomicAdd(tracker.NTracklets(), 1u);
75 if (itrout >= tracker.NMaxTracklets()) {
76 tracker.raiseError(GPUErrors::ERROR_TRACKLET_OVERFLOW, tracker.ISector(), itrout, tracker.NMaxTracklets());
77 CAMath::AtomicExch(tracker.NTracklets(), tracker.NMaxTracklets());
78 return;
79 }
80
81 GPUglobalref() GPUTPCTracklet& GPUrestrict() tracklet = tracker.Tracklets()[itrout];
82
83 CADEBUG(printf(" Storing tracklet: %d rows\n", nHits));
84
85 tracklet.SetFirstRow(r.mFirstRow);
86 tracklet.SetLastRow(r.mLastRow);
87 tracklet.SetFirstHit(hitout);
88 tracklet.SetParam(tParam.GetParam());
89 int32_t w = tracker.CalculateHitWeight(r.mNHits, tParam.GetChi2());
90 tracklet.SetHitWeight(w);
91#ifdef __HIPCC__ // Todo: fixme!
92 for (int32_t iRow = r.mFirstRow - 1; ++iRow <= r.mLastRow; /*iRow++*/) {
93#else
94 for (int32_t iRow = r.mFirstRow; iRow <= r.mLastRow; iRow++) {
95#endif
96 calink ih = rowHits[iRow];
97 tracker.TrackletRowHits()[hitout + (iRow - r.mFirstRow)] = ih;
98 if (ih != CALINK_INVAL && ih != CALINK_DEAD_CHANNEL) {
99 CA_MAKE_SHARED_REF(GPUTPCRow, row, tracker.Row(iRow), s.mRows[iRow]);
100 tracker.MaximizeHitWeight(row, ih, w);
101 }
102 }
103}
104
105template <class T>
106GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int32_t /*nBlocks*/, int32_t /*nThreads*/, int32_t /*iBlock*/, int32_t /*iThread*/, GPUsharedref() T& s, GPUTPCThreadMemory& GPUrestrict() r, GPUconstantref() GPUTPCTracker& GPUrestrict() tracker, GPUTPCTrackParam& GPUrestrict() tParam, int32_t iRow, calink& rowHit, calink* rowHits)
107{
108 // reconstruction of tracklets, tracklets update step
109 CA_MAKE_SHARED_REF(GPUTPCRow, row, tracker.Row(iRow), s.mRows[iRow]);
110
111 float y0 = row.Grid().YMin();
112 float stepY = row.HstepY();
113 float z0 = row.Grid().ZMin() - tParam.ZOffset();
114 float stepZ = row.HstepZ();
115
116 if (r.mStage == 0) { // fitting part
117 do {
118 if (iRow < r.mStartRow || r.mCurrIH == CALINK_INVAL) {
119 break;
120 }
121 if ((iRow - r.mStartRow) & 1) {
122 rowHit = CALINK_INVAL;
123 break; // SG!!! - jump over the row
124 }
125
126 cahit2 hh = CA_TEXTURE_FETCH(cahit22, gAliTexRefu2, tracker.HitData(row), r.mCurrIH);
127
128 int32_t seedIH = r.mCurrIH;
129 r.mCurrIH = CA_TEXTURE_FETCH(calink, gAliTexRefs, tracker.HitLinkUpData(row), r.mCurrIH);
130
131 float x = row.X();
132 float y = y0 + hh.x * stepY;
133 float z = z0 + hh.y * stepZ;
134 if (iRow != r.mStartRow || !tracker.Param().par.continuousTracking) {
135 tParam.ConstrainZ(z, tracker.ISector(), z0, r.mLastZ);
136 tracker.GetConstantMem()->calibObjects.fastTransformHelper->TransformXYZ(tracker.ISector(), iRow, x, y, z);
137 }
138 if (iRow == r.mStartRow) {
139 if (tracker.Param().par.continuousTracking) {
140 float refZ = ((z > 0) ? tracker.Param().rec.tpc.defaultZOffsetOverR : -tracker.Param().rec.tpc.defaultZOffsetOverR) * x;
141 float zTmp = refZ;
142 tracker.GetConstantMem()->calibObjects.fastTransformHelper->TransformXYZ(tracker.ISector(), iRow, x, y, zTmp);
143 z += zTmp - refZ; // Add zCorrection (=zTmp - refZ) to z, such that zOffset is set such, that transformed (z - zOffset) becomes refZ
144 tParam.SetZOffset(z - refZ);
145 tParam.SetZ(refZ);
146 r.mLastZ = refZ;
147 } else {
148 tParam.SetZ(z);
149 r.mLastZ = z;
150 tParam.SetZOffset(0.f);
151 }
152 tParam.SetX(x);
153 tParam.SetY(y);
154 r.mLastY = y;
155 CADEBUG(printf("Tracklet %5d: FIT INIT ROW %3d X %8.3f -", r.mISH, iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n"));
156 } else {
157 float dx = x - tParam.X();
158 float dy, dz;
159 if (r.mNHits >= 10) {
160 dy = y - tParam.Y();
161 dz = z - tParam.Z();
162 } else {
163 dy = y - r.mLastY;
164 dz = z - r.mLastZ;
165 }
166 r.mLastY = y;
167 r.mLastZ = z;
168
169 float ri = 1.f / CAMath::Sqrt(dx * dx + dy * dy);
170 if (iRow == r.mStartRow + 2) {
171 tParam.SetSinPhi(dy * ri);
172 tParam.SetSignCosPhi(dx);
173 tParam.SetDzDs(dz * ri);
174 float err2Y, err2Z;
175 tracker.GetErrors2Seeding(iRow, tParam, -1.f, err2Y, err2Z); // Use correct time
176 tParam.SetCov(0, err2Y);
177 tParam.SetCov(2, err2Z);
178 }
179 float sinPhi, cosPhi;
180 if (r.mNHits >= 10 && CAMath::Abs(tParam.SinPhi()) < GPUCA_MAX_SIN_PHI_LOW) {
181 sinPhi = tParam.SinPhi();
182 cosPhi = CAMath::Sqrt(1 - sinPhi * sinPhi);
183 } else {
184 sinPhi = dy * ri;
185 cosPhi = dx * ri;
186 }
187 CADEBUG(printf("%14s: FIT TRACK ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n"));
188 if (!tParam.TransportToX(x, sinPhi, cosPhi, tracker.Param().bzCLight, GPUCA_MAX_SIN_PHI)) {
189 rowHit = CALINK_INVAL;
190 break;
191 }
192 CADEBUG(printf("%5s hits %3d: FIT PROP ROW %3d X %8.3f -", "", r.mNHits, iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n"));
193 float err2Y, err2Z;
194 tracker.GetErrors2Seeding(iRow, tParam.GetZ(), sinPhi, tParam.GetDzDs(), -1.f, err2Y, err2Z); // TODO: Use correct time
195
196 if (r.mNHits >= 10) {
197 const float sErr2 = tracker.Param().GetSystematicClusterErrorIFC2(x, tParam.GetY(), tParam.GetZ(), tracker.ISector() >= 18);
198 err2Y += sErr2;
199 err2Z += sErr2;
200 const float kFactor = tracker.Param().rec.tpc.hitPickUpFactor * tracker.Param().rec.tpc.hitPickUpFactor * 3.5f * 3.5f;
201 float sy2 = kFactor * (tParam.Err2Y() + err2Y);
202 float sz2 = kFactor * (tParam.Err2Z() + err2Z);
203 if (sy2 > tracker.Param().rec.tpc.hitSearchArea2) {
204 sy2 = tracker.Param().rec.tpc.hitSearchArea2;
205 }
206 if (sz2 > tracker.Param().rec.tpc.hitSearchArea2) {
207 sz2 = tracker.Param().rec.tpc.hitSearchArea2;
208 }
209 dy = y - tParam.Y();
210 dz = z - tParam.Z();
211 if (dy * dy > sy2 || dz * dz > sz2) {
212 if (++r.mNMissed >= tracker.Param().rec.tpc.trackFollowingMaxRowGapSeed) {
213 r.mCurrIH = CALINK_INVAL;
214 }
215 rowHit = CALINK_INVAL;
216 break;
217 }
218 }
219
220 if (!tParam.Filter(y, z, err2Y, err2Z, GPUCA_MAX_SIN_PHI_LOW)) {
221 rowHit = CALINK_INVAL;
222 break;
223 }
224 CADEBUG(printf("%14s: FIT FILT ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n"));
225 }
226 rowHit = seedIH;
227 r.mNHitsEndRow = ++r.mNHits;
228 r.mLastRow = iRow;
229 r.mEndRow = iRow;
230 r.mNMissed = 0;
231 } while (0);
232
233 /*printf("Extrapolate Row %d X %f Y %f Z %f SinPhi %f DzDs %f QPt %f", iRow, tParam.X(), tParam.Y(), tParam.Z(), tParam.SinPhi(), tParam.DzDs(), tParam.QPt());
234 for (int32_t i = 0;i < 15;i++) printf(" C%d=%6.2f", i, tParam.GetCov(i));
235 printf("\n");*/
236
237 if (r.mCurrIH == CALINK_INVAL) {
238 r.mStage = 1;
239 r.mLastY = tParam.Y(); // Store last spatial position here to start inward following from here
240 r.mLastZ = tParam.Z();
241 if (CAMath::Abs(tParam.SinPhi()) > GPUCA_MAX_SIN_PHI) {
242 r.mGo = 0;
243 }
244 }
245 } else { // forward/backward searching part
246 do {
247 if (r.mStage == 2 && iRow > r.mEndRow) {
248 break;
249 }
250 if (r.mNMissed > tracker.Param().rec.tpc.trackFollowingMaxRowGap) {
251 r.mGo = 0;
252 break;
253 }
254
255 r.mNMissed++;
256
257 float x = row.X();
258 {
259 float tmpY, tmpZ;
260 if (!tParam.GetPropagatedYZ(tracker.Param().bzCLight, x, tmpY, tmpZ)) {
261 r.mGo = 0;
262 rowHit = CALINK_INVAL;
263 break;
264 }
265 tParam.ConstrainZ(tmpZ, tracker.ISector(), z0, r.mLastZ);
266 tracker.GetConstantMem()->calibObjects.fastTransformHelper->InverseTransformYZtoX(tracker.ISector(), iRow, tmpY, tmpZ, x);
267 }
268
269 CADEBUG(printf("%14s: SEA TRACK ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n"));
270 if (!tParam.TransportToX(x, tParam.SinPhi(), tParam.GetCosPhi(), tracker.Param().bzCLight, GPUCA_MAX_SIN_PHI_LOW)) {
271 r.mGo = 0;
272 rowHit = CALINK_INVAL;
273 break;
274 }
275 CADEBUG(printf("%14s: SEA PROP ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n"));
276
277 bool found = false;
278 float yUncorrected = tParam.GetY(), zUncorrected = tParam.GetZ();
279 do {
280 if (row.NHits() < 1) {
281 rowHit = CALINK_INVAL;
282 break;
283 }
284
285#ifndef GPUCA_TEXTURE_FETCH_CONSTRUCTOR
286 GPUglobalref() const cahit2* hits = tracker.HitData(row);
287 GPUglobalref() const calink* firsthit = tracker.FirstHitInBin(row);
288#endif
289 tracker.GetConstantMem()->calibObjects.fastTransformHelper->InverseTransformYZtoNominalYZ(tracker.ISector(), iRow, yUncorrected, zUncorrected, yUncorrected, zUncorrected);
290
291 if (tracker.Param().rec.tpc.rejectEdgeClustersInSeeding && tracker.Param().rejectEdgeClusterByY(yUncorrected, iRow, CAMath::Sqrt(tParam.Err2Y()))) {
292 rowHit = CALINK_INVAL;
293 break;
294 }
295 calink best = CALINK_INVAL;
296
297 float err2Y, err2Z;
298 tracker.GetErrors2Seeding(iRow, *((GPUTPCTrackParam*)&tParam), -1.f, err2Y, err2Z); // TODO: Use correct time
299 if (r.mNHits >= 10) {
300 const float sErr2 = tracker.Param().GetSystematicClusterErrorIFC2(x, tParam.GetY(), tParam.GetZ(), tracker.ISector() >= 18);
301 err2Y += sErr2;
302 err2Z += sErr2;
303 }
304 if (CAMath::Abs(yUncorrected) < x * GPUTPCRow::getTPCMaxY1X()) { // search for the closest hit
305 const float kFactor = tracker.Param().rec.tpc.hitPickUpFactor * tracker.Param().rec.tpc.hitPickUpFactor * 7.0f * 7.0f;
306 const float maxWindow2 = tracker.Param().rec.tpc.hitSearchArea2;
307 const float sy2 = CAMath::Min(maxWindow2, kFactor * (tParam.Err2Y() + err2Y));
308 const float sz2 = CAMath::Min(maxWindow2, kFactor * (tParam.Err2Z() + err2Z));
309
310 int32_t bin, ny, nz;
311 row.Grid().GetBinArea(yUncorrected, zUncorrected + tParam.ZOffset(), CAMath::Sqrt(sy2), CAMath::Sqrt(sz2), bin, ny, nz);
312 float ds = 1e6f;
313
314#ifdef __HIPCC__ // Todo: fixme!
315 for (int32_t k = -1; ++k <= nz; /*k++*/) {
316#else
317 for (int32_t k = 0; k <= nz; k++) {
318#endif
319 int32_t nBinsY = row.Grid().Ny();
320 int32_t mybin = bin + k * nBinsY;
321 uint32_t hitFst = CA_TEXTURE_FETCH(calink, gAliTexRefu, firsthit, mybin);
322 uint32_t hitLst = CA_TEXTURE_FETCH(calink, gAliTexRefu, firsthit, mybin + ny + 1);
323#ifdef __HIPCC__ // Todo: fixme!
324 for (uint32_t ih = hitFst - 1; ++ih < hitLst; /*ih++*/) {
325#else
326 for (uint32_t ih = hitFst; ih < hitLst; ih++) {
327#endif
328 cahit2 hh = CA_TEXTURE_FETCH(cahit2, gAliTexRefu2, hits, ih);
329 float y = y0 + hh.x * stepY;
330 float z = z0 + hh.y * stepZ;
331 float dy = y - yUncorrected;
332 float dz = z - zUncorrected;
333 if (dy * dy < sy2 && dz * dz < sz2) {
334 float dds = tracker.Param().rec.tpc.trackFollowingYFactor * CAMath::Abs(dy) + CAMath::Abs(dz);
335 if (dds < ds) {
336 ds = dds;
337 best = ih;
338 }
339 }
340 }
341 }
342 } // end of search for the closest hit
343
344 if (best == CALINK_INVAL) {
345 if (r.mNHits == 0 && r.mStage < 3) {
346 if (rowHit == CALINK_INVAL || rowHit == CALINK_DEAD_CHANNEL) {
347 break;
348 }
349 best = rowHit;
350 } else {
351 rowHit = CALINK_INVAL;
352 break;
353 }
354 }
355
356 cahit2 hh = CA_TEXTURE_FETCH(cahit2, gAliTexRefu2, hits, best);
357 float y = y0 + hh.x * stepY + tParam.GetY() - yUncorrected;
358 float z = z0 + hh.y * stepZ + tParam.GetZ() - zUncorrected;
359
360 CADEBUG(printf("%14s: SEA Hit %5d (%8.3f %8.3f), Res %f %f\n", "", best, y, z, tParam.Y() - y, tParam.Z() - z));
361
362 calink oldHit = (r.mStage == 2 && iRow >= r.mStartRow) ? rowHit : CALINK_INVAL;
363 if (oldHit != best && !tParam.Filter(y, z, err2Y, err2Z, GPUCA_MAX_SIN_PHI_LOW, oldHit != CALINK_INVAL) && r.mNHits != 0) {
364 rowHit = CALINK_INVAL;
365 break;
366 }
367 found = true;
368 rowHit = best;
369 r.mNHits++;
370 r.mNMissed = 0;
371 CADEBUG(printf("%5s hits %3d: SEA FILT ROW %3d X %8.3f -", "", r.mNHits, iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n"));
372 if (r.mStage == 1) {
373 r.mLastRow = iRow;
374 } else {
375 r.mFirstRow = iRow;
376 }
377 } while (false);
378 (void)found;
379 if (!found && tracker.GetConstantMem()->calibObjects.dEdxCalibContainer) {
380 uint32_t pad = CAMath::Float2UIntRn(tracker.Param().tpcGeometry.LinearY2Pad(tracker.ISector(), iRow, yUncorrected));
381 if (pad < tracker.Param().tpcGeometry.NPads(iRow) && tracker.GetConstantMem()->calibObjects.dEdxCalibContainer->isDead(tracker.ISector(), iRow, pad)) {
382 r.mNMissed--;
383 rowHit = CALINK_DEAD_CHANNEL;
384 }
385 }
386 } while (0);
387 }
388 if (r.mNHits == 8 && r.mNMissed == 0 && rowHit != CALINK_INVAL && rowHit != CALINK_DEAD_CHANNEL && rowHits && tracker.Param().par.continuousTracking && rowHits[r.mFirstRow] != CALINK_INVAL && rowHits[r.mFirstRow] != CALINK_DEAD_CHANNEL && rowHits[r.mLastRow] != CALINK_INVAL && rowHits[r.mLastRow] != CALINK_DEAD_CHANNEL) {
389 const GPUglobalref() GPUTPCRow& GPUrestrict() row1 = tracker.Row(r.mFirstRow);
390 const GPUglobalref() GPUTPCRow& GPUrestrict() row2 = tracker.Row(r.mLastRow);
391 GPUglobalref() const cahit2* hits1 = tracker.HitData(row1);
392 GPUglobalref() const cahit2* hits2 = tracker.HitData(row2);
393 const cahit2 hh1 = CA_TEXTURE_FETCH(cahit2, gAliTexRefu2, hits1, rowHits[r.mFirstRow]);
394 const cahit2 hh2 = CA_TEXTURE_FETCH(cahit2, gAliTexRefu2, hits2, rowHits[r.mLastRow]);
395 const float z1 = row1.Grid().ZMin() + hh1.y * row1.HstepZ();
396 const float z2 = row2.Grid().ZMin() + hh2.y * row2.HstepZ();
397 float oldOffset = tParam.ZOffset();
398 tParam.ShiftZ(z1, z2, tracker.Param().tpcGeometry.Row2X(r.mFirstRow), tracker.Param().tpcGeometry.Row2X(r.mLastRow), tracker.Param().bzCLight, tracker.Param().rec.tpc.defaultZOffsetOverR);
399 r.mLastZ -= tParam.ZOffset() - oldOffset;
400 CADEBUG(printf("Shifted z from %f to %f\n", oldOffset, tParam.ZOffset()));
401 }
402}
403
404GPUdic(2, 1) void GPUTPCTrackletConstructor::DoTracklet(GPUconstantref() GPUTPCTracker& GPUrestrict() tracker, GPUsharedref() GPUTPCTrackletConstructor::GPUSharedMemory& s, GPUTPCThreadMemory& GPUrestrict() r)
405{
406 int32_t iRow = 0, iRowEnd = GPUCA_ROW_COUNT;
407 GPUTPCTrackParam tParam;
408 calink rowHits[GPUCA_ROW_COUNT];
409 if (r.mGo) {
410 GPUTPCHitId id = tracker.TrackletStartHits()[r.mISH];
411
412 r.mStartRow = r.mEndRow = r.mFirstRow = r.mLastRow = id.RowIndex();
413 r.mCurrIH = id.HitIndex();
414 r.mNMissed = 0;
415 iRow = r.mStartRow;
416 GPUTPCTrackletConstructor::InitTracklet(tParam);
417 }
418 r.mStage = 0;
419 r.mNHits = 0;
420 CADEBUG(printf("Start tracklet\n"));
421
422#ifdef __HIPCC__ // Todo: fixme!
423 for (int32_t iStage = -1; ++iStage < 2; /*iStage++*/) {
424#else
425 for (int32_t iStage = 0; iStage < 2; iStage++) {
426#endif
427 for (; iRow != iRowEnd; iRow += r.mStage == 2 ? -1 : 1) {
428 if (!r.mGo) {
429 break;
430 }
431 UpdateTracklet(0, 0, 0, 0, s, r, tracker, tParam, iRow, rowHits[iRow], rowHits);
432 }
433 if (!r.mGo && r.mStage == 2) {
434 for (; iRow >= r.mStartRow; iRow--) {
435 rowHits[iRow] = CALINK_INVAL;
436 }
437 }
438 if (r.mStage == 2) {
439 StoreTracklet(0, 0, 0, 0, s, r, tracker, tParam, rowHits);
440 } else {
441 r.mStage = 2;
442 r.mNMissed = 0;
443 iRow = r.mEndRow;
444 iRowEnd = -1;
445 float x = tracker.Row(r.mEndRow).X();
446 {
447 float tmpY, tmpZ;
448 if (tParam.GetPropagatedYZ(tracker.Param().bzCLight, x, tmpY, tmpZ)) {
449 if (tracker.ISector() < GPUCA_NSECTORS / 2 ? (tmpZ < 0) : (tmpZ > 0)) {
450 tmpZ = 0;
451 } else if (tracker.ISector() < GPUCA_NSECTORS / 2 ? (tmpZ > GPUTPCGeometry::TPCLength()) : (tmpZ < -GPUTPCGeometry::TPCLength())) {
452 tmpZ = tracker.ISector() < GPUCA_NSECTORS / 2 ? GPUTPCGeometry::TPCLength() : -GPUTPCGeometry::TPCLength();
453 }
454 tracker.GetConstantMem()->calibObjects.fastTransformHelper->InverseTransformYZtoX(tracker.ISector(), iRow, tmpY, tmpZ, x);
455 } else {
456 r.mGo = 0;
457 continue;
458 }
459 }
460 if ((r.mGo = (tParam.TransportToX(x, tracker.Param().bzCLight, GPUCA_MAX_SIN_PHI) && tParam.Filter(r.mLastY, r.mLastZ, tParam.Err2Y() * 0.5f, tParam.Err2Z() * 0.5f, GPUCA_MAX_SIN_PHI_LOW, true)))) {
461 CADEBUG(printf("%14s: SEA BACK ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n"));
462 float err2Y, err2Z;
463 tracker.GetErrors2Seeding(r.mEndRow, tParam, -1.f, err2Y, err2Z); // TODO: Use correct time
464 if (tParam.GetCov(0) < err2Y) {
465 tParam.SetCov(0, err2Y);
466 }
467 if (tParam.GetCov(2) < err2Z) {
468 tParam.SetCov(2, err2Z);
469 }
470 CADEBUG(printf("%14s: SEA ADJUS ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n"));
471 r.mNHits -= r.mNHitsEndRow;
472 }
473 }
474 }
475 CADEBUG(printf("End tracklet\n"));
476}
477
478template <>
479GPUdii() void GPUTPCTrackletConstructor::Thread<GPUTPCTrackletConstructor::singleSector>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& sMem, processorType& GPUrestrict() tracker)
480{
481 if (get_local_id(0) == 0) {
482 sMem.mNStartHits = *tracker.NStartHits();
483 }
484 CA_SHARED_CACHE(&sMem.mRows[0], tracker.TrackingDataRows(), GPUCA_ROW_COUNT * sizeof(GPUTPCRow));
485 GPUbarrier();
486
487 GPUTPCThreadMemory rMem;
488 for (rMem.mISH = get_global_id(0); rMem.mISH < sMem.mNStartHits; rMem.mISH += get_global_size(0)) {
489 rMem.mGo = 1;
490 DoTracklet(tracker, sMem, rMem);
491 }
492}
493
494template <>
495GPUdii() void GPUTPCTrackletConstructor::Thread<GPUTPCTrackletConstructor::allSectors>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& sMem, processorType& GPUrestrict() tracker0)
496{
497 GPUconstantref() GPUTPCTracker* GPUrestrict() pTracker = &tracker0;
498#ifdef GPUCA_GPUCODE
499 int32_t mySector = get_group_id(0) % GPUCA_NSECTORS;
500 int32_t currentSector = -1;
501
502 if (get_local_id(0) == 0) {
503 sMem.mNextStartHitFirstRun = 1;
504 }
505 GPUCA_UNROLL(, U())
506 for (uint32_t iSector = 0; iSector < GPUCA_NSECTORS; iSector++) {
507 GPUconstantref() GPUTPCTracker& GPUrestrict() tracker = pTracker[mySector];
508
509 GPUTPCThreadMemory rMem;
510
511 while ((rMem.mISH = FetchTracklet(tracker, sMem)) != -2) {
512 if (rMem.mISH >= 0 && get_local_id(0) < GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCTrackletConstructor)) {
513 rMem.mISH += get_local_id(0);
514 } else {
515 rMem.mISH = -1;
516 }
517
518 if (mySector != currentSector) {
519 if (get_local_id(0) == 0) {
520 sMem.mNStartHits = *tracker.NStartHits();
521 }
522 CA_SHARED_CACHE(&sMem.mRows[0], tracker.TrackingDataRows(), GPUCA_ROW_COUNT * sizeof(GPUTPCRow));
523 GPUbarrier();
524 currentSector = mySector;
525 }
526
527 if (rMem.mISH >= 0 && rMem.mISH < sMem.mNStartHits) {
528 rMem.mGo = true;
529 DoTracklet(tracker, sMem, rMem);
530 }
531 }
532 if (++mySector >= GPUCA_NSECTORS) {
533 mySector = 0;
534 }
535 }
536#else
537 for (int32_t iSector = 0; iSector < GPUCA_NSECTORS; iSector++) {
538 Thread<singleSector>(nBlocks, nThreads, iBlock, iThread, sMem, pTracker[iSector]);
539 }
540#endif
541}
542
543#ifdef GPUCA_GPUCODE
544
545GPUd() int32_t GPUTPCTrackletConstructor::FetchTracklet(GPUconstantref() GPUTPCTracker& GPUrestrict() tracker, GPUsharedref() GPUSharedMemory& sMem)
546{
547 const uint32_t nStartHit = *tracker.NStartHits();
548 GPUbarrier();
549 if (get_local_id(0) == 0) {
550 int32_t firstStartHit = -2;
551 if (sMem.mNextStartHitFirstRun == 1) {
552 firstStartHit = (get_group_id(0) - tracker.ISector()) / GPUCA_NSECTORS * GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCTrackletConstructor);
553 sMem.mNextStartHitFirstRun = 0;
554 } else {
555 if (tracker.GPUParameters()->nextStartHit < nStartHit) {
556 firstStartHit = CAMath::AtomicAdd<uint32_t>(&tracker.GPUParameters()->nextStartHit, GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCTrackletConstructor));
557 }
558 }
559 sMem.mNextStartHitFirst = firstStartHit < (int32_t)nStartHit ? firstStartHit : -2;
560 }
561 GPUbarrier();
562 return (sMem.mNextStartHitFirst);
563}
564
565#endif // GPUCA_GPUCODE
566
567template <> // FIXME: GPUgeneric() needed to make the clang spirv output link correctly
568GPUd() int32_t GPUTPCTrackletConstructor::GPUTPCTrackletConstructorExtrapolationTracking<GPUgeneric() GPUTPCExtrapolationTracking::GPUSharedMemory>(GPUconstantref() GPUTPCTracker& GPUrestrict() tracker, GPUsharedref() GPUTPCExtrapolationTracking::GPUSharedMemory& sMem, GPUTPCTrackParam& GPUrestrict() tParam, int32_t row, int32_t increment, int32_t iTracklet, calink* rowHits)
569{
570 GPUTPCThreadMemory rMem;
571 rMem.mISH = iTracklet;
572 rMem.mStage = 3;
573 rMem.mNHits = rMem.mNMissed = 0;
574 rMem.mGo = 1;
575 while (rMem.mGo && row >= 0 && row < GPUCA_ROW_COUNT) {
576 UpdateTracklet(1, 1, 0, 0, sMem, rMem, tracker, tParam, row, rowHits[row], nullptr);
577 row += increment;
578 }
579 if (!CheckCov(tParam)) {
580 rMem.mNHits = 0;
581 }
582 return (rMem.mNHits);
583}
Definition of container class for dE/dx corrections.
Helper class to access correction maps.
int32_t i
#define get_local_id(dim)
#define GPUsharedref()
#define GPUconstantref()
#define GPUdic(...)
#define get_global_size(dim)
#define GPUbarrier()
#define GPUgeneric()
#define GPUrestrict()
#define get_global_id(dim)
#define get_group_id(dim)
#define GPUglobalref()
#define GPUCA_MAX_SIN_PHI_LOW
#define GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(QPTB5)
#define GPUCA_MAX_SIN_PHI
#define GPUCA_GET_THREAD_COUNT(...)
#define CA_MAKE_SHARED_REF(vartype, varname, varglobal, varshared)
Definition GPUDef.h:55
#define CADEBUG(...)
Definition GPUDef.h:85
#define CA_SHARED_CACHE(target, src, size)
Definition GPUDef.h:57
#define CA_TEXTURE_FETCH(type, texture, address, entry)
Definition GPUDef.h:64
#define GPUCA_UNROLL(optCu, optHi)
#define CALINK_DEAD_CHANNEL
Definition GPUTPCDef.h:22
#define CALINK_INVAL
Definition GPUTPCDef.h:21
#define GPUCA_NSECTORS
#define GPUCA_ROW_COUNT
GPUdii() void GPUTPCTrackletConstructor
GPUd() bool GPUTPCTrackletConstructor
uint32_t c
Definition RawData.h:2
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLint y
Definition glcorearb.h:270
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean r
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
GLuint GLfloat GLfloat y0
Definition glcorearb.h:5034
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
uint32_t calink
Definition GPUTPCDef.h:30
o2::mch::DsIndex ds
std::vector< int > row
std::vector< ReadoutWindowData > rows