4848using namespace o2 ::gpu;
4949using namespace o2 ::tpc;
5050
51- 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)
51+ 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;
5454
@@ -92,7 +92,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
9292 const bool finalFit = iWay == nWays - 1 ;
9393
9494 ResetCovariance ();
95- prop.SetSeedingErrors (!(refit));
95+ prop.SetSeedingErrors (!(refit && !retryAttempt ));
9696 prop.SetFitInProjections (true ); // param.rec.fitInProjections == -1 ? (iWay == 0) : param.rec.fitInProjections); // TODO: Reenable once fixed
9797 prop.SetPropagateBzOnly (param.rec .fitPropagateBzOnly == -1 ? !finalFit : param.rec .fitPropagateBzOnly );
9898 prop.SetMatLUT ((param.rec .useMatLUT && finalFit) ? merger.GetConstantMem ()->calibObjects .matLUT : nullptr );
@@ -240,7 +240,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
240240 continue ;
241241 }
242242
243- 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);
243+ 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 );
244244 if (retValHit == 0 ) {
245245 DodEdx (dEdx, dEdxAlt, merger, finalFit, ihit, ihitMergeFirst, wayDirection, clusters, clusterState, zz, dEdxSubThresholdRow);
246246 ihitStart = ihit;
@@ -257,7 +257,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
257257 lastUpdateRow = cluster.row ;
258258 assert (!param.rec .tpc .mergerInterpolateErrors || rebuilt || iWay != nWays - 2 || ihit || interpolationIndex == 0 );
259259 }
260- if (finalOutInFit && !(param.rec .tpc .disableRefitAttachment & 4 ) && lastUpdateRow != 255 ) {
260+ if (finalOutInFit && !(param.rec .tpc .disableRefitAttachment & 4 ) && lastUpdateRow != 255 && !retryAttempt ) {
261261 StoreLoopPropagation (merger, lastSector, lastUpdateRow, iTrk, lastUpdateRow > clusters[(iWay & 1 ) ? (maxN - 1 ) : 0 ].row , prop.GetAlpha ());
262262 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 ));
263263 }
@@ -348,7 +348,7 @@ GPUdii() void GPUTPCGMTrackParam::HandleCrossCE(const GPUParam& GPUrestrict() pa
348348 }
349349}
350350
351- 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)
351+ 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 )
352352{
353353 const GPUParam& GPUrestrict () param = merger.Param ();
354354 const int32_t nWays = param.rec .tpc .nWays ;
@@ -372,23 +372,25 @@ GPUdii() int32_t GPUTPCGMTrackParam::FitHit(GPUTPCGMMerger& GPUrestrict() merger
372372
373373 prop.GetErr2 (err2Y, err2Z, param, zz, cluster.row , clusterState, cluster.sector , time, invAvgCharge, invCharge);
374374
375- bool rejectChi2 = (clusterState & GPUTPCGMMergedTrackHit::flagReject);
376- if (param.rec .tpc .mergerInterpolateErrors ) {
377- if (iWay == nWays - 2 ) {
378- if (!param.rec .tpc .rebuildTrackInFit ) {
379- if (inter.isValid ()) {
380- retValInt = prop.InterpolateReject (param, yy, zz, clusterState, &inter, err2Y, err2Z, deltaZ);
381- } else {
375+ bool rejectChi2 = !retryAttempt && (clusterState & GPUTPCGMMergedTrackHit::flagReject);
376+ if (!retryAttempt) {
377+ if (param.rec .tpc .mergerInterpolateErrors ) {
378+ if (iWay == nWays - 2 ) {
379+ if (!param.rec .tpc .rebuildTrackInFit ) {
380+ if (inter.isValid ()) {
381+ retValInt = prop.InterpolateReject (param, yy, zz, clusterState, &inter, err2Y, err2Z, deltaZ);
382+ } else {
383+ rejectChi2 = true ;
384+ }
385+ }
386+ } else if (iWay == nWays - 1 ) {
387+ if (param.rec .tpc .mergerInterpolateRejectAlsoOnCurrentPosition && GetNDF () > (int32_t )param.rec .tpc .mergerNonInterpolateRejectMinNDF ) {
382388 rejectChi2 = true ;
383389 }
384390 }
385- } else if (iWay == nWays - 1 ) {
386- if (param.rec .tpc .mergerInterpolateRejectAlsoOnCurrentPosition && GetNDF () > (int32_t )param.rec .tpc .mergerNonInterpolateRejectMinNDF ) {
387- rejectChi2 = true ;
388- }
391+ } else {
392+ rejectChi2 = allowChangeClusters;
389393 }
390- } else {
391- rejectChi2 = allowChangeClusters;
392394 }
393395
394396 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,29 @@ 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 && (!merger.Param ().rec .tpc .rebuildTrackInFit || 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+ if (retryAttempt && (t.mNDF < 10 || t.mChi2 / t.mNDF >= 6 .f )) {
1175+ ok = false ;
1176+ }
1177+
11601178 if (CAMath::Abs (t.QPt ()) < 1 .e -4f ) {
11611179 t.QPt () = CAMath::Copysign (1 .e -4f , t.QPt ());
11621180 }
11631181
11641182 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 ()); });
11651183
1166- track.SetOK (ok); // TODO: Should we recover tracks who failed the fit in iWay0/1 for the rebuild?
1184+ track.SetOK (ok);
11671185 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?
11681186 track.Param ().NDF () = 0 ;
11691187 } else {
0 commit comments