@@ -112,7 +112,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
112112 const bool inFlyDirection = iWay & 1 ;
113113 const int32_t wayDirection = (iWay & 1 ) ? -1 : 1 ;
114114
115- for (int32_t ihit = ihitStart, interpolationIndex = interpolatedStart - wayDirection ; ihit >= 0 && ihit < maxN; ihit += wayDirection) {
115+ for (int32_t ihit = ihitStart, interpolationIndex = interpolatedStart; ihit >= 0 && ihit < maxN; ihit += wayDirection, interpolationIndex += wayDirection) {
116116 if (!param.rec .tpc .rebuildTrackInFit || rebuilt) {
117117 if ((param.rec .tpc .trackFitRejectMode > 0 && nMissed >= param.rec .tpc .trackFitRejectMode ) || nMissed2 >= param.rec .tpc .trackFitMaxRowMissedHard || (clusters[ihit].state & GPUTPCGMMergedTrackHit::flagReject) || (rebuilt && (clusters[ihit].state & GPUTPCGMMergedTrackHit::flagHighIncl))) {
118118 CADEBUG (printf (" \t Skipping hit %d, %d hits rejected, flag %X\n " , ihit, nMissed, (int32_t )clusters[ihit].state ));
@@ -129,7 +129,6 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
129129 const bool allowChangeClusters = finalOutInFit && (nWays == 1 || ((iWay & 1 ) ? (ihit <= CAMath::Max (maxN / 2 , maxN - 30 )) : (ihit >= CAMath::Min (maxN / 2 , 30 ))));
130130
131131 int32_t ihitMergeFirst = ihit;
132- interpolationIndex += wayDirection;
133132 uint8_t clusterState = clusters[ihit].state ;
134133 const float clAlpha = param.Alpha (clusters[ihit].sector );
135134 float xx, yy, zz;
@@ -163,6 +162,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
163162 }
164163 lastPropagateRow = cluster.row ;
165164
165+ auto & inter = interpolation.hit [interpolationIndex];
166166 int32_t retValProp = prop.PropagateToXAlpha (xx, clAlpha, inFlyDirection);
167167 if ((retValProp == -2 && // Rotation failed, try to bring to new x with old alpha first, rotate, and then propagate to x, alpha
168168 (prop.PropagateToXAlpha (xx, prop.GetAlpha (), inFlyDirection) != 0 || // Cannot rotate to new alpha at all
@@ -172,26 +172,31 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
172172 MarkClusters (clusters, ihitMergeFirst, ihit, wayDirection, GPUTPCGMMergedTrackHit::flagHighIncl);
173173 nMissed2++;
174174 NTolerated++;
175+ if (param.rec .tpc .rebuildTrackInFit && iWay == nWays - 2 && param.rec .tpc .rebuildTrackMaxNonIntCov > 0 ) {
176+ FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk, true );
177+ }
175178 continue ;
176179 }
177180 // clang-format off
178181 CADEBUG (if (!CheckCov ()){printf (" INVALID COV AFTER PROPAGATE!!!\n " );});
179182 CADEBUG (printf (" \t %21sPropaga Alpha %8.3f , X %8.3f - Y %8.3f, Z %8.3f - QPt %7.2f (%7.2f), SP %5.2f (%5.2f) --- Res %8.3f %8.3f --- Cov sY %8.3f sZ %8.3f sSP %8.3f sPt %8.3f - YPt %8.3f - PErr %d\n " , " " , prop.GetAlpha (), mX , mP [0 ], mP [1 ], mP [4 ], prop.GetQPt0 (), mP [2 ], prop.GetSinPhi0 (), mP [0 ] - yy, mP [1 ] - zz, sqrtf (mC [0 ]), sqrtf (mC [2 ]), sqrtf (mC [5 ]), sqrtf (mC [14 ]), mC [10 ], retValProp));
180183 // clang-format on
181184 if (mNDF >= 0 && (mC [0 ] > param.rec .tpc .trackFitCovLimit || mC [2 ] > param.rec .tpc .trackFitCovLimit )) {
185+ if (param.rec .tpc .rebuildTrackInFit && iWay == nWays - 2 && param.rec .tpc .rebuildTrackMaxNonIntCov > 0 ) {
186+ InterpolateMissingRows (merger, interpolation, clusters, ihit, interpolationIndex, cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk);
187+ }
182188 break ; // bad chi2 for the whole track, stop the fit
183189 }
184190
185191 if ((uint32_t )interpolationIndex >= interpolation.size ) {
186192 merger.raiseError (GPUErrors::ERROR_MERGER_INTERPOLATION_OVERFLOW, interpolationIndex, interpolation.size );
187193 break ;
188194 }
189- auto & inter = interpolation.hit [interpolationIndex];
190195
191196 float uncorrectedY = -1e6f;
192197 if (param.rec .tpc .rebuildTrackInFit ) {
193198 if (iWay == nWays - 2 ) {
194- uncorrectedY = FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk);
199+ uncorrectedY = FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk, false );
195200 }
196201 if (allowChangeClusters) {
197202 AttachClusters (merger, cluster.sector , cluster.row , iTrk, track.Leg () == 0 , prop); // TODO: Do this during FindBestInterpolatedHit
@@ -246,6 +251,9 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
246251 N++;
247252 covYYUpd = mC [0 ];
248253 } else if (retValHit == 1 ) {
254+ if (param.rec .tpc .rebuildTrackInFit && iWay == nWays - 2 && param.rec .tpc .rebuildTrackMaxNonIntCov > 0 ) {
255+ InterpolateMissingRows (merger, interpolation, clusters, ihit + wayDirection, interpolationIndex + wayDirection, cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk);
256+ }
249257 break ;
250258 }
251259
@@ -419,15 +427,15 @@ GPUdii() int32_t GPUTPCGMTrackParam::FitHit(GPUTPCGMMerger& GPUrestrict() merger
419427 }
420428}
421429
422- GPUdii () float GPUTPCGMTrackParam::FindBestInterpolatedHit(GPUTPCGMMerger& GPUrestrict () merger, gputpcgmmergertypes::InterpolationErrorHit& GPUrestrict() inter, const uint8_t sector, const uint8_t row, const float deltaZ, const float sumInvSqrtCharge, const int nAvgCharge, const GPUTPCGMPropagator& GPUrestrict() prop, const int32_t iTrk)
430+ GPUdii () float GPUTPCGMTrackParam::FindBestInterpolatedHit(GPUTPCGMMerger& GPUrestrict () merger, gputpcgmmergertypes::InterpolationErrorHit& GPUrestrict() inter, const uint8_t sector, const uint8_t row, const float deltaZ, const float sumInvSqrtCharge, const int nAvgCharge, const GPUTPCGMPropagator& GPUrestrict() prop, const int32_t iTrk, bool interOnly )
423431{
424432 const GPUParam& GPUrestrict () param = merger.Param ();
425433 const GPUTPCTracker& GPUrestrict () tracker = *(merger.GetConstantMem ()->tpcTrackers + sector);
426434 const GPUTPCRow& GPUrestrict () rowData = tracker.Row (row);
427435 GPUglobalref () const cahit2* hits = tracker.HitData (rowData);
428436 GPUglobalref () const calink* firsthit = tracker.FirstHitInBin (rowData);
429437 float uncorrectedY = -1e6f, uncorrectedZ;
430- if (rowData.NHits () && (inter.errorY >= (GPUCA_PAR_MERGER_INTERPOLATION_ERROR_TYPE_A)0 || (param.rec .tpc .rebuildTrackMaxNonIntCov > 0 && mC [0 ] < param.rec .tpc .rebuildTrackMaxNonIntCov && mC [2 ] < param.rec .tpc .rebuildTrackMaxNonIntCov ))) {
438+ if (rowData.NHits () && (inter.errorY >= (GPUCA_PAR_MERGER_INTERPOLATION_ERROR_TYPE_A)0 || (!interOnly && param.rec .tpc .rebuildTrackMaxNonIntCov > 0 && mC [0 ] < param.rec .tpc .rebuildTrackMaxNonIntCov && mC [2 ] < param.rec .tpc .rebuildTrackMaxNonIntCov ))) {
431439 const float zOffset = param.par .continuousTracking ? merger.GetConstantMem ()->calibObjects .fastTransformHelper ->getCorrMap ()->convVertexTimeToZOffset (sector, mTOffset , param.continuousMaxTimeBin ) : 0 ;
432440 const float y0 = rowData.Grid ().YMin ();
433441 const float stepY = rowData.HstepY ();
@@ -436,9 +444,14 @@ GPUdii() float GPUTPCGMTrackParam::FindBestInterpolatedHit(GPUTPCGMMerger& GPUre
436444 int32_t bin, ny, nz;
437445
438446 float ImP0, ImP1, ImC0, ImC2;
439- if (inter.errorY >= (GPUCA_PAR_MERGER_INTERPOLATION_ERROR_TYPE_A)0 ) {
440- const float Iz0 = inter.posY - mP [0 ];
441- const float Iz1 = inter.posZ + deltaZ - mP [1 ];
447+ if (interOnly) {
448+ ImP0 = (float )inter.posY ;
449+ ImP1 = (float )inter.posZ + deltaZ;
450+ ImC0 = (float )inter.errorY ;
451+ ImC2 = (float )inter.errorZ ;
452+ } else if (inter.errorY >= (GPUCA_PAR_MERGER_INTERPOLATION_ERROR_TYPE_A)0 ) {
453+ const float Iz0 = (float )inter.posY - mP [0 ];
454+ const float Iz1 = (float )inter.posZ + deltaZ - mP [1 ];
442455 const float Iw0 = 1 .f / (mC [0 ] + (float )inter.errorY );
443456 const float Iw2 = 1 .f / (mC [2 ] + (float )inter.errorZ );
444457 const float Ik00 = mC [0 ] * Iw0;
@@ -523,14 +536,34 @@ GPUdii() float GPUTPCGMTrackParam::FindBestInterpolatedHit(GPUTPCGMMerger& GPUre
523536 }
524537 CADEBUG (const auto * dbgCand = &merger.ClusterCandidates ()[(iTrk * GPUCA_ROW_COUNT + row) * param.rec .tpc .rebuildTrackInFitClusterCandidates ]; for (int dbgi = 0 ; dbgi < nCandidates; dbgi++) { if (dbgCand[dbgi].id > 1 ) printf (" \t\t\t iTrk %d Row %d Candidate %d hit %d err %f\n " , iTrk, (int )row, dbgi, dbgCand[dbgi].id - 2 , dbgCand[dbgi].error ); else break ; });
525538 }
526- if (nCandidates == 0 ) {
539+ if (nCandidates == 0 && !interOnly ) { // TODO: remove the interOnly here when rebuilding is fully working
527540 merger.ClusterCandidates ()[(iTrk * GPUCA_ROW_COUNT + row) * param.rec .tpc .rebuildTrackInFitClusterCandidates + 0 ].id = 1 ;
528541 }
529542 }
530543 return uncorrectedY;
531544}
532545
533- GPUdii () void GPUTPCGMTrackParam::DodEdx(GPUdEdx& GPUrestrict () dEdx, GPUdEdx& GPUrestrict() dEdxAlt, GPUTPCGMMerger& GPUrestrict() merger, bool finalFit, int ihit, int ihitMergeFirst, int wayDirection, const GPUTPCGMMergedTrackHit* GPUrestrict() clusters, uint8_t clusterState, float zz, uint8_t dEdxSubThresholdRow)
546+ GPUdni () void GPUTPCGMTrackParam::InterpolateMissingRows(GPUTPCGMMerger& GPUrestrict () merger, gputpcgmmergertypes::InterpolationErrors& GPUrestrict() interpolation, GPUTPCGMMergedTrackHit* GPUrestrict() clusters, int32_t ihit, int32_t interpolationIndex, int32_t lastRow, const float deltaZ, const float sumInvSqrtCharge, const int32_t nAvgCharge, const GPUTPCGMPropagator& GPUrestrict() prop, const int32_t iTrk)
547+ {
548+ for (; ihit >= 0 ; ihit--, interpolationIndex--) {
549+ while (ihit > 0 && clusters[ihit].row == clusters[ihit - 1 ].row && clusters[ihit].sector == clusters[ihit - 1 ].sector ) {
550+ ihit--;
551+ }
552+ const auto & cluster = clusters[ihit];
553+ if (CAMath::Abs (cluster.row - lastRow) > 1 ) {
554+ interpolationIndex -= CAMath::Abs (cluster.row - lastRow) - 1 ;
555+ }
556+ lastRow = cluster.row ;
557+ if (interpolationIndex < 0 ) {
558+ printf (" Fail ihit %d index %d\n " , ihit, interpolationIndex);
559+ return ;
560+ }
561+ auto inter = interpolation.hit [interpolationIndex];
562+ FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk, true );
563+ }
564+ }
565+
566+ GPUd () void GPUTPCGMTrackParam::DodEdx(GPUdEdx& GPUrestrict () dEdx, GPUdEdx& GPUrestrict() dEdxAlt, GPUTPCGMMerger& GPUrestrict() merger, bool finalFit, int ihit, int ihitMergeFirst, int wayDirection, const GPUTPCGMMergedTrackHit* GPUrestrict() clusters, uint8_t clusterState, float zz, uint8_t dEdxSubThresholdRow)
534567{
535568 const GPUParam& GPUrestrict () param = merger.Param ();
536569 if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR (param.par , dodEdx)) {
0 commit comments