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 memcpy((void*)(mVertexBuffer[iSector].data() + 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 uint32_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 (uint32_t i = 0; i < GPUTPCGeometry::NROWS; i++) {
216 const GPUTPCRow& row = tracker.Data().Row(i);
217
218 if (i < GPUTPCGeometry::NROWS - 2) {
219 const GPUTPCRow& rowUp = tracker.Data().Row(i + 2);
220 for (uint32_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 (uint32_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 uint32_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 uint32_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 (uint32_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 uint32_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->fastTransform->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->fastTransform->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#ifndef GPUCA_RUN2
575 if (mc.t0 == -100.f) {
576 break;
577 }
578#endif
579 alphaOrg = mParam->Alpha(iSector);
580 float c = cosf(alphaOrg);
581 float s = sinf(alphaOrg);
582 float mclocal[4];
583 x = mc.x;
584 float y = mc.y;
585 mclocal[0] = x * c + y * s;
586 mclocal[1] = -x * s + y * c;
587 float px = mc.pX;
588 float py = mc.pY;
589 mclocal[2] = px * c + py * s;
590 mclocal[3] = -px * s + py * c;
591 float charge = mc.charge > 0 ? 1.f : -1.f;
592
593 x = mclocal[0];
594#ifndef GPUCA_RUN2
595 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
596 if (mParam->par.continuousTracking) {
597 ZOffset = fabsf(mCalib->fastTransform->convVertexTimeToZOffset(0, mc.t0, mParam->continuousMaxTimeBin)) * (mc.z < 0 ? -1 : 1);
598 }
599#else
600 if (fabsf(mc.z) > GPUTPCGeometry::TPCLength()) {
601 ZOffset = mc.z > 0 ? (mc.z - GPUTPCGeometry::TPCLength()) : (mc.z + GPUTPCGeometry::TPCLength());
602 }
603 trkParam.Set(mclocal[0], mclocal[1], mc.z - ZOffset, mclocal[2], mclocal[3], mc.pZ, charge);
604#endif
605 }
606 float z0 = trkParam.Z();
607 if (iMC && inFlyDirection == 0) {
608 buffer.clear();
609 }
610 if (x < 1) {
611 break;
612 }
613 if (fabsf(trkParam.SinPhi()) > 1) {
614 break;
615 }
616 float alpha = alphaOrg;
617 vecpod<vtx>& useBuffer = iMC && inFlyDirection == 0 ? buffer : mVertexBuffer[iSector];
618 int32_t nPoints = 0;
619
620 while (nPoints++ < 5000) {
621 if ((inFlyDirection == 0 && x < 0) || (inFlyDirection && x * x + trkParam.Y() * trkParam.Y() > (iMC ? (450 * 450) : (300 * 300)))) {
622 break;
623 }
624 if (fabsf(trkParam.Z() + ZOffset) > mMaxClusterZ) {
625 break;
626 }
627 if (fabsf(trkParam.Z() - z0) > (iMC ? GPUTPCGeometry::TPCLength() : GPUTPCGeometry::TPCLength())) {
628 break;
629 }
630 if (inFlyDirection) {
631 if (fabsf(trkParam.SinPhi()) > 0.4f) {
632 float dalpha = asinf(trkParam.SinPhi());
633 trkParam.Rotate(dalpha);
634 alpha += dalpha;
635 }
636 x = trkParam.X() + 1.f;
637 if (!mCfgH.propagateLoopers) {
638 float diff = fabsf(alpha - alphaOrg) / (2.f * CAMath::Pi());
639 diff -= floor(diff);
640 if (diff > 0.25f && diff < 0.75f) {
641 break;
642 }
643 }
644 }
645 float B[3];
646 prop->GetBxByBz(alpha, trkParam.GetX(), trkParam.GetY(), trkParam.GetZ(), B);
647 float dLp = 0;
648 if (trkParam.PropagateToXBxByBz(x, B[0], B[1], B[2], dLp)) {
649 break;
650 }
651 if (fabsf(trkParam.SinPhi()) > 0.9f) {
652 break;
653 }
654 float sa = sinf(alpha), ca = cosf(alpha);
655 float drawX = trkParam.X() + mCfgH.xAdd;
656 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);
657 x += inFlyDirection ? 1 : -1;
658 }
659
660 if (inFlyDirection == 0) {
661 if (iMC) {
662 for (int32_t k = (int32_t)buffer.size() - 1; k >= 0; k--) {
663 mVertexBuffer[iSector].emplace_back(buffer[k]);
664 }
665 } else {
666 insertVertexList(vBuf[1], startCountInner, mVertexBuffer[iSector].size());
667 startCountInner = mVertexBuffer[iSector].size();
668 }
669 }
670 }
671 insertVertexList(vBuf[iMC ? 3 : 2], startCountInner, mVertexBuffer[iSector].size());
672 }
673 }
674}
675
676GPUDisplay::vboList GPUDisplay::DrawGrid(const GPUTPCTracker& tracker)
677{
678 uint32_t iSector = tracker.ISector();
679 size_t startCount = mVertexBufferStart[iSector].size();
680 size_t startCountInner = mVertexBuffer[iSector].size();
681 for (uint32_t i = 0; i < GPUTPCGeometry::NROWS; i++) {
682 const GPUTPCRow& row = tracker.Data().Row(i);
683 for (int32_t j = 0; j <= (signed)row.Grid().Ny(); j++) {
684 float z1 = row.Grid().ZMin();
685 float z2 = row.Grid().ZMax();
686 float x = row.X() + mCfgH.xAdd;
687 float y = row.Grid().YMin() + (float)j / row.Grid().StepYInv();
688 float zz1, zz2, yy1, yy2, xx1, xx2;
689 mParam->Sector2Global(tracker.ISector(), x, y, z1, &xx1, &yy1, &zz1);
690 mParam->Sector2Global(tracker.ISector(), x, y, z2, &xx2, &yy2, &zz2);
691 if (iSector < 18) {
692 zz1 += mCfgH.zAdd;
693 zz2 += mCfgH.zAdd;
694 } else {
695 zz1 -= mCfgH.zAdd;
696 zz2 -= mCfgH.zAdd;
697 }
698 mVertexBuffer[iSector].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR);
699 mVertexBuffer[iSector].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR);
700 }
701 for (int32_t j = 0; j <= (signed)row.Grid().Nz(); j++) {
702 float y1 = row.Grid().YMin();
703 float y2 = row.Grid().YMax();
704 float x = row.X() + mCfgH.xAdd;
705 float z = row.Grid().ZMin() + (float)j / row.Grid().StepZInv();
706 float zz1, zz2, yy1, yy2, xx1, xx2;
707 mParam->Sector2Global(tracker.ISector(), x, y1, z, &xx1, &yy1, &zz1);
708 mParam->Sector2Global(tracker.ISector(), x, y2, z, &xx2, &yy2, &zz2);
709 if (iSector < 18) {
710 zz1 += mCfgH.zAdd;
711 zz2 += mCfgH.zAdd;
712 } else {
713 zz1 -= mCfgH.zAdd;
714 zz2 -= mCfgH.zAdd;
715 }
716 mVertexBuffer[iSector].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR);
717 mVertexBuffer[iSector].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR);
718 }
719 }
720 insertVertexList(tracker.ISector(), startCountInner, mVertexBuffer[iSector].size());
721 return (vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector));
722}
723
724GPUDisplay::vboList GPUDisplay::DrawGridTRD(int32_t sector)
725{
726 // TODO: tilted pads ignored at the moment
727 size_t startCount = mVertexBufferStart[sector].size();
728 size_t startCountInner = mVertexBuffer[sector].size();
729 auto* geo = trdGeometry();
730 if (geo) {
731 int32_t trdsector = NSECTORS / 2 - 1 - sector;
732 float alpha = geo->GetAlpha() / 2.f + geo->GetAlpha() * trdsector;
733 if (trdsector >= 9) {
734 alpha -= 2 * CAMath::Pi();
735 }
736 for (int32_t iLy = 0; iLy < GPUTRDTracker::EGPUTRDTracker::kNLayers; iLy++) {
737 for (int32_t iStack = 0; iStack < GPUTRDTracker::EGPUTRDTracker::kNStacks; iStack++) {
738 int32_t iDet = geo->GetDetector(iLy, iStack, trdsector);
739 auto matrix = geo->GetClusterMatrix(iDet);
740 if (!matrix) {
741 continue;
742 }
743 auto pp = geo->GetPadPlane(iDet);
744 for (int32_t i = 0; i < pp->GetNrows(); i++) {
745 float xyzLoc1[3];
746 float xyzLoc2[3];
747 float xyzGlb1[3];
748 float xyzGlb2[3];
749 xyzLoc1[0] = xyzLoc2[0] = geo->AnodePos();
750 xyzLoc1[1] = pp->GetCol0();
751 xyzLoc2[1] = pp->GetColEnd();
752 xyzLoc1[2] = xyzLoc2[2] = pp->GetRowPos(i) - pp->GetRowPos(pp->GetNrows() / 2);
753 matrix->LocalToMaster(xyzLoc1, xyzGlb1);
754 matrix->LocalToMaster(xyzLoc2, xyzGlb2);
755 float x1Tmp = xyzGlb1[0];
756 xyzGlb1[0] = xyzGlb1[0] * cosf(alpha) + xyzGlb1[1] * sinf(alpha);
757 xyzGlb1[1] = -x1Tmp * sinf(alpha) + xyzGlb1[1] * cosf(alpha);
758 float x2Tmp = xyzGlb2[0];
759 xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha);
760 xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha);
761 mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR);
762 mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR);
763 }
764 for (int32_t j = 0; j < pp->GetNcols(); ++j) {
765 float xyzLoc1[3];
766 float xyzLoc2[3];
767 float xyzGlb1[3];
768 float xyzGlb2[3];
769 xyzLoc1[0] = xyzLoc2[0] = geo->AnodePos();
770 xyzLoc1[1] = xyzLoc2[1] = pp->GetColPos(j) + pp->GetColSize(j) / 2.f;
771 xyzLoc1[2] = pp->GetRow0() - pp->GetRowPos(pp->GetNrows() / 2);
772 xyzLoc2[2] = pp->GetRowEnd() - pp->GetRowPos(pp->GetNrows() / 2);
773 matrix->LocalToMaster(xyzLoc1, xyzGlb1);
774 matrix->LocalToMaster(xyzLoc2, xyzGlb2);
775 float x1Tmp = xyzGlb1[0];
776 xyzGlb1[0] = xyzGlb1[0] * cosf(alpha) + xyzGlb1[1] * sinf(alpha);
777 xyzGlb1[1] = -x1Tmp * sinf(alpha) + xyzGlb1[1] * cosf(alpha);
778 float x2Tmp = xyzGlb2[0];
779 xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha);
780 xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha);
781 mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR);
782 mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR);
783 }
784 }
785 }
786 }
787 insertVertexList(sector, startCountInner, mVertexBuffer[sector].size());
788 return (vboList(startCount, mVertexBufferStart[sector].size() - startCount, sector));
789}
790
791size_t GPUDisplay::DrawGLScene_updateVertexList()
792{
793 HighResTimer timer(mChain->GetProcessingSettings().debugLevel >= 2);
794 for (int32_t i = 0; i < NSECTORS; i++) {
795 mVertexBuffer[i].clear();
796 mVertexBufferStart[i].clear();
797 mVertexBufferCount[i].clear();
798 }
799
800 for (int32_t i = 0; i < mCurrentClusters; i++) {
801 mGlobalPos[i].w = tCLUSTER;
802 }
803 for (int32_t i = 0; i < mCurrentSpacePointsTRD; i++) {
804 mGlobalPosTRD[i].w = tTRDCLUSTER;
805 }
806
807 for (int32_t iSector = 0; iSector < NSECTORS; iSector++) {
808 for (int32_t i = 0; i < N_POINTS_TYPE; i++) {
809 mGlDLPoints[iSector][i].resize(mNCollissions);
810 }
811 for (int32_t i = 0; i < N_FINAL_TYPE; i++) {
812 mGlDLFinal[iSector].resize(mNCollissions);
813 }
814 }
815 if (timer.IsRunning()) {
816 GPUInfo("Display Time: Vertex Init:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
817 }
818
819 int32_t numThreads = getNumThreads();
820 tbb::task_arena(numThreads).execute([&] {
821 if (mChain && (mChain->GetRecoSteps() & gpudatatypes::RecoStep::TPCSectorTracking)) {
822 tbb::parallel_for(0, NSECTORS, [&](int32_t iSector) {
823 GPUTPCTracker& tracker = (GPUTPCTracker&)sectorTracker(iSector);
824 tracker.SetPointersDataLinks(tracker.LinkTmpMemory());
825 mGlDLLines[iSector][tINITLINK] = DrawLinks(tracker, tINITLINK, true);
826 tracker.SetPointersDataLinks(mChain->rec()->Res(tracker.MemoryResLinks()).Ptr()); // clang-format off
827 }, tbb::simple_partitioner()); // clang-format on
828 if (timer.IsRunning()) {
829 GPUInfo("Display Time: Vertex Links:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
830 }
831
832 tbb::parallel_for(0, NSECTORS, [&](int32_t iSector) {
833 const GPUTPCTracker& tracker = sectorTracker(iSector);
834
835 mGlDLLines[iSector][tLINK] = DrawLinks(tracker, tLINK);
836 mGlDLLines[iSector][tSEED] = DrawSeeds(tracker);
837 mGlDLLines[iSector][tTRACKLET] = DrawTracklets(tracker);
838 mGlDLLines[iSector][tSECTORTRACK] = DrawTracks(tracker, 0);
839 mGlDLGrid[iSector] = DrawGrid(tracker);
840 if (iSector < NSECTORS / 2) {
841 mGlDLGridTRD[iSector] = DrawGridTRD(iSector);
842 } // clang-format off
843 }, tbb::simple_partitioner()); // clang-format on
844 if (timer.IsRunning()) {
845 GPUInfo("Display Time: Vertex Seeds:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
846 }
847
848 tbb::parallel_for(0, NSECTORS, [&](int32_t iSector) {
849 const GPUTPCTracker& tracker = sectorTracker(iSector);
850 mGlDLLines[iSector][tEXTRAPOLATEDTRACK] = DrawTracks(tracker, 1); // clang-format off
851 }, tbb::simple_partitioner()); // clang-format on
852 if (timer.IsRunning()) {
853 GPUInfo("Display Time: Vertex Sector Tracks:\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
854 }
855 }
856 tbb::parallel_for(0, numThreads, [&](int32_t iThread) {
857 mThreadTracks[iThread].resize(mNCollissions);
858 for (int32_t i = 0; i < mNCollissions; i++) {
859 for (int32_t j = 0; j < NSECTORS; j++) {
860 for (int32_t k = 0; k < 2; k++) {
861 mThreadTracks[iThread][i][j][k].clear();
862 }
863 }
864 } // clang-format off
865 }, tbb::simple_partitioner()); // clang-format on
866 if (mConfig.showTPCTracksFromO2Format) {
867#ifndef GPUCA_RUN2
868 uint32_t col = 0;
869 tbb::parallel_for<uint32_t>(0, mIOPtrs->nOutputTracksTPCO2, [&](auto i) {
870 uint8_t sector, row;
871 if (mIOPtrs->clustersNative) {
872 mIOPtrs->outputTracksTPCO2[i].getCluster(mIOPtrs->outputClusRefsTPCO2, 0, *mIOPtrs->clustersNative, sector, row);
873 } else {
874 sector = 0;
875 }
876 if (mQA && mIOPtrs->outputTracksTPCO2MC) {
877 col = mQA->GetMCLabelCol(mIOPtrs->outputTracksTPCO2MC[i]);
878 }
879 mThreadTracks[GPUReconstruction::getHostThreadIndex()][col][sector][0].emplace_back(i);
880 });
881#endif
882 } else {
883 tbb::parallel_for<uint32_t>(0, mIOPtrs->nMergedTracks, [&](auto i) {
884 const GPUTPCGMMergedTrack* track = &mIOPtrs->mergedTracks[i];
885 if (track->NClusters() == 0) {
886 return;
887 }
888 if (mCfgH.hideRejectedTracks && !track->OK()) {
889 return;
890 }
891 int32_t sector = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + track->NClusters() - 1].sector;
892 uint32_t col = 0;
893 if (mQA) {
894 const auto& label = mQA->GetMCTrackLabel(i);
895#ifndef GPUCA_RUN2
896 col = mQA->GetMCLabelCol(label);
897#else
898 while (label.isValid() && col < mOverlayTFClusters.size() && mOverlayTFClusters[col][NSECTORS] < label.track) {
899 col++;
900 }
901#endif
902 }
903 mThreadTracks[GPUReconstruction::getHostThreadIndex()][col][sector][0].emplace_back(i);
904 });
905 }
906 for (uint32_t col = 0; col < mIOPtrs->nMCInfosTPCCol; col++) {
907 tbb::parallel_for(mIOPtrs->mcInfosTPCCol[col].first, mIOPtrs->mcInfosTPCCol[col].first + mIOPtrs->mcInfosTPCCol[col].num, [&](uint32_t i) {
908 const GPUTPCMCInfo& mc = mIOPtrs->mcInfosTPC[i];
909 if (mc.charge == 0.f) {
910 return;
911 }
912 if (mc.pid < 0) {
913 return;
914 }
915
916 float alpha = atan2f(mc.y, mc.x);
917 if (alpha < 0) {
918 alpha += 2 * CAMath::Pi();
919 }
920 int32_t sector = alpha / (2 * CAMath::Pi()) * 18;
921 if (mc.z < 0) {
922 sector += 18;
923 }
924 mThreadTracks[GPUReconstruction::getHostThreadIndex()][col][sector][1].emplace_back(i);
925 });
926 }
927 if (timer.IsRunning()) {
928 GPUInfo("Display Time: Vertex Sort merged tracks:\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
929 }
930
932 prop.SetMaxSinPhi(.999);
933 prop.SetMaterialTPC();
934 prop.SetPolynomialField(&mParam->polynomialField);
935
936 tbb::parallel_for(0, NSECTORS, [&](int32_t iSector) {
937 int32_t numThread = GPUReconstruction::getHostThreadIndex();
938 for (int32_t iCol = 0; iCol < mNCollissions; iCol++) {
939 mThreadBuffers[numThread].clear();
940 for (int32_t iSet = 0; iSet < numThreads; iSet++) {
941 if (mConfig.showTPCTracksFromO2Format) {
942 DrawFinal<o2::tpc::TrackTPC>(iSector, iCol, &prop, mThreadTracks[iSet][iCol][iSector], mThreadBuffers[numThread]);
943 } else {
944 DrawFinal<GPUTPCGMMergedTrack>(iSector, iCol, &prop, mThreadTracks[iSet][iCol][iSector], mThreadBuffers[numThread]);
945 }
946 }
947 vboList* list = &mGlDLFinal[iSector][iCol][0];
948 for (int32_t i = 0; i < N_FINAL_TYPE; i++) {
949 size_t startCount = mVertexBufferStart[iSector].size();
950 for (uint32_t j = 0; j < mThreadBuffers[numThread].start[i].size(); j++) {
951 mVertexBufferStart[iSector].emplace_back(mThreadBuffers[numThread].start[i][j]);
952 mVertexBufferCount[iSector].emplace_back(mThreadBuffers[numThread].count[i][j]);
953 }
954 list[i] = vboList(startCount, mVertexBufferStart[iSector].size() - startCount, iSector);
955 }
956 } // clang-format off
957 }, tbb::simple_partitioner()); // clang-format on
958 if (timer.IsRunning()) {
959 GPUInfo("Display Time: Vertex Merged Tracks:\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
960 }
961
962 tbb::parallel_for(0, NSECTORS, [&](int32_t iSector) {
963 DrawClusters(iSector); // clang-format off
964 }, tbb::simple_partitioner()); // clang-format on
965 if (timer.IsRunning()) {
966 GPUInfo("Display Time: Vertex Clusters:\t\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
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 (uint32_t i = 1; i < GPUTPCGeometry::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 (uint32_t i = 0; i < (mUseMultiVBO ? GPUTPCGeometry::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}
std::vector< std::string > labels
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.
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:80
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
static constexpr uint32_t NROWS
static constexpr uint32_t NSECTORS
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
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:78
float float float float z1
Definition MathUtils.h:77
float float float y2
Definition MathUtils.h:44
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