@@ -107,7 +107,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
107107 const bool inFlyDirection = iWay & 1 ;
108108 const int32_t wayDirection = (iWay & 1 ) ? -1 : 1 ;
109109
110- for (int32_t ihit = ihitStart, interpolationIndex = interpolatedStart - wayDirection ; ihit >= 0 && ihit < maxN; ihit += wayDirection) {
110+ for (int32_t ihit = ihitStart, interpolationIndex = interpolatedStart; ihit >= 0 && ihit < maxN; ihit += wayDirection, interpolationIndex += wayDirection) {
111111 if (!param.rec .tpc .rebuildTrackInFit || rebuilt) {
112112 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))) {
113113 CADEBUG (printf (" \t Skipping hit %d, %d hits rejected, flag %X\n " , ihit, nMissed, (int32_t )clusters[ihit].state ));
@@ -124,7 +124,6 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
124124 const bool allowChangeClusters = finalOutInFit && (nWays == 1 || ((iWay & 1 ) ? (ihit <= CAMath::Max (maxN / 2 , maxN - 30 )) : (ihit >= CAMath::Min (maxN / 2 , 30 ))));
125125
126126 int32_t ihitMergeFirst = ihit;
127- interpolationIndex += wayDirection;
128127 uint8_t clusterState = clusters[ihit].state ;
129128 const float clAlpha = param.Alpha (clusters[ihit].sector );
130129 float xx, yy, zz;
@@ -158,6 +157,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
158157 }
159158 lastPropagateRow = cluster.row ;
160159
160+ auto & inter = interpolation.hit [interpolationIndex];
161161 int32_t retValProp = prop.PropagateToXAlpha (xx, clAlpha, inFlyDirection);
162162 if ((retValProp == -2 && // Rotation failed, try to bring to new x with old alpha first, rotate, and then propagate to x, alpha
163163 (prop.PropagateToXAlpha (xx, prop.GetAlpha (), inFlyDirection) != 0 || // Cannot rotate to new alpha at all
@@ -167,26 +167,31 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
167167 MarkClusters (clusters, ihitMergeFirst, ihit, wayDirection, GPUTPCGMMergedTrackHit::flagHighIncl);
168168 nMissed2++;
169169 NTolerated++;
170+ if (param.rec .tpc .rebuildTrackInFit && iWay == nWays - 2 && param.rec .tpc .rebuildTrackMaxNonIntCov > 0 ) {
171+ FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk, true ); // TODO: mark clusters from single-sided finding as dubious, and apply stricter restriction cut later
172+ }
170173 continue ;
171174 }
172175 // clang-format off
173176 CADEBUG (if (!CheckCov ()){printf (" INVALID COV AFTER PROPAGATE!!!\n " );});
174177 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));
175178 // clang-format on
176179 if (mNDF >= 0 && (mC [0 ] > param.rec .tpc .trackFitCovLimit || mC [2 ] > param.rec .tpc .trackFitCovLimit )) {
180+ if (param.rec .tpc .rebuildTrackInFit && iWay == nWays - 2 && param.rec .tpc .rebuildTrackMaxNonIntCov > 0 ) {
181+ InterpolateMissingRows (merger, interpolation, clusters, ihit, interpolationIndex, cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk);
182+ }
177183 break ; // bad chi2 for the whole track, stop the fit
178184 }
179185
180186 if ((uint32_t )interpolationIndex >= interpolation.size ) {
181187 merger.raiseError (GPUErrors::ERROR_MERGER_INTERPOLATION_OVERFLOW, interpolationIndex, interpolation.size );
182188 break ;
183189 }
184- auto & inter = interpolation.hit [interpolationIndex];
185190
186191 float uncorrectedY = -1e6f;
187192 if (param.rec .tpc .rebuildTrackInFit ) {
188193 if (iWay == nWays - 2 ) {
189- uncorrectedY = FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk);
194+ uncorrectedY = FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk, false );
190195 }
191196 if (allowChangeClusters) {
192197 AttachClusters (merger, cluster.sector , cluster.row , iTrk, track.Leg () == 0 , prop); // TODO: Do this during FindBestInterpolatedHit
@@ -241,6 +246,9 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
241246 N++;
242247 covYYUpd = mC [0 ];
243248 } else if (retValHit == 1 ) {
249+ if (param.rec .tpc .rebuildTrackInFit && iWay == nWays - 2 && param.rec .tpc .rebuildTrackMaxNonIntCov > 0 ) {
250+ InterpolateMissingRows (merger, interpolation, clusters, ihit + wayDirection, interpolationIndex + wayDirection, cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk);
251+ }
244252 break ;
245253 }
246254
@@ -414,15 +422,15 @@ GPUdii() int32_t GPUTPCGMTrackParam::FitHit(GPUTPCGMMerger& GPUrestrict() merger
414422 }
415423}
416424
417- 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)
425+ 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 )
418426{
419427 const GPUParam& GPUrestrict () param = merger.Param ();
420428 const GPUTPCTracker& GPUrestrict () tracker = *(merger.GetConstantMem ()->tpcTrackers + sector);
421429 const GPUTPCRow& GPUrestrict () rowData = tracker.Row (row);
422430 GPUglobalref () const cahit2* hits = tracker.HitData (rowData);
423431 GPUglobalref () const calink* firsthit = tracker.FirstHitInBin (rowData);
424432 float uncorrectedY = -1e6f, uncorrectedZ;
425- 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 ))) {
433+ 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 ))) {
426434 const float zOffset = param.par .continuousTracking ? merger.GetConstantMem ()->calibObjects .fastTransformHelper ->getCorrMap ()->convVertexTimeToZOffset (sector, mTOffset , param.continuousMaxTimeBin ) : 0 ;
427435 const float y0 = rowData.Grid ().YMin ();
428436 const float stepY = rowData.HstepY ();
@@ -431,9 +439,14 @@ GPUdii() float GPUTPCGMTrackParam::FindBestInterpolatedHit(GPUTPCGMMerger& GPUre
431439 int32_t bin, ny, nz;
432440
433441 float ImP0, ImP1, ImC0, ImC2;
434- if (inter.errorY >= (GPUCA_PAR_MERGER_INTERPOLATION_ERROR_TYPE_A)0 ) {
435- const float Iz0 = inter.posY - mP [0 ];
436- const float Iz1 = inter.posZ + deltaZ - mP [1 ];
442+ if (interOnly) {
443+ ImP0 = (float )inter.posY ;
444+ ImP1 = (float )inter.posZ + deltaZ;
445+ ImC0 = (float )inter.errorY ;
446+ ImC2 = (float )inter.errorZ ;
447+ } else if (inter.errorY >= (GPUCA_PAR_MERGER_INTERPOLATION_ERROR_TYPE_A)0 ) {
448+ const float Iz0 = (float )inter.posY - mP [0 ];
449+ const float Iz1 = (float )inter.posZ + deltaZ - mP [1 ];
437450 const float Iw0 = 1 .f / (mC [0 ] + (float )inter.errorY );
438451 const float Iw2 = 1 .f / (mC [2 ] + (float )inter.errorZ );
439452 const float Ik00 = mC [0 ] * Iw0;
@@ -518,14 +531,33 @@ GPUdii() float GPUTPCGMTrackParam::FindBestInterpolatedHit(GPUTPCGMMerger& GPUre
518531 }
519532 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 ; });
520533 }
521- if (nCandidates == 0 ) {
534+ if (nCandidates == 0 && !interOnly ) { // TODO: remove the interOnly here when rebuilding is fully working
522535 merger.ClusterCandidates ()[(iTrk * GPUCA_ROW_COUNT + row) * param.rec .tpc .rebuildTrackInFitClusterCandidates + 0 ].id = 1 ;
523536 }
524537 }
525538 return uncorrectedY;
526539}
527540
528- 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)
541+ 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)
542+ {
543+ for (; ihit >= 0 ; ihit--, interpolationIndex--) {
544+ while (ihit > 0 && clusters[ihit].row == clusters[ihit - 1 ].row && clusters[ihit].sector == clusters[ihit - 1 ].sector ) {
545+ ihit--;
546+ }
547+ const auto & cluster = clusters[ihit];
548+ if (CAMath::Abs (cluster.row - lastRow) > 1 ) {
549+ interpolationIndex -= CAMath::Abs (cluster.row - lastRow) - 1 ;
550+ }
551+ lastRow = cluster.row ;
552+ if (interpolationIndex < 0 ) { // TODO: Is this check needed?
553+ return ;
554+ }
555+ auto inter = interpolation.hit [interpolationIndex];
556+ FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk, true );
557+ }
558+ }
559+
560+ 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)
529561{
530562 const GPUParam& GPUrestrict () param = merger.Param ();
531563 if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR (param.par , dodEdx)) {
0 commit comments