2828namespace o2 ::tpc
2929{
3030
31- struct CMVPerTF ; // forward declaration
32- struct CMVPerTFSparse ; // forward declaration
33- struct CMVPerTFHuffman ; // forward declaration
31+ struct CMVPerTF ; // forward declaration
32+ struct CMVPerTFSparse ; // forward declaration
33+ struct CMVPerTFHuffman ; // forward declaration
34+ struct CMVPerTFCombined ; // forward declaration
3435
3536// / Delta+zigzag+varint compressed CMV data for one TF across all CRUs
36- // / Produced by CMVPerTF::compress (), restored with decompress()
37- // / Each TTree entry corresponds to one CMVPerTFCompressed object (one TF)
38- struct CMVPerTFCompressed {
37+ // / Produced by CMVPerTF::compressVarint (), restored with decompress()
38+ // / Each TTree entry corresponds to one CMVPerTFVarint object (one TF)
39+ struct CMVPerTFVarint {
3940 uint32_t firstOrbit{0 }; // /< First orbit of this TF (copied from CMVPerTF)
4041 uint16_t firstBC{0 }; // /< First bunch crossing of this TF (copied from CMVPerTF)
4142
@@ -52,7 +53,7 @@ struct CMVPerTFCompressed {
5253 static uint32_t decodeVarint (const uint8_t *& data, const uint8_t * end); // /< Varint decode
5354
5455 public:
55- ClassDefNV (CMVPerTFCompressed , 1 )
56+ ClassDefNV (CMVPerTFVarint , 1 )
5657};
5758
5859// / Sparse-encoded CMV data for one TF across all CRUs
@@ -105,6 +106,35 @@ struct CMVPerTFHuffman {
105106 ClassDefNV (CMVPerTFHuffman, 1 )
106107};
107108
109+ // / Hybrid sparse+compressed-value encoding for one TF across all CRUs
110+ // /
111+ // / Non-zero positions are stored as sparse varint deltas (same as CMVPerTFSparse).
112+ // / The remaining non-zero values are encoded according to mValueMode:
113+ // /
114+ // / Mode 0 raw uint16_t — identical value encoding to CMVPerTFSparse
115+ // / Mode 1 varint signed — zigzag+varint of the exact signed CMV value
116+ // / Mode 2 Huffman signed — canonical Huffman over the same zigzag-encoded exact values
117+ // /
118+ // / Binary layout of mData:
119+ // / 4 bytes LE posStreamSize
120+ // / [posStream] for each CRU: varint(N), N×varint(tb_delta)
121+ // / [valStream]
122+ // / mode 0: N_total × uint16_t LE
123+ // / mode 1: N_total × varint(zigzag(cmvToSigned(raw)))
124+ // / mode 2: [canonical Huffman table] + [8-byte totalBits] + [bitstream]
125+ struct CMVPerTFCombined {
126+ uint32_t firstOrbit{0 }; // /< First orbit of this TF
127+ uint16_t firstBC{0 }; // /< First bunch crossing of this TF
128+ uint8_t mValueMode {0 }; // /< 0 = raw uint16, 1 = varint signed CMV, 2 = Huffman signed CMV
129+
130+ std::vector<uint8_t > mData ; // /< Encoded payload
131+
132+ // / Restore a CMVPerTF from this object into *cmv (must not be null)
133+ void decompress (CMVPerTF* cmv) const ;
134+
135+ ClassDefNV (CMVPerTFCombined, 1 )
136+ };
137+
108138// / CMV data for one TF across all CRUs
109139// / Raw 16-bit CMV values are stored in a flat C array indexed as [cru * NTimeBinsPerTF + timeBin]
110140// / CRU::MaxCRU and cmv::NTimeBinsPerTF are compile-time constants, so no dynamic allocation is needed
@@ -125,23 +155,30 @@ struct CMVPerTF {
125155 // / This converts the sign-magnitude raw value to 0x0000 for all entries with |float value| < threshold
126156 void zeroSmallValues (float threshold = 1 .0f );
127157
128- // / Apply dynamic precision reduction: round values to the nearest integer ADC for all values whose rounded magnitude is <= steps
129- // / Example: steps =3
158+ // / Round values to the nearest integer ADC for all values whose rounded magnitude is <= threshold
159+ // / Example: threshold =3
130160 // / |v| < 0.5 ADC -> 0
131161 // / |v| in [0.5, 1.5) ADC -> 1.0 ADC
132162 // / |v| in [1.5, 2.5) ADC -> 2.0 ADC
133163 // / |v| in [2.5, 3.5) ADC -> 3.0 ADC
134164 // / |v| >= 3.5 ADC -> unchanged (full precision)
135165 // /
136- // / steps =0 dynamic precision is not applied
137- void applyDynamicPrecision (uint16_t steps );
166+ // / threshold =0 rounding is not applied
167+ void roundToIntegers (uint16_t threshold );
138168
139- // / Compress this object into a CMVPerTFCompressed using delta+zigzag+varint encoding
140- CMVPerTFCompressed compress () const ;
169+ // / Compress this object into a CMVPerTFVarint using delta+zigzag+varint encoding
170+ CMVPerTFVarint compressVarint () const ;
141171
142172 // / Compress this object into a CMVPerTFSparse storing only non-zero timebins
143173 CMVPerTFSparse compressSparse () const ;
144174
175+ // / Hybrid sparse+compressed-value compression
176+ // / Positions encoded as sparse varint deltas; values encoded according to valueMode:
177+ // / 0 = raw uint16_t (same as compressSparse, no additional gain)
178+ // / 1 = varint signed CMV value
179+ // / 2 = Huffman signed CMV value
180+ CMVPerTFCombined compressCombined (uint8_t valueMode = 0 ) const ;
181+
145182 // / Compress this object using delta+zigzag+canonical-Huffman encoding
146183 CMVPerTFHuffman compressHuffman () const ;
147184
@@ -162,4 +199,4 @@ struct CMVPerTF {
162199
163200} // namespace o2::tpc
164201
165- #endif // ALICEO2_TPC_CMVCONTAINER_H_
202+ #endif // ALICEO2_TPC_CMVCONTAINER_H_
0 commit comments