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