diff --git a/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/SpacePointsCalibConfParam.h b/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/SpacePointsCalibConfParam.h index 5e25b4717118c..6ef3839991d04 100644 --- a/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/SpacePointsCalibConfParam.h +++ b/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/SpacePointsCalibConfParam.h @@ -48,6 +48,7 @@ struct SpacePointsCalibConfParam : public o2::conf::ConfigurableParamHelper= 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 float maxStep{2.f}; ///< maximum step for propagation 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 diff --git a/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/TrackInterpolation.h b/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/TrackInterpolation.h index 99e85cf19101a..2a662591b0ac8 100644 --- a/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/TrackInterpolation.h +++ b/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/TrackInterpolation.h @@ -94,6 +94,8 @@ struct UnbinnedResid { short channel{-1}; ///< extra channel info (ITS chip ID, TRD chamber, TOF main pad within the sector) bool rejected{false}; ///< residual is flagged as rejected in the validateTrack + /// true if tgSlp was saturated at +-param::MaxTgSlp (scdcalib.clampTgSlp): unclamped values have |tgSlp| <= 0x7fff - 1 + bool isTgSlpClamped() const { return tgSlp == 0x7fff || tgSlp == -0x7fff; } bool isTPC() const { return row < constants::MAXGLOBALPADROW; } bool isTRD() const { return row >= 160 && row < 166; } bool isTOF() const { return row == 170; } diff --git a/Detectors/TPC/calibration/SpacePoints/macro/staticMapCreator.C b/Detectors/TPC/calibration/SpacePoints/macro/staticMapCreator.C index 9ac12884d2a3f..3bf01f21f1dce 100644 --- a/Detectors/TPC/calibration/SpacePoints/macro/staticMapCreator.C +++ b/Detectors/TPC/calibration/SpacePoints/macro/staticMapCreator.C @@ -320,6 +320,11 @@ void staticMapCreator(std::string fileInput = "files.txt", if (useResidualsForVd && residualsVd.size() < 10'000'000UL) { residualsVd.push_back(residIn); } + if (residIn.isTgSlpClamped()) { + // scdcalib.clampTgSlp: tgSlp saturated -- the voxel fit (dX from dY vs tan(phi)) and the map correction below + // use it, so keep this residual out of the binned residuals + continue; + } int sec = residIn.sec; auto& residVecOut = binnedResidualsSec[sec]; auto& statVecOut = voxStatsSec[sec]; diff --git a/Detectors/TPC/calibration/SpacePoints/src/ResidualAggregator.cxx b/Detectors/TPC/calibration/SpacePoints/src/ResidualAggregator.cxx index b916e14dbf741..c5594ddc40b02 100644 --- a/Detectors/TPC/calibration/SpacePoints/src/ResidualAggregator.cxx +++ b/Detectors/TPC/calibration/SpacePoints/src/ResidualAggregator.cxx @@ -197,6 +197,11 @@ void ResidualsContainer::fill(const o2::dataformats::TFIDInfo& ti, const gsl::sp if (!writeBinnedResid) { continue; } + if (residIn.isTgSlpClamped()) { + // scdcalib.clampTgSlp: kept in the unbinned output, but its tgSlp is saturated and the voxel fit uses tgSlp (dX from + // dY vs tan(phi)), so it must not enter the binned residuals + continue; + } int sec = residIn.sec; auto& residVecOut = residuals[sec]; auto& statVecOut = stats[sec]; diff --git a/Detectors/TPC/calibration/SpacePoints/src/TrackInterpolation.cxx b/Detectors/TPC/calibration/SpacePoints/src/TrackInterpolation.cxx index 571bc00a48763..8265bce0582bd 100644 --- a/Detectors/TPC/calibration/SpacePoints/src/TrackInterpolation.cxx +++ b/Detectors/TPC/calibration/SpacePoints/src/TrackInterpolation.cxx @@ -725,8 +725,11 @@ void TrackInterpolation::interpolateTrack(int iSeed) const auto z = clusterResiduals[iCl].z; const auto sec = clusterResiduals[iCl].sec; const short flags = clusterResiduals[iCl].flags; - 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)) { - mClRes.emplace_back(dy, dz, tgPhi, y, z, iRow, sec, flags, rej); + // scdcalib.clampTgSlp: keep a cluster whose |tan(phi)| exceeds the packing range, with tgSlp saturated, instead of dropping it + const bool tgPhiOK = (std::abs(tgPhi) < param::MaxTgSlp) || mParams->clampTgSlp; + const float tgPhiStore = std::clamp(tgPhi, -param::MaxTgSlp, param::MaxTgSlp); + if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(y) < param::MaxY) && (std::abs(z) < param::MaxZ) && tgPhiOK) { + mClRes.emplace_back(dy, dz, tgPhiStore, y, z, iRow, sec, flags, rej); mDetInfoRes.emplace_back().setTPC(mCacheDEDX[iRow].first, mCacheDEDX[iRow].second); // qtot, qmax ++nClValidated; } else { @@ -1076,8 +1079,11 @@ void TrackInterpolation::extrapolateTrack(int iSeed) const auto y = clusterResiduals[iCl].y; const auto z = clusterResiduals[iCl].z; const short flags = clusterResiduals[iCl].flags; - 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)) { - mClRes.emplace_back(dy, dz, tgPhi, y, z, iRow, clusterResiduals[iCl].sec, flags, rej); + // scdcalib.clampTgSlp: keep a cluster whose |tan(phi)| exceeds the packing range, with tgSlp saturated, instead of dropping it + const bool tgPhiOK = (std::abs(tgPhi) < param::MaxTgSlp) || mParams->clampTgSlp; + const float tgPhiStore = std::clamp(tgPhi, -param::MaxTgSlp, param::MaxTgSlp); + if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(y) < param::MaxY) && (std::abs(z) < param::MaxZ) && tgPhiOK) { + mClRes.emplace_back(dy, dz, tgPhiStore, y, z, iRow, clusterResiduals[iCl].sec, flags, rej); mDetInfoRes.emplace_back().setTPC(mCacheDEDX[iRow].first, mCacheDEDX[iRow].second); // qtot, qmax ++nClValidated; } else {