Project
Loading...
Searching...
No Matches
GPUTPCExtrapolationTracking.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#include "GPUTPCDef.h"
19#include "GPUTPCTracker.h"
20#include "GPUCommonMath.h"
21#include "GPUParam.inc"
22
23using namespace o2::gpu;
24
25GPUd() int32_t GPUTPCExtrapolationTracking::PerformExtrapolationTrackingRun(GPUTPCTracker& tracker, GPUsharedref() GPUSharedMemory& smem, const GPUTPCTracker& GPUrestrict() sectorSource, int32_t iTrack, int32_t rowIndex, float angle, int32_t direction)
26{
27 /*for (int32_t j = 0;j < Tracks()[j].NHits();j++)
28 {
29 GPUInfo("Hit %3d: Row %3d: X %3.7lf Y %3.7lf", j, mTrackHits[Tracks()[iTrack].FirstHitID() + j].RowIndex(), Row(mTrackHits[Tracks()[iTrack].FirstHitID() + j].RowIndex()).X(),
30 (float) Data().HitDataY(Row(mTrackHits[Tracks()[iTrack].FirstHitID() + j].RowIndex()), mTrackHits[Tracks()[iTrack].FirstHitID() + j].HitIndex()) * Row(mTrackHits[Tracks()[iTrack].FirstHitID() + j].RowIndex()).HstepY() + Row(mTrackHits[Tracks()[iTrack].FirstHitID() + j].RowIndex()).Grid().YMin());
31 }*/
32
33 GPUTPCTrackParam tParam;
34 tParam.InitParam();
35 tParam.SetCov(0, 0.05f);
36 tParam.SetCov(2, 0.05f);
37 tParam.SetCov(5, 0.001f);
38 tParam.SetCov(9, 0.001f);
39 tParam.SetCov(14, 0.05f);
40 tParam.SetParam(sectorSource.Tracks()[iTrack].Param());
41
42 // GPUInfo("Parameters X %f Y %f Z %f SinPhi %f DzDs %f QPt %f SignCosPhi %f", tParam.X(), tParam.Y(), tParam.Z(), tParam.SinPhi(), tParam.DzDs(), tParam.QPt(), tParam.SignCosPhi());
43 if (!tParam.Rotate(angle, GPUCA_MAX_SIN_PHI)) {
44 return 0;
45 }
46 // GPUInfo("Rotated X %f Y %f Z %f SinPhi %f DzDs %f QPt %f SignCosPhi %f", tParam.X(), tParam.Y(), tParam.Z(), tParam.SinPhi(), tParam.DzDs(), tParam.QPt(), tParam.SignCosPhi());
47
48 int32_t maxRowGap = 10;
50 do {
51 rowIndex += direction;
52 if (!tParam.TransportToX(tracker.Row(rowIndex).X(), t0, tracker.Param().bzCLight, GPUCA_MAX_SIN_PHI)) {
53 return 0; // Reuse t0 linearization until we are in the next sector
54 }
55 // GPUInfo("Transported X %f Y %f Z %f SinPhi %f DzDs %f QPt %f SignCosPhi %f (MaxY %f)", tParam.X(), tParam.Y(), tParam.Z(), tParam.SinPhi(), tParam.DzDs(), tParam.QPt(), tParam.SignCosPhi(), Row(rowIndex).MaxY());
56 if (--maxRowGap == 0) {
57 return 0;
58 }
59 } while (CAMath::Abs(tParam.Y()) > tracker.Row(rowIndex).MaxY());
60
61 float err2Y, err2Z;
62 tracker.GetErrors2Seeding(rowIndex, tParam.Z(), tParam.SinPhi(), tParam.DzDs(), -1.f, err2Y, err2Z); // TODO: Use correct time for multiplicity part of error estimation
63 if (tParam.GetCov(0) < err2Y) {
64 tParam.SetCov(0, err2Y);
65 }
66 if (tParam.GetCov(2) < err2Z) {
67 tParam.SetCov(2, err2Z);
68 }
69
70 calink rowHits[GPUCA_ROW_COUNT];
71 int32_t nHits = GPUTPCTrackletConstructor::GPUTPCTrackletConstructorExtrapolationTracking(tracker, smem, tParam, rowIndex, direction, 0, rowHits);
72 if (nHits >= tracker.Param().rec.tpc.extrapolationTrackingMinHits) {
73 // GPUInfo("%d hits found", nHits);
74 uint32_t hitId = CAMath::AtomicAdd(&tracker.CommonMemory()->nTrackHits, (uint32_t)nHits);
75 if (hitId + nHits > tracker.NMaxTrackHits()) {
76 tracker.raiseError(GPUErrors::ERROR_GLOBAL_TRACKING_TRACK_HIT_OVERFLOW, tracker.ISector(), hitId + nHits, tracker.NMaxTrackHits());
77 CAMath::AtomicExch(&tracker.CommonMemory()->nTrackHits, tracker.NMaxTrackHits());
78 return 0;
79 }
80 uint32_t trackId = CAMath::AtomicAdd(&tracker.CommonMemory()->nTracks, 1u);
81 if (trackId >= tracker.NMaxTracks()) { // >= since will increase by 1
82 tracker.raiseError(GPUErrors::ERROR_GLOBAL_TRACKING_TRACK_OVERFLOW, tracker.ISector(), trackId, tracker.NMaxTracks());
83 CAMath::AtomicExch(&tracker.CommonMemory()->nTracks, tracker.NMaxTracks());
84 return 0;
85 }
86
87 if (direction == 1) {
88 int32_t i = 0;
89 while (i < nHits) {
90 const calink rowHit = rowHits[rowIndex];
91 if (rowHit != CALINK_INVAL && rowHit != CALINK_DEAD_CHANNEL) {
92 // GPUInfo("New track: entry %d, row %d, hitindex %d", i, rowIndex, mTrackletRowHits[rowIndex * tracker.CommonMemory()->nTracklets]);
93 tracker.TrackHits()[hitId + i].Set(rowIndex, rowHit);
94 // if (i == 0) tParam.TransportToX(Row(rowIndex).X(), Param().bzCLight(), GPUCA_MAX_SIN_PHI); //Use transport with new linearisation, we have changed the track in between - NOT needed, fitting will always start at outer end of the extrapolated track!
95 i++;
96 }
97 rowIndex++;
98 }
99 } else {
100 int32_t i = nHits - 1;
101 while (i >= 0) {
102 const calink rowHit = rowHits[rowIndex];
103 if (rowHit != CALINK_INVAL && rowHit != CALINK_DEAD_CHANNEL) {
104 // GPUInfo("New track: entry %d, row %d, hitindex %d", i, rowIndex, mTrackletRowHits[rowIndex * tracker.CommonMemory()->nTracklets]);
105 tracker.TrackHits()[hitId + i].Set(rowIndex, rowHit);
106 i--;
107 }
108 rowIndex--;
109 }
110 }
111 GPUTPCTrack& GPUrestrict() track = tracker.Tracks()[trackId];
112 track.SetParam(tParam.GetParam());
113 track.SetNHits(nHits);
114 track.SetFirstHitID(hitId);
115 track.SetLocalTrackId((sectorSource.ISector() << 24) | sectorSource.Tracks()[iTrack].LocalTrackId());
116 }
117
118 return (nHits >= tracker.Param().rec.tpc.extrapolationTrackingMinHits);
119}
120
121GPUd() void GPUTPCExtrapolationTracking::PerformExtrapolationTracking(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, const GPUTPCTracker& tracker, GPUsharedref() GPUSharedMemory& smem, GPUTPCTracker& GPUrestrict() sectorTarget, bool right)
122{
123 for (int32_t i = iBlock * nThreads + iThread; i < tracker.CommonMemory()->nLocalTracks; i += nThreads * nBlocks) {
124 {
125 const int32_t tmpHit = tracker.Tracks()[i].FirstHitID();
126 if (tracker.TrackHits()[tmpHit].RowIndex() >= tracker.Param().rec.tpc.extrapolationTrackingMinRows && tracker.TrackHits()[tmpHit].RowIndex() < tracker.Param().rec.tpc.extrapolationTrackingRowRange) {
127 int32_t rowIndex = tracker.TrackHits()[tmpHit].RowIndex();
128 const GPUTPCRow& GPUrestrict() row = tracker.Row(rowIndex);
129 float Y = (float)tracker.Data().HitDataY(row, tracker.TrackHits()[tmpHit].HitIndex()) * row.HstepY() + row.Grid().YMin();
130 if (!right && Y < -row.MaxY() * tracker.Param().rec.tpc.extrapolationTrackingYRangeLower) {
131 // GPUInfo("Track %d, lower row %d, left border (%f of %f)", i, mTrackHits[tmpHit].RowIndex(), Y, -row.MaxY());
132 PerformExtrapolationTrackingRun(sectorTarget, smem, tracker, i, rowIndex, -tracker.Param().par.dAlpha, -1);
133 }
134 if (right && Y > row.MaxY() * tracker.Param().rec.tpc.extrapolationTrackingYRangeLower) {
135 // GPUInfo("Track %d, lower row %d, right border (%f of %f)", i, mTrackHits[tmpHit].RowIndex(), Y, row.MaxY());
136 PerformExtrapolationTrackingRun(sectorTarget, smem, tracker, i, rowIndex, tracker.Param().par.dAlpha, -1);
137 }
138 }
139 }
140
141 {
142 const int32_t tmpHit = tracker.Tracks()[i].FirstHitID() + tracker.Tracks()[i].NHits() - 1;
143 if (tracker.TrackHits()[tmpHit].RowIndex() < GPUCA_ROW_COUNT - tracker.Param().rec.tpc.extrapolationTrackingMinRows && tracker.TrackHits()[tmpHit].RowIndex() >= GPUCA_ROW_COUNT - tracker.Param().rec.tpc.extrapolationTrackingRowRange) {
144 int32_t rowIndex = tracker.TrackHits()[tmpHit].RowIndex();
145 const GPUTPCRow& GPUrestrict() row = tracker.Row(rowIndex);
146 float Y = (float)tracker.Data().HitDataY(row, tracker.TrackHits()[tmpHit].HitIndex()) * row.HstepY() + row.Grid().YMin();
147 if (!right && Y < -row.MaxY() * tracker.Param().rec.tpc.extrapolationTrackingYRangeUpper) {
148 // GPUInfo("Track %d, upper row %d, left border (%f of %f)", i, mTrackHits[tmpHit].RowIndex(), Y, -row.MaxY());
149 PerformExtrapolationTrackingRun(sectorTarget, smem, tracker, i, rowIndex, -tracker.Param().par.dAlpha, 1);
150 }
151 if (right && Y > row.MaxY() * tracker.Param().rec.tpc.extrapolationTrackingYRangeUpper) {
152 // GPUInfo("Track %d, upper row %d, right border (%f of %f)", i, mTrackHits[tmpHit].RowIndex(), Y, row.MaxY());
153 PerformExtrapolationTrackingRun(sectorTarget, smem, tracker, i, rowIndex, tracker.Param().par.dAlpha, 1);
154 }
155 }
156 }
157 }
158}
159
160template <>
161GPUdii() void GPUTPCExtrapolationTracking::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() tracker)
162{
163 CA_SHARED_CACHE(&smem.mRows[0], tracker.TrackingDataRows(), GPUCA_ROW_COUNT * sizeof(GPUTPCRow));
164 GPUbarrier();
165
166 if (tracker.NHitsTotal() == 0) {
167 return;
168 }
169 const int32_t iSector = tracker.ISector();
170 int32_t sectorLeft = (iSector + (GPUDataTypes::NSECTORS / 2 - 1)) % (GPUDataTypes::NSECTORS / 2);
171 int32_t sectorRight = (iSector + 1) % (GPUDataTypes::NSECTORS / 2);
172 if (iSector >= (int32_t)GPUDataTypes::NSECTORS / 2) {
173 sectorLeft += GPUDataTypes::NSECTORS / 2;
174 sectorRight += GPUDataTypes::NSECTORS / 2;
175 }
176 PerformExtrapolationTracking(nBlocks, nThreads, iBlock, iThread, tracker.GetConstantMem()->tpcTrackers[sectorLeft], smem, tracker, true);
177 PerformExtrapolationTracking(nBlocks, nThreads, iBlock, iThread, tracker.GetConstantMem()->tpcTrackers[sectorRight], smem, tracker, false);
178}
179
180GPUd() int32_t GPUTPCExtrapolationTracking::ExtrapolationTrackingSectorOrder(int32_t iSector)
181{
182 iSector++;
183 if (iSector == GPUDataTypes::NSECTORS / 2) {
184 iSector = 0;
185 }
186 if (iSector == GPUDataTypes::NSECTORS) {
187 iSector = GPUDataTypes::NSECTORS / 2;
188 }
189 return iSector;
190}
191
192GPUd() void GPUTPCExtrapolationTracking::ExtrapolationTrackingSectorLeftRight(uint32_t iSector, uint32_t& left, uint32_t& right)
193{
194 left = (iSector + (GPUDataTypes::NSECTORS / 2 - 1)) % (GPUDataTypes::NSECTORS / 2);
195 right = (iSector + 1) % (GPUDataTypes::NSECTORS / 2);
196 if (iSector >= (int32_t)GPUDataTypes::NSECTORS / 2) {
199 }
200}
201
202template <>
203GPUdii() void GPUTPCExtrapolationTrackingCopyNumbers::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() tracker, int32_t n)
204{
205 for (int32_t i = get_global_id(0); i < n; i += get_global_size(0)) {
206 GPUconstantref() GPUTPCTracker& GPUrestrict() trk = (&tracker)[i];
207 trk.CommonMemory()->nLocalTracks = trk.CommonMemory()->nTracks;
208 trk.CommonMemory()->nLocalTrackHits = trk.CommonMemory()->nTrackHits;
209 }
210}
int32_t i
#define GPUsharedref()
#define GPUconstantref()
#define get_global_size(dim)
#define GPUbarrier()
#define GPUrestrict()
#define get_global_id(dim)
#define GPUCA_MAX_SIN_PHI
#define CA_SHARED_CACHE(target, src, size)
Definition GPUDef.h:57
#define CALINK_DEAD_CHANNEL
Definition GPUTPCDef.h:22
#define CALINK_INVAL
Definition GPUTPCDef.h:21
GPUd() int32_t GPUTPCExtrapolationTracking
GPUdii() void GPUTPCExtrapolationTracking
#define GPUCA_ROW_COUNT
static constexpr uint32_t NSECTORS
GLdouble n
Definition glcorearb.h:1982
GLdouble GLdouble right
Definition glcorearb.h:4077
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLfloat angle
Definition glcorearb.h:4071
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition glcorearb.h:5034
uint32_t calink
Definition GPUTPCDef.h:30
GPUReconstruction * rec
std::vector< int > row