Belle II Software  release-06-01-15
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 
10 using namespace Belle2;
11 
12 void 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  // cppcheck-suppress knownConditionTrueFalse
18  if (getPackerVersion() == 0) {
19  dst = src;
20  // cppcheck-suppress knownConditionTrueFalse
21  } else if (getPackerVersion() >= 1) {
22  // Apply reversible transformation to shrink the range
23  // of saved coefficients into much smaller interval.
24  // This improves the compression by a factor of ~2.
25 
26  dst.resize(size);
27  for (int i = size - 1; i >= 0; i--) {
28  if (i >= 2 * N_CHANNELS)
29  dst[i] = src[i] - 2 * src[i - N_CHANNELS] + src[i - 2 * N_CHANNELS];
30  else if (i >= N_CHANNELS)
31  dst[i] = src[i] - 2 * src[i - N_CHANNELS];
32  else
33  dst[i] = src[i];
34  }
35  }
36 
37  // cppcheck-suppress knownConditionTrueFalse
38  if (getPackerVersion() == 2) {
39  // Rearrange the data in such a way that each coeff
40  // only takes up 4 bits (special value 0xF indicates
41  // coefficients that are too big to be packed)
42  //
43  // Vector structure after packing:
44  // [big_coefs | packed_coefs | packed_coefs.size()]
45 
46  // Bits allocated for each value
47  const int value_bits = 4;
48  const long value_max = 0xF;
49  const int values_packed = sizeof(short) * 8 / value_bits;
50 
51  int shift = -6;
52 
53  std::vector<short> packed(size / values_packed, 0);
54  int len = -1;
55 
56  for (int i = 0; i < size; i++) {
57  short val = dst[i] - shift;
58  if (val >= 0 && val < value_max) {
59  if (len < 0) len = i;
60  packed[i / values_packed] |= val << (value_bits * (i % values_packed));
61  } else {
62  if (len >= 0 && len < i) {
63  dst[len++] = dst[i];
64  }
65  packed[i / values_packed] |= short(value_max) << (value_bits * (i % values_packed));
66  }
67  }
68 
69  int packed_size = 0;
70 
71  if (len >= 0) {
72  dst.resize(len + packed.size());
73  packed_size = packed.size();
74  for (int i = 0; i < packed_size; i++) {
75  dst[len + i] = packed[i];
76  }
77  }
78  dst.push_back(packed_size);
79  dst.shrink_to_fit();
80  }
81 }
82 void ECLDspData::unpackCoefVector(const std::vector<short int>& src, std::vector<short int>& dst) const
83 {
84  const int N_CHANNELS = 16;
85 
86  int packer_version = m_extraData[1];
87  int dst_size = 0;
88 
89  if (packer_version == 1) {
90  dst_size = src.size();
91  dst.resize(dst_size);
92  }
93  if (packer_version >= 2) {
94  // Number of bits allocated for each value
95  const int value_bits = 4;
96  const long value_max = 0xF;
97  const int values_packed = sizeof(short) * 8 / value_bits;
98 
99  int size = src.size();
100  int packed_size = src[--size];
101 
102  int packed_start = size - packed_size;
103  dst_size = packed_size * values_packed;
104 
105  dst.resize(dst_size);
106 
107  if (packed_size > 0) {
108  int unpacked_index = 0;
109  int dst_index = 0;
110  const int shift = -6;
111 
112  for (int i = packed_start; i < size; i++) {
113  auto package = src[i];
114  for (int k = 0; k < values_packed; k++) {
115  short val = package & value_max;
116  if (val != value_max) {
117  dst[dst_index++] = val + shift;
118  } else {
119  dst[dst_index++] = src[unpacked_index++];
120  }
121  package >>= value_bits;
122  }
123  }
124  } else {
125  dst = src;
126  dst.resize(size);
127  }
128  }
129 
130 
131  if (packer_version == 0) {
132  dst = src;
133  } else if (packer_version >= 1) {
134  const std::vector<short int>& new_src = packer_version >= 2 ? dst : src;
135 
136  for (int i = 0; i < dst_size; i++) {
137  if (i >= 2 * N_CHANNELS)
138  dst[i] = new_src[i] + 2 * dst[i - N_CHANNELS] - dst[i - 2 * N_CHANNELS];
139  else if (i >= N_CHANNELS)
140  dst[i] = new_src[i] + 2 * dst[i - N_CHANNELS];
141  else
142  dst[i] = new_src[i];
143  }
144  }
145 }
146 
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:82
Abstract base class for different kinds of events.