28 for (uint32_t
i = iThread;
i <
sizeof(
GPUTPCRow) /
sizeof(int32_t);
i += nThreads) {
29 reinterpret_cast<GPUsharedref() int32_t*
>(&s.mRow)[
i] =
reinterpret_cast<GPUglobalref() int32_t*
>(&tracker.TrackingDataRows()[iBlock])[
i];
31 reinterpret_cast<GPUsharedref() int32_t*
>(&s.mRowUp)[
i] =
reinterpret_cast<GPUglobalref() int32_t*
>(&tracker.TrackingDataRows()[iBlock + 2])[
i];
32 reinterpret_cast<GPUsharedref() int32_t*
>(&s.mRowDown)[
i] =
reinterpret_cast<GPUglobalref() int32_t*
>(&tracker.TrackingDataRows()[iBlock - 2])[
i];
47 s.mIRowUp = iBlock + 2;
48 s.mIRowDn = iBlock - 2;
50 s.mNHits =
row.mNHits;
53 const float xDn = rowDn.mX;
54 const float x =
row.mX;
55 const float xUp = rowUp.mX;
69 if ((s.mIRow <= 1) || (s.mIRow >=
GPUCA_ROW_COUNT - 2) || (rowUp.mNHits <= 0) || (rowDn.mNHits <= 0)) {
70 const int32_t lHitNumberOffset =
row.mHitNumberOffset;
71 for (int32_t ih = iThread; ih < s.mNHits; ih += nThreads) {
72 tracker.mData.mLinkUpData[lHitNumberOffset + ih] =
CALINK_INVAL;
73 tracker.mData.mLinkDownData[lHitNumberOffset + ih] =
CALINK_INVAL;
79#define MaxShared GPUCA_NEIGHBOURS_FINDER_MAX_NNEIGHUP
80#if MaxShared < GPUCA_MAXN
81#define MaxGlobal ((GPUCA_MAXN - MaxShared - 1) / UnrollGlobal + 1) * UnrollGlobal
85#define MaxTotal MaxShared + MaxGlobal
87 const float chi2Cut = 3.f * 3.f * 4 * (s.mUpDx * s.mUpDx + s.mDnDx * s.mDnDx);
90 const int32_t lHitNumberOffset =
row.mHitNumberOffset;
91 const int32_t lHitNumberOffsetUp = rowUp.mHitNumberOffset;
92 const int32_t lHitNumberOffsetDn = rowDn.mHitNumberOffset;
93 const uint32_t lFirstHitInBinOffsetUp = rowUp.mFirstHitInBinOffset;
94 const uint32_t lFirstHitInBinOffsetDn = rowDn.mFirstHitInBinOffset;
98 const float y0 =
row.mGrid.mYMin;
99 const float z0 =
row.mGrid.mZMin;
100 const float stepY =
row.mHstepY;
101 const float stepZ =
row.mHstepZ;
103 const float y0Up = rowUp.mGrid.mYMin;
104 const float z0Up = rowUp.mGrid.mZMin;
105 const float stepYUp = rowUp.mHstepY;
106 const float stepZUp = rowUp.mHstepZ;
108 const float y0Dn = rowDn.mGrid.mYMin;
109 const float z0Dn = rowDn.mGrid.mZMin;
110 const float stepYDn = rowDn.mHstepY;
111 const float stepZDn = rowDn.mHstepZ;
113 const float kAngularMultiplier = tracker.mConstantMem->param.rec.tpc.searchWindowDZDR;
114 const float kAreaSizeY = tracker.mConstantMem->param.rec.tpc.neighboursSearchArea;
115 const float kAreaSizeZUp = kAngularMultiplier != 0.f ? (s.mUpDx * kAngularMultiplier) : kAreaSizeY;
116 const float kAreaSizeZDn = kAngularMultiplier != 0.f ? (-s.mDnDx * kAngularMultiplier) : kAreaSizeY;
117 const float kAreaSlopeZUp = kAngularMultiplier != 0.f ? 1.f : s.mUpTx;
118 const float kAreaSlopeZDn = kAngularMultiplier != 0.f ? 1.f : s.mDnTx;
125 for (int32_t ih = iThread; ih < s.mNHits; ih += nThreads) {
128 const float y =
y0 + hitData.
x * stepY;
129 const float z = z0 + hitData.
y * stepZ;
131 int32_t nNeighUp = 0;
133 int32_t binYmin, binYmax, binZmin, binZmax;
137 const float yy =
y * s.mUpTx;
138 const float zz =
z * kAreaSlopeZUp;
139 minZ = zz - kAreaSizeZUp;
140 maxZ = zz + kAreaSizeZUp;
141 minY = yy - kAreaSizeY;
142 maxY = yy + kAreaSizeY;
143 rowUp.Grid().GetBin(
minY,
minZ, &binYmin, &binZmin);
144 rowUp.Grid().GetBin(
maxY,
maxZ, &binYmax, &binZmax);
145 nY = rowUp.Grid().Ny();
148 for (int32_t k1 = binZmin; k1 <= binZmax && (nNeighUp <
MaxTotal); k1++) {
149 int32_t iMin = lFirstHitInBin[lFirstHitInBinOffsetUp + k1 * nY + binYmin];
150 int32_t iMax = lFirstHitInBin[lFirstHitInBinOffsetUp + k1 * nY + binYmax + 1];
152 for (int32_t
i = iMin;
i < iMax && (nNeighUp <
MaxTotal);
i++) {
155 h.mY = y0Up + (hitDataUp.
x) * stepYUp;
156 h.mZ = z0Up + (hitDataUp.
y) * stepZUp;
169 yzUp[2 * (nNeighUp -
MaxShared)] = s.mDnDx * (
h.Y() -
y);
170 yzUp[2 * (nNeighUp -
MaxShared) + 1] = s.mDnDx * (
h.Z() -
z);
175 s.mB[nNeighUp][iThread] = (
calink)
i;
176 s.mA1[nNeighUp][iThread] = s.mDnDx * (
h.Y() -
y);
177 s.mA2[nNeighUp][iThread] = s.mDnDx * (
h.Z() -
z);
185 for (int32_t iUp = nNeighUp; iUp <
MaxShared; iUp++) {
186 s.mA1[iUp][iThread] = -1.e10f;
187 s.mA2[iUp][iThread] = -1.e10f;
188 s.mB[iUp][iThread] = (
calink)-1;
199 if (Nrest + k < N4) {
200 yzUp[2 * (Nrest + k)] = -1.e10f;
201 yzUp[2 * (Nrest + k) + 1] = -1.e10f;
202 neighUp[Nrest + k] = (
calink)-1;
209 const float yy =
y * s.mDnTx;
210 const float zz =
z * kAreaSlopeZDn;
211 minZ = zz - kAreaSizeZDn;
212 maxZ = zz + kAreaSizeZDn;
213 minY = yy - kAreaSizeY;
214 maxY = yy + kAreaSizeY;
216 rowDn.Grid().GetBin(
minY,
minZ, &binYmin, &binZmin);
217 rowDn.Grid().GetBin(
maxY,
maxZ, &binYmax, &binZmax);
218 nY = rowDn.Grid().Ny();
222 float bestD = chi2Cut;
224 for (int32_t k1 = binZmin; k1 <= binZmax; k1++) {
225 int32_t iMin = lFirstHitInBin[lFirstHitInBinOffsetDn + k1 * nY + binYmin];
226 int32_t iMax = lFirstHitInBin[lFirstHitInBinOffsetDn + k1 * nY + binYmax + 1];
227 for (int32_t
i = iMin;
i < iMax;
i++) {
229 float yDn = y0Dn + (hitDataDn.
x) * stepYDn;
230 float zDn = z0Dn + (hitDataDn.
y) * stepZDn;
232 if (yDn < minY || yDn >
maxY || zDn < minZ || zDn >
maxZ) {
236 float yDnProjUp = s.mUpDx * (yDn -
y);
237 float zDnProjUp = s.mUpDx * (zDn -
z);
241 for (int32_t iUp = 0; iUp <
MaxShared; iUp++) {
242 const float dy = yDnProjUp - s.mA1[iUp][iThread];
243 const float dz = zDnProjUp - s.mA2[iUp][iThread];
244 const float d = dy * dy + dz * dz;
257 int32_t jUp = iUp + k;
258 const float dy = yDnProjUp - yzUp[2 * jUp];
259 const float dz = zDnProjUp - yzUp[2 * jUp + 1];
260 const float d = dy * dy + dz * dz;
273#if MaxShared > 0 && MaxGlobal > 0
276 linkUp = s.mB[linkUp][iThread];
278 linkUp = neighUp[linkUp];
282 tracker.mData.mLinkUpData[lHitNumberOffset + ih] = linkUp;
283 tracker.mData.mLinkDownData[lHitNumberOffset + ih] = linkDn;