Skip to content

Commit e4416a0

Browse files
committed
GPU TPC: Extrapolate track inward and outward when rebuilding
1 parent c2dc568 commit e4416a0

File tree

2 files changed

+113
-7
lines changed

2 files changed

+113
-7
lines changed

GPU/GPUTracking/Definitions/GPUSettingsList.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ AddOptionRTC(cfEdgeTwoPads, uint8_t, 0, "", 0, "Flag clusters with peak on the 2
142142
AddOptionRTC(nWays, uint8_t, 3, "", 0, "Do N fit passes in final fit of merger (must be odd to end with inward fit)")
143143
AddOptionRTC(rebuildTrackInFit, uint8_t, 1, "", 0, "Rebuild track completely during fit based on clusters closed to interpolated track positions")
144144
AddOptionRTC(rebuildTrackInFitClusterCandidates, uint8_t, 3, "", 0, "Number of cluster candidates per row for rebuilt track")
145-
AddOptionRTC(disableRebuildAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during track rebuid (1: current row, 2: interpolate missing row, 4: one sided interpolation, 8: original hit)")
145+
AddOptionRTC(disableRebuildAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during track rebuid (1: current row, 2: interpolate missing row, 4: one sided interpolation, 8: original hit, 16: extrapolation)")
146146
AddOptionRTC(disableMarkAdjacent, uint8_t, 0, "", 0, "Bitmask to disable certain steps during refit to mark adjacenrt clusters (1: current row, 2: extrapolate missing rows, 4: loop following)") // TODO: Add history
147147
AddOptionRTC(trackFitRejectMode, int8_t, 5, "", 0, "0: no limit on rejection or missed hits, >0: break after n rejected hits")
148148
AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit")
@@ -171,7 +171,9 @@ AddOptionRTC(rejectEdgeClustersInSeeding, int8_t, 0, "", 0, "Reject edge cluster
171171
AddOptionRTC(rejectEdgeClustersInTrackFit, int8_t, 0, "", 0, "Reject edge clusters based on uncorrected track Y during track fit")
172172
AddOptionRTC(tubeExtraProtectMinRow, uint8_t, 20, "", 0, "Increase Protection, decrease removal by factor 2, when below this row")
173173
AddOptionRTC(tubeExtraProtectEdgePads, uint8_t, 2, "", 0, "Increase Protection, decrease removal by factor 2, when on this number of pads from the edge")
174-
174+
AddOptionRTC(rebuildTrackExtrMaxMissingRows, uint8_t, 15, "", 0, "Maximum total number of rows allowed to be missing during track extrapolation")
175+
AddOptionRTC(rebuildTrackExtrMinConsecGoodRows, uint8_t, 6, "", 0, "Minimum number of consecutive rows required to accept extrapolated segment")
176+
AddOptionRTC(rebuildTrackExtrConsecGoodRowsMaxGap, uint8_t, 1, "", 0, "Max row gap size to consider the segment as consecutive rows")
175177
AddOptionArray(PID_remap, int8_t, 9, (0, 1, 2, 3, 4, 5, 6, 7, 8), "", 0, "Remap Ipid to PID_reamp[Ipid] (no remap if<0)") // BUG: CUDA cannot yet handle AddOptionArrayRTC
176178
AddHelp("help", 'h')
177179
EndConfig()

GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ using namespace o2::tpc;
5151
GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_t iTrk, int32_t& GPUrestrict() N, int32_t& GPUrestrict() NTolerated, float& GPUrestrict() Alpha, GPUTPCGMMergedTrack& GPUrestrict() track, bool rebuilt, bool retryAttempt)
5252
{
5353
static constexpr float maxSinPhi = GPUCA_MAX_SIN_PHI;
54+
const float maxSinForUpdate = CAMath::Sin(70.f * CAMath::Deg2Rad());
5455

5556
const GPUParam& GPUrestrict() param = merger.Param();
5657
GPUTPCGMMergedTrackHit* GPUrestrict() clusters = merger.Clusters() + track.FirstClusterRef();
@@ -219,7 +220,6 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
219220
continue;
220221
}
221222

222-
const float maxSinForUpdate = CAMath::Sin(70.f * CAMath::Deg2Rad());
223223
if (mNDF > 0 && CAMath::Abs(prop.GetSinPhi0()) >= maxSinForUpdate) { // TODO: If NDF is large enough, and mP[2] is not yet out of range, reinit linearization
224224
const bool inward = clusters[0].row > clusters[maxN - 1].row;
225225
const bool markHighIncl = (mP[2] > 0) ^ (mP[4] < 0) ^ inward ^ (iWay & 1);
@@ -270,16 +270,120 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
270270
lastUpdateRow = cluster.row;
271271
assert(!param.rec.tpc.mergerInterpolateErrors || rebuilt || iWay != nWays - 2 || ihit || interpolationIndex == 0);
272272
}
273-
if (finalOutInFit && !(param.rec.tpc.disableMarkAdjacent & 4) && lastUpdateRow != 255 && !retryAttempt) {
274-
StoreLoopPropagation(merger, lastSector, lastUpdateRow, iTrk, lastUpdateRow > clusters[(iWay & 1) ? (maxN - 1) : 0].row, prop.GetAlpha());
275-
CADEBUG(printf("\t\tSTORING %d lastUpdateRow %d row %d out %d\n", iTrk, (int)lastUpdateRow, (int)clusters[(iWay & 1) ? (maxN - 1) : 0].row, lastUpdateRow > clusters[(iWay & 1) ? (maxN - 1) : 0].row));
276-
}
277273
if (!(iWay & 1) && !finalFit && !track.CCE() && !track.Looper()) {
278274
deltaZ = ShiftZ(clusters, merger, maxN);
279275
} else {
280276
deltaZ = 0.f;
281277
}
282278

279+
if (param.rec.tpc.rebuildTrackInFit && !rebuilt && !(param.rec.tpc.disableRebuildAttachment & 16) && iWay >= nWays - 3 && CAMath::Abs(mP[2]) < maxSinForUpdate && lastUpdateRow != 255) {
280+
const int32_t up = ((clusters[0].row < clusters[maxN - 1].row) ^ (iWay & 1)) ? 1 : -1;
281+
int32_t sector = lastSector;
282+
uint8_t rowGapActive = 0, rowGapTotal = 0, missingRowsTotal = 0;
283+
uint8_t lastGoodRow = lastPropagateRow, lastExtrapolateRow = lastPropagateRow;
284+
uint8_t consecGoodRows = param.rec.tpc.rebuildTrackExtrMinConsecGoodRows, consecGoodRowsMissing = 0;
285+
prop.SetTrack(this, prop.GetAlpha());
286+
for (int32_t iRow = lastPropagateRow + up; iRow >= 0 && iRow < GPUCA_ROW_COUNT; iRow += up) { // TODO: Try to reduce some variables to int8/uint8 to save registers
287+
bool fail = false;
288+
for (int32_t iAttempt = 0; iAttempt < 2; iAttempt++) {
289+
float tmpX, tmpY, tmpZ;
290+
if (prop.GetPropagatedYZ(GPUTPCGeometry::Row2X(iRow), tmpY, tmpZ)) {
291+
fail = true;
292+
break;
293+
}
294+
merger.GetConstantMem()->calibObjects.fastTransformHelper->InverseTransformYZtoX(sector, iRow, tmpY, tmpZ, tmpX);
295+
if (prop.PropagateToXAlpha(tmpX, param.Alpha(sector), inFlyDirection)) {
296+
fail = true;
297+
break;
298+
}
299+
if (CAMath::Abs(mP[2]) > maxSinForUpdate) {
300+
fail = true;
301+
break;
302+
}
303+
if (CAMath::Abs(mP[0]) > CAMath::Abs(mX) * CAMath::Tan(GPUTPCGeometry::kSectAngle() / 2.f) + 0.1f) {
304+
if (iAttempt) {
305+
fail = true;
306+
break;
307+
}
308+
const int32_t sectorSide = sector >= (GPUCA_NSECTORS / 2) ? (GPUCA_NSECTORS / 2) : 0;
309+
if (mP[0] > 0) {
310+
if (++sector >= sectorSide + 18) {
311+
sector -= 18;
312+
}
313+
} else {
314+
if (--sector < sectorSide) {
315+
sector += 18;
316+
}
317+
}
318+
}
319+
}
320+
if (fail) {
321+
break;
322+
}
323+
CADEBUG(printf("\tExtrapol. Sec %2d Row %3d Propaga Alpha %8.3f , X %8.3f - Y %8.3f, Z %8.3f - QPt %7.2f (%7.2f), SP %5.2f (%5.2f) --- Cov sY %8.3f sZ %8.3f sSP %8.3f sPt %8.3f - YPt %8.3f\n", sector, iRow, prop.GetAlpha(), mX, mP[0], mP[1], mP[4], prop.GetQPt0(), mP[2], prop.GetSinPhi0(), sqrtf(mC[0]), sqrtf(mC[2]), sqrtf(mC[5]), sqrtf(mC[14]), mC[10]));
324+
gputpcgmmergertypes::InterpolationErrorHit inter;
325+
inter.markInvalid();
326+
float uncorrectedY = FindBestInterpolatedHit(merger, inter, sector, iRow, deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk, false);
327+
auto& candidate = merger.ClusterCandidates()[(iTrk * GPUCA_ROW_COUNT + iRow) * param.rec.tpc.rebuildTrackInFitClusterCandidates + 0];
328+
if (candidate.id >= 2) {
329+
lastExtrapolateRow = iRow;
330+
float err2Y, err2Z, xx, yy, zz;
331+
const ClusterNative& GPUrestrict() cl = merger.GetConstantMem()->ioPtrs.clustersNative->clustersLinear[candidate.id - 2];
332+
merger.GetConstantMem()->calibObjects.fastTransformHelper->Transform(sector, iRow, cl.getPad(), cl.getTime(), xx, yy, zz, mTOffset);
333+
if (prop.PropagateToXAlpha(xx, prop.GetAlpha(), inFlyDirection)) {
334+
candidate.best = -1;
335+
break;
336+
}
337+
const float time = merger.GetConstantMem()->ioPtrs.clustersNative ? cl.getTime() : -1.f; // TODO: When is it possible that we do not have clusterNative?
338+
const float invSqrtCharge = merger.GetConstantMem()->ioPtrs.clustersNative ? CAMath::InvSqrt(cl.qMax) : 0.f;
339+
const float invCharge = merger.GetConstantMem()->ioPtrs.clustersNative ? (1.f / cl.qMax) : 0.f;
340+
float invAvgCharge = (sumInvSqrtCharge += invSqrtCharge) / ++nAvgCharge;
341+
invAvgCharge *= invAvgCharge;
342+
const uint8_t clusterState = cl.getFlags();
343+
prop.GetErr2(err2Y, err2Z, param, zz, iRow, clusterState, sector, time, invAvgCharge, invCharge);
344+
CADEBUG(printf("\t%21sResiduals %8.3f %8.3f --- Errors %8.3f %8.3f\n", "", yy - mP[0], zz - mP[1], CAMath::Sqrt(err2Y), CAMath::Sqrt(err2Z)));
345+
uint32_t retValUpd = prop.Update(yy, zz, iRow, param, clusterState, true, refit, err2Y, err2Z);
346+
CADEBUG(printf("\tExtrapol. Sec %2d Row %3d Fit Alpha %8.3f , X %8.3f - Y %8.3f, Z %8.3f - QPt %7.2f (%7.2f), SP %5.2f (%5.2f), DzDs %5.2f %16s --- Cov sY %8.3f sZ %8.3f sSP %8.3f sPt %8.3f - YPt %8.3f - FErr %d\n", sector, iRow, prop.GetAlpha(), mX, mP[0], mP[1], mP[4], prop.GetQPt0(), mP[2], prop.GetSinPhi0(), mP[3], "", sqrtf(mC[0]), sqrtf(mC[2]), sqrtf(mC[5]), sqrtf(mC[14]), mC[10], retValUpd));
347+
if (retValUpd == 1) {
348+
candidate.best = -1;
349+
break;
350+
}
351+
if (++consecGoodRows >= param.rec.tpc.rebuildTrackExtrMinConsecGoodRows) {
352+
lastGoodRow = iRow;
353+
consecGoodRowsMissing = 0;
354+
}
355+
rowGapActive = rowGapTotal = 0;
356+
} else {
357+
if (++missingRowsTotal > param.rec.tpc.rebuildTrackExtrMaxMissingRows) {
358+
break;
359+
}
360+
if (++rowGapTotal > param.rec.tpc.trackFollowingMaxRowGap) {
361+
consecGoodRows = consecGoodRowsMissing = 0;
362+
}
363+
uint32_t pad = CAMath::Float2UIntRn(GPUTPCGeometry::LinearY2Pad(sector, iRow, uncorrectedY));
364+
if (pad < GPUTPCGeometry::NPads(iRow) && (!merger.GetConstantMem()->calibObjects.dEdxCalibContainer || !merger.GetConstantMem()->calibObjects.dEdxCalibContainer->isDead(sector, iRow, pad))) {
365+
if (rowGapActive++ >= param.rec.tpc.trackFollowingMaxRowGap) {
366+
break;
367+
}
368+
if (consecGoodRowsMissing++ >= param.rec.tpc.rebuildTrackExtrConsecGoodRowsMaxGap) {
369+
consecGoodRows = consecGoodRowsMissing = 0;
370+
}
371+
}
372+
}
373+
}
374+
if (lastGoodRow != lastExtrapolateRow) {
375+
for (int32_t iRow = lastGoodRow + up; iRow != lastExtrapolateRow + up; iRow += up) {
376+
auto& candidate = merger.ClusterCandidates()[(iTrk * GPUCA_ROW_COUNT + iRow) * param.rec.tpc.rebuildTrackInFitClusterCandidates + 0];
377+
candidate.best = -1;
378+
}
379+
}
380+
}
381+
382+
if (finalOutInFit && !(param.rec.tpc.disableMarkAdjacent & 4) && lastUpdateRow != 255 && !retryAttempt) {
383+
StoreLoopPropagation(merger, lastSector, lastUpdateRow, iTrk, lastUpdateRow > clusters[(iWay & 1) ? (maxN - 1) : 0].row, prop.GetAlpha());
384+
CADEBUG(printf("\t\tSTORING %d lastUpdateRow %d row %d out %d\n", iTrk, (int)lastUpdateRow, (int)clusters[(iWay & 1) ? (maxN - 1) : 0].row, lastUpdateRow > clusters[(iWay & 1) ? (maxN - 1) : 0].row));
385+
}
386+
283387
if (param.rec.tpc.rebuildTrackInFit && iWay == nWays - 2) {
284388
Alpha = prop.GetAlpha();
285389
if (ihitStart != 0) {

0 commit comments

Comments
 (0)