Skip to content

Commit a7bb34b

Browse files
committed
GPU TPC: Extrapolate track inward and outward when rebuilding
1 parent 05f3f78 commit a7bb34b

2 files changed

Lines changed: 113 additions & 7 deletions

File tree

‎GPU/GPUTracking/Definitions/GPUSettingsList.h‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ AddOptionRTC(cfEdgeTwoPads, uint8_t, 0, "", 0, "Flag clusters with peak on the 2
139139
AddOptionRTC(nWays, uint8_t, 3, "", 0, "Do N fit passes in final fit of merger (must be odd to end with inward fit)")
140140
AddOptionRTC(rebuildTrackInFit, uint8_t, 1, "", 0, "Rebuild track completely during fit based on clusters closed to interpolated track positions")
141141
AddOptionRTC(rebuildTrackInFitClusterCandidates, uint8_t, 3, "", 0, "Number of cluster candidates per row for rebuilt track")
142-
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)")
142+
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)")
143143
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
144144
AddOptionRTC(trackFitRejectMode, int8_t, 5, "", 0, "0: no limit on rejection or missed hits, >0: break after n rejected hits")
145145
AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit")
@@ -168,7 +168,9 @@ AddOptionRTC(rejectEdgeClustersInSeeding, int8_t, 0, "", 0, "Reject edge cluster
168168
AddOptionRTC(rejectEdgeClustersInTrackFit, int8_t, 0, "", 0, "Reject edge clusters based on uncorrected track Y during track fit")
169169
AddOptionRTC(tubeExtraProtectMinRow, uint8_t, 20, "", 0, "Increase Protection, decrease removal by factor 2, when below this row")
170170
AddOptionRTC(tubeExtraProtectEdgePads, uint8_t, 2, "", 0, "Increase Protection, decrease removal by factor 2, when on this number of pads from the edge")
171-
171+
AddOptionRTC(rebuildTrackExtrMaxMissingRows, uint8_t, 15, "", 0, "Maximum total number of rows allowed to be missing during track extrapolation")
172+
AddOptionRTC(rebuildTrackExtrMinConsecGoodRows, uint8_t, 6, "", 0, "Minimum number of consecutive rows required to accept extrapolated segment")
173+
AddOptionRTC(rebuildTrackExtrConsecGoodRowsMaxGap, uint8_t, 1, "", 0, "Max row gap size to consider the segment as consecutive rows")
172174
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
173175
AddHelp("help", 'h')
174176
EndConfig()

‎GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx‎

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ using namespace o2::tpc;
5050
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)
5151
{
5252
constexpr float maxSinPhi = constants::MAX_SIN_PHI;
53+
const float maxSinForUpdate = CAMath::Sin(70.f * CAMath::Deg2Rad());
5354

5455
const GPUParam& GPUrestrict() param = merger.Param();
5556
GPUTPCGMMergedTrackHit* GPUrestrict() clusters = merger.Clusters() + track.FirstClusterRef();
@@ -217,7 +218,6 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
217218
continue;
218219
}
219220

220-
const float maxSinForUpdate = CAMath::Sin(70.f * CAMath::Deg2Rad());
221221
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
222222
const bool inward = clusters[0].row > clusters[maxN - 1].row;
223223
const bool markHighIncl = (mP[2] > 0) ^ (mP[4] < 0) ^ inward ^ (iWay & 1);
@@ -268,16 +268,120 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
268268
lastUpdateRow = cluster.row;
269269
assert(!param.rec.tpc.mergerInterpolateErrors || rebuilt || iWay != nWays - 2 || ihit || interpolationIndex == 0);
270270
}
271-
if (finalOutInFit && !(param.rec.tpc.disableMarkAdjacent & 4) && lastUpdateRow != 255 && !retryAttempt) {
272-
StoreLoopPropagation(merger, lastSector, lastUpdateRow, iTrk, lastUpdateRow > clusters[(iWay & 1) ? (maxN - 1) : 0].row, prop.GetAlpha());
273-
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));
274-
}
275271
if (!(iWay & 1) && !finalFit && !track.CCE() && !track.Looper()) {
276272
deltaZ = ShiftZ(clusters, merger, maxN);
277273
} else {
278274
deltaZ = 0.f;
279275
}
280276

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

0 commit comments

Comments
 (0)