1818#define ALICEO2_TPC_TRACKINTERPOLATION_H_
1919
2020#include < gsl/span>
21+ #include < algorithm>
22+ #include < cmath>
2123#include " CommonDataFormat/EvIndex.h"
2224#include " CommonDataFormat/RangeReference.h"
2325#include " ReconstructionDataFormats/Track.h"
@@ -77,11 +79,11 @@ struct TPCClusterResiduals {
7779struct UnbinnedResid {
7880 UnbinnedResid () = default ;
7981 UnbinnedResid (float dyIn, float dzIn, float tgSlpIn, float yIn, float zIn,
80- unsigned char rowIn, unsigned char secIn, short chanIn = -1 , bool rejFlag = false ) : dy(static_cast < short > (dyIn * 0x7fff / param::MaxResid)),
81- dz (static_cast < short > (dzIn * 0x7fff / param::MaxResid)),
82- tgSlp(static_cast < short > (tgSlpIn * 0x7fff / param::MaxTgSlp)),
83- y(static_cast < short > (yIn * 0x7fff / param::MaxY)),
84- z(static_cast < short > (zIn * 0x7fff / param::MaxZ)),
82+ unsigned char rowIn, unsigned char secIn, short chanIn = -1 , bool rejFlag = false ) : dy(packToShort (dyIn, param::MaxResid)),
83+ dz (packToShort (dzIn, param::MaxResid)),
84+ tgSlp(packToShort (tgSlpIn, param::MaxTgSlp, std::abs(tgSlpIn) < param::MaxTgSlp ? 0x7fff - 1 : 0x7fff )),
85+ y(packToShort (yIn, param::MaxY)),
86+ z(packToShort (zIn, param::MaxZ)),
8587 row(rowIn),
8688 sec(secIn),
8789 channel(chanIn),
@@ -96,6 +98,16 @@ struct UnbinnedResid {
9698 short channel{-1 }; // /< extra channel info (ITS chip ID, TRD chamber, TOF main pad within the sector)
9799 bool rejected{false }; // /< residual is flagged as rejected in the validateTrack
98100
101+ // / value (|value| <= maximum) packed into a signed short, rounded to the nearest step. The scale is fixed at 0x7fff steps per maximum
102+ // / (decoded everywhere as short * maximum / 0x7fff); limit only clips the result to +-limit (e.g. 0x7fff - 1 for an unclamped tgSlp, to
103+ // / keep 0x7fff as the clamp marker), it does not change the scale. A plain cast would truncate towards zero, i.e. move every value
104+ // / towards zero by up to one step: the decoded cluster position y + dy then depends on the sign of dy below the step size, which
105+ // / biases residuals binned by the cluster position on sub-pad scales
106+ static short packToShort (float value, float maximum, int limit = 0x7fff )
107+ {
108+ return static_cast <short >(std::clamp<long >(std::lround (value * 0x7fff / maximum), -limit, limit));
109+ }
110+
99111 // / true if tgSlp was saturated at +-param::MaxTgSlp (scdcalib.clampTgSlp): unclamped values have |tgSlp| <= 0x7fff - 1
100112 bool isTgSlpClamped () const { return tgSlp == 0x7fff || tgSlp == -0x7fff ; }
101113 // / tgSlp marker of a position-only TPC cluster (scdcalib.keepClustersOnPropFail): no reference track at this cluster,
0 commit comments