Skip to content

Commit c784b9e

Browse files
TPC SCD: add clampTgSlp to keep residuals beyond MaxTgSlp
The |tan(phi)| < param::MaxTgSlp condition on a TPC cluster residual is evaluated on the REFERENCE track's direction. For ITS-TPC tracks that direction carries the ITS curvature error, so dropping the cluster selects on that error (over-curved references reach the limit first), a one-sided selection that grows with radius for pt below ~0.3 GeV. With clampTgSlp=true the cluster is kept and tgSlp is stored saturated at +-MaxTgSlp (tgSlp == +-0x7fff, UnbinnedResid::isTgSlpClamped()); dy, dz, y, z are unchanged. Default false = unchanged behaviour and file content; the format is not changed. With clampTgSlp the saturated tgSlp is not the track's angle, and the voxel fit extracts dX from dY vs tan(phi) (also used by the map-correction check in staticMapCreator.C). ResidualsContainer::fill and staticMapCreator.C therefore skip UnbinnedResid::isTgSlpClamped() residuals when binning; they stay in the unbinned output. The vDrift estimate (dz vs z only) still uses them. No effect unless clampTgSlp is on. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 1de80c9 commit c784b9e

5 files changed

Lines changed: 23 additions & 4 deletions

File tree

‎Detectors/TPC/calibration/SpacePoints/include/SpacePoints/SpacePointsCalibConfParam.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct SpacePointsCalibConfParam : public o2::conf::ConfigurableParamHelper<Spac
4848
// other settings for track interpolation
4949
float sigYZ2TOF{.75f}; ///< for now assume cluster error for TOF equal for all clusters in both Y and Z
5050
float maxSnp{.85f}; ///< max snp when propagating tracks
51+
bool clampTgSlp{false}; ///< store TPC cluster residuals with |tan(phi)| >= param::MaxTgSlp saturated (tgSlp = +-0x7fff, see UnbinnedResid::isTgSlpClamped) instead of dropping them: the cut is on the reference track's direction, so dropping selects on the reference's error
5152
float maxStep{2.f}; ///< maximum step for propagation
5253
bool debugTRDTOF{false}; ///< if true, ITS-TPC-TRD-TOF tracks and their seeding ITS-TPC-TRD track will both be interpolated and their residuals stored
5354

‎Detectors/TPC/calibration/SpacePoints/include/SpacePoints/TrackInterpolation.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ struct UnbinnedResid {
9494
short channel{-1}; ///< extra channel info (ITS chip ID, TRD chamber, TOF main pad within the sector)
9595
bool rejected{false}; ///< residual is flagged as rejected in the validateTrack
9696

97+
/// true if tgSlp was saturated at +-param::MaxTgSlp (scdcalib.clampTgSlp): unclamped values have |tgSlp| <= 0x7fff - 1
98+
bool isTgSlpClamped() const { return tgSlp == 0x7fff || tgSlp == -0x7fff; }
9799
bool isTPC() const { return row < constants::MAXGLOBALPADROW; }
98100
bool isTRD() const { return row >= 160 && row < 166; }
99101
bool isTOF() const { return row == 170; }

‎Detectors/TPC/calibration/SpacePoints/macro/staticMapCreator.C‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,11 @@ void staticMapCreator(std::string fileInput = "files.txt",
320320
if (useResidualsForVd && residualsVd.size() < 10'000'000UL) {
321321
residualsVd.push_back(residIn);
322322
}
323+
if (residIn.isTgSlpClamped()) {
324+
// scdcalib.clampTgSlp: tgSlp saturated -- the voxel fit (dX from dY vs tan(phi)) and the map correction below
325+
// use it, so keep this residual out of the binned residuals
326+
continue;
327+
}
323328
int sec = residIn.sec;
324329
auto& residVecOut = binnedResidualsSec[sec];
325330
auto& statVecOut = voxStatsSec[sec];

‎Detectors/TPC/calibration/SpacePoints/src/ResidualAggregator.cxx‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ void ResidualsContainer::fill(const o2::dataformats::TFIDInfo& ti, const gsl::sp
197197
if (!writeBinnedResid) {
198198
continue;
199199
}
200+
if (residIn.isTgSlpClamped()) {
201+
// scdcalib.clampTgSlp: kept in the unbinned output, but its tgSlp is saturated and the voxel fit uses tgSlp (dX from
202+
// dY vs tan(phi)), so it must not enter the binned residuals
203+
continue;
204+
}
200205
int sec = residIn.sec;
201206
auto& residVecOut = residuals[sec];
202207
auto& statVecOut = stats[sec];

‎Detectors/TPC/calibration/SpacePoints/src/TrackInterpolation.cxx‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -725,8 +725,11 @@ void TrackInterpolation::interpolateTrack(int iSeed)
725725
const auto z = clusterResiduals[iCl].z;
726726
const auto sec = clusterResiduals[iCl].sec;
727727
const short flags = clusterResiduals[iCl].flags;
728-
if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(y) < param::MaxY) && (std::abs(z) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
729-
mClRes.emplace_back(dy, dz, tgPhi, y, z, iRow, sec, flags, rej);
728+
// scdcalib.clampTgSlp: keep a cluster whose |tan(phi)| exceeds the packing range, with tgSlp saturated, instead of dropping it
729+
const bool tgPhiOK = (std::abs(tgPhi) < param::MaxTgSlp) || mParams->clampTgSlp;
730+
const float tgPhiStore = std::clamp(tgPhi, -param::MaxTgSlp, param::MaxTgSlp);
731+
if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(y) < param::MaxY) && (std::abs(z) < param::MaxZ) && tgPhiOK) {
732+
mClRes.emplace_back(dy, dz, tgPhiStore, y, z, iRow, sec, flags, rej);
730733
mDetInfoRes.emplace_back().setTPC(mCacheDEDX[iRow].first, mCacheDEDX[iRow].second); // qtot, qmax
731734
++nClValidated;
732735
} else {
@@ -1076,8 +1079,11 @@ void TrackInterpolation::extrapolateTrack(int iSeed)
10761079
const auto y = clusterResiduals[iCl].y;
10771080
const auto z = clusterResiduals[iCl].z;
10781081
const short flags = clusterResiduals[iCl].flags;
1079-
if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(y) < param::MaxY) && (std::abs(z) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
1080-
mClRes.emplace_back(dy, dz, tgPhi, y, z, iRow, clusterResiduals[iCl].sec, flags, rej);
1082+
// scdcalib.clampTgSlp: keep a cluster whose |tan(phi)| exceeds the packing range, with tgSlp saturated, instead of dropping it
1083+
const bool tgPhiOK = (std::abs(tgPhi) < param::MaxTgSlp) || mParams->clampTgSlp;
1084+
const float tgPhiStore = std::clamp(tgPhi, -param::MaxTgSlp, param::MaxTgSlp);
1085+
if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(y) < param::MaxY) && (std::abs(z) < param::MaxZ) && tgPhiOK) {
1086+
mClRes.emplace_back(dy, dz, tgPhiStore, y, z, iRow, clusterResiduals[iCl].sec, flags, rej);
10811087
mDetInfoRes.emplace_back().setTPC(mCacheDEDX[iRow].first, mCacheDEDX[iRow].second); // qtot, qmax
10821088
++nClValidated;
10831089
} else {

0 commit comments

Comments
 (0)