Skip to content

Commit ab7a0c4

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

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
@@ -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
@@ -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
static 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();
@@ -218,7 +219,6 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
218219
continue;
219220
}
220221

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

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

0 commit comments

Comments
 (0)