Belle II Software  release-08-01-10
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  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 }
79 void 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.