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