LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
raw.cxx
Go to the documentation of this file.
1 
7 
8 #include <bitset>
9 #include <iostream>
10 #include <iterator> // std::back_inserter()
11 #include <numeric> // std::adjacent_difference()
12 
13 #include "cetlib_except/exception.h"
15 
16 namespace raw {
17 
18  //----------------------------------------------------------
19  void Compress(std::vector<short>& adc, raw::Compress_t compress)
20  {
21  if (compress == raw::kHuffman)
22  CompressHuffman(adc);
23  else if (compress == raw::kZeroHuffman) {
24  unsigned int zerothreshold = 5;
25  ZeroSuppression(adc, zerothreshold);
26  CompressHuffman(adc);
27  }
28  else if (compress == raw::kZeroSuppression) {
29  unsigned int zerothreshold = 5;
30  ZeroSuppression(adc, zerothreshold);
31  }
32  else if (compress == raw::kFibonacci) {
33  CompressFibonacci(adc);
34  }
35 
36  return;
37  }
38  //----------------------------------------------------------
39  void Compress(std::vector<short>& adc, raw::Compress_t compress, int& nearestneighbor)
40  {
41  if (compress == raw::kHuffman)
42  CompressHuffman(adc);
43  else if (compress == raw::kZeroHuffman) {
44  unsigned int zerothreshold = 5;
45  ZeroSuppression(adc, zerothreshold, nearestneighbor);
46  CompressHuffman(adc);
47  }
48  else if (compress == raw::kZeroSuppression) {
49  unsigned int zerothreshold = 5;
50  ZeroSuppression(adc, zerothreshold, nearestneighbor);
51  }
52  else if (compress == raw::kFibonacci) {
53  CompressFibonacci(adc);
54  }
55 
56  return;
57  }
58 
59  //----------------------------------------------------------
60  void Compress(std::vector<short>& adc, raw::Compress_t compress, unsigned int& zerothreshold)
61  {
62  if (compress == raw::kHuffman)
63  CompressHuffman(adc);
64 
65  else if (compress == raw::kZeroSuppression)
66  ZeroSuppression(adc, zerothreshold);
67  else if (compress == raw::kZeroHuffman) {
68  ZeroSuppression(adc, zerothreshold);
69  CompressHuffman(adc);
70  }
71  else if (compress == raw::kFibonacci) {
72  CompressFibonacci(adc);
73  }
74 
75  return;
76  }
77  //----------------------------------------------------------
78  void Compress(std::vector<short>& adc,
79  raw::Compress_t compress,
80  unsigned int& zerothreshold,
81  int& nearestneighbor)
82  {
83  if (compress == raw::kHuffman)
84  CompressHuffman(adc);
85  else if (compress == raw::kZeroSuppression)
86  ZeroSuppression(adc, zerothreshold, nearestneighbor);
87  else if (compress == raw::kZeroHuffman) {
88  ZeroSuppression(adc, zerothreshold, nearestneighbor);
89  CompressHuffman(adc);
90  }
91  else if (compress == raw::kFibonacci) {
92  CompressFibonacci(adc);
93  }
94 
95  return;
96  }
97 
98  //----------------------------------------------------------
99  void Compress(const boost::circular_buffer<std::vector<short>>& adcvec_neighbors,
100  std::vector<short>& adc,
101  raw::Compress_t compress,
102  unsigned int& zerothreshold,
103  int& nearestneighbor)
104  {
105  if (compress == raw::kHuffman)
106  CompressHuffman(adc);
107  else if (compress == raw::kZeroSuppression)
108  ZeroSuppression(adcvec_neighbors, adc, zerothreshold, nearestneighbor);
109  else if (compress == raw::kZeroHuffman) {
110  ZeroSuppression(adcvec_neighbors, adc, zerothreshold, nearestneighbor);
111  CompressHuffman(adc);
112  }
113  else if (compress == raw::kFibonacci) {
114  CompressFibonacci(adc);
115  }
116 
117  return;
118  }
119 
120  //----------------------------------------------------------
121  void Compress(std::vector<short>& adc,
122  raw::Compress_t compress,
123  unsigned int& zerothreshold,
124  int pedestal,
125  int& nearestneighbor,
126  bool fADCStickyCodeFeature)
127  {
128  if (compress == raw::kHuffman)
129  CompressHuffman(adc);
130  else if (compress == raw::kZeroSuppression)
131  ZeroSuppression(adc, zerothreshold, pedestal, nearestneighbor, fADCStickyCodeFeature);
132  else if (compress == raw::kZeroHuffman) {
133  ZeroSuppression(adc, zerothreshold, pedestal, nearestneighbor, fADCStickyCodeFeature);
134  CompressHuffman(adc);
135  }
136  else if (compress == raw::kFibonacci) {
137  CompressFibonacci(adc);
138  }
139 
140  return;
141  }
142 
143  //----------------------------------------------------------
144  void Compress(const boost::circular_buffer<std::vector<short>>& adcvec_neighbors,
145  std::vector<short>& adc,
146  raw::Compress_t compress,
147  unsigned int& zerothreshold,
148  int pedestal,
149  int& nearestneighbor,
150  bool fADCStickyCodeFeature)
151  {
152  if (compress == raw::kHuffman)
153  CompressHuffman(adc);
154  else if (compress == raw::kZeroSuppression)
156  adcvec_neighbors, adc, zerothreshold, pedestal, nearestneighbor, fADCStickyCodeFeature);
157  else if (compress == raw::kZeroHuffman) {
159  adcvec_neighbors, adc, zerothreshold, pedestal, nearestneighbor, fADCStickyCodeFeature);
160  CompressHuffman(adc);
161  }
162  else if (compress == raw::kFibonacci) {
163  CompressFibonacci(adc);
164  }
165 
166  return;
167  }
168 
169  //----------------------------------------------------------
170  // Zero suppression function
171  void ZeroSuppression(std::vector<short>& adc, unsigned int& zerothreshold)
172  {
173  const int adcsize = adc.size();
174  const int zerothresholdsigned = zerothreshold;
175 
176  std::vector<short> zerosuppressed(adc.size());
177  int maxblocks = adcsize / 2 + 1;
178  std::vector<short> blockbegin(maxblocks);
179  std::vector<short> blocksize(maxblocks);
180 
181  unsigned int nblocks = 0;
182  unsigned int zerosuppressedsize = 0;
183 
184  int blockcheck = 0;
185 
186  for (int i = 0; i < adcsize; ++i) {
187  int adc_current_value = std::abs(adc[i]);
188 
189  if (adc_current_value > zerothresholdsigned) {
190 
191  if (blockcheck == 0) {
192 
193  blockbegin[nblocks] = i;
194  blocksize[nblocks] = 0;
195  blockcheck = 1;
196  }
197 
198  zerosuppressed[zerosuppressedsize] = adc[i];
199  zerosuppressedsize++;
200  blocksize[nblocks]++;
201 
202  if (i == adcsize - 1) nblocks++;
203  }
204 
205  if (adc_current_value <= zerothresholdsigned && blockcheck == 1) {
206  zerosuppressed[zerosuppressedsize] = adc[i];
207  zerosuppressedsize++;
208  blocksize[nblocks]++;
209  nblocks++;
210  blockcheck = 0;
211  }
212  }
213 
214  adc.resize(2 + nblocks + nblocks + zerosuppressedsize);
215 
216  adc[0] = adcsize; //fill first entry in adc with length of uncompressed vector
217  adc[1] = nblocks;
218 
219  for (unsigned int i = 0; i < nblocks; ++i)
220  adc[i + 2] = blockbegin[i];
221 
222  for (unsigned int i = 0; i < nblocks; ++i)
223  adc[i + nblocks + 2] = blocksize[i];
224 
225  for (unsigned int i = 0; i < zerosuppressedsize; ++i)
226  adc[i + nblocks + nblocks + 2] = zerosuppressed[i];
227  }
228 
229  //----------------------------------------------------------
230  // Zero suppression function which merges blocks if they are
231  // within parameter nearestneighbor of each other
232  void ZeroSuppression(std::vector<short>& adc, unsigned int& zerothreshold, int& nearestneighbor)
233  {
234 
235  const int adcsize = adc.size();
236  const int zerothresholdsigned = zerothreshold;
237 
238  std::vector<short> zerosuppressed(adcsize);
239  int maxblocks = adcsize / 2 + 1;
240  std::vector<short> blockbegin(maxblocks);
241  std::vector<short> blocksize(maxblocks);
242 
243  int nblocks = 0;
244  int zerosuppressedsize = 0;
245 
246  int blockstartcheck = 0;
247  int endofblockcheck = 0;
248 
249  for (int i = 0; i < adcsize; ++i) {
250  int adc_current_value = std::abs(adc[i]);
251 
252  if (blockstartcheck == 0) {
253  if (adc_current_value > zerothresholdsigned) {
254  if (nblocks > 0) {
255  if ((i - nearestneighbor) <= (blockbegin[nblocks - 1] + blocksize[nblocks - 1] + 1)) {
256 
257  nblocks--;
258  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
259  blockstartcheck = 1;
260  }
261  else {
262  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
263  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
264  blockstartcheck = 1;
265  }
266  }
267  else {
268  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
269  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
270  blockstartcheck = 1;
271  }
272  }
273  }
274  else if (blockstartcheck == 1) {
275  if (adc_current_value > zerothresholdsigned) {
276  blocksize[nblocks]++;
277  endofblockcheck = 0;
278  }
279  else {
280  if (endofblockcheck < nearestneighbor) {
281  endofblockcheck++;
282  blocksize[nblocks]++;
283  }
284  //block has ended
285  else if (i + 2 < adcsize) { //check if end of adc vector is near
286  if (std::abs(adc[i + 1]) <= zerothresholdsigned &&
287  std::abs(adc[i + 2]) <= zerothresholdsigned) {
288  endofblockcheck = 0;
289  blockstartcheck = 0;
290  nblocks++;
291  }
292  }
293 
294  } // end else
295  } // end if blockstartcheck == 1
296  } // end loop over adc size
297 
298  if (blockstartcheck == 1) { // we reached the end of the adc vector with the block still going
299  ++nblocks;
300  }
301 
302  for (int i = 0; i < nblocks; ++i)
303  zerosuppressedsize += blocksize[i];
304 
305  adc.resize(2 + nblocks + nblocks + zerosuppressedsize);
306  zerosuppressed.resize(2 + nblocks + nblocks + zerosuppressedsize);
307 
308  int zerosuppressedcount = 0;
309  for (int i = 0; i < nblocks; ++i) {
310  //zerosuppressedsize += blocksize[i];
311  for (int j = 0; j < blocksize[i]; ++j) {
312  zerosuppressed[zerosuppressedcount] = adc[blockbegin[i] + j];
313  zerosuppressedcount++;
314  }
315  }
316 
317  adc[0] = adcsize; //fill first entry in adc with length of uncompressed vector
318  adc[1] = nblocks;
319  for (int i = 0; i < nblocks; ++i) {
320  adc[i + 2] = blockbegin[i];
321  adc[i + nblocks + 2] = blocksize[i];
322  }
323 
324  for (int i = 0; i < zerosuppressedsize; ++i)
325  adc[i + nblocks + nblocks + 2] = zerosuppressed[i];
326 
327  // for(int i = 0; i < 2 + 2*nblocks + zerosuppressedsize; ++i)
328  // std::cout << adc[i] << std::endl;
329  //adc.resize(2+nblocks+nblocks+zerosuppressedsize);
330  }
331 
332  //----------------------------------------------------------
333  // Zero suppression function which merges blocks if they are
334  // within parameter nearestneighbor of each other
335  // after subtracting pedestal value
336  void ZeroSuppression(std::vector<short>& adc,
337  unsigned int& zerothreshold,
338  int pedestal,
339  int& nearestneighbor,
340  bool fADCStickyCodeFeature)
341  {
342 
343  const int adcsize = adc.size();
344  const int zerothresholdsigned = zerothreshold;
345 
346  std::vector<short> zerosuppressed(adcsize);
347  int maxblocks = adcsize / 2 + 1;
348  std::vector<short> blockbegin(maxblocks);
349  std::vector<short> blocksize(maxblocks);
350 
351  int nblocks = 0;
352  int zerosuppressedsize = 0;
353 
354  int blockstartcheck = 0;
355  int endofblockcheck = 0;
356 
357  for (int i = 0; i < adcsize; ++i) {
358  int adc_current_value = ADCStickyCodeCheck(adc[i], pedestal, fADCStickyCodeFeature);
359 
360  if (blockstartcheck == 0) {
361  if (adc_current_value > zerothresholdsigned) {
362  if (nblocks > 0) {
363  if (i - nearestneighbor <= blockbegin[nblocks - 1] + blocksize[nblocks - 1] + 1) {
364  nblocks--;
365  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
366  blockstartcheck = 1;
367  }
368  else {
369  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
370  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
371  blockstartcheck = 1;
372  }
373  }
374  else {
375  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
376  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
377  blockstartcheck = 1;
378  }
379  }
380  }
381  else if (blockstartcheck == 1) {
382  if (adc_current_value > zerothresholdsigned) {
383  blocksize[nblocks]++;
384  endofblockcheck = 0;
385  }
386  else {
387  if (endofblockcheck < nearestneighbor) {
388  endofblockcheck++;
389  blocksize[nblocks]++;
390  }
391  //block has ended
392  else if (i + 2 < adcsize) { //check if end of adc vector is near
393  if (ADCStickyCodeCheck(adc[i + 1], pedestal, fADCStickyCodeFeature) <=
394  zerothresholdsigned &&
395  ADCStickyCodeCheck(adc[i + 2], pedestal, fADCStickyCodeFeature) <=
396  zerothresholdsigned) {
397  endofblockcheck = 0;
398  blockstartcheck = 0;
399  nblocks++;
400  }
401  }
402  } // end else
403  } // end if blockstartcheck == 1
404  } // end loop over adc size
405 
406  if (blockstartcheck == 1) { // we reached the end of the adc vector with the block still going
407  ++nblocks;
408  }
409 
410  for (int i = 0; i < nblocks; ++i)
411  zerosuppressedsize += blocksize[i];
412 
413  adc.resize(2 + nblocks + nblocks + zerosuppressedsize);
414  zerosuppressed.resize(2 + nblocks + nblocks + zerosuppressedsize);
415 
416  int zerosuppressedcount = 0;
417  for (int i = 0; i < nblocks; ++i) {
418  //zerosuppressedsize += blocksize[i];
419  for (int j = 0; j < blocksize[i]; ++j) {
420  zerosuppressed[zerosuppressedcount] = adc[blockbegin[i] + j];
421  zerosuppressedcount++;
422  }
423  }
424 
425  adc[0] = adcsize; //fill first entry in adc with length of uncompressed vector
426  adc[1] = nblocks;
427  for (int i = 0; i < nblocks; ++i) {
428  adc[i + 2] = blockbegin[i];
429  adc[i + nblocks + 2] = blocksize[i];
430  }
431 
432  for (int i = 0; i < zerosuppressedsize; ++i)
433  adc[i + nblocks + nblocks + 2] = zerosuppressed[i];
434 
435  // for(int i = 0; i < 2 + 2*nblocks + zerosuppressedsize; ++i)
436  // std::cout << adc[i] << std::endl;
437  //adc.resize(2+nblocks+nblocks+zerosuppressedsize);
438  }
439 
440  //----------------------------------------------------------
441  // Zero suppression function which merges blocks if they are
442  // within parameter nearest neighbor of each other and makes
443  // blocks if neighboring wires have nonzero blocks there
444  void ZeroSuppression(const boost::circular_buffer<std::vector<short>>& adcvec_neighbors,
445  std::vector<short>& adc,
446  unsigned int& zerothreshold,
447  int& nearestneighbor)
448  {
449 
450  const int adcsize = adc.size();
451  const int zerothresholdsigned = zerothreshold;
452 
453  std::vector<short> zerosuppressed(adcsize);
454  const int maxblocks = adcsize / 2 + 1;
455  std::vector<short> blockbegin(maxblocks);
456  std::vector<short> blocksize(maxblocks);
457 
458  int nblocks = 0;
459  int zerosuppressedsize = 0;
460 
461  int blockstartcheck = 0;
462  int endofblockcheck = 0;
463 
464  for (int i = 0; i < adcsize; ++i) {
465 
466  //find maximum adc value among all neighboring channels within the nearest neighbor channel distance
467 
468  int adc_current_value = 0;
469 
470  for (boost::circular_buffer<std::vector<short>>::const_iterator adcveciter =
471  adcvec_neighbors.begin();
472  adcveciter != adcvec_neighbors.end();
473  ++adcveciter) {
474  const std::vector<short>& adcvec_current = *adcveciter;
475  const int adcvec_current_single = std::abs(adcvec_current[i]);
476 
477  if (adc_current_value < adcvec_current_single) {
478  adc_current_value = adcvec_current_single;
479  }
480  }
481  if (blockstartcheck == 0) {
482  if (adc_current_value > zerothresholdsigned) {
483  if (nblocks > 0) {
484  if (i - nearestneighbor <= blockbegin[nblocks - 1] + blocksize[nblocks - 1] + 1) {
485  nblocks--;
486  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
487  blockstartcheck = 1;
488  }
489  else {
490  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
491  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
492  blockstartcheck = 1;
493  }
494  }
495  else {
496  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
497  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
498  blockstartcheck = 1;
499  }
500  }
501  }
502  else if (blockstartcheck == 1) {
503  if (adc_current_value > zerothresholdsigned) {
504  blocksize[nblocks]++;
505  endofblockcheck = 0;
506  }
507  else {
508  if (endofblockcheck < nearestneighbor) {
509  endofblockcheck++;
510  blocksize[nblocks]++;
511  }
512  //block has ended
513  else if (i + 2 < adcsize) { //check if end of adc vector is near
514  if (std::abs(adc[i + 1]) <= zerothresholdsigned &&
515  std::abs(adc[i + 2]) <= zerothresholdsigned) {
516  endofblockcheck = 0;
517  blockstartcheck = 0;
518  nblocks++;
519  }
520  }
521 
522  } // end else
523  } // end if blockstartcheck == 1
524  } // end loop over adc size
525 
526  if (blockstartcheck == 1) { // we reached the end of the adc vector with the block still going
527  ++nblocks;
528  }
529 
530  for (int i = 0; i < nblocks; ++i)
531  zerosuppressedsize += blocksize[i];
532 
533  adc.resize(2 + nblocks + nblocks + zerosuppressedsize);
534  zerosuppressed.resize(2 + nblocks + nblocks + zerosuppressedsize);
535 
536  int zerosuppressedcount = 0;
537  for (int i = 0; i < nblocks; ++i) {
538  //zerosuppressedsize += blocksize[i];
539  for (int j = 0; j < blocksize[i]; ++j) {
540  zerosuppressed[zerosuppressedcount] = adc[blockbegin[i] + j];
541  zerosuppressedcount++;
542  }
543  }
544 
545  adc[0] = adcsize; //fill first entry in adc with length of uncompressed vector
546  adc[1] = nblocks;
547  for (int i = 0; i < nblocks; ++i) {
548  adc[i + 2] = blockbegin[i];
549  adc[i + nblocks + 2] = blocksize[i];
550  }
551 
552  for (int i = 0; i < zerosuppressedsize; ++i)
553  adc[i + nblocks + nblocks + 2] = zerosuppressed[i];
554 
555  // for(int i = 0; i < 2 + 2*nblocks + zerosuppressedsize; ++i)
556  // std::cout << adc[i] << std::endl;
557  //adc.resize(2+nblocks+nblocks+zerosuppressedsize);
558  }
559 
560  //----------------------------------------------------------
561  // Zero suppression function which merges blocks if they are
562  // within parameter nearest neighbor of each other and makes
563  // blocks if neighboring wires have nonzero blocks there
564  // after subtracting pedestal values
565  void ZeroSuppression(const boost::circular_buffer<std::vector<short>>& adcvec_neighbors,
566  std::vector<short>& adc,
567  unsigned int& zerothreshold,
568  int pedestal,
569  int& nearestneighbor,
570  bool fADCStickyCodeFeature)
571  {
572 
573  const int adcsize = adc.size();
574  const int zerothresholdsigned = zerothreshold;
575 
576  std::vector<short> zerosuppressed(adcsize);
577  const int maxblocks = adcsize / 2 + 1;
578  std::vector<short> blockbegin(maxblocks);
579  std::vector<short> blocksize(maxblocks);
580 
581  int nblocks = 0;
582  int zerosuppressedsize = 0;
583 
584  int blockstartcheck = 0;
585  int endofblockcheck = 0;
586 
587  for (int i = 0; i < adcsize; ++i) {
588 
589  //find maximum adc value among all neighboring channels within the nearest neighbor channel distance
590 
591  int adc_current_value = ADCStickyCodeCheck(adc[i], pedestal, fADCStickyCodeFeature);
592 
593  for (boost::circular_buffer<std::vector<short>>::const_iterator adcveciter =
594  adcvec_neighbors.begin();
595  adcveciter != adcvec_neighbors.end();
596  ++adcveciter) {
597  const std::vector<short>& adcvec_current = *adcveciter;
598  const int adcvec_current_single = std::abs(adcvec_current[i] - pedestal);
599 
600  if (adc_current_value < adcvec_current_single) {
601  adc_current_value = adcvec_current_single;
602  }
603  }
604  if (blockstartcheck == 0) {
605  if (adc_current_value > zerothresholdsigned) {
606  if (nblocks > 0) {
607  if (i - nearestneighbor <= blockbegin[nblocks - 1] + blocksize[nblocks - 1] + 1) {
608  nblocks--;
609  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
610  blockstartcheck = 1;
611  }
612  else {
613  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
614  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
615  blockstartcheck = 1;
616  }
617  }
618  else {
619  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
620  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
621  blockstartcheck = 1;
622  }
623  }
624  }
625  else if (blockstartcheck == 1) {
626  if (adc_current_value > zerothresholdsigned) {
627  blocksize[nblocks]++;
628  endofblockcheck = 0;
629  }
630  else {
631  if (endofblockcheck < nearestneighbor) {
632  endofblockcheck++;
633  blocksize[nblocks]++;
634  }
635  //block has ended
636 
637  else if (i + 2 < adcsize) { //check if end of adc vector is near
638  if (ADCStickyCodeCheck(adc[i + 1], pedestal, fADCStickyCodeFeature) <=
639  zerothresholdsigned &&
640  ADCStickyCodeCheck(adc[i + 2], pedestal, fADCStickyCodeFeature) <=
641  zerothresholdsigned) {
642  endofblockcheck = 0;
643  blockstartcheck = 0;
644  nblocks++;
645  }
646  }
647 
648  } // end else
649  } // end if blockstartcheck == 1
650  } // end loop over adc size
651 
652  if (blockstartcheck == 1) { // we reached the end of the adc vector with the block still going
653  ++nblocks;
654  }
655 
656  for (int i = 0; i < nblocks; ++i)
657  zerosuppressedsize += blocksize[i];
658 
659  adc.resize(2 + nblocks + nblocks + zerosuppressedsize);
660  zerosuppressed.resize(2 + nblocks + nblocks + zerosuppressedsize);
661 
662  int zerosuppressedcount = 0;
663  for (int i = 0; i < nblocks; ++i) {
664  //zerosuppressedsize += blocksize[i];
665  for (int j = 0; j < blocksize[i]; ++j) {
666  zerosuppressed[zerosuppressedcount] = adc[blockbegin[i] + j];
667  zerosuppressedcount++;
668  }
669  }
670 
671  adc[0] = adcsize; //fill first entry in adc with length of uncompressed vector
672  adc[1] = nblocks;
673  for (int i = 0; i < nblocks; ++i) {
674  adc[i + 2] = blockbegin[i];
675  adc[i + nblocks + 2] = blocksize[i];
676  }
677 
678  for (int i = 0; i < zerosuppressedsize; ++i)
679  adc[i + nblocks + nblocks + 2] = zerosuppressed[i];
680 
681  // for(int i = 0; i < 2 + 2*nblocks + zerosuppressedsize; ++i)
682  // std::cout << adc[i] << std::endl;
683  //adc.resize(2+nblocks+nblocks+zerosuppressedsize);
684  }
685 
686  //----------------------------------------------------------
687  // Reverse zero suppression function
688  void ZeroUnsuppression(const std::vector<short>& adc, std::vector<short>& uncompressed)
689  {
690  const int lengthofadc = adc[0];
691  const int nblocks = adc[1];
692 
693  uncompressed.resize(lengthofadc);
694  for (int i = 0; i < lengthofadc; ++i) {
695  uncompressed[i] = 0;
696  }
697 
698  int zerosuppressedindex = nblocks * 2 + 2;
699 
700  for (int i = 0; i < nblocks; ++i) { //loop over each nonzero block of the compressed vector
701 
702  for (int j = 0; j < adc[2 + nblocks + i]; ++j) { //loop over each block size
703 
704  //set uncompressed value
705  uncompressed[adc[2 + i] + j] = adc[zerosuppressedindex];
706  zerosuppressedindex++;
707  }
708  }
709 
710  return;
711  }
712 
713  //----------------------------------------------------------
714  // Reverse zero suppression function with pedestal re-addition
715  void ZeroUnsuppression(const std::vector<short>& adc,
716  std::vector<short>& uncompressed,
717  int pedestal)
718  {
719  const int lengthofadc = adc[0];
720  const int nblocks = adc[1];
721 
722  uncompressed.resize(lengthofadc);
723  for (int i = 0; i < lengthofadc; ++i) {
724  uncompressed[i] = pedestal;
725  }
726 
727  int zerosuppressedindex = nblocks * 2 + 2;
728 
729  for (int i = 0; i < nblocks; ++i) { //loop over each nonzero block of the compressed vector
730 
731  for (int j = 0; j < adc[2 + nblocks + i]; ++j) { //loop over each block size
732 
733  //set uncompressed value
734  uncompressed[adc[2 + i] + j] = adc[zerosuppressedindex];
735  zerosuppressedindex++;
736  }
737  }
738 
739  return;
740  }
741 
742  //----------------------------------------------------------
743  // if the compression type is kNone, copy the adc vector into the uncompressed vector
744  void Uncompress(const std::vector<short>& adc,
745  std::vector<short>& uncompressed,
746  raw::Compress_t compress)
747  {
748  if (compress == raw::kHuffman)
749  UncompressHuffman(adc, uncompressed);
750  else if (compress == raw::kZeroSuppression) {
751  ZeroUnsuppression(adc, uncompressed);
752  }
753  else if (compress == raw::kZeroHuffman) {
754  std::vector<short> tmp(2 * adc[0]);
755  UncompressHuffman(adc, tmp);
756  ZeroUnsuppression(tmp, uncompressed);
757  }
758  else if (compress == raw::kNone) {
759  for (unsigned int i = 0; i < adc.size(); ++i)
760  uncompressed[i] = adc[i];
761  }
762  else if (compress == raw::kFibonacci) {
763  UncompressFibonacci(adc, uncompressed);
764  }
765  else {
766  throw cet::exception("raw") << "raw::Uncompress() does not support compression #"
767  << ((int)compress);
768  }
769  return;
770  }
771 
772  //----------------------------------------------------------
773  // if the compression type is kNone, copy the adc vector into the uncompressed vector
774  void Uncompress(const std::vector<short>& adc,
775  std::vector<short>& uncompressed,
776  int pedestal,
777  raw::Compress_t compress)
778  {
779  if (compress == raw::kHuffman)
780  UncompressHuffman(adc, uncompressed);
781  else if (compress == raw::kZeroSuppression) {
782  ZeroUnsuppression(adc, uncompressed, pedestal);
783  }
784  else if (compress == raw::kZeroHuffman) {
785  std::vector<short> tmp(2 * adc[0]);
786  UncompressHuffman(adc, tmp);
787  ZeroUnsuppression(tmp, uncompressed, pedestal);
788  }
789  else if (compress == raw::kNone) {
790  for (unsigned int i = 0; i < adc.size(); ++i)
791  uncompressed[i] = adc[i];
792  }
793  else if (compress == raw::kFibonacci) {
794  UncompressFibonacci(adc, uncompressed);
795  }
796  else {
797  throw cet::exception("raw") << "raw::Uncompress() does not support compression #"
798  << ((int)compress);
799  }
800  return;
801  }
802 
803  // the current Huffman Coding scheme used by uBooNE is
804  // based on differences between adc values in adjacent time bins
805  // the code is
806  // no change for 4 ticks --> 1
807  // no change for 1 tick --> 01
808  // +1 change --> 001
809  // -1 change --> 0001
810  // +2 change --> 00001
811  // -2 change --> 000001
812  // +3 change --> 0000001
813  // -3 change --> 00000001
814  // abs(change) > 3 --> write actual value to short
815  // use 15th bit to set whether a block is encoded or raw value
816  // 1 --> Huffman coded, 0 --> raw
817  // pad out the lowest bits in a word with 0's
818  void CompressHuffman(std::vector<short>& adc)
819  {
820  std::vector<short> const orig_adc(std::move(adc));
821 
822  // diffs contains the difference between an element of adc and the previous
823  // one; the first entry is never used.
824  std::vector<short> diffs;
825  diffs.reserve(orig_adc.size());
826  std::adjacent_difference(orig_adc.begin(), orig_adc.end(), std::back_inserter(diffs));
827 
828  // prepare adc for the new data; we kind-of-expect the size,
829  // so we pre-allocate it; we might want to shrink-to-fit at the end
830  adc.clear();
831  adc.reserve(orig_adc.size());
832  // now loop over the diffs and do the Huffman encoding
833  adc.push_back(orig_adc.front());
834  unsigned int curb = 15U;
835 
836  std::bitset<16> bset;
837  bset.set(15);
838 
839  for (size_t i = 1U; i < diffs.size(); ++i) {
840 
841  switch (diffs[i]) {
842  // if the difference is 0, check to see what the next 3 differences are
843  case 0: {
844  if (i < diffs.size() - 3) {
845  // if next 3 are also 0, set the next bit to be 1
846  if (diffs[i + 1] == 0 && diffs[i + 2] == 0 && diffs[i + 3] == 0) {
847  if (curb > 0) {
848  --curb;
849  bset.set(curb);
850  i += 3;
851  continue;
852  }
853  else {
854  adc.push_back(bset.to_ulong());
855 
856  // reset the bitset to be ready for the next word
857  bset.reset();
858  bset.set(15);
859  bset.set(14); // account for the fact that this is a zero diff
860  curb = 14;
861  i += 3;
862  continue;
863  } // end if curb is not big enough to put current difference in bset
864  } // end if next 3 are also zero
865  else {
866  // 0 diff is encoded as 01, so move the current bit one to the right
867  if (curb > 1) {
868  curb -= 2;
869  bset.set(curb);
870  continue;
871  } // end if the current bit is large enough to set this one
872  else {
873  adc.push_back(bset.to_ulong());
874  // reset the bitset to be ready for the next word
875  bset.reset();
876  bset.set(15);
877  bset.set(13); // account for the fact that this is a zero diff
878  curb = 13;
879  continue;
880  } // end if curb is not big enough to put current difference in bset
881  } // end if next 3 are not also 0
882  } // end if able to check next 3
883  else {
884  // 0 diff is encoded as 01, so move the current bit one to the right
885  if (curb > 1) {
886  curb -= 2;
887  bset.set(curb);
888  continue;
889  } // end if the current bit is large enough to set this one
890  else {
891  adc.push_back(bset.to_ulong());
892  // reset the bitset to be ready for the next word
893  bset.reset();
894  bset.set(15);
895  bset.set(13); // account for the fact that this is a zero diff
896  curb = 13;
897  continue;
898  } // end if curb is not big enough to put current difference in bset
899  } // end if not able to check the next 3
900  break;
901  } // end if current difference is zero
902  case 1: {
903  if (curb > 2) {
904  curb -= 3;
905  bset.set(curb);
906  }
907  else {
908  adc.push_back(bset.to_ulong());
909  // reset the bitset to be ready for the next word
910  bset.reset();
911  bset.set(15);
912  bset.set(12); // account for the fact that this is a +1 diff
913  curb = 12;
914  } // end if curb is not big enough to put current difference in bset
915  break;
916  } // end if difference = 1
917  case -1: {
918  if (curb > 3) {
919  curb -= 4;
920  bset.set(curb);
921  }
922  else {
923  adc.push_back(bset.to_ulong());
924  // reset the bitset to be ready for the next word
925  bset.reset();
926  bset.set(15);
927  bset.set(11); // account for the fact that this is a -1 diff
928  curb = 11;
929  } // end if curb is not big enough to put current difference in bset
930  break;
931  } // end if difference = -1
932  case 2: {
933  if (curb > 4) {
934  curb -= 5;
935  bset.set(curb);
936  }
937  else {
938  adc.push_back(bset.to_ulong());
939  // reset the bitset to be ready for the next word
940  bset.reset();
941  bset.set(15);
942  bset.set(10); // account for the fact that this is a +2 diff
943  curb = 10;
944  } // end if curb is not big enough to put current difference in bset
945  break;
946  } // end if difference = 2
947  case -2: {
948  if (curb > 5) {
949  curb -= 6;
950  bset.set(curb);
951  }
952  else {
953  adc.push_back(bset.to_ulong());
954  // reset the bitset to be ready for the next word
955  bset.reset();
956  bset.set(15);
957  bset.set(9); // account for the fact that this is a -2 diff
958  curb = 9;
959  } // end if curb is not big enough to put current difference in bset
960  break;
961  } // end if difference = -2
962  case 3: {
963  if (curb > 6) {
964  curb -= 7;
965  bset.set(curb);
966  }
967  else {
968  adc.push_back(bset.to_ulong());
969  // reset the bitset to be ready for the next word
970  bset.reset();
971  bset.set(15);
972  bset.set(8); // account for the fact that this is a +3 diff
973  curb = 8;
974  } // end if curb is not big enough to put current difference in bset
975  break;
976  } // end if difference = 3
977  case -3: {
978  if (curb > 7) {
979  curb -= 8;
980  bset.set(curb);
981  }
982  else {
983  adc.push_back(bset.to_ulong());
984  // reset the bitset to be ready for the next word
985  bset.reset();
986  bset.set(15);
987  bset.set(7); // account for the fact that this is a -3 diff
988  curb = 7;
989  } // end if curb is not big enough to put current difference in bset
990  break;
991  } // end if difference = -3
992  default: {
993  // if the difference is too large that we have to put the entire adc value in:
994  // put the current value into the adc vec unless the current bit is 15, then there
995  // were multiple large difference values in a row
996  if (curb != 15) { adc.push_back(bset.to_ulong()); }
997 
998  bset.reset();
999  bset.set(15);
1000  curb = 15;
1001 
1002  // put the current adcvalue in adc, with its bit 15 set to 0
1003  if (orig_adc[i] > 0)
1004  adc.push_back(orig_adc[i]);
1005  else {
1006  std::bitset<16> tbit(-orig_adc[i]);
1007  tbit.set(14);
1008  adc.push_back(tbit.to_ulong());
1009  }
1010  break;
1011  } // if |difference| > 3
1012  } // switch diff[i]
1013  } // end loop over differences
1014 
1015  //write out the last bitset
1016  adc.push_back(bset.to_ulong());
1017 
1018  // this would reduce global memory usage,
1019  // at the cost of a new allocation and copy
1020  // adc.shrink_to_fit();
1021 
1022  } // CompressHuffman()
1023  //--------------------------------------------------------
1024  // need to decrement the bit you are looking at to determine the deltas as that is how
1025  // the bits are set
1026  void UncompressHuffman(const std::vector<short>& adc, std::vector<short>& uncompressed)
1027  {
1028 
1029  //the first entry in adc is a data value by construction
1030  uncompressed[0] = adc[0];
1031 
1032  unsigned int curu = 1;
1033  short curADC = uncompressed[0];
1034 
1035  // loop over the entries in adc and uncompress them according to the
1036  // encoding scheme above the CompressHuffman method
1037  for (unsigned int i = 1; i < adc.size() && curu < uncompressed.size(); ++i) {
1038 
1039  std::bitset<16> bset(adc[i]);
1040 
1041  int numu = 0;
1042 
1043  //check the 15 bit to see if this entry is a full data value or not
1044  if (!bset.test(15)) {
1045  curADC = adc[i];
1046  if (bset.test(14)) {
1047  bset.set(14, false);
1048  curADC = -1 * bset.to_ulong();
1049  }
1050  uncompressed[curu] = curADC;
1051 
1052  ++curu;
1053  }
1054  else {
1055 
1056  int b = 14;
1057  int lowestb = 0;
1058 
1059  // ignore any padding with zeros in the lower order bits
1060  while (!bset.test(lowestb) && lowestb < 15)
1061  ++lowestb;
1062 
1063  if (lowestb > 14) {
1064  mf::LogWarning("raw.cxx")
1065  << "encoded entry has no set bits!!! " << i << " "
1066  << bset.to_string<char, std::char_traits<char>, std::allocator<char>>();
1067  continue;
1068  }
1069 
1070  while (b >= lowestb) {
1071 
1072  // count the zeros between the current bit and the next on bit
1073  int zerocnt = 0;
1074  while (!bset.test(b - zerocnt) && b - zerocnt > lowestb)
1075  ++zerocnt;
1076 
1077  b -= zerocnt;
1078 
1079  if (zerocnt == 0) {
1080  for (int s = 0; s < 4; ++s) {
1081  uncompressed[curu] = curADC;
1082  ++curu;
1083  ++numu;
1084  if (curu > uncompressed.size() - 1) break;
1085  }
1086  --b;
1087  }
1088  else if (zerocnt == 1) {
1089  uncompressed[curu] = curADC;
1090  ++curu;
1091  ++numu;
1092  --b;
1093  }
1094  else if (zerocnt == 2) {
1095  curADC += 1;
1096  uncompressed[curu] = curADC;
1097  ++curu;
1098  ++numu;
1099  --b;
1100  }
1101  else if (zerocnt == 3) {
1102  curADC -= 1;
1103  uncompressed[curu] = curADC;
1104  ++curu;
1105  ++numu;
1106  --b;
1107  }
1108  else if (zerocnt == 4) {
1109  curADC += 2;
1110  uncompressed[curu] = curADC;
1111  ++curu;
1112  ++numu;
1113  --b;
1114  }
1115  else if (zerocnt == 5) {
1116  curADC -= 2;
1117  uncompressed[curu] = curADC;
1118  ++curu;
1119  ++numu;
1120  --b;
1121  }
1122  else if (zerocnt == 6) {
1123  curADC += 3;
1124  uncompressed[curu] = curADC;
1125  ++curu;
1126  ++numu;
1127  --b;
1128  }
1129  else if (zerocnt == 7) {
1130  curADC -= 3;
1131  uncompressed[curu] = curADC;
1132  ++curu;
1133  ++numu;
1134  --b;
1135  }
1136 
1137  if (curu > uncompressed.size() - 1) break;
1138 
1139  } // end loop over bits
1140 
1141  if (curu > uncompressed.size() - 1) break;
1142 
1143  } // end if this entry in the vector is encoded
1144 
1145  } // end loop over entries in adc
1146 
1147  return;
1148  }
1149 
1150  //--------------------------------------------------------
1151  // need to decrement the bit you are looking at to determine the deltas as that is how
1152  // the bits are set
1153  int ADCStickyCodeCheck(const short adc_value, const int pedestal, bool fADCStickyCodeFeature)
1154  {
1155 
1156  int adc_return_value = std::abs(adc_value - pedestal);
1157 
1158  if (!fADCStickyCodeFeature) { return adc_return_value; }
1159  // if DUNE 35t ADC sticky code feature is enabled in simulation, skip over ADC codes with LSBs of 0x00 or 0x3f
1160  unsigned int sixlsbs = adc_value & onemask;
1161 
1162  if ((sixlsbs == onemask || sixlsbs == 0) && std::abs(adc_value - pedestal) < 64) {
1163  adc_return_value =
1164  0; //set current adc value to zero if its LSBs are at sticky values and if it is within one MSB cell (64 ADC counts) of the pedestal value
1165  }
1166  return adc_return_value;
1167  }
1168 
1169  inline void add_to_sequence_terminate(std::vector<bool> array, std::vector<bool>& cmp)
1170  {
1171  cmp.insert(cmp.end(), array.begin(), array.end());
1172  cmp.push_back(1);
1173  }
1174 
1175  void CompressFibonacci(std::vector<short>& wf,
1176  std::function<void(int, std::vector<std::vector<bool>>&)> add_to_table)
1177  {
1178 
1179  std::vector<std::vector<bool>> table;
1180  add_to_table(100, table);
1181 
1182  std::vector<short> comp_short;
1183  // First numbers are not encoded (size and baseline)
1184  assert(not empty(wf));
1185 
1186  unsigned int size_short = sizeof(wf[0]) * 8 - 1; // assuming we don't encode over the sign bits
1187  unsigned int max_2_short =
1188  (1 << (size_short *
1189  2)); //this number is then: 1,073,741,824 (i.e. almost 9min of data at 2MHz)
1190  size_t wf_size = wf.size();
1191 
1192  if (wf_size > max_2_short) {
1193  throw cet::exception("raw")
1194  << "WOW! You are trying to compress a " << wf_size << " long waveform"
1195  << " in a vector of shorts.\nUnfortunately, the encoded waveform needs to store the size"
1196  << " of the wavefom (in its first number) and " << wf_size
1197  << " is bigger than the maximum\n"
1198  << " number you can encode with 2 shorts (" << max_2_short << ").\n"
1199  << " Bailing out disgracefully to avoid massive trouble.\n";
1200  }
1201 
1202  short high = (wf_size >> (sizeof(short) * 8 - 1));
1203  short low = wf_size % ((std::numeric_limits<short>::max() + 1));
1204  comp_short.push_back(high);
1205  comp_short.push_back(low);
1206  comp_short.push_back(*wf.begin());
1207 
1208  // The format we are working with
1209  std::vector<bool> cmp;
1210  cmp.reserve(wf.size() * sizeof(wf[0]) * 8);
1211 
1212  // The input is changed to be the difference between ticks
1213  std::vector<short> diff;
1214  diff.reserve(wf.size());
1215  // Fibonacci number are positive, so need a way to get negative number
1216  // We use the ZigZag approach (even numbers are positive, odd are negative)
1217  std::adjacent_difference(
1218  wf.begin(), wf.end(), std::back_inserter(diff), [](const short& it1, const short& it2) {
1219  short d = it1 - it2;
1220  if (d > 0)
1221  d = 2 * d;
1222  else
1223  d = -2 * d + 1;
1224  return d;
1225  });
1226 
1227  // Start from 1 to avoid the first number
1228  for (size_t iSample = 1; iSample < diff.size(); ++iSample) {
1229 
1230  short d = diff[iSample];
1231  if ((unsigned)d < table.size()) { add_to_sequence_terminate(table[d], cmp); }
1232  else { // catch if the table is too small...
1233  int end = d + 1;
1234  // use the user provided function to fill the table
1235  add_to_table(end, table);
1236  // and add again to the sequence
1237  add_to_sequence_terminate(table[d], cmp);
1238  }
1239  }
1240 
1241  // Now convert all this to a vector of short and it's just another day in paradise for larsoft
1242  size_t n_vector = cmp.size();
1243 
1244  // Create a bitset of the size of the short to simplify things
1245  std::bitset<8 * sizeof(short)> this_encoded;
1246  // Set the bitset to match the stream
1247  size_t bit_counter = 0;
1248 
1249  for (size_t it = 0; it < n_vector; ++it) {
1250 
1251  if (bit_counter >= 8 * sizeof(short)) {
1252  short comp_s = (short)this_encoded.to_ulong();
1253  comp_short.push_back(comp_s);
1254  bit_counter = 0;
1255  this_encoded.reset();
1256  }
1257 
1258  if (cmp[it]) this_encoded.set(bit_counter);
1259 
1260  bit_counter++;
1261  }
1262 
1263  // Deal with the last part
1264  short comp_s = (short)this_encoded.to_ulong();
1265  comp_short.push_back(comp_s);
1266 
1267  wf = comp_short;
1268 
1269  return;
1270  }
1271 
1272  void UncompressFibonacci(const std::vector<short>& adc,
1273  std::vector<short>& uncompressed,
1274  std::function<int(std::vector<bool>&)> decode_table_chunk)
1275  {
1276 
1277  // First compressed sample is the size
1278  size_t n_samples = (adc[0] << (sizeof(short) * 8 - 1)) + adc[1];
1279  // The second compressed sample is the first uncompressed sample
1280  uncompressed.push_back(adc[2]);
1281 
1282  // The thing that we want to decode (rather than jumbled short vector)
1283  std::vector<bool> comp;
1284 
1285  for (size_t i = 3; i < adc.size(); ++i) {
1286 
1287  std::bitset<8 * sizeof(short)> this_encoded(adc[i]);
1288  for (size_t i2 = 0; i2 < this_encoded.size(); ++i2) {
1289  comp.push_back(this_encoded[i2]);
1290  }
1291  }
1292 
1293  // The bit which has to be decoded ("chunk")
1294  std::vector<bool> current_number;
1295  for (size_t it = 0; it < comp.size(); ++it) {
1296  current_number.push_back(comp[it]);
1297  // If we have at least 2 numbers in the current chunk
1298  // and if the last 2 number are one
1299  // and if we are not at the end
1300  if ((current_number.size() >= 2 && it >= 1 && comp[it - 1] == 1 && comp[it] == 1) ||
1301  it == comp.size() - 1) {
1302  current_number.pop_back();
1303  short zigzag_number = decode_table_chunk(current_number);
1304 
1305  short decoded = 0;
1306  if (zigzag_number % 2 == 0)
1307  decoded = zigzag_number / 2;
1308  else
1309  decoded = -(zigzag_number - 1) / 2;
1310  short baseline = uncompressed.back();
1311 
1312  uncompressed.push_back(baseline + decoded);
1313 
1314  current_number.clear();
1315  if (uncompressed.size() == n_samples) break;
1316  }
1317  }
1318  return;
1319  }
1320 
1321  void fibonacci_encode_table(int end, std::vector<std::vector<bool>>& table)
1322  {
1323  if ((int)table.size() > end) return;
1324 
1325  std::map<int, int> fibn; // no need for this to be static
1326  fibn[0] = 0;
1327  fibn[1] = 1;
1328  fibn[2] = 1;
1329 
1330  // if the table was empty, fill it
1331  if (empty(table)) {
1332  table.push_back(
1333  std::vector<
1334  bool>()); // we need this one so that the index of the vector is the same as the number we want to encode
1335  table.push_back({true});
1336  table.push_back({false, true});
1337  }
1338 
1339  if ((int)table.size() > end) return;
1340 
1341  // start at the third fibonacci number
1342  for (int i = 2; fibn.rbegin()->second < end; ++i) {
1343  fibn[i] = fibn[i - 1] + fibn[i - 2];
1344  }
1345 
1346  for (int i = table.size(); i <= end; ++i) {
1347  int current_number = i;
1348  std::vector<bool> seq; // the final sequence of numbers
1349  while (current_number > 0) {
1350  // find the biggest fibonacci number that is smaller than the current number
1351  for (auto fib = fibn.rbegin(); fib != fibn.rend(); ++fib) {
1352  if (fib->second <= current_number) {
1353  // if this is the first number, create the vector
1354  if (!seq.size()) seq = std::vector<bool>(fib->first - 1, false);
1355  // fill the sequence
1356  seq[fib->first - 2] = true;
1357  // subtract the current number
1358  current_number -= fib->second;
1359  break;
1360  }
1361  }
1362  }
1363 
1364  table.push_back(seq);
1365  }
1366  }
1367 
1368  short fibonacci_decode(std::vector<bool>& chunk)
1369  {
1370  std::vector<int> FibNumbers = {1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987};
1371 
1372  if (chunk.size() > FibNumbers.size()) {
1373  for (int i = FibNumbers.size(); i <= (int)chunk.size(); ++i) {
1374  FibNumbers.push_back(FibNumbers.at(i - 1) + FibNumbers.at(i - 2));
1375  }
1376  }
1377  short decoded = 0;
1378  for (size_t it = 0; it < chunk.size(); ++it) {
1379  if (chunk[it]) decoded += FibNumbers[it];
1380  }
1381  return decoded;
1382  }
1383 }
void CompressHuffman(std::vector< short > &adc)
Definition: raw.cxx:818
Huffman Encoding.
Definition: RawTypes.h:10
enum raw::_compress Compress_t
void UncompressHuffman(const std::vector< short > &adc, std::vector< short > &uncompressed)
Definition: raw.cxx:1026
constexpr auto abs(T v)
Returns the absolute value of the argument.
const unsigned int onemask
Definition: raw.h:129
Zero Suppression followed by Huffman Encoding.
Definition: RawTypes.h:12
Raw data description.
Definition: RawTypes.h:6
Float_t tmp
Definition: plot.C:35
no compression
Definition: RawTypes.h:9
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
Zero Suppression algorithm.
Definition: RawTypes.h:11
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
int ADCStickyCodeCheck(const short adc_value, const int pedestal, bool fADCStickyCodeFeature)
Definition: raw.cxx:1153
auto array(Array const &a)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:250
void fibonacci_encode_table(int end, std::vector< std::vector< bool >> &table)
Definition: raw.cxx:1321
Collect all the RawData header files together.
Float_t d
Definition: plot.C:235
void ZeroUnsuppression(const std::vector< short > &adc, std::vector< short > &uncompressed)
Definition: raw.cxx:688
void add_to_sequence_terminate(std::vector< bool > array, std::vector< bool > &cmp)
Definition: raw.cxx:1169
Fibonacci encoding.
Definition: RawTypes.h:14
void UncompressFibonacci(const std::vector< short > &adc, std::vector< short > &uncompressed, std::function< int(std::vector< bool > &)> decode_table_chunk)
Definition: raw.cxx:1272
void CompressFibonacci(std::vector< short > &wf, std::function< void(int, std::vector< std::vector< bool >> &)> add_to_table)
Definition: raw.cxx:1175
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void Compress(std::vector< short > &adc, raw::Compress_t compress)
Compresses a raw data buffer.
Definition: raw.cxx:19
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:744
void ZeroSuppression(std::vector< short > &adc, unsigned int &zerothreshold)
Definition: raw.cxx:171
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:109
short fibonacci_decode(std::vector< bool > &chunk)
Definition: raw.cxx:1368