Skip to content

TPC SCD: round instead of truncate when packing the unbinned residuals - #16046

Merged
shahor02 merged 2 commits into
AliceO2Group:devfrom
matthias-kleiner:tpc-fine-map-gbl-residround
Nov 4, 2026
Merged

shahor02 merged 2 commits into
AliceO2Group:devfrom
matthias-kleiner:tpc-fine-map-gbl-residround

Conversation

@matthias-kleiner

Copy link
Copy Markdown
Contributor

UnbinnedResid packed y, z, dy, dz and tgSlp into shorts with a plain cast, i.e. truncated towards zero. Every value moves towards zero by up to one step (15.3 µm for y, 6.1 µm for dy), so the decoded cluster position y + dy depends on the sign of dy below the step size. The cluster positions lie on the ClusterNative 1/64-pad grid; binning residuals by the cluster position on sub-pad scales therefore splits the clusters of a grid point by the sign of dy, giving a comb of up to ±0.8 mm in the mean residual. It appears identically in Pb-Pb data and in MC without distortions; snapping the decoded position back to the 1/64-pad grid removes it, and the snapped MC agrees with the MC-truth reference.

Change: UnbinnedResid::pack() rounds to the nearest step. Unclamped tgSlp stays at |tgSlp| ≤ 0x7fff − 1, so isTgSlpClamped() is unchanged. Same rounding for the vertex x and the TRD tracklet slope. No format change.

Effect on the maps: negligible; voxels are far coarser than the packing step. The fix matters for analyses that bin by the cluster position on sub-pad scales (pad-response / sector-edge studies). Existing productions can be corrected in the analysis by snapping y + dy to the 1/64-pad grid (the packing error, ≤ 21 µm, is below half a grid step).

pr_unbinned_resid_packing

Mean TPC residual vs the pad phase of the decoded cluster position (40 bins per pad); grey: as decoded, colour: snapped to the 1/64-pad grid, dashed: MC truth. Clusters without split / single / shared flags, > 3.5 pads from the sector edge, |tan φ| < 0.3.

🤖 Generated with Claude Code

UnbinnedResid packed y, z, dy, dz and tgSlp into shorts with a plain cast, i.e. truncated towards zero: every value
moved towards zero by up to one step (15 um for y, 6 um for dy). The decoded cluster position y + dy then depends on
the sign of dy below the step size, and since the cluster positions lie on the ClusterNative 1/64-pad grid, binning
residuals by the cluster position on sub-pad scales splits the clusters of a grid point by the sign of dy: a comb of
up to +-0.8 mm in the mean residual (seen identically in PbPb data and no-distortion MC; snapping the decoded position
back to the 1/64-pad grid removes it). Pack with rounding instead (UnbinnedResid::pack); unclamped tgSlp stays at
|tgSlp| <= 0x7fff - 1, so isTgSlpClamped() is unchanged. Same rounding for the vertex x and the TRD tracklet slope.
No format change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/// y + dy then depends on the sign of dy below the step size, which biases residuals binned by the cluster position on sub-pad scales
static short pack(float value, float maximum, int limit = 0x7fff)
{
return static_cast<short>(std::clamp<long>(std::lround(value * 0x7fff / maximum), -limit, limit));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better do this as

return static_cast<short>(std::clamp<long>(std::lround(value * limit / maximum), -limit, limit));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tgSlp the limit is std::abs(tgSlpIn) < param::MaxTgSlp ? 0x7fff - 1 : 0x7fff (unclamped values must not round onto 0x7fff, which isTgSlpClamped() uses as the clamp marker). With limit as the scale, unclamped tgSlp would be packed with 0x7ffe while the decoding uses 0x7fff, a relative difference of 3e-5. Negligible in practice, but packing and decoding would no longer use the same scale. Shall I still change it or keep 0x7fff as the scale and limit only for the clipping?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, indeed. I just find it confusing that the pack() looks generic, but the limit is intrinsically tied to the scale constant. Perhaps one should simply rename pack to packToUShort

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree. I renamed it, thanks!

…d 0x7fff scale

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alibuild

alibuild commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

Error while checking build/O2/fullCI_slc9 for 261ba2d at 2026-11-04 16:25:

No log files found

Full log here.

@shahor02
shahor02 merged commit cfb5a4b into AliceO2Group:dev Nov 4, 2026
11 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants