5353using namespace o2 ::gpu;
5454using namespace o2 ::tpc;
5555
56- 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)
56+ 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 )
5757{
5858 static constexpr float maxSinPhi = GPUCA_MAX_SIN_PHI;
5959
@@ -97,7 +97,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
9797 const bool finalFit = iWay == nWays - 1 ;
9898
9999 ResetCovariance ();
100- prop.SetSeedingErrors (!(refit));
100+ prop.SetSeedingErrors (!(refit && !retryAttempt ));
101101 prop.SetFitInProjections (true ); // param.rec.fitInProjections == -1 ? (iWay == 0) : param.rec.fitInProjections); // TODO: Reenable once fixed
102102 prop.SetPropagateBzOnly (param.rec .fitPropagateBzOnly == -1 ? !finalFit : param.rec .fitPropagateBzOnly );
103103 prop.SetMatLUT ((param.rec .useMatLUT && finalFit) ? merger.GetConstantMem ()->calibObjects .matLUT : nullptr );
@@ -245,7 +245,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
245245 continue ;
246246 }
247247
248- int32_t retValHit = FitHit (merger, iTrk, track, xx, yy, zz, clusterState, clAlpha, iWay, inFlyDirection, deltaZ, lastUpdateX, clusters, prop, inter, dEdx, dEdxAlt, sumInvSqrtCharge, nAvgCharge, ihit, ihitMergeFirst, allowChangeClusters, refit, finalFit, nMissed, nMissed2, resetT0, uncorrectedY);
248+ int32_t retValHit = FitHit (merger, iTrk, track, xx, yy, zz, clusterState, clAlpha, iWay, inFlyDirection, deltaZ, lastUpdateX, clusters, prop, inter, dEdx, dEdxAlt, sumInvSqrtCharge, nAvgCharge, ihit, ihitMergeFirst, allowChangeClusters, refit, finalFit, nMissed, nMissed2, resetT0, uncorrectedY, retryAttempt );
249249 if (retValHit == 0 ) {
250250 DodEdx (dEdx, dEdxAlt, merger, finalFit, ihit, ihitMergeFirst, wayDirection, clusters, clusterState, zz, dEdxSubThresholdRow);
251251 ihitStart = ihit;
@@ -262,7 +262,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
262262 lastUpdateRow = cluster.row ;
263263 assert (!param.rec .tpc .mergerInterpolateErrors || rebuilt || iWay != nWays - 2 || ihit || interpolationIndex == 0 );
264264 }
265- if (finalOutInFit && !(param.rec .tpc .disableRefitAttachment & 4 ) && lastUpdateRow != 255 ) {
265+ if (finalOutInFit && !(param.rec .tpc .disableRefitAttachment & 4 ) && lastUpdateRow != 255 && !retryAttempt ) {
266266 StoreLoopPropagation (merger, lastSector, lastUpdateRow, iTrk, lastUpdateRow > clusters[(iWay & 1 ) ? (maxN - 1 ) : 0 ].row , prop.GetAlpha ());
267267 CADEBUG (printf (" \t\t STORING %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 ));
268268 }
@@ -353,7 +353,7 @@ GPUdii() void GPUTPCGMTrackParam::HandleCrossCE(const GPUParam& GPUrestrict() pa
353353 }
354354}
355355
356- GPUdii () int32_t GPUTPCGMTrackParam::FitHit(GPUTPCGMMerger& GPUrestrict () merger, const int32_t iTrk, const GPUTPCGMMergedTrack& GPUrestrict() track, const float xx, const float yy, const float zz, const uint8_t clusterState, const float clAlpha, const int32_t iWay, const bool inFlyDirection, float& GPUrestrict() deltaZ, float& GPUrestrict() lastUpdateX, GPUTPCGMMergedTrackHit* GPUrestrict() clusters, GPUTPCGMPropagator& GPUrestrict() prop, gputpcgmmergertypes::InterpolationErrorHit& GPUrestrict() inter, GPUdEdx& GPUrestrict() dEdx, GPUdEdx& GPUrestrict() dEdxAlt, float& GPUrestrict() sumInvSqrtCharge, int32_t& GPUrestrict() nAvgCharge, const int32_t ihit, const int32_t ihitMergeFirst, const bool allowChangeClusters, const bool refit, const bool finalFit, int32_t& GPUrestrict() nMissed, int32_t& GPUrestrict() nMissed2, int32_t& GPUrestrict() resetT0, float uncorrectedY)
356+ GPUdii () int32_t GPUTPCGMTrackParam::FitHit(GPUTPCGMMerger& GPUrestrict () merger, const int32_t iTrk, const GPUTPCGMMergedTrack& GPUrestrict() track, const float xx, const float yy, const float zz, const uint8_t clusterState, const float clAlpha, const int32_t iWay, const bool inFlyDirection, float& GPUrestrict() deltaZ, float& GPUrestrict() lastUpdateX, GPUTPCGMMergedTrackHit* GPUrestrict() clusters, GPUTPCGMPropagator& GPUrestrict() prop, gputpcgmmergertypes::InterpolationErrorHit& GPUrestrict() inter, GPUdEdx& GPUrestrict() dEdx, GPUdEdx& GPUrestrict() dEdxAlt, float& GPUrestrict() sumInvSqrtCharge, int32_t& GPUrestrict() nAvgCharge, const int32_t ihit, const int32_t ihitMergeFirst, const bool allowChangeClusters, const bool refit, const bool finalFit, int32_t& GPUrestrict() nMissed, int32_t& GPUrestrict() nMissed2, int32_t& GPUrestrict() resetT0, float uncorrectedY, bool retryAttempt )
357357{
358358 const GPUParam& GPUrestrict () param = merger.Param ();
359359 const int32_t nWays = param.rec .tpc .nWays ;
@@ -377,23 +377,25 @@ GPUdii() int32_t GPUTPCGMTrackParam::FitHit(GPUTPCGMMerger& GPUrestrict() merger
377377
378378 prop.GetErr2 (err2Y, err2Z, param, zz, cluster.row , clusterState, cluster.sector , time, invAvgCharge, invCharge);
379379
380- bool rejectChi2 = (clusterState & GPUTPCGMMergedTrackHit::flagReject);
381- if (param.rec .tpc .mergerInterpolateErrors ) {
382- if (iWay == nWays - 2 ) {
383- if (!param.rec .tpc .rebuildTrackInFit ) {
384- if (inter.isValid ()) {
385- retValInt = prop.InterpolateReject (param, yy, zz, clusterState, &inter, err2Y, err2Z, deltaZ);
386- } else {
380+ bool rejectChi2 = !retryAttempt && (clusterState & GPUTPCGMMergedTrackHit::flagReject);
381+ if (!retryAttempt) {
382+ if (param.rec .tpc .mergerInterpolateErrors ) {
383+ if (iWay == nWays - 2 ) {
384+ if (!param.rec .tpc .rebuildTrackInFit ) {
385+ if (inter.isValid ()) {
386+ retValInt = prop.InterpolateReject (param, yy, zz, clusterState, &inter, err2Y, err2Z, deltaZ);
387+ } else {
388+ rejectChi2 = true ;
389+ }
390+ }
391+ } else if (iWay == nWays - 1 ) {
392+ if (param.rec .tpc .mergerInterpolateRejectAlsoOnCurrentPosition && GetNDF () > (int32_t )param.rec .tpc .mergerNonInterpolateRejectMinNDF ) {
387393 rejectChi2 = true ;
388394 }
389395 }
390- } else if (iWay == nWays - 1 ) {
391- if (param.rec .tpc .mergerInterpolateRejectAlsoOnCurrentPosition && GetNDF () > (int32_t )param.rec .tpc .mergerNonInterpolateRejectMinNDF ) {
392- rejectChi2 = true ;
393- }
396+ } else {
397+ rejectChi2 = allowChangeClusters;
394398 }
395- } else {
396- rejectChi2 = allowChangeClusters;
397399 }
398400
399401 if (param.rec .tpc .rejectEdgeClustersInTrackFit && uncorrectedY > -1e6f && param.rejectEdgeClusterByY (uncorrectedY, cluster.row , CAMath::Sqrt (mC [0 ]))) {
@@ -894,6 +896,10 @@ GPUdic(0, 1) void GPUTPCGMTrackParam::StoreLoopPropagation(const GPUTPCGMMerger&
894896
895897GPUdii () void GPUTPCGMTrackParam::PropagateLooper(const GPUTPCGMMerger& GPUrestrict () merger, int32_t loopIdx)
896898{
899+ GPUTPCGMLoopData& data = merger.LoopData ()[loopIdx];
900+ if (!merger.MergedTracks ()[data.track ].OK ()) {
901+ return ;
902+ }
897903 GPUTPCGMPropagator prop;
898904 prop.SetMaterialTPC ();
899905 prop.SetPolynomialField (&merger.Param ().polynomialField );
@@ -903,7 +909,6 @@ GPUdii() void GPUTPCGMTrackParam::PropagateLooper(const GPUTPCGMMerger& GPUrestr
903909 prop.SetFitInProjections (true );
904910 prop.SetPropagateBzOnly (false );
905911
906- GPUTPCGMLoopData& data = merger.LoopData ()[loopIdx];
907912 prop.SetTrack (&data.param , data.alpha );
908913 if (merger.Param ().rec .tpc .looperFollowMode == 1 ) {
909914 data.param .AttachClustersLooperFollow (merger, prop, data.sector , data.row , data.track , data.outwards );
@@ -1142,7 +1147,7 @@ GPUd() bool GPUTPCGMTrackParam::CheckNumericalQuality(float overrideCovYY) const
11421147 return ok;
11431148}
11441149
1145- GPUdii () void GPUTPCGMTrackParam::RefitTrack(GPUTPCGMMergedTrack& GPUrestrict () track, int32_t iTrk, GPUTPCGMMerger& GPUrestrict() merger, bool rebuilt) // VS: GPUd changed to GPUdii. No change in output and no performance penalty.
1150+ GPUdii () void GPUTPCGMTrackParam::RefitTrack(GPUTPCGMMergedTrack& GPUrestrict () track, int32_t iTrk, GPUTPCGMMerger& GPUrestrict() merger, bool rebuilt, bool retryAttempt)
11461151{
11471152 if (!track.OK ()) {
11481153 return ;
@@ -1154,16 +1159,26 @@ GPUdii() void GPUTPCGMTrackParam::RefitTrack(GPUTPCGMMergedTrack& GPUrestrict()
11541159 int32_t NTolerated = 0 ; // Clusters not fit but tollerated for track length cut
11551160 GPUTPCGMTrackParam t = track.Param ();
11561161 float Alpha = track.Alpha ();
1157- bool ok = t.Fit (merger, iTrk, nTrackHits, NTolerated, Alpha, track, rebuilt);
1162+ bool ok = t.Fit (merger, iTrk, nTrackHits, NTolerated, Alpha, track, rebuilt, retryAttempt );
11581163 CADEBUG (if (!merger.Param ().rec .tpc .rebuildTrackInFit || rebuilt) printf (" Finished Fit Track %7d --- OUTPUT hits %d -> %d+%d = %d, QPt %f -> %f, SP %f, OK %d chi2 %f chi2ndf %f\n " , iTrk, track.NClusters (), nTrackHits, NTolerated, nTrackHits + NTolerated, track.GetParam ().GetQPt (), t.QPt (), t.SinPhi (), (int32_t )ok, t.Chi2 (), t.Chi2 () / CAMath::Max (1 , nTrackHits)));
11591164
1165+ if ((!ok || t.GetNDF () <= 0 ) && !rebuilt && !retryAttempt && merger.Param ().rec .tpc .retryRefit ) {
1166+ for (uint32_t i = 0 ; i < track.NClusters (); i++) {
1167+ merger.Clusters ()[track.FirstClusterRef () + i].state &= GPUTPCGMMergedTrackHit::clustererAndSharedFlags;
1168+ }
1169+ CADEBUG (printf (" Track rejected, marking for retry\n " ));
1170+ uint32_t nRefit = CAMath::AtomicAdd (&merger.Memory ()->nRetryRefit , 1u );
1171+ merger.RetryRefitIds ()[nRefit] = iTrk;
1172+ return ;
1173+ }
1174+
11601175 if (CAMath::Abs (t.QPt ()) < 1 .e -4f ) {
11611176 t.QPt () = CAMath::Copysign (1 .e -4f , t.QPt ());
11621177 }
11631178
11641179 CADEBUG (if (t.GetX () > 250 ) { printf (" ERROR, Track %d at impossible X %f, Pt %f, Looper %d\n " , iTrk, t.GetX (), CAMath::Abs (1 .f / t.QPt ()), (int32_t )merger.MergedTracks ()[iTrk].Looper ()); });
11651180
1166- track.SetOK (ok); // TODO: Should we recover tracks who failed the fit in iWay0/1 for the rebuild?
1181+ track.SetOK (ok);
11671182 if (t.GetNDF () <= 0 && !rebuilt && merger.Param ().rec .tpc .rebuildTrackInFit ) { // TODO: Better handling of NDF<0 tracks, how do we want to do cluster rejection?
11681183 track.Param ().NDF () = 0 ;
11691184 } else {
0 commit comments