Belle II Software development
ECLDspData.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include <ecl/dbobjects/ECLDspData.h>
9
10using namespace Belle2;
11
12void ECLDspData::packCoefVector(const std::vector<short int>& src, std::vector<short int>& dst)
13{
14 const int N_CHANNELS = 16;
15 int size = src.size();
16
17 if (getPackerVersion() == 0) {
18 dst = src;
19 } else if (getPackerVersion() >= 1) {
20 // Apply reversible transformation to shrink the range
21 // of saved coefficients into much smaller interval.
22 // This improves the compression by a factor of ~2.
23
24 dst.resize(size);
25 for (int i = size - 1; i >= 0; i--) {
26 if (i >= 2 * N_CHANNELS)
27 dst[i] = src[i] - 2 * src[i - N_CHANNELS] + src[i - 2 * N_CHANNELS];
28 else if (i >= N_CHANNELS)
29 dst[i] = src[i] - 2 * src[i - N_CHANNELS];
30 else
31 dst[i] = src[i];
32 }
33 }
34
35 if (getPackerVersion() == 2) {
36 // Rearrange the data in such a way that each coeff
37 // only takes up 4 bits (special value 0xF indicates
38 // coefficients that are too big to be packed)
39 //
40 // Vector structure after packing:
41 // [big_coefs | packed_coefs | packed_coefs.size()]
42
43 // Bits allocated for each value
44 const int value_bits = 4;
45 const long value_max = 0xF;
46 const int values_packed = sizeof(short) * 8 / value_bits;
47
48 int shift = -6;
49
50 std::vector<short> packed(size / values_packed, 0);
51 int len = -1;
52
53 for (int i = 0; i < size; i++) {
54 short val = dst[i] - shift;
55 if (val >= 0 && val < value_max) {
56 if (len < 0) len = i;
57 packed[i / values_packed] |= val << (value_bits * (i % values_packed));
58 } else {
59 if (len >= 0 && len < i) {
60 dst[len++] = dst[i];
61 }
62 packed[i / values_packed] |= short(value_max) << (value_bits * (i % values_packed));
63 }
64 }
65
66 int packed_size = 0;
67
68 if (len >= 0) {
69 dst.resize(len + packed.size());
70 packed_size = packed.size();
71 for (int i = 0; i < packed_size; i++) {
72 dst[len + i] = packed[i];
73 }
74 }
75 dst.push_back(packed_size);
76 dst.shrink_to_fit();
77 }
78}
79void ECLDspData::unpackCoefVector(const std::vector<short int>& src, std::vector<short int>& dst) const
80{
81 const int N_CHANNELS = 16;
82
83 int packer_version = m_extraData[1];
84 int dst_size = 0;
85
86 if (packer_version == 1) {
87 dst_size = src.size();
88 dst.resize(dst_size);
89 }
90 if (packer_version >= 2) {
91 // Number of bits allocated for each value
92 const int value_bits = 4;
93 const long value_max = 0xF;
94 const int values_packed = sizeof(short) * 8 / value_bits;
95
96 int size = src.size();
97 int packed_size = src[--size];
98
99 int packed_start = size - packed_size;
100 dst_size = packed_size * values_packed;
101
102 dst.resize(dst_size);
103
104 if (packed_size > 0) {
105 int unpacked_index = 0;
106 int dst_index = 0;
107 const int shift = -6;
108
109 for (int i = packed_start; i < size; i++) {
110 auto package = src[i];
111 for (int k = 0; k < values_packed; k++) {
112 short val = package & value_max;
113 if (val != value_max) {
114 dst[dst_index++] = val + shift;
115 } else {
116 dst[dst_index++] = src[unpacked_index++];
117 }
118 package >>= value_bits;
119 }
120 }
121 } else {
122 dst = src;
123 dst.resize(size);
124 }
125 }
126
127
128 if (packer_version == 0) {
129 dst = src;
130 } else if (packer_version >= 1) {
131 const std::vector<short int>& new_src = packer_version >= 2 ? dst : src;
132
133 for (int i = 0; i < dst_size; i++) {
134 if (i >= 2 * N_CHANNELS)
135 dst[i] = new_src[i] + 2 * dst[i - N_CHANNELS] - dst[i - 2 * N_CHANNELS];
136 else if (i >= N_CHANNELS)
137 dst[i] = new_src[i] + 2 * dst[i - N_CHANNELS];
138 else
139 dst[i] = new_src[i];
140 }
141 }
142}
143
std::vector< short int > m_extraData
This vector contains all parameters that didn't exist in the initial version of ECL DSP file format.
Definition: ECLDspData.h:92
void packCoefVector(const std::vector< short int > &src, std::vector< short int > &dst)
Convert vector of DSP coefficients (src) to ECLDspData internal format (dst).
Definition: ECLDspData.cc:12
static constexpr short int getPackerVersion()
GETTERS.
Definition: ECLDspData.h:129
void unpackCoefVector(const std::vector< short int > &src, std::vector< short int > &dst) const
Convert vector of DSP coefficients (src) to ECLDspData internal format (dst).
Definition: ECLDspData.cc:79
Abstract base class for different kinds of events.