@@ -106,7 +106,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
106106 const bool inFlyDirection = iWay & 1 ;
107107 const int32_t wayDirection = (iWay & 1 ) ? -1 : 1 ;
108108
109- for (int32_t ihit = ihitStart, interpolationIndex = interpolatedStart - wayDirection ; ihit >= 0 && ihit < maxN; ihit += wayDirection) {
109+ for (int32_t ihit = ihitStart, interpolationIndex = interpolatedStart; ihit >= 0 && ihit < maxN; ihit += wayDirection, interpolationIndex += wayDirection) {
110110 if (!param.rec .tpc .rebuildTrackInFit || rebuilt) {
111111 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))) {
112112 CADEBUG (printf (" \t Skipping hit %d, %d hits rejected, flag %X\n " , ihit, nMissed, (int32_t )clusters[ihit].state ));
@@ -123,7 +123,6 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
123123 const bool allowChangeClusters = finalOutInFit && (nWays == 1 || ((iWay & 1 ) ? (ihit <= CAMath::Max (maxN / 2 , maxN - 30 )) : (ihit >= CAMath::Min (maxN / 2 , 30 ))));
124124
125125 int32_t ihitMergeFirst = ihit;
126- interpolationIndex += wayDirection;
127126 uint8_t clusterState = clusters[ihit].state ;
128127 const float clAlpha = param.Alpha (clusters[ihit].sector );
129128 float xx, yy, zz;
@@ -157,6 +156,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
157156 }
158157 lastPropagateRow = cluster.row ;
159158
159+ auto & inter = interpolation.hit [interpolationIndex];
160160 int32_t retValProp = prop.PropagateToXAlpha (xx, clAlpha, inFlyDirection);
161161 if ((retValProp == -2 && // Rotation failed, try to bring to new x with old alpha first, rotate, and then propagate to x, alpha
162162 (prop.PropagateToXAlpha (xx, prop.GetAlpha (), inFlyDirection) != 0 || // Cannot rotate to new alpha at all
@@ -166,26 +166,31 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
166166 MarkClusters (clusters, ihitMergeFirst, ihit, wayDirection, GPUTPCGMMergedTrackHit::flagHighIncl);
167167 nMissed2++;
168168 NTolerated++;
169+ if (param.rec .tpc .rebuildTrackInFit && iWay == nWays - 2 && param.rec .tpc .rebuildTrackMaxNonIntCov > 0 ) {
170+ 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
171+ }
169172 continue ;
170173 }
171174 // clang-format off
172175 CADEBUG (if (!CheckCov ()){printf (" INVALID COV AFTER PROPAGATE!!!\n " );});
173176 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));
174177 // clang-format on
175178 if (mNDF >= 0 && (mC [0 ] > param.rec .tpc .trackFitCovLimit || mC [2 ] > param.rec .tpc .trackFitCovLimit )) {
179+ if (param.rec .tpc .rebuildTrackInFit && iWay == nWays - 2 && param.rec .tpc .rebuildTrackMaxNonIntCov > 0 ) {
180+ InterpolateMissingRows (merger, interpolation, clusters, ihit, interpolationIndex, cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk);
181+ }
176182 break ; // bad chi2 for the whole track, stop the fit
177183 }
178184
179185 if ((uint32_t )interpolationIndex >= interpolation.size ) {
180186 merger.raiseError (GPUErrors::ERROR_MERGER_INTERPOLATION_OVERFLOW, interpolationIndex, interpolation.size );
181187 break ;
182188 }
183- auto & inter = interpolation.hit [interpolationIndex];
184189
185190 float uncorrectedY = -1e6f;
186191 if (param.rec .tpc .rebuildTrackInFit ) {
187192 if (iWay == nWays - 2 ) {
188- uncorrectedY = FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk);
193+ uncorrectedY = FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk, false );
189194 }
190195 if (allowChangeClusters) {
191196 AttachClusters (merger, cluster.sector , cluster.row , iTrk, track.Leg () == 0 , prop); // TODO: Do this during FindBestInterpolatedHit
@@ -240,6 +245,9 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger& GPUrestrict() merger, int32_
240245 N++;
241246 covYYUpd = mC [0 ];
242247 } else if (retValHit == 1 ) {
248+ if (param.rec .tpc .rebuildTrackInFit && iWay == nWays - 2 && param.rec .tpc .rebuildTrackMaxNonIntCov > 0 ) {
249+ InterpolateMissingRows (merger, interpolation, clusters, ihit + wayDirection, interpolationIndex + wayDirection, cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk);
250+ }
243251 break ;
244252 }
245253
@@ -413,15 +421,15 @@ GPUdii() int32_t GPUTPCGMTrackParam::FitHit(GPUTPCGMMerger& GPUrestrict() merger
413421 }
414422}
415423
416- 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)
424+ 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 )
417425{
418426 const GPUParam& GPUrestrict () param = merger.Param ();
419427 const GPUTPCTracker& GPUrestrict () tracker = *(merger.GetConstantMem ()->tpcTrackers + sector);
420428 const GPUTPCRow& GPUrestrict () rowData = tracker.Row (row);
421429 GPUglobalref () const cahit2* hits = tracker.HitData (rowData);
422430 GPUglobalref () const calink* firsthit = tracker.FirstHitInBin (rowData);
423431 float uncorrectedY = -1e6f, uncorrectedZ;
424- 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 ))) {
432+ 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 ))) {
425433 const float zOffset = param.par .continuousTracking ? merger.GetConstantMem ()->calibObjects .fastTransform ->convVertexTimeToZOffset (sector, mTOffset , param.continuousMaxTimeBin ) : 0 ;
426434 const float y0 = rowData.Grid ().YMin ();
427435 const float stepY = rowData.HstepY ();
@@ -430,9 +438,14 @@ GPUdii() float GPUTPCGMTrackParam::FindBestInterpolatedHit(GPUTPCGMMerger& GPUre
430438 int32_t bin, ny, nz;
431439
432440 float ImP0, ImP1, ImC0, ImC2;
433- if (inter.errorY >= (GPUCA_PAR_MERGER_INTERPOLATION_ERROR_TYPE_A)0 ) {
434- const float Iz0 = inter.posY - mP [0 ];
435- const float Iz1 = inter.posZ + deltaZ - mP [1 ];
441+ if (interOnly) {
442+ ImP0 = (float )inter.posY ;
443+ ImP1 = (float )inter.posZ + deltaZ;
444+ ImC0 = (float )inter.errorY ;
445+ ImC2 = (float )inter.errorZ ;
446+ } else if (inter.errorY >= (GPUCA_PAR_MERGER_INTERPOLATION_ERROR_TYPE_A)0 ) {
447+ const float Iz0 = (float )inter.posY - mP [0 ];
448+ const float Iz1 = (float )inter.posZ + deltaZ - mP [1 ];
436449 const float Iw0 = 1 .f / (mC [0 ] + (float )inter.errorY );
437450 const float Iw2 = 1 .f / (mC [2 ] + (float )inter.errorZ );
438451 const float Ik00 = mC [0 ] * Iw0;
@@ -517,14 +530,33 @@ GPUdii() float GPUTPCGMTrackParam::FindBestInterpolatedHit(GPUTPCGMMerger& GPUre
517530 }
518531 CADEBUG (const auto * dbgCand = &merger.ClusterCandidates ()[(iTrk * GPUTPCGeometry::NROWS + 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 ; });
519532 }
520- if (nCandidates == 0 ) {
533+ if (nCandidates == 0 && !interOnly ) { // TODO: remove the interOnly here when rebuilding is fully working
521534 merger.ClusterCandidates ()[(iTrk * GPUTPCGeometry::NROWS + row) * param.rec .tpc .rebuildTrackInFitClusterCandidates + 0 ].id = 1 ;
522535 }
523536 }
524537 return uncorrectedY;
525538}
526539
527- 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)
540+ 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)
541+ {
542+ for (; ihit >= 0 ; ihit--, interpolationIndex--) {
543+ while (ihit > 0 && clusters[ihit].row == clusters[ihit - 1 ].row && clusters[ihit].sector == clusters[ihit - 1 ].sector ) {
544+ ihit--;
545+ }
546+ const auto & cluster = clusters[ihit];
547+ if (CAMath::Abs (cluster.row - lastRow) > 1 ) {
548+ interpolationIndex -= CAMath::Abs (cluster.row - lastRow) - 1 ;
549+ }
550+ lastRow = cluster.row ;
551+ if (interpolationIndex < 0 ) { // TODO: Is this check needed?
552+ return ;
553+ }
554+ auto inter = interpolation.hit [interpolationIndex];
555+ FindBestInterpolatedHit (merger, inter, cluster.sector , cluster.row , deltaZ, sumInvSqrtCharge, nAvgCharge, prop, iTrk, true );
556+ }
557+ }
558+
559+ 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)
528560{
529561 const GPUParam& GPUrestrict () param = merger.Param ();
530562 if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR (param.par , dodEdx)) {
0 commit comments