Project
Loading...
Searching...
No Matches
GPUDisplayDraw.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#ifndef GPUCA_NO_ROOT
16#include "Rtypes.h" // Include ROOT header first, to use ROOT and disable replacements
17#endif
18
19#include "GPUDisplay.h"
20#include "GPUTRDGeometry.h"
21#include "GPUO2DataTypes.h"
22#include "GPUTRDTracker.h"
23#include "GPUTRDTrackletWord.h"
24#include "GPUQA.h"
25#include "GPUTPCConvertImpl.h"
26#include "GPUTPCGMPropagator.h"
27#include "GPUTPCMCInfo.h"
28#include "GPUParam.inc"
29#include "GPUCommonMath.h"
30#include "GPUChainTracking.h"
31
32#include <type_traits>
33
38
39#include <oneapi/tbb.h>
40
41using namespace o2::gpu;
42
43#define GET_CID(sector, i) (mIOPtrs->clustersNative->clusterOffset[sector][0] + i)
44
45const GPUTRDGeometry* GPUDisplay::trdGeometry() { return (GPUTRDGeometry*)mCalib->trdGeometry; }
46const GPUTPCTracker& GPUDisplay::sectorTracker(int32_t iSector) { return mChain->GetProcessors()->tpcTrackers[iSector]; }
47
48inline void GPUDisplay::insertVertexList(std::pair<vecpod<int32_t>*, vecpod<uint32_t>*>& vBuf, size_t first, size_t last)
49{
50 if (first == last) {
51 return;
52 }
53 vBuf.first->emplace_back(first);
54 vBuf.second->emplace_back(last - first);
55}
56inline void GPUDisplay::insertVertexList(int32_t iSector, size_t first, size_t last)
57{
58 std::pair<vecpod<int32_t>*, vecpod<uint32_t>*> vBuf(mVertexBufferStart + iSector, mVertexBufferCount + iSector);
59 insertVertexList(vBuf, first, last);
60}
61
62inline void GPUDisplay::drawPointLinestrip(int32_t iSector, int32_t cid, int32_t id, int32_t id_limit)
63{
64 mVertexBuffer[iSector].emplace_back(mGlobalPos[cid].x, mGlobalPos[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPos[cid].z);
65 float curVal;
66 while ((curVal = mGlobalPos[cid].w) < id_limit) {
67 if (CAMath::AtomicCAS(&mGlobalPos[cid].w, curVal, (float)id)) {
68 break;
69 }
70 curVal = mGlobalPos[cid].w;
71 }
72}
73
74GPUDisplay::vboList GPUDisplay::DrawSpacePointsTRD(int32_t iSector, int32_t select, int32_t iCol)
75{
76 size_t startCount = mVertexBufferStart[iSector].size();
77 size_t startCountInner = mVertexBuffer[iSector].size();
78
79 if (iCol == 0 && mCurrentSpacePointsTRD > 0) {
80 for (uint32_t i = 0; i < mIOPtrs->nTRDTracklets; i++) {
81 int32_t iSec = trdGeometry()->GetSector(mIOPtrs->trdTracklets[i].GetDetector());
82 bool draw = iSector == iSec && mGlobalPosTRD[i].w == select;
83 if (draw) {
84 mVertexBuffer[iSector].emplace_back(mGlobalPosTRD[i].x, mGlobalPosTRD[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD[i].z);
85 mVertexBuffer[iSector].emplace_back(mGlobalPosTRD2[i].x, mGlobalPosTRD2[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD2[i].z);
86 }
87 }
88 }
89
90 insertVertexList(iSector, startCountInner, mVertexBuffer[iSector].size());
91 return (vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector));
92}
93
94GPUDisplay::vboList GPUDisplay::DrawSpacePointsTOF(int32_t iSector, int32_t select, int32_t iCol)
95{
96 size_t startCount = mVertexBufferStart[iSector].size();
97 size_t startCountInner = mVertexBuffer[iSector].size();
98
99 if (iCol == 0 && iSector == 0) {
100 for (uint32_t i = 0; i < mIOPtrs->nTOFClusters; i++) {
101 mVertexBuffer[iSector].emplace_back(mGlobalPosTOF[i].x, mGlobalPosTOF[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTOF[i].z);
102 }
103 }
104
105 insertVertexList(iSector, startCountInner, mVertexBuffer[iSector].size());
106 return (vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector));
107}
108
109GPUDisplay::vboList GPUDisplay::DrawSpacePointsITS(int32_t iSector, int32_t select, int32_t iCol)
110{
111 size_t startCount = mVertexBufferStart[iSector].size();
112 size_t startCountInner = mVertexBuffer[iSector].size();
113
114 if (iCol == 0 && iSector == 0 && mIOPtrs->itsClusters) {
115 for (uint32_t i = 0; i < mIOPtrs->nItsClusters; i++) {
116 mVertexBuffer[iSector].emplace_back(mGlobalPosITS[i].x, mGlobalPosITS[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosITS[i].z);
117 }
118 }
119
120 insertVertexList(iSector, startCountInner, mVertexBuffer[iSector].size());
121 return (vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector));
122}
123
124void GPUDisplay::DrawClusters(int32_t iSector)
125{
126 std::vector<std::array<vecpod<vtx>, N_POINTS_TYPE_TPC>> vertexCache(mNCollissions);
127 if (mClusterBufferSizeCache[iSector].size() < (uint32_t)mNCollissions) {
128 mClusterBufferSizeCache[iSector].resize(mNCollissions);
129 }
130 for (int32_t iCol = 0; iCol < mNCollissions; iCol++) {
131 for (int32_t i = 0; i < N_POINTS_TYPE_TPC; i++) {
132 vertexCache[iCol][i].reserve(mClusterBufferSizeCache[iSector][iCol][i]);
133 }
134 }
135
136 uint32_t col = 0;
137 const int32_t nClustersInSector = mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSector] : 0;
138 [[maybe_unused]] const bool checkClusterCollision = mQA && mNCollissions && mOverlayTFClusters.size() == 0 && mIOPtrs->clustersNative && mIOPtrs->clustersNative->clustersMCTruth;
139 for (int32_t cidInSector = 0; cidInSector < nClustersInSector; cidInSector++) {
140 const int32_t cid = GET_CID(iSector, cidInSector);
141#ifndef GPUCA_RUN2
142 if (checkClusterCollision) {
143 const auto& labels = mIOPtrs->clustersNative->clustersMCTruth->getLabels(cid);
144 col = labels.size() ? mQA->GetMCLabelCol(labels[0]) : 0;
145 } else
146#endif
147 if (mOverlayTFClusters.size()) {
148 while (col < mOverlayTFClusters.size() && cidInSector >= mOverlayTFClusters[col][iSector]) {
149 col++;
150 }
151 }
152 if (mCfgH.hideUnmatchedClusters && mQA && mQA->SuppressHit(cid)) {
153 continue;
154 }
155 int32_t select = mGlobalPos[cid].w;
156
157 if (mCfgH.markAdjacentClusters) {
158 const int32_t attach = mIOPtrs->mergedTrackHitAttachment[cid];
159 if (attach) {
160 if (mCfgH.markAdjacentClusters >= 32) {
161 if (mQA && mQA->clusterRemovable(attach, mCfgH.markAdjacentClusters == 33)) {
162 select = tMARKED;
163 }
164 } else if ((mCfgH.markAdjacentClusters & 2) && (attach & gputpcgmmergertypes::attachTube)) {
165 select = tMARKED;
166 } else if ((mCfgH.markAdjacentClusters & 1) && (attach & (gputpcgmmergertypes::attachGood | gputpcgmmergertypes::attachTube)) == 0) {
167 select = tMARKED;
168 } else if ((mCfgH.markAdjacentClusters & 4) && (attach & gputpcgmmergertypes::attachGoodLeg) == 0) {
169 select = tMARKED;
170 } else if ((mCfgH.markAdjacentClusters & 16) && (attach & gputpcgmmergertypes::attachHighIncl)) {
171 select = tMARKED;
172 } else if (mCfgH.markAdjacentClusters & 8) {
173 if (fabsf(mIOPtrs->mergedTracks[attach & gputpcgmmergertypes::attachTrackMask].GetParam().GetQPt()) > 20.f) {
174 select = tMARKED;
175 }
176 }
177 }
178 } else if (mCfgH.markClusters) {
179 int16_t flags;
180 flags = mIOPtrs->clustersNative->clustersLinear[cid].getFlags();
181 if (flags & mCfgH.markClusters) {
182 select = tMARKED;
183 }
184 } else if (mCfgH.markFakeClusters) {
185 if (mQA->HitAttachStatus(cid)) {
186 select = tMARKED;
187 }
188 }
189 vertexCache[col][select].emplace_back(mGlobalPos[cid].x, mGlobalPos[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPos[cid].z);
190 }
191
192 size_t startCountInner = mVertexBuffer[iSector].size();
193 mVertexBuffer[iSector].resize(mVertexBuffer[iSector].size() + nClustersInSector);
194 for (int32_t iCol = 0; iCol < mNCollissions; iCol++) {
195 for (int32_t i = 0; i < N_POINTS_TYPE_TPC; i++) {
196 uint32_t count = vertexCache[iCol][i].size();
197 mClusterBufferSizeCache[iSector][iCol][i] = std::max(mClusterBufferSizeCache[iSector][iCol][i], count);
198 if (count) {
199 memcpy((void*)(mVertexBuffer[iSector].data() + startCountInner), (const void*)vertexCache[iCol][i].data(), count * sizeof(vertexCache[iCol][i][0]));
200 }
201 size_t startCount = mVertexBufferStart[iSector].size();
202 insertVertexList(iSector, startCountInner, startCountInner + count);
203 startCountInner += count;
204 mGlDLPoints[iSector][i][iCol] = vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector);
205 }
206 }
207}
208
209GPUDisplay::vboList GPUDisplay::DrawLinks(const GPUTPCTracker& tracker, int32_t id, bool dodown)
210{
211 uint32_t iSector = tracker.ISector();
212 if (mCfgH.clustersOnly) {
213 return (vboList(0, 0, iSector));
214 }
215 size_t startCount = mVertexBufferStart[iSector].size();
216 size_t startCountInner = mVertexBuffer[iSector].size();
217 for (uint32_t i = 0; i < GPUTPCGeometry::NROWS; i++) {
218 const GPUTPCRow& row = tracker.Data().Row(i);
219
220 if (i < GPUTPCGeometry::NROWS - 2) {
221 const GPUTPCRow& rowUp = tracker.Data().Row(i + 2);
222 for (uint32_t j = 0; j < row.NHits(); j++) {
223 if (tracker.Data().HitLinkUpData(row, j) != CALINK_INVAL) {
224 const int32_t cid1 = GET_CID(iSector, tracker.Data().ClusterDataIndex(row, j));
225 const int32_t cid2 = GET_CID(iSector, tracker.Data().ClusterDataIndex(rowUp, tracker.Data().HitLinkUpData(row, j)));
226 drawPointLinestrip(iSector, cid1, id);
227 drawPointLinestrip(iSector, cid2, id);
228 }
229 }
230 }
231
232 if (dodown && i >= 2) {
233 const GPUTPCRow& rowDown = tracker.Data().Row(i - 2);
234 for (uint32_t j = 0; j < row.NHits(); j++) {
235 if (tracker.Data().HitLinkDownData(row, j) != CALINK_INVAL) {
236 const int32_t cid1 = GET_CID(iSector, tracker.Data().ClusterDataIndex(row, j));
237 const int32_t cid2 = GET_CID(iSector, tracker.Data().ClusterDataIndex(rowDown, tracker.Data().HitLinkDownData(row, j)));
238 drawPointLinestrip(iSector, cid1, id);
239 drawPointLinestrip(iSector, cid2, id);
240 }
241 }
242 }
243 }
244 insertVertexList(iSector, startCountInner, mVertexBuffer[iSector].size());
245 return (vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector));
246}
247
248GPUDisplay::vboList GPUDisplay::DrawSeeds(const GPUTPCTracker& tracker)
249{
250 uint32_t iSector = tracker.ISector();
251 if (mCfgH.clustersOnly) {
252 return (vboList(0, 0, iSector));
253 }
254 size_t startCount = mVertexBufferStart[iSector].size();
255 for (uint32_t i = 0; i < *tracker.NStartHits(); i++) {
256 const GPUTPCHitId& hit = tracker.TrackletStartHit(i);
257 size_t startCountInner = mVertexBuffer[iSector].size();
258 int32_t ir = hit.RowIndex();
259 calink ih = hit.HitIndex();
260 do {
261 const GPUTPCRow& row = tracker.Data().Row(ir);
262 const int32_t cid = GET_CID(iSector, tracker.Data().ClusterDataIndex(row, ih));
263 drawPointLinestrip(iSector, cid, tSEED);
264 ir += 2;
265 ih = tracker.Data().HitLinkUpData(row, ih);
266 } while (ih != CALINK_INVAL);
267 insertVertexList(iSector, startCountInner, mVertexBuffer[iSector].size());
268 }
269 return (vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector));
270}
271
272GPUDisplay::vboList GPUDisplay::DrawTracklets(const GPUTPCTracker& tracker)
273{
274 uint32_t iSector = tracker.ISector();
275 if (mCfgH.clustersOnly) {
276 return (vboList(0, 0, iSector));
277 }
278 size_t startCount = mVertexBufferStart[iSector].size();
279 for (uint32_t i = 0; i < *tracker.NTracklets(); i++) {
280 const GPUTPCTracklet& tracklet = tracker.Tracklet(i);
281 size_t startCountInner = mVertexBuffer[iSector].size();
282 float4 oldpos;
283 for (uint32_t j = tracklet.FirstRow(); j <= tracklet.LastRow(); j++) {
284 const calink rowHit = tracker.TrackletRowHits()[tracklet.FirstHit() + (j - tracklet.FirstRow())];
285 if (rowHit != CALINK_INVAL && rowHit != CALINK_DEAD_CHANNEL) {
286 const GPUTPCRow& row = tracker.Data().Row(j);
287 const int32_t cid = GET_CID(iSector, tracker.Data().ClusterDataIndex(row, rowHit));
288 oldpos = mGlobalPos[cid];
289 drawPointLinestrip(iSector, cid, tTRACKLET);
290 }
291 }
292 insertVertexList(iSector, startCountInner, mVertexBuffer[iSector].size());
293 }
294 return (vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector));
295}
296
297GPUDisplay::vboList GPUDisplay::DrawTracks(const GPUTPCTracker& tracker, int32_t global)
298{
299 uint32_t iSector = tracker.ISector();
300 if (mCfgH.clustersOnly) {
301 return (vboList(0, 0, iSector));
302 }
303 size_t startCount = mVertexBufferStart[iSector].size();
304 for (uint32_t i = (global ? tracker.CommonMemory()->nLocalTracks : 0); i < (global ? *tracker.NTracks() : tracker.CommonMemory()->nLocalTracks); i++) {
305 GPUTPCTrack& track = tracker.Tracks()[i];
306 size_t startCountInner = mVertexBuffer[iSector].size();
307 for (int32_t j = 0; j < track.NHits(); j++) {
308 const GPUTPCHitId& hit = tracker.TrackHits()[track.FirstHitID() + j];
309 const GPUTPCRow& row = tracker.Data().Row(hit.RowIndex());
310 const int32_t cid = GET_CID(iSector, tracker.Data().ClusterDataIndex(row, hit.HitIndex()));
311 drawPointLinestrip(iSector, cid, tSECTORTRACK + global);
312 }
313 insertVertexList(iSector, startCountInner, mVertexBuffer[iSector].size());
314 }
315 return (vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector));
316}
317
318void GPUDisplay::DrawTrackITS(int32_t trackId, int32_t iSector)
319{
320 const auto& trk = mIOPtrs->itsTracks[trackId];
321 for (int32_t k = 0; k < trk.getNClusters(); k++) {
322 int32_t cid = mIOPtrs->itsTrackClusIdx[trk.getFirstClusterEntry() + k];
323 mVertexBuffer[iSector].emplace_back(mGlobalPosITS[cid].x, mGlobalPosITS[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosITS[cid].z);
324 mGlobalPosITS[cid].w = tITSATTACHED;
325 }
326}
327
328GPUDisplay::vboList GPUDisplay::DrawFinalITS()
329{
330 const int32_t iSector = 0;
331 size_t startCount = mVertexBufferStart[iSector].size();
332 for (uint32_t i = 0; i < mIOPtrs->nItsTracks; i++) {
333 if (mITSStandaloneTracks[i]) {
334 size_t startCountInner = mVertexBuffer[iSector].size();
335 DrawTrackITS(i, iSector);
336 insertVertexList(iSector, startCountInner, mVertexBuffer[iSector].size());
337 }
338 }
339 return (vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector));
340}
341
342template <class T>
343void GPUDisplay::DrawFinal(int32_t iSector, int32_t /*iCol*/, const GPUTPCGMPropagator* prop, std::array<vecpod<int32_t>, 2>& trackList, threadVertexBuffer& threadBuffer)
344{
345 auto& vBuf = threadBuffer.vBuf;
346 auto& buffer = threadBuffer.buffer;
347 uint32_t nTracks = std::max(trackList[0].size(), trackList[1].size());
348 if (mCfgH.clustersOnly) {
349 nTracks = 0;
350 }
351 for (uint32_t ii = 0; ii < nTracks; ii++) {
352 int32_t i = 0;
353 const T* track = nullptr;
354 int32_t lastCluster = -1;
355 while (true) {
356 if (ii >= trackList[0].size()) {
357 break;
358 }
359 i = trackList[0][ii];
360 int32_t nClusters;
361 if constexpr (std::is_same_v<T, GPUTPCGMMergedTrack>) {
362 track = &mIOPtrs->mergedTracks[i];
363 nClusters = track->NClusters();
364 } else if constexpr (std::is_same_v<T, o2::tpc::TrackTPC>) {
365 track = &mIOPtrs->outputTracksTPCO2[i];
366 nClusters = track->getNClusters();
367 if (!mIOPtrs->clustersNative) {
368 break;
369 }
370 } else {
371 throw std::runtime_error("invalid type");
372 }
373
374 size_t startCountInner = mVertexBuffer[iSector].size();
375 bool drawing = false;
376 uint32_t lastSide = -1;
377
378 if constexpr (std::is_same_v<T, o2::tpc::TrackTPC>) {
379 if (!mCfgH.drawTracksAndFilter && !(mCfgH.drawTPCTracks || (mCfgH.drawITSTracks && mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1) || (mCfgH.drawTRDTracks && mIOPtrs->tpcLinkTRD && mIOPtrs->tpcLinkTRD[i] != -1) || (mCfgH.drawTOFTracks && mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1))) {
380 break;
381 }
382 if (mCfgH.drawTracksAndFilter && ((mCfgH.drawITSTracks && !(mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1)) || (mCfgH.drawTRDTracks && !(mIOPtrs->tpcLinkTRD && mIOPtrs->tpcLinkTRD[i] != -1)) || (mCfgH.drawTOFTracks && !(mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1)))) {
383 break;
384 }
385 }
386
387 if (mCfgH.trackFilter && !mTrackFilter[i]) {
388 break;
389 }
390
391 // Print TOF part of track
392 if constexpr (std::is_same_v<T, o2::tpc::TrackTPC>) {
393 if (mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1 && mIOPtrs->nTOFClusters) {
394 int32_t cid = mIOPtrs->tpcLinkTOF[i];
395 drawing = true;
396 mVertexBuffer[iSector].emplace_back(mGlobalPosTOF[cid].x, mGlobalPosTOF[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTOF[cid].z);
397 mGlobalPosTOF[cid].w = tTOFATTACHED;
398 lastSide = mGlobalPosTOF[cid].z < 0;
399 }
400 }
401
402 // Print TRD part of track
403 auto tmpDoTRDTracklets = [this, &drawing, &lastSide, iSector](const auto& trk) {
404 for (int32_t k = 5; k >= 0; k--) {
405 int32_t cid = trk.getTrackletIndex(k);
406 if (cid < 0) {
407 continue;
408 }
409 drawing = true;
410 mVertexBuffer[iSector].emplace_back(mGlobalPosTRD2[cid].x, mGlobalPosTRD2[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD2[cid].z);
411 mVertexBuffer[iSector].emplace_back(mGlobalPosTRD[cid].x, mGlobalPosTRD[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD[cid].z);
412 lastSide = mGlobalPosTRD[cid].z < 0;
413 mGlobalPosTRD[cid].w = tTRDATTACHED;
414 }
415 };
416 if (std::is_same_v<T, GPUTPCGMMergedTrack> || (!mIOPtrs->tpcLinkTRD && mIOPtrs->trdTracksO2)) {
417 if (mChain && ((int32_t)mConfig.showTPCTracksFromO2Format == (int32_t)GetProcessingSettings().trdTrackModelO2) && mTRDTrackIds[i] != -1 && mIOPtrs->nTRDTracklets) {
418 if (mIOPtrs->trdTracksO2) {
419 tmpDoTRDTracklets(mIOPtrs->trdTracksO2[mTRDTrackIds[i]]);
420 } else {
421 tmpDoTRDTracklets(mIOPtrs->trdTracks[mTRDTrackIds[i]]);
422 }
423 }
424 } else if constexpr (std::is_same_v<T, o2::tpc::TrackTPC>) {
425 if (mIOPtrs->tpcLinkTRD && mIOPtrs->tpcLinkTRD[i] != -1 && mIOPtrs->nTRDTracklets) {
426 if ((mIOPtrs->tpcLinkTRD[i] & 0x40000000) ? mIOPtrs->nTRDTracksITSTPCTRD : mIOPtrs->nTRDTracksTPCTRD) {
427 const auto* container = (mIOPtrs->tpcLinkTRD[i] & 0x40000000) ? mIOPtrs->trdTracksITSTPCTRD : mIOPtrs->trdTracksTPCTRD;
428 const auto& trk = container[mIOPtrs->tpcLinkTRD[i] & 0x3FFFFFFF];
429 tmpDoTRDTracklets(trk);
430 }
431 }
432 }
433
434 // Print TPC part of track
435 int32_t separateExtrapolatedTracksLimit = (mCfgH.separateExtrapolatedTracks ? tEXTRAPOLATEDTRACK : TRACK_TYPE_ID_LIMIT);
436 if constexpr (std::is_same_v<T, GPUTPCGMMergedTrack>) {
437 if (track->PrevSegment() >= 0) {
438 const auto& prevtrk = mIOPtrs->mergedTracks[track->PrevSegment()];
439 for (int32_t iChk = prevtrk.NClusters() - 1; iChk >= 0; iChk--) {
440 const auto& hit = mIOPtrs->mergedTrackHits[prevtrk.FirstClusterRef() + iChk];
441 if (!mCfgH.hideRejectedClusters || !(hit.state & GPUTPCGMMergedTrackHit::flagReject)) {
442 drawPointLinestrip(iSector, hit.num, tFINALTRACK, separateExtrapolatedTracksLimit);
443 lastSide = mGlobalPos[hit.num].z < 0;
444 drawing = true;
445 break;
446 }
447 }
448 }
449 }
450
451 for (int32_t k = 0; k < nClusters; k++) {
452 if constexpr (std::is_same_v<T, GPUTPCGMMergedTrack>) {
453 if (mCfgH.hideRejectedClusters && (mIOPtrs->mergedTrackHits[track->FirstClusterRef() + k].state & GPUTPCGMMergedTrackHit::flagReject)) {
454 continue;
455 }
456 }
457 int32_t cid;
458 if constexpr (std::is_same_v<T, GPUTPCGMMergedTrack>) {
459 cid = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + k].num;
460 } else {
461 cid = &track->getCluster(mIOPtrs->outputClusRefsTPCO2, k, *mIOPtrs->clustersNative) - mIOPtrs->clustersNative->clustersLinear;
462 }
463 int32_t w = mGlobalPos[cid].w;
464 if (drawing) {
465 if (mCfgH.splitCETracks && lastSide != (mGlobalPos[cid].z < 0)) {
466 insertVertexList(vBuf[0], startCountInner, mVertexBuffer[iSector].size());
467 drawing = false;
468 lastCluster = -1;
469 } else {
470 drawPointLinestrip(iSector, cid, tFINALTRACK, separateExtrapolatedTracksLimit);
471 }
472 }
473 if (w == separateExtrapolatedTracksLimit) {
474 if (drawing) {
475 insertVertexList(vBuf[0], startCountInner, mVertexBuffer[iSector].size());
476 }
477 drawing = false;
478 } else {
479 if (!drawing) {
480 startCountInner = mVertexBuffer[iSector].size();
481 if (lastCluster != -1 && (!mCfgH.splitCETracks || lastSide == (mGlobalPos[cid].z < 0))) {
482 int32_t lastcid;
483 if constexpr (std::is_same_v<T, GPUTPCGMMergedTrack>) {
484 lastcid = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + lastCluster].num;
485 } else {
486 lastcid = &track->getCluster(mIOPtrs->outputClusRefsTPCO2, lastCluster, *mIOPtrs->clustersNative) - mIOPtrs->clustersNative->clustersLinear;
487 }
488 drawPointLinestrip(iSector, lastcid, tFINALTRACK, separateExtrapolatedTracksLimit);
489 }
490 drawPointLinestrip(iSector, cid, tFINALTRACK, separateExtrapolatedTracksLimit);
491 }
492 drawing = true;
493 }
494 lastCluster = k;
495 lastSide = mGlobalPos[cid].z < 0;
496 }
497
498 // Print ITS part of track
499 if constexpr (std::is_same_v<T, o2::tpc::TrackTPC>) {
500 if (mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1 && mIOPtrs->nItsTracks && mIOPtrs->nItsClusters) {
501 DrawTrackITS(mIOPtrs->tpcLinkITS[i], iSector);
502 }
503 }
504 insertVertexList(vBuf[0], startCountInner, mVertexBuffer[iSector].size());
505 break;
506 }
507
508 if (!mIOPtrs->clustersNative) {
509 continue;
510 }
511 if (mCfgL.propagateTracks == 0) {
512 continue;
513 }
514
515 // Propagate track paramters / plot MC tracks
516 for (int32_t iMC = 0; iMC < 2; iMC++) {
517 if (iMC) {
518 if (ii >= trackList[1].size()) {
519 continue;
520 }
521 i = trackList[1][ii];
522 } else {
523 if (track == nullptr) {
524 continue;
525 }
526 if (lastCluster == -1) {
527 continue;
528 }
529 if constexpr (std::is_same_v<T, GPUTPCGMMergedTrack>) {
530 if (track->MergedLooperConnected()) {
531 continue;
532 }
533 }
534 }
535
536 size_t startCountInner = mVertexBuffer[iSector].size();
537 for (int32_t inFlyDirection = 0; inFlyDirection < 2; inFlyDirection++) {
539 float ZOffset = 0;
540 float x = 0;
541 float alphaOrg = 0;
542 if (iMC == 0) {
543 if (!inFlyDirection && mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1) {
544 continue;
545 }
546 if constexpr (std::is_same_v<T, GPUTPCGMMergedTrack>) {
547 trkParam.Set(track->GetParam());
548 alphaOrg = mParam->Alpha(iSector);
549 } else {
551 convertTrackParam(t, *track);
552 alphaOrg = track->getAlpha();
553 trkParam.Set(t);
554 }
555
556 float y, z;
557 if constexpr (std::is_same_v<T, GPUTPCGMMergedTrack>) {
558 auto cl = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + lastCluster];
559 const auto& cln = mIOPtrs->clustersNative->clustersLinear[cl.num];
560 GPUTPCConvertImpl::convert(*mCalib->fastTransform, *mParam, cl.sector, cl.row, cln.getPad(), cln.getTime(), x, y, z);
561 ZOffset = mCalib->fastTransform->convVertexTimeToZOffset(iSector, track->GetParam().GetTOffset(), mParam->continuousMaxTimeBin);
562 } else {
563 uint8_t sector, row;
564 auto cln = track->getCluster(mIOPtrs->outputClusRefsTPCO2, lastCluster, *mIOPtrs->clustersNative, sector, row);
565 GPUTPCConvertImpl::convert(*mCalib->fastTransform, *mParam, sector, row, cln.getPad(), cln.getTime(), x, y, z);
566 ZOffset = mCalib->fastTransform->convVertexTimeToZOffset(sector, track->getTime0(), mParam->continuousMaxTimeBin);
567 }
568 } else {
569 const GPUTPCMCInfo& mc = mIOPtrs->mcInfosTPC[i];
570 if (mc.charge == 0.f) {
571 break;
572 }
573 if (mc.pid < 0) {
574 break;
575 }
576#ifndef GPUCA_RUN2
577 if (mc.t0 == -100.f) {
578 break;
579 }
580#endif
581 alphaOrg = mParam->Alpha(iSector);
582 float c = cosf(alphaOrg);
583 float s = sinf(alphaOrg);
584 float mclocal[4];
585 x = mc.x;
586 float y = mc.y;
587 mclocal[0] = x * c + y * s;
588 mclocal[1] = -x * s + y * c;
589 float px = mc.pX;
590 float py = mc.pY;
591 mclocal[2] = px * c + py * s;
592 mclocal[3] = -px * s + py * c;
593 float charge = mc.charge > 0 ? 1.f : -1.f;
594
595 x = mclocal[0];
596#ifndef GPUCA_RUN2
597 trkParam.Set(mclocal[0], mclocal[1], mc.z, mclocal[2], mclocal[3], mc.pZ, -charge); // TODO: DR: unclear to me why we need -charge here
598 if (mParam->par.continuousTracking) {
599 ZOffset = fabsf(mCalib->fastTransform->convVertexTimeToZOffset(0, mc.t0, mParam->continuousMaxTimeBin)) * (mc.z < 0 ? -1 : 1);
600 }
601#else
602 if (fabsf(mc.z) > GPUTPCGeometry::TPCLength()) {
603 ZOffset = mc.z > 0 ? (mc.z - GPUTPCGeometry::TPCLength()) : (mc.z + GPUTPCGeometry::TPCLength());
604 }
605 trkParam.Set(mclocal[0], mclocal[1], mc.z - ZOffset, mclocal[2], mclocal[3], mc.pZ, charge);
606#endif
607 }
608 float z0 = trkParam.Z();
609 if (iMC && inFlyDirection == 0) {
610 buffer.clear();
611 }
612 if (x < 1) {
613 break;
614 }
615 if (fabsf(trkParam.SinPhi()) > 1) {
616 break;
617 }
618 float alpha = alphaOrg;
619 vecpod<vtx>& useBuffer = iMC && inFlyDirection == 0 ? buffer : mVertexBuffer[iSector];
620 int32_t nPoints = 0;
621
622 while (nPoints++ < 5000) {
623 if ((inFlyDirection == 0 && x < 0) || (inFlyDirection && x * x + trkParam.Y() * trkParam.Y() > (iMC ? (450 * 450) : (300 * 300)))) {
624 break;
625 }
626 if (fabsf(trkParam.Z() + ZOffset) > mMaxClusterZ) {
627 break;
628 }
629 if (fabsf(trkParam.Z() - z0) > (iMC ? GPUTPCGeometry::TPCLength() : GPUTPCGeometry::TPCLength())) {
630 break;
631 }
632 if (inFlyDirection) {
633 if (fabsf(trkParam.SinPhi()) > 0.4f) {
634 float dalpha = asinf(trkParam.SinPhi());
635 trkParam.Rotate(dalpha);
636 alpha += dalpha;
637 }
638 x = trkParam.X() + 1.f;
639 if (!mCfgH.propagateLoopers) {
640 float diff = fabsf(alpha - alphaOrg) / (2.f * CAMath::Pi());
641 diff -= floor(diff);
642 if (diff > 0.25f && diff < 0.75f) {
643 break;
644 }
645 }
646 }
647 float B[3];
648 prop->GetBxByBz(alpha, trkParam.GetX(), trkParam.GetY(), trkParam.GetZ(), B);
649 float dLp = 0;
650 if (trkParam.PropagateToXBxByBz(x, B[0], B[1], B[2], dLp)) {
651 break;
652 }
653 if (fabsf(trkParam.SinPhi()) > 0.9f) {
654 break;
655 }
656 float sa = sinf(alpha), ca = cosf(alpha);
657 float drawX = trkParam.X() + mCfgH.xAdd;
658 useBuffer.emplace_back((ca * drawX - sa * trkParam.Y()) * GL_SCALE_FACTOR, (ca * trkParam.Y() + sa * drawX) * mYFactor * GL_SCALE_FACTOR, mCfgH.projectXY ? 0 : (trkParam.Z() + ZOffset) * GL_SCALE_FACTOR);
659 x += inFlyDirection ? 1 : -1;
660 }
661
662 if (inFlyDirection == 0) {
663 if (iMC) {
664 for (int32_t k = (int32_t)buffer.size() - 1; k >= 0; k--) {
665 mVertexBuffer[iSector].emplace_back(buffer[k]);
666 }
667 } else {
668 insertVertexList(vBuf[1], startCountInner, mVertexBuffer[iSector].size());
669 startCountInner = mVertexBuffer[iSector].size();
670 }
671 }
672 }
673 insertVertexList(vBuf[iMC ? 3 : 2], startCountInner, mVertexBuffer[iSector].size());
674 }
675 }
676}
677
678GPUDisplay::vboList GPUDisplay::DrawGrid(const GPUTPCTracker& tracker)
679{
680 uint32_t iSector = tracker.ISector();
681 size_t startCount = mVertexBufferStart[iSector].size();
682 size_t startCountInner = mVertexBuffer[iSector].size();
683 for (uint32_t i = 0; i < GPUTPCGeometry::NROWS; i++) {
684 const GPUTPCRow& row = tracker.Data().Row(i);
685 for (int32_t j = 0; j <= (signed)row.Grid().Ny(); j++) {
686 float z1 = row.Grid().ZMin();
687 float z2 = row.Grid().ZMax();
688 float x = row.X() + mCfgH.xAdd;
689 float y = row.Grid().YMin() + (float)j / row.Grid().StepYInv();
690 float zz1, zz2, yy1, yy2, xx1, xx2;
691 mParam->Sector2Global(tracker.ISector(), x, y, z1, &xx1, &yy1, &zz1);
692 mParam->Sector2Global(tracker.ISector(), x, y, z2, &xx2, &yy2, &zz2);
693 if (iSector < 18) {
694 zz1 += mCfgH.zAdd;
695 zz2 += mCfgH.zAdd;
696 } else {
697 zz1 -= mCfgH.zAdd;
698 zz2 -= mCfgH.zAdd;
699 }
700 mVertexBuffer[iSector].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR);
701 mVertexBuffer[iSector].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR);
702 }
703 for (int32_t j = 0; j <= (signed)row.Grid().Nz(); j++) {
704 float y1 = row.Grid().YMin();
705 float y2 = row.Grid().YMax();
706 float x = row.X() + mCfgH.xAdd;
707 float z = row.Grid().ZMin() + (float)j / row.Grid().StepZInv();
708 float zz1, zz2, yy1, yy2, xx1, xx2;
709 mParam->Sector2Global(tracker.ISector(), x, y1, z, &xx1, &yy1, &zz1);
710 mParam->Sector2Global(tracker.ISector(), x, y2, z, &xx2, &yy2, &zz2);
711 if (iSector < 18) {
712 zz1 += mCfgH.zAdd;
713 zz2 += mCfgH.zAdd;
714 } else {
715 zz1 -= mCfgH.zAdd;
716 zz2 -= mCfgH.zAdd;
717 }
718 mVertexBuffer[iSector].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR);
719 mVertexBuffer[iSector].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR);
720 }
721 }
722 insertVertexList(tracker.ISector(), startCountInner, mVertexBuffer[iSector].size());
723 return (vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector));
724}
725
726GPUDisplay::vboList GPUDisplay::DrawGridTRD(int32_t sector)
727{
728 // TODO: tilted pads ignored at the moment
729 size_t startCount = mVertexBufferStart[sector].size();
730 size_t startCountInner = mVertexBuffer[sector].size();
731 auto* geo = trdGeometry();
732 if (geo) {
733 int32_t trdsector = NSECTORS / 2 - 1 - sector;
734 float alpha = geo->GetAlpha() / 2.f + geo->GetAlpha() * trdsector;
735 if (trdsector >= 9) {
736 alpha -= 2 * CAMath::Pi();
737 }
738 for (int32_t iLy = 0; iLy < GPUTRDTracker::EGPUTRDTracker::kNLayers; iLy++) {
739 for (int32_t iStack = 0; iStack < GPUTRDTracker::EGPUTRDTracker::kNStacks; iStack++) {
740 int32_t iDet = geo->GetDetector(iLy, iStack, trdsector);
741 auto matrix = geo->GetClusterMatrix(iDet);
742 if (!matrix) {
743 continue;
744 }
745 auto pp = geo->GetPadPlane(iDet);
746 for (int32_t i = 0; i < pp->GetNrows(); i++) {
747 float xyzLoc1[3];
748 float xyzLoc2[3];
749 float xyzGlb1[3];
750 float xyzGlb2[3];
751 xyzLoc1[0] = xyzLoc2[0] = geo->AnodePos();
752 xyzLoc1[1] = pp->GetCol0();
753 xyzLoc2[1] = pp->GetColEnd();
754 xyzLoc1[2] = xyzLoc2[2] = pp->GetRowPos(i) - pp->GetRowPos(pp->GetNrows() / 2);
755 matrix->LocalToMaster(xyzLoc1, xyzGlb1);
756 matrix->LocalToMaster(xyzLoc2, xyzGlb2);
757 float x1Tmp = xyzGlb1[0];
758 xyzGlb1[0] = xyzGlb1[0] * cosf(alpha) + xyzGlb1[1] * sinf(alpha);
759 xyzGlb1[1] = -x1Tmp * sinf(alpha) + xyzGlb1[1] * cosf(alpha);
760 float x2Tmp = xyzGlb2[0];
761 xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha);
762 xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha);
763 mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR);
764 mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR);
765 }
766 for (int32_t j = 0; j < pp->GetNcols(); ++j) {
767 float xyzLoc1[3];
768 float xyzLoc2[3];
769 float xyzGlb1[3];
770 float xyzGlb2[3];
771 xyzLoc1[0] = xyzLoc2[0] = geo->AnodePos();
772 xyzLoc1[1] = xyzLoc2[1] = pp->GetColPos(j) + pp->GetColSize(j) / 2.f;
773 xyzLoc1[2] = pp->GetRow0() - pp->GetRowPos(pp->GetNrows() / 2);
774 xyzLoc2[2] = pp->GetRowEnd() - pp->GetRowPos(pp->GetNrows() / 2);
775 matrix->LocalToMaster(xyzLoc1, xyzGlb1);
776 matrix->LocalToMaster(xyzLoc2, xyzGlb2);
777 float x1Tmp = xyzGlb1[0];
778 xyzGlb1[0] = xyzGlb1[0] * cosf(alpha) + xyzGlb1[1] * sinf(alpha);
779 xyzGlb1[1] = -x1Tmp * sinf(alpha) + xyzGlb1[1] * cosf(alpha);
780 float x2Tmp = xyzGlb2[0];
781 xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha);
782 xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha);
783 mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR);
784 mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR);
785 }
786 }
787 }
788 }
789 insertVertexList(sector, startCountInner, mVertexBuffer[sector].size());
790 return (vboList(startCount, mVertexBufferStart[sector].size() - startCount, sector));
791}
792
793size_t GPUDisplay::DrawGLScene_updateVertexList()
794{
795 HighResTimer timer(mChain->GetProcessingSettings().debugLevel >= 2);
796 for (int32_t i = 0; i < NSECTORS; i++) {
797 mVertexBuffer[i].clear();
798 mVertexBufferStart[i].clear();
799 mVertexBufferCount[i].clear();
800 }
801
802 for (int32_t i = 0; i < mCurrentClusters; i++) {
803 mGlobalPos[i].w = tCLUSTER;
804 }
805 for (int32_t i = 0; i < mCurrentSpacePointsTRD; i++) {
806 mGlobalPosTRD[i].w = tTRDCLUSTER;
807 }
808
809 for (int32_t iSector = 0; iSector < NSECTORS; iSector++) {
810 for (int32_t i = 0; i < N_POINTS_TYPE; i++) {
811 mGlDLPoints[iSector][i].resize(mNCollissions);
812 }
813 for (int32_t i = 0; i < N_FINAL_TYPE; i++) {
814 mGlDLFinal[iSector].resize(mNCollissions);
815 }
816 }
817 if (timer.IsRunning()) {
818 GPUInfo("Display Time: Vertex Init:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
819 }
820
821 int32_t numThreads = getNumThreads();
822 tbb::task_arena(numThreads).execute([this, &timer, numThreads] {
823 if (mChain && (mChain->GetRecoSteps() & gpudatatypes::RecoStep::TPCSectorTracking)) {
824 tbb::parallel_for(0, NSECTORS, [this](int32_t iSector) {
825 GPUTPCTracker& tracker = (GPUTPCTracker&)sectorTracker(iSector);
826 tracker.SetPointersDataLinks(tracker.LinkTmpMemory());
827 mGlDLLines[iSector][tINITLINK] = DrawLinks(tracker, tINITLINK, true);
828 tracker.SetPointersDataLinks(mChain->rec()->Res(tracker.MemoryResLinks()).Ptr()); // clang-format off
829 }, tbb::simple_partitioner()); // clang-format on
830 if (timer.IsRunning()) {
831 GPUInfo("Display Time: Vertex Links:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
832 }
833
834 tbb::parallel_for(0, NSECTORS, [this](int32_t iSector) {
835 const GPUTPCTracker& tracker = sectorTracker(iSector);
836
837 mGlDLLines[iSector][tLINK] = DrawLinks(tracker, tLINK);
838 mGlDLLines[iSector][tSEED] = DrawSeeds(tracker);
839 mGlDLLines[iSector][tTRACKLET] = DrawTracklets(tracker);
840 mGlDLLines[iSector][tSECTORTRACK] = DrawTracks(tracker, 0);
841 mGlDLGrid[iSector] = DrawGrid(tracker);
842 if (iSector < NSECTORS / 2) {
843 mGlDLGridTRD[iSector] = DrawGridTRD(iSector);
844 } // clang-format off
845 }, tbb::simple_partitioner()); // clang-format on
846 if (timer.IsRunning()) {
847 GPUInfo("Display Time: Vertex Seeds:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
848 }
849
850 tbb::parallel_for(0, NSECTORS, [this](int32_t iSector) {
851 const GPUTPCTracker& tracker = sectorTracker(iSector);
852 mGlDLLines[iSector][tEXTRAPOLATEDTRACK] = DrawTracks(tracker, 1); // clang-format off
853 }, tbb::simple_partitioner()); // clang-format on
854 if (timer.IsRunning()) {
855 GPUInfo("Display Time: Vertex Sector Tracks:\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
856 }
857 }
858 tbb::parallel_for(0, numThreads, [this](int32_t iThread) {
859 mThreadTracks[iThread].resize(mNCollissions);
860 for (int32_t i = 0; i < mNCollissions; i++) {
861 for (int32_t j = 0; j < NSECTORS; j++) {
862 for (int32_t k = 0; k < 2; k++) {
863 mThreadTracks[iThread][i][j][k].clear();
864 }
865 }
866 } // clang-format off
867 }, tbb::simple_partitioner()); // clang-format on
868 if (mConfig.showTPCTracksFromO2Format) {
869#ifndef GPUCA_RUN2
870 tbb::parallel_for<uint32_t>(0, mIOPtrs->nOutputTracksTPCO2, [this](auto i) {
871 uint8_t sector, row;
872 uint32_t col = 0;
873 if (mIOPtrs->clustersNative) {
874 mIOPtrs->outputTracksTPCO2[i].getCluster(mIOPtrs->outputClusRefsTPCO2, 0, *mIOPtrs->clustersNative, sector, row);
875 } else {
876 sector = 0;
877 }
878 if (mQA && mIOPtrs->outputTracksTPCO2MC) {
879 col = mQA->GetMCLabelCol(mIOPtrs->outputTracksTPCO2MC[i]);
880 }
881 mThreadTracks[GPUReconstruction::getHostThreadIndex()][col][sector][0].emplace_back(i);
882 });
883#endif
884 } else {
885 tbb::parallel_for<uint32_t>(0, mIOPtrs->nMergedTracks, [this](auto i) {
886 const GPUTPCGMMergedTrack* track = &mIOPtrs->mergedTracks[i];
887 if (track->NClusters() == 0) {
888 return;
889 }
890 if (mCfgH.hideRejectedTracks && !track->OK()) {
891 return;
892 }
893 int32_t sector = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + track->NClusters() - 1].sector;
894 uint32_t col = 0;
895 if (mQA) {
896 const auto& label = mQA->GetMCTrackLabel(i);
897#ifndef GPUCA_RUN2
898 col = mQA->GetMCLabelCol(label);
899#else
900 while (label.isValid() && col < mOverlayTFClusters.size() && mOverlayTFClusters[col][NSECTORS] < label.track) {
901 col++;
902 }
903#endif
904 }
905 mThreadTracks[GPUReconstruction::getHostThreadIndex()][col][sector][0].emplace_back(i);
906 });
907 }
908 for (uint32_t col = 0; col < mIOPtrs->nMCInfosTPCCol; col++) {
909 tbb::parallel_for(mIOPtrs->mcInfosTPCCol[col].first, mIOPtrs->mcInfosTPCCol[col].first + mIOPtrs->mcInfosTPCCol[col].num, [this, col](uint32_t i) {
910 const GPUTPCMCInfo& mc = mIOPtrs->mcInfosTPC[i];
911 if (mc.charge == 0.f) {
912 return;
913 }
914 if (mc.pid < 0) {
915 return;
916 }
917
918 float alpha = atan2f(mc.y, mc.x);
919 if (alpha < 0) {
920 alpha += 2 * CAMath::Pi();
921 }
922 int32_t sector = alpha / (2 * CAMath::Pi()) * 18;
923 if (mc.z < 0) {
924 sector += 18;
925 }
926 mThreadTracks[GPUReconstruction::getHostThreadIndex()][col][sector][1].emplace_back(i);
927 });
928 }
929 if (timer.IsRunning()) {
930 GPUInfo("Display Time: Vertex Sort merged tracks:\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
931 }
932
934 prop.SetMaxSinPhi(.999);
935 prop.SetMaterialTPC();
936 prop.SetPolynomialField(&mParam->polynomialField);
937
938 tbb::parallel_for(0, NSECTORS, [this, numThreads, prop](int32_t iSector) {
939 int32_t numThread = GPUReconstruction::getHostThreadIndex();
940 for (int32_t iCol = 0; iCol < mNCollissions; iCol++) {
941 mThreadBuffers[numThread].clear();
942 for (int32_t iSet = 0; iSet < numThreads; iSet++) {
943 if (mConfig.showTPCTracksFromO2Format) {
944 DrawFinal<o2::tpc::TrackTPC>(iSector, iCol, &prop, mThreadTracks[iSet][iCol][iSector], mThreadBuffers[numThread]);
945 } else {
946 DrawFinal<GPUTPCGMMergedTrack>(iSector, iCol, &prop, mThreadTracks[iSet][iCol][iSector], mThreadBuffers[numThread]);
947 }
948 }
949 vboList* list = &mGlDLFinal[iSector][iCol][0];
950 for (int32_t i = 0; i < N_FINAL_TYPE; i++) {
951 size_t startCount = mVertexBufferStart[iSector].size();
952 for (uint32_t j = 0; j < mThreadBuffers[numThread].start[i].size(); j++) {
953 mVertexBufferStart[iSector].emplace_back(mThreadBuffers[numThread].start[i][j]);
954 mVertexBufferCount[iSector].emplace_back(mThreadBuffers[numThread].count[i][j]);
955 }
956 list[i] = vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector);
957 }
958 } // clang-format off
959 }, tbb::simple_partitioner()); // clang-format on
960 if (timer.IsRunning()) {
961 GPUInfo("Display Time: Vertex Merged Tracks:\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
962 }
963
964 tbb::parallel_for(0, NSECTORS, [this](int32_t iSector) {
965 DrawClusters(iSector); // clang-format off
966 }, tbb::simple_partitioner()); // clang-format on
967 if (timer.IsRunning()) {
968 GPUInfo("Display Time: Vertex Clusters:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
969 }
970 });
971 // End tbb task arena
972
973 mGlDLFinalITS = DrawFinalITS();
974 for (int32_t iSector = 0; iSector < NSECTORS; iSector++) {
975 for (int32_t i = N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF + N_POINTS_TYPE_ITS; i++) {
976 for (int32_t iCol = 0; iCol < mNCollissions; iCol++) {
977 mGlDLPoints[iSector][i][iCol] = DrawSpacePointsITS(iSector, i, iCol);
978 break; // TODO: Only collision 0 filled for now
979 }
980 }
981 break; // TODO: Only sector 0 filled for now
982 }
983
984 if (timer.IsRunning()) {
985 GPUInfo("Display Time: Vertex ITS:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
986 }
987
988 for (int32_t iSector = 0; iSector < NSECTORS; iSector++) {
989 for (int32_t i = N_POINTS_TYPE_TPC; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD; i++) {
990 for (int32_t iCol = 0; iCol < mNCollissions; iCol++) {
991 mGlDLPoints[iSector][i][iCol] = DrawSpacePointsTRD(iSector, i, iCol);
992 }
993 }
994 }
995 if (timer.IsRunning()) {
996 GPUInfo("Display Time: Vertex TRD:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
997 }
998
999 for (int32_t iSector = 0; iSector < NSECTORS; iSector++) {
1000 for (int32_t i = N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF; i++) {
1001 for (int32_t iCol = 0; iCol < mNCollissions; iCol++) {
1002 mGlDLPoints[iSector][i][iCol] = DrawSpacePointsTOF(iSector, i, iCol);
1003 break; // TODO: Only collision 0 filled for now
1004 }
1005 }
1006 break; // TODO: Only sector 0 filled for now
1007 }
1008 if (timer.IsRunning()) {
1009 GPUInfo("Display Time: Vertex TOF:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
1010 }
1011
1012 mTracksArePropagated = mCfgL.propagateTracks != 0;
1013 mUpdateVertexLists = false;
1014 size_t totalVertizes = 0;
1015 for (int32_t i = 0; i < NSECTORS; i++) {
1016 totalVertizes += mVertexBuffer[i].size();
1017 }
1018 if (totalVertizes > 0xFFFFFFFF) {
1019 throw std::runtime_error("Display vertex count exceeds 32bit uint32_t counter");
1020 }
1021 size_t needMultiVBOSize = mBackend->needMultiVBO();
1022 mUseMultiVBO = needMultiVBOSize && (totalVertizes * sizeof(mVertexBuffer[0][0]) >= needMultiVBOSize);
1023 if (!mUseMultiVBO) {
1024 size_t totalYet = mVertexBuffer[0].size();
1025 mVertexBuffer[0].resize(totalVertizes);
1026 for (uint32_t i = 1; i < GPUTPCGeometry::NSECTORS; i++) {
1027 for (uint32_t j = 0; j < mVertexBufferStart[i].size(); j++) {
1028 mVertexBufferStart[i][j] += totalYet;
1029 }
1030 memcpy(&mVertexBuffer[0][totalYet], &mVertexBuffer[i][0], mVertexBuffer[i].size() * sizeof(mVertexBuffer[i][0]));
1031 totalYet += mVertexBuffer[i].size();
1032 mVertexBuffer[i].clear();
1033 }
1034 }
1035 mBackend->loadDataToGPU(totalVertizes);
1036 for (uint32_t i = 0; i < (mUseMultiVBO ? GPUTPCGeometry::NSECTORS : 1); i++) {
1037 mVertexBuffer[i].clear();
1038 }
1039 if (timer.IsRunning()) {
1040 GPUInfo("Display Time: Vertex Final:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
1041 }
1042
1043 return totalVertizes;
1044}
A const (ready only) version of MCTruthContainer.
int16_t charge
Definition RawEventData.h:5
int32_t i
#define GET_CID(sector, i)
uint32_t iSector
#define CALINK_DEAD_CHANNEL
Definition GPUTPCDef.h:22
#define CALINK_INVAL
Definition GPUTPCDef.h:21
Online TRD tracker based on extrapolated TPC tracks.
TRD Tracklet word for GPU tracker - 32bit tracklet info + half chamber ID + index.
std::vector< o2::MCCompLabel > labels
uint32_t j
Definition RawData.h:0
uint32_t col
Definition RawData.h:4
uint32_t c
Definition RawData.h:2
Definition of the ITS track.
int nClusters
Definition B.h:16
gsl::span< const TruthElement > getLabels(uint32_t dataindex) const
GPUReconstruction::RecoStepField GetRecoSteps() const
Definition GPUChain.h:71
const GPUSettingsProcessing & GetProcessingSettings() const
Definition GPUChain.h:76
const GPUConstantMem * GetProcessors() const
Definition GPUChain.h:68
const GPUSettingsProcessing & GetProcessingSettings() const
Definition GPUDisplay.h:84
bool clusterRemovable(int32_t attach, bool prot) const
Definition GPUQA.h:53
int32_t HitAttachStatus(int32_t iHit) const
Definition GPUQA.h:51
bool SuppressHit(int32_t iHit) const
Definition GPUQA.h:50
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLint GLsizei count
Definition glcorearb.h:399
GLuint buffer
Definition glcorearb.h:655
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition glcorearb.h:5034
GLsizeiptr size
Definition glcorearb.h:659
GLint first
Definition glcorearb.h:399
GLint y
Definition glcorearb.h:270
GLboolean * data
Definition glcorearb.h:298
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLbitfield flags
Definition glcorearb.h:1570
GLuint start
Definition glcorearb.h:469
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
bool list(IEventListener &reporter, Config const &config)
uint8_t itsSharedClusterMap uint8_t
std::vector< InputSpec > select(char const *matcher="")
uint32_t calink
Definition GPUTPCDef.h:26
float float float float float z2
Definition MathUtils.h:83
float float float float z1
Definition MathUtils.h:82
float float float y2
Definition MathUtils.h:49
const bool const int TrackITSInternal< NLayers > & track
if(!okForPhiMin(phi0, phi1))
S< o2::trd::GeometryFlat >::type * trdGeometry
S< TPCFastTransformPOD >::type * fastTransform
GPUTPCTracker tpcTrackers[GPUTPCGeometry::NSECTORS]
const o2::tpc::ClusterNativeAccess * clustersNative
const o2::BaseCluster< float > * itsClusters
const GPUTRDTrackGPU * trdTracks
const GPUTRDTrackletWord * trdTracklets
const o2::its::TrackITS * itsTracks
const o2::MCCompLabel * outputTracksTPCO2MC
const o2::tpc::TrackTPC * outputTracksTPCO2
const GPUTPCGMMergedTrackHit * mergedTrackHits
const GPUTRDTrack * trdTracksITSTPCTRD
const GPUTPCGMMergedTrack * mergedTracks
unsigned int nClustersSector[constants::MAXSECTOR]
const o2::dataformats::ConstMCTruthContainerView< o2::MCCompLabel > * clustersMCTruth
const ClusterNative * clustersLinear
o2::InteractionRecord ir(0, 0)
std::vector< int > row
typename std::vector< T, vecpod_allocator< T > > vecpod
Definition vecpod.h:31