LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
raw.cxx
Go to the documentation of this file.
1 
7 
8 #include <iostream>
9 #include <string>
10 #include <bitset>
11 #include <numeric> // std::adjacent_difference()
12 #include <iterator> // std::back_inserter()
13 
14 #include "cetlib_except/exception.h"
16 
17 namespace raw {
18 
19  //----------------------------------------------------------
20  void Compress(std::vector<short> &adc,
21  raw::Compress_t compress)
22  {
23  if(compress == raw::kHuffman) CompressHuffman(adc);
24  else if(compress == raw::kZeroHuffman){
25  unsigned int zerothreshold = 5;
26  ZeroSuppression(adc,zerothreshold);
27  CompressHuffman(adc);
28  }
29  else if(compress == raw::kZeroSuppression){
30  unsigned int zerothreshold = 5;
31  ZeroSuppression(adc,zerothreshold);
32  }
33 
34 
35  return;
36  }
37  //----------------------------------------------------------
38  void Compress(std::vector<short> &adc,
39  raw::Compress_t compress,
40  int &nearestneighbor)
41  {
42  if(compress == raw::kHuffman) 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 
53 
54  return;
55  }
56 
57  //----------------------------------------------------------
58  void Compress(std::vector<short> &adc,
59  raw::Compress_t compress,
60  unsigned int &zerothreshold)
61  {
62  if(compress == raw::kHuffman) CompressHuffman(adc);
63 
64  else if(compress == raw::kZeroSuppression) ZeroSuppression(adc,zerothreshold);
65  else if(compress == raw::kZeroHuffman){
66  ZeroSuppression(adc,zerothreshold);
67  CompressHuffman(adc);
68  }
69 
70  return;
71  }
72  //----------------------------------------------------------
73  void Compress(std::vector<short> &adc,
74  raw::Compress_t compress,
75  unsigned int &zerothreshold,
76  int &nearestneighbor)
77  {
78  if(compress == raw::kHuffman)
79  CompressHuffman(adc);
80  else if(compress == raw::kZeroSuppression)
81  ZeroSuppression(adc,zerothreshold, nearestneighbor);
82  else if(compress == raw::kZeroHuffman){
83  ZeroSuppression(adc,zerothreshold, nearestneighbor);
84  CompressHuffman(adc);
85  }
86 
87  return;
88  }
89 
90  //----------------------------------------------------------
91  void Compress(const boost::circular_buffer<std::vector<short>> &adcvec_neighbors,
92  std::vector<short> &adc,
93  raw::Compress_t compress,
94  unsigned int &zerothreshold,
95  int &nearestneighbor)
96  {
97  if(compress == raw::kHuffman)
98  CompressHuffman(adc);
99  else if(compress == raw::kZeroSuppression)
100  ZeroSuppression(adcvec_neighbors,adc,zerothreshold, nearestneighbor);
101  else if(compress == raw::kZeroHuffman){
102  ZeroSuppression(adcvec_neighbors,adc,zerothreshold, nearestneighbor);
103  CompressHuffman(adc);
104  }
105 
106  return;
107  }
108 
109  //----------------------------------------------------------
110  void Compress(std::vector<short> &adc,
111  raw::Compress_t compress,
112  unsigned int &zerothreshold,
113  int pedestal,
114  int &nearestneighbor,
115  bool fADCStickyCodeFeature)
116  {
117  if(compress == raw::kHuffman)
118  CompressHuffman(adc);
119  else if(compress == raw::kZeroSuppression)
120  ZeroSuppression(adc,zerothreshold, pedestal, nearestneighbor, fADCStickyCodeFeature);
121  else if(compress == raw::kZeroHuffman){
122  ZeroSuppression(adc,zerothreshold, pedestal, nearestneighbor, fADCStickyCodeFeature);
123  CompressHuffman(adc);
124  }
125 
126  return;
127  }
128 
129  //----------------------------------------------------------
130  void Compress(const boost::circular_buffer<std::vector<short>> &adcvec_neighbors,
131  std::vector<short> &adc,
132  raw::Compress_t compress,
133  unsigned int &zerothreshold,
134  int pedestal,
135  int &nearestneighbor,
136  bool fADCStickyCodeFeature)
137  {
138  if(compress == raw::kHuffman)
139  CompressHuffman(adc);
140  else if(compress == raw::kZeroSuppression)
141  ZeroSuppression(adcvec_neighbors,adc,zerothreshold, pedestal, nearestneighbor, fADCStickyCodeFeature);
142  else if(compress == raw::kZeroHuffman){
143  ZeroSuppression(adcvec_neighbors,adc,zerothreshold, pedestal, nearestneighbor, fADCStickyCodeFeature);
144  CompressHuffman(adc);
145  }
146 
147  return;
148  }
149 
150 
151  //----------------------------------------------------------
152  // Zero suppression function
153  void ZeroSuppression(std::vector<short> &adc,
154  unsigned int &zerothreshold)
155  {
156  const int adcsize = adc.size();
157  const int zerothresholdsigned = zerothreshold;
158 
159  std::vector<short> zerosuppressed(adc.size());
160  int maxblocks = adcsize/2 + 1;
161  std::vector<short> blockbegin(maxblocks);
162  std::vector<short> blocksize(maxblocks);
163 
164  unsigned int nblocks = 0;
165  unsigned int zerosuppressedsize = 0;
166 
167  int blockcheck = 0;
168 
169  for(int i = 0; i < adcsize; ++i){
170  int adc_current_value = std::abs(adc[i]);
171 
172  if(adc_current_value > zerothresholdsigned){
173 
174  if(blockcheck == 0){
175 
176  blockbegin[nblocks] = i;
177  blocksize[nblocks] = 0;
178  blockcheck=1;
179  }
180 
181  zerosuppressed[zerosuppressedsize] = adc[i];
182  zerosuppressedsize++;
183  blocksize[nblocks]++;
184 
185  if(i == adcsize-1) nblocks++;
186  }
187 
188  if(adc_current_value <= zerothresholdsigned && blockcheck == 1){
189  zerosuppressed[zerosuppressedsize] = adc[i];
190  zerosuppressedsize++;
191  blocksize[nblocks]++;
192  nblocks++;
193  blockcheck = 0;
194  }
195  }
196 
197 
198 
199  adc.resize(2+nblocks+nblocks+zerosuppressedsize);
200 
201  adc[0] = adcsize; //fill first entry in adc with length of uncompressed vector
202  adc[1] = nblocks;
203 
204 
205 
206  for(unsigned int i = 0; i < nblocks; ++i)
207  adc[i+2] = blockbegin[i];
208 
209  for(unsigned int i = 0; i < nblocks; ++i)
210  adc[i+nblocks+2] = blocksize[i];
211 
212  for(unsigned int i = 0; i < zerosuppressedsize; ++i)
213  adc[i+nblocks+nblocks+2] = zerosuppressed[i];
214 
215 
216  }
217 
218 
219 
220  //----------------------------------------------------------
221  // Zero suppression function which merges blocks if they are
222  // within parameter nearestneighbor of each other
223  void ZeroSuppression(std::vector<short> &adc,
224  unsigned int &zerothreshold,
225  int &nearestneighbor)
226  {
227 
228  const int adcsize = adc.size();
229  const int zerothresholdsigned = zerothreshold;
230 
231  std::vector<short> zerosuppressed(adcsize);
232  int maxblocks = adcsize/2 + 1;
233  std::vector<short> blockbegin(maxblocks);
234  std::vector<short> blocksize(maxblocks);
235 
236  int nblocks = 0;
237  int zerosuppressedsize = 0;
238 
239  int blockstartcheck = 0;
240  int endofblockcheck = 0;
241 
242  for(int i = 0; i < adcsize; ++i){
243  int adc_current_value = std::abs(adc[i]);
244 
245  if(blockstartcheck==0){
246  if(adc_current_value>zerothresholdsigned){
247  if(nblocks>0){
248  if((i-nearestneighbor)<=(blockbegin[nblocks-1]+blocksize[nblocks-1]+1)){
249 
250  nblocks--;
251  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
252  blockstartcheck = 1;
253  }
254  else{
255  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
256  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
257  blockstartcheck = 1;
258  }
259  }
260  else{
261  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
262  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
263  blockstartcheck = 1;
264  }
265  }
266  }
267  else if(blockstartcheck==1){
268  if(adc_current_value>zerothresholdsigned){
269  blocksize[nblocks]++;
270  endofblockcheck = 0;
271  }
272  else{
273  if(endofblockcheck<nearestneighbor){
274  endofblockcheck++;
275  blocksize[nblocks]++;
276  }
277  //block has ended
278  else if(i+2<adcsize){ //check if end of adc vector is near
279  if(std::abs(adc[i+1]) <= zerothresholdsigned && std::abs(adc[i+2]) <= zerothresholdsigned){
280  endofblockcheck = 0;
281  blockstartcheck = 0;
282  nblocks++;
283  }
284  }
285 
286 
287  } // end else
288  } // end if blockstartcheck == 1
289  }// end loop over adc size
290 
291  if(blockstartcheck==1){ // we reached the end of the adc vector with the block still going
292  ++nblocks;
293  }
294 
295  for(int i = 0; i < nblocks; ++i)
296  zerosuppressedsize += blocksize[i];
297 
298 
299  adc.resize(2+nblocks+nblocks+zerosuppressedsize);
300  zerosuppressed.resize(2+nblocks+nblocks+zerosuppressedsize);
301 
302 
303  int zerosuppressedcount = 0;
304  for(int i = 0; i < nblocks; ++i){
305  //zerosuppressedsize += blocksize[i];
306  for(int j = 0; j < blocksize[i]; ++j){
307  zerosuppressed[zerosuppressedcount] = adc[blockbegin[i] + j];
308  zerosuppressedcount++;
309  }
310  }
311 
312  adc[0] = adcsize; //fill first entry in adc with length of uncompressed vector
313  adc[1] = nblocks;
314  for(int i = 0; i < nblocks; ++i){
315  adc[i+2] = blockbegin[i];
316  adc[i+nblocks+2] = blocksize[i];
317  }
318 
319 
320 
321  for(int i = 0; i < zerosuppressedsize; ++i)
322  adc[i+nblocks+nblocks+2] = zerosuppressed[i];
323 
324 
325  // for(int i = 0; i < 2 + 2*nblocks + zerosuppressedsize; ++i)
326  // std::cout << adc[i] << std::endl;
327  //adc.resize(2+nblocks+nblocks+zerosuppressedsize);
328  }
329 
330  //----------------------------------------------------------
331  // Zero suppression function which merges blocks if they are
332  // within parameter nearestneighbor of each other
333  // after subtracting pedestal value
334  void ZeroSuppression(std::vector<short> &adc,
335  unsigned int &zerothreshold,
336  int pedestal,
337  int &nearestneighbor,
338  bool fADCStickyCodeFeature)
339  {
340 
341  const int adcsize = adc.size();
342  const int zerothresholdsigned = zerothreshold;
343 
344  std::vector<short> zerosuppressed(adcsize);
345  int maxblocks = adcsize/2 + 1;
346  std::vector<short> blockbegin(maxblocks);
347  std::vector<short> blocksize(maxblocks);
348 
349  int nblocks = 0;
350  int zerosuppressedsize = 0;
351 
352  int blockstartcheck = 0;
353  int endofblockcheck = 0;
354 
355  for(int i = 0; i < adcsize; ++i){
356  int adc_current_value = ADCStickyCodeCheck(adc[i],pedestal,fADCStickyCodeFeature);
357 
358  if(blockstartcheck==0){
359  if(adc_current_value>zerothresholdsigned){
360  if(nblocks>0){
361  if(i-nearestneighbor<=blockbegin[nblocks-1]+blocksize[nblocks-1]+1){
362  nblocks--;
363  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
364  blockstartcheck = 1;
365  }
366  else{
367  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
368  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
369  blockstartcheck = 1;
370  }
371  }
372  else{
373  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
374  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
375  blockstartcheck = 1;
376  }
377  }
378  }
379  else if(blockstartcheck==1){
380  if(adc_current_value>zerothresholdsigned){
381  blocksize[nblocks]++;
382  endofblockcheck = 0;
383  }
384  else{
385  if(endofblockcheck<nearestneighbor){
386  endofblockcheck++;
387  blocksize[nblocks]++;
388  }
389  //block has ended
390  else if(i+2<adcsize){ //check if end of adc vector is near
391  if(ADCStickyCodeCheck(adc[i+1],pedestal,fADCStickyCodeFeature) <= zerothresholdsigned && ADCStickyCodeCheck(adc[i+2],pedestal,fADCStickyCodeFeature) <= zerothresholdsigned){
392  endofblockcheck = 0;
393  blockstartcheck = 0;
394  nblocks++;
395  }
396  }
397  } // end else
398  } // end if blockstartcheck == 1
399  }// end loop over adc size
400 
401  if(blockstartcheck==1){ // we reached the end of the adc vector with the block still going
402  ++nblocks;
403  }
404 
405 
406  for(int i = 0; i < nblocks; ++i)
407  zerosuppressedsize += blocksize[i];
408 
409 
410  adc.resize(2+nblocks+nblocks+zerosuppressedsize);
411  zerosuppressed.resize(2+nblocks+nblocks+zerosuppressedsize);
412 
413 
414  int zerosuppressedcount = 0;
415  for(int i = 0; i < nblocks; ++i){
416  //zerosuppressedsize += blocksize[i];
417  for(int j = 0; j < blocksize[i]; ++j){
418  zerosuppressed[zerosuppressedcount] = adc[blockbegin[i] + j];
419  zerosuppressedcount++;
420  }
421  }
422 
423  adc[0] = adcsize; //fill first entry in adc with length of uncompressed vector
424  adc[1] = nblocks;
425  for(int i = 0; i < nblocks; ++i){
426  adc[i+2] = blockbegin[i];
427  adc[i+nblocks+2] = blocksize[i];
428  }
429 
430 
431 
432  for(int i = 0; i < zerosuppressedsize; ++i)
433  adc[i+nblocks+nblocks+2] = zerosuppressed[i];
434 
435 
436  // for(int i = 0; i < 2 + 2*nblocks + zerosuppressedsize; ++i)
437  // std::cout << adc[i] << std::endl;
438  //adc.resize(2+nblocks+nblocks+zerosuppressedsize);
439  }
440 
441  //----------------------------------------------------------
442  // Zero suppression function which merges blocks if they are
443  // within parameter nearest neighbor of each other and makes
444  // blocks if neighboring wires have nonzero blocks there
445  void ZeroSuppression(const boost::circular_buffer<std::vector<short>> &adcvec_neighbors,
446  std::vector<short> &adc,
447  unsigned int &zerothreshold,
448  int &nearestneighbor)
449  {
450 
451  const int adcsize = adc.size();
452  const int zerothresholdsigned = zerothreshold;
453 
454  std::vector<short> zerosuppressed(adcsize);
455  const int maxblocks = adcsize/2 + 1;
456  std::vector<short> blockbegin(maxblocks);
457  std::vector<short> blocksize(maxblocks);
458 
459  int nblocks = 0;
460  int zerosuppressedsize = 0;
461 
462  int blockstartcheck = 0;
463  int endofblockcheck = 0;
464 
465  for(int i = 0; i < adcsize; ++i){
466 
467  //find maximum adc value among all neighboring channels within the nearest neighbor channel distance
468 
469  int adc_current_value = 0;
470 
471  for(boost::circular_buffer<std::vector<short>>::const_iterator adcveciter = adcvec_neighbors.begin(); adcveciter!=adcvec_neighbors.end();++adcveciter){
472  const std::vector<short> &adcvec_current = *adcveciter;
473  const int adcvec_current_single = std::abs(adcvec_current[i]);
474 
475  if(adc_current_value < adcvec_current_single){
476  adc_current_value = adcvec_current_single;
477  }
478 
479  }
480  if(blockstartcheck==0){
481  if(adc_current_value>zerothresholdsigned){
482  if(nblocks>0){
483  if(i-nearestneighbor<=blockbegin[nblocks-1]+blocksize[nblocks-1]+1){
484  nblocks--;
485  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
486  blockstartcheck = 1;
487  }
488  else{
489  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
490  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
491  blockstartcheck = 1;
492  }
493  }
494  else{
495  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
496  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
497  blockstartcheck = 1;
498  }
499  }
500  }
501  else if(blockstartcheck==1){
502  if(adc_current_value>zerothresholdsigned){
503  blocksize[nblocks]++;
504  endofblockcheck = 0;
505  }
506  else{
507  if(endofblockcheck<nearestneighbor){
508  endofblockcheck++;
509  blocksize[nblocks]++;
510  }
511  //block has ended
512  else if(i+2<adcsize){ //check if end of adc vector is near
513  if(std::abs(adc[i+1]) <= zerothresholdsigned && std::abs(adc[i+2]) <= zerothresholdsigned){
514  endofblockcheck = 0;
515  blockstartcheck = 0;
516  nblocks++;
517  }
518  }
519 
520  } // end else
521  } // end if blockstartcheck == 1
522  }// end loop over adc size
523 
524  if(blockstartcheck==1){ // we reached the end of the adc vector with the block still going
525  ++nblocks;
526  }
527 
528 
529 
530  for(int i = 0; i < nblocks; ++i)
531  zerosuppressedsize += blocksize[i];
532 
533 
534  adc.resize(2+nblocks+nblocks+zerosuppressedsize);
535  zerosuppressed.resize(2+nblocks+nblocks+zerosuppressedsize);
536 
537 
538  int zerosuppressedcount = 0;
539  for(int i = 0; i < nblocks; ++i){
540  //zerosuppressedsize += blocksize[i];
541  for(int j = 0; j < blocksize[i]; ++j){
542  zerosuppressed[zerosuppressedcount] = adc[blockbegin[i] + j];
543  zerosuppressedcount++;
544  }
545  }
546 
547  adc[0] = adcsize; //fill first entry in adc with length of uncompressed vector
548  adc[1] = nblocks;
549  for(int i = 0; i < nblocks; ++i){
550  adc[i+2] = blockbegin[i];
551  adc[i+nblocks+2] = blocksize[i];
552  }
553 
554 
555 
556  for(int i = 0; i < zerosuppressedsize; ++i)
557  adc[i+nblocks+nblocks+2] = zerosuppressed[i];
558 
559 
560  // for(int i = 0; i < 2 + 2*nblocks + zerosuppressedsize; ++i)
561  // std::cout << adc[i] << std::endl;
562  //adc.resize(2+nblocks+nblocks+zerosuppressedsize);
563  }
564 
565  //----------------------------------------------------------
566  // Zero suppression function which merges blocks if they are
567  // within parameter nearest neighbor of each other and makes
568  // blocks if neighboring wires have nonzero blocks there
569  // after subtracting pedestal values
570  void ZeroSuppression(const boost::circular_buffer<std::vector<short>> &adcvec_neighbors,
571  std::vector<short> &adc,
572  unsigned int &zerothreshold,
573  int pedestal,
574  int &nearestneighbor,
575  bool fADCStickyCodeFeature)
576  {
577 
578  const int adcsize = adc.size();
579  const int zerothresholdsigned = zerothreshold;
580 
581  std::vector<short> zerosuppressed(adcsize);
582  const int maxblocks = adcsize/2 + 1;
583  std::vector<short> blockbegin(maxblocks);
584  std::vector<short> blocksize(maxblocks);
585 
586  int nblocks = 0;
587  int zerosuppressedsize = 0;
588 
589  int blockstartcheck = 0;
590  int endofblockcheck = 0;
591 
592  for(int i = 0; i < adcsize; ++i){
593 
594  //find maximum adc value among all neighboring channels within the nearest neighbor channel distance
595 
596  int adc_current_value = ADCStickyCodeCheck(adc[i],pedestal,fADCStickyCodeFeature);
597 
598  for(boost::circular_buffer<std::vector<short>>::const_iterator adcveciter = adcvec_neighbors.begin(); adcveciter!=adcvec_neighbors.end();++adcveciter){
599  const std::vector<short> &adcvec_current = *adcveciter;
600  const int adcvec_current_single = std::abs(adcvec_current[i] - pedestal);
601 
602  if(adc_current_value < adcvec_current_single){
603  adc_current_value = adcvec_current_single;
604  }
605 
606  }
607  if(blockstartcheck==0){
608  if(adc_current_value>zerothresholdsigned){
609  if(nblocks>0){
610  if(i-nearestneighbor<=blockbegin[nblocks-1]+blocksize[nblocks-1]+1){
611  nblocks--;
612  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
613  blockstartcheck = 1;
614  }
615  else{
616  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
617  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
618  blockstartcheck = 1;
619  }
620  }
621  else{
622  blockbegin[nblocks] = (i - nearestneighbor > 0) ? i - nearestneighbor : 0;
623  blocksize[nblocks] = i - blockbegin[nblocks] + 1;
624  blockstartcheck = 1;
625  }
626  }
627  }
628  else if(blockstartcheck==1){
629  if(adc_current_value>zerothresholdsigned){
630  blocksize[nblocks]++;
631  endofblockcheck = 0;
632  }
633  else{
634  if(endofblockcheck<nearestneighbor){
635  endofblockcheck++;
636  blocksize[nblocks]++;
637  }
638  //block has ended
639 
640  else if(i+2<adcsize){ //check if end of adc vector is near
641  if(ADCStickyCodeCheck(adc[i+1],pedestal,fADCStickyCodeFeature) <= zerothresholdsigned && ADCStickyCodeCheck(adc[i+2],pedestal,fADCStickyCodeFeature) <= 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 
657 
658  for(int i = 0; i < nblocks; ++i)
659  zerosuppressedsize += blocksize[i];
660 
661 
662  adc.resize(2+nblocks+nblocks+zerosuppressedsize);
663  zerosuppressed.resize(2+nblocks+nblocks+zerosuppressedsize);
664 
665 
666  int zerosuppressedcount = 0;
667  for(int i = 0; i < nblocks; ++i){
668  //zerosuppressedsize += blocksize[i];
669  for(int j = 0; j < blocksize[i]; ++j){
670  zerosuppressed[zerosuppressedcount] = adc[blockbegin[i] + j];
671  zerosuppressedcount++;
672  }
673  }
674 
675  adc[0] = adcsize; //fill first entry in adc with length of uncompressed vector
676  adc[1] = nblocks;
677  for(int i = 0; i < nblocks; ++i){
678  adc[i+2] = blockbegin[i];
679  adc[i+nblocks+2] = blocksize[i];
680  }
681 
682 
683 
684  for(int i = 0; i < zerosuppressedsize; ++i)
685  adc[i+nblocks+nblocks+2] = zerosuppressed[i];
686 
687 
688  // for(int i = 0; i < 2 + 2*nblocks + zerosuppressedsize; ++i)
689  // std::cout << adc[i] << std::endl;
690  //adc.resize(2+nblocks+nblocks+zerosuppressedsize);
691  }
692 
693 
694  //----------------------------------------------------------
695  // Reverse zero suppression function
696  void ZeroUnsuppression(const std::vector<short>& adc,
697  std::vector<short> &uncompressed)
698  {
699  const int lengthofadc = adc[0];
700  const int nblocks = adc[1];
701 
702  uncompressed.resize(lengthofadc);
703  for (int i = 0;i < lengthofadc; ++i){
704  uncompressed[i] = 0;
705  }
706 
707  int zerosuppressedindex = nblocks*2 + 2;
708 
709  for(int i = 0; i < nblocks; ++i){ //loop over each nonzero block of the compressed vector
710 
711  for(int j = 0; j < adc[2+nblocks+i]; ++j){//loop over each block size
712 
713  //set uncompressed value
714  uncompressed[adc[2+i]+j] = adc[zerosuppressedindex];
715  zerosuppressedindex++;
716 
717  }
718  }
719 
720  return;
721  }
722 
723  //----------------------------------------------------------
724  // Reverse zero suppression function with pedestal re-addition
725  void ZeroUnsuppression(const std::vector<short>& adc,
726  std::vector<short> &uncompressed,
727  int pedestal)
728  {
729  const int lengthofadc = adc[0];
730  const int nblocks = adc[1];
731 
732  uncompressed.resize(lengthofadc);
733  for (int i = 0;i < lengthofadc; ++i){
734  uncompressed[i] = pedestal;
735  }
736 
737  int zerosuppressedindex = nblocks*2 + 2;
738 
739  for(int i = 0; i < nblocks; ++i){ //loop over each nonzero block of the compressed vector
740 
741  for(int j = 0; j < adc[2+nblocks+i]; ++j){//loop over each block size
742 
743  //set uncompressed value
744  uncompressed[adc[2+i]+j] = adc[zerosuppressedindex];
745  zerosuppressedindex++;
746 
747  }
748  }
749 
750  return;
751  }
752 
753 
754  //----------------------------------------------------------
755  // if the compression type is kNone, copy the adc vector into the uncompressed vector
756  void Uncompress(const std::vector<short>& adc,
757  std::vector<short> &uncompressed,
758  raw::Compress_t compress)
759  {
760  if(compress == raw::kHuffman) UncompressHuffman(adc, uncompressed);
761  else if(compress == raw::kZeroSuppression){
762  ZeroUnsuppression(adc, uncompressed);
763  }
764  else if(compress == raw::kZeroHuffman){
765  std::vector<short> tmp(2*adc[0]);
766  UncompressHuffman(adc, tmp);
767  ZeroUnsuppression(tmp, uncompressed);
768  }
769  else if(compress == raw::kNone){
770  for(unsigned int i = 0; i < adc.size(); ++i) uncompressed[i] = adc[i];
771  }
772  else {
773  throw cet::exception("raw")
774  << "raw::Uncompress() does not support compression #"
775  << ((int) compress);
776  }
777  return;
778  }
779 
780  //----------------------------------------------------------
781  // if the compression type is kNone, copy the adc vector into the uncompressed vector
782  void Uncompress(const std::vector<short>& adc,
783  std::vector<short> &uncompressed,
784  int pedestal,
785  raw::Compress_t compress)
786  {
787  if(compress == raw::kHuffman) UncompressHuffman(adc, uncompressed);
788  else if(compress == raw::kZeroSuppression){
789  ZeroUnsuppression(adc, uncompressed, pedestal);
790  }
791  else if(compress == raw::kZeroHuffman){
792  std::vector<short> tmp(2*adc[0]);
793  UncompressHuffman(adc, tmp);
794  ZeroUnsuppression(tmp, uncompressed, pedestal);
795  }
796  else if(compress == raw::kNone){
797  for(unsigned int i = 0; i < adc.size(); ++i) uncompressed[i] = adc[i];
798  }
799  else {
800  throw cet::exception("raw")
801  << "raw::Uncompress() does not support compression #"
802  << ((int) compress);
803  }
804  return;
805  }
806 
807 
808  // the current Huffman Coding scheme used by uBooNE is
809  // based on differences between adc values in adjacent time bins
810  // the code is
811  // no change for 4 ticks --> 1
812  // no change for 1 tick --> 01
813  // +1 change --> 001
814  // -1 change --> 0001
815  // +2 change --> 00001
816  // -2 change --> 000001
817  // +3 change --> 0000001
818  // -3 change --> 00000001
819  // abs(change) > 3 --> write actual value to short
820  // use 15th bit to set whether a block is encoded or raw value
821  // 1 --> Huffman coded, 0 --> raw
822  // pad out the lowest bits in a word with 0's
823  void CompressHuffman(std::vector<short> &adc)
824  {
825  std::vector<short> const orig_adc(std::move(adc));
826 
827  // diffs contains the difference between an element of adc and the previous
828  // one; the first entry is never used.
829  std::vector<short> diffs;
830  diffs.reserve(orig_adc.size());
831  std::adjacent_difference
832  (orig_adc.begin(), orig_adc.end(), std::back_inserter(diffs));
833 
834  // prepare adc for the new data; we kind-of-expect the size,
835  // so we pre-allocate it; we might want to shrink-to-fit at the end
836  adc.clear();
837  adc.reserve(orig_adc.size());
838  // now loop over the diffs and do the Huffman encoding
839  adc.push_back(orig_adc.front());
840  unsigned int curb = 15U;
841 
842  std::bitset<16> bset;
843  bset.set(15);
844 
845  for(size_t i = 1U; i < diffs.size(); ++i){
846 
847  switch (diffs[i]) {
848  // if the difference is 0, check to see what the next 3 differences are
849  case 0 : {
850  if(i < diffs.size() - 3){
851  // if next 3 are also 0, set the next bit to be 1
852  if(diffs[i+1] == 0 && diffs[i+2] == 0 && diffs[i+3] == 0){
853  if(curb > 0){
854  --curb;
855  bset.set(curb);
856  i += 3;
857  continue;
858  }
859  else{
860  adc.push_back(bset.to_ulong());
861 
862  // reset the bitset to be ready for the next word
863  bset.reset();
864  bset.set(15);
865  bset.set(14); // account for the fact that this is a zero diff
866  curb = 14;
867  i += 3;
868  continue;
869  } // end if curb is not big enough to put current difference in bset
870  } // end if next 3 are also zero
871  else{
872  // 0 diff is encoded as 01, so move the current bit one to the right
873  if(curb > 1){
874  curb -= 2;
875  bset.set(curb);
876  continue;
877  } // end if the current bit is large enough to set this one
878  else{
879  adc.push_back(bset.to_ulong());
880  // reset the bitset to be ready for the next word
881  bset.reset();
882  bset.set(15);
883  bset.set(13); // account for the fact that this is a zero diff
884  curb = 13;
885  continue;
886  } // end if curb is not big enough to put current difference in bset
887  } // end if next 3 are not also 0
888  }// end if able to check next 3
889  else{
890  // 0 diff is encoded as 01, so move the current bit one to the right
891  if(curb > 1){
892  curb -= 2;
893  bset.set(curb);
894  continue;
895  } // end if the current bit is large enough to set this one
896  else{
897  adc.push_back(bset.to_ulong());
898  // reset the bitset to be ready for the next word
899  bset.reset();
900  bset.set(15);
901  bset.set(13); // account for the fact that this is a zero diff
902  curb = 13;
903  continue;
904  } // end if curb is not big enough to put current difference in bset
905  }// end if not able to check the next 3
906  break;
907  }// end if current difference is zero
908  case 1: {
909  if(curb > 2){
910  curb -= 3;
911  bset.set(curb);
912  }
913  else{
914  adc.push_back(bset.to_ulong());
915  // reset the bitset to be ready for the next word
916  bset.reset();
917  bset.set(15);
918  bset.set(12); // account for the fact that this is a +1 diff
919  curb = 12;
920  } // end if curb is not big enough to put current difference in bset
921  break;
922  } // end if difference = 1
923  case -1: {
924  if(curb > 3){
925  curb -= 4;
926  bset.set(curb);
927  }
928  else{
929  adc.push_back(bset.to_ulong());
930  // reset the bitset to be ready for the next word
931  bset.reset();
932  bset.set(15);
933  bset.set(11); // account for the fact that this is a -1 diff
934  curb = 11;
935  } // end if curb is not big enough to put current difference in bset
936  break;
937  }// end if difference = -1
938  case 2: {
939  if(curb > 4){
940  curb -= 5;
941  bset.set(curb);
942  }
943  else{
944  adc.push_back(bset.to_ulong());
945  // reset the bitset to be ready for the next word
946  bset.reset();
947  bset.set(15);
948  bset.set(10); // account for the fact that this is a +2 diff
949  curb = 10;
950  } // end if curb is not big enough to put current difference in bset
951  break;
952  }// end if difference = 2
953  case -2: {
954  if(curb > 5){
955  curb -= 6;
956  bset.set(curb);
957  }
958  else{
959  adc.push_back(bset.to_ulong());
960  // reset the bitset to be ready for the next word
961  bset.reset();
962  bset.set(15);
963  bset.set(9); // account for the fact that this is a -2 diff
964  curb = 9;
965  } // end if curb is not big enough to put current difference in bset
966  break;
967  }// end if difference = -2
968  case 3: {
969  if(curb > 6){
970  curb -= 7;
971  bset.set(curb);
972  }
973  else{
974  adc.push_back(bset.to_ulong());
975  // reset the bitset to be ready for the next word
976  bset.reset();
977  bset.set(15);
978  bset.set(8); // account for the fact that this is a +3 diff
979  curb = 8;
980  } // end if curb is not big enough to put current difference in bset
981  break;
982  }// end if difference = 3
983  case -3: {
984  if(curb > 7){
985  curb -= 8;
986  bset.set(curb);
987  }
988  else{
989  adc.push_back(bset.to_ulong());
990  // reset the bitset to be ready for the next word
991  bset.reset();
992  bset.set(15);
993  bset.set(7); // account for the fact that this is a -3 diff
994  curb = 7;
995  } // end if curb is not big enough to put current difference in bset
996  break;
997  }// end if difference = -3
998  default: {
999  // if the difference is too large that we have to put the entire adc value in:
1000  // put the current value into the adc vec unless the current bit is 15, then there
1001  // were multiple large difference values in a row
1002  if(curb != 15){
1003  adc.push_back(bset.to_ulong());
1004  }
1005 
1006  bset.reset();
1007  bset.set(15);
1008  curb = 15;
1009 
1010  // put the current adcvalue in adc, with its bit 15 set to 0
1011  if(orig_adc[i] > 0) adc.push_back(orig_adc[i]);
1012  else{
1013  std::bitset<16> tbit(-orig_adc[i]);
1014  tbit.set(14);
1015  adc.push_back(tbit.to_ulong());
1016  }
1017  break;
1018  } // if |difference| > 3
1019  }// switch diff[i]
1020  }// end loop over differences
1021 
1022  //write out the last bitset
1023  adc.push_back(bset.to_ulong());
1024 
1025  // this would reduce global memory usage,
1026  // at the cost of a new allocation and copy
1027  // adc.shrink_to_fit();
1028 
1029  } // CompressHuffman()
1030  //--------------------------------------------------------
1031  // need to decrement the bit you are looking at to determine the deltas as that is how
1032  // the bits are set
1033  void UncompressHuffman(const std::vector<short>& adc,
1034  std::vector<short> &uncompressed)
1035  {
1036 
1037  //the first entry in adc is a data value by construction
1038  uncompressed[0] = adc[0];
1039 
1040  unsigned int curu = 1;
1041  short curADC = uncompressed[0];
1042 
1043  // loop over the entries in adc and uncompress them according to the
1044  // encoding scheme above the CompressHuffman method
1045  for(unsigned int i = 1; i < adc.size() && curu < uncompressed.size(); ++i){
1046 
1047  std::bitset<16> bset(adc[i]);
1048 
1049  int numu = 0;
1050 
1051  //check the 15 bit to see if this entry is a full data value or not
1052  if( !bset.test(15) ){
1053  curADC = adc[i];
1054  if(bset.test(14)){
1055  bset.set(14, false);
1056  curADC = -1*bset.to_ulong();
1057  }
1058  uncompressed[curu] = curADC;
1059 
1060  ++curu;
1061  }
1062  else{
1063 
1064  int b = 14;
1065  int lowestb = 0;
1066 
1067  // ignore any padding with zeros in the lower order bits
1068  while( !bset.test(lowestb) && lowestb < 15) ++lowestb;
1069 
1070  if(lowestb > 14){
1071  mf::LogWarning("raw.cxx") << "encoded entry has no set bits!!! "
1072  << i << " "
1073  << bset.to_string< char,std::char_traits<char>,std::allocator<char> >();
1074  continue;
1075  }
1076 
1077  while( b >= lowestb){
1078 
1079  // count the zeros between the current bit and the next on bit
1080  int zerocnt = 0;
1081  while( !bset.test(b-zerocnt) && b-zerocnt > lowestb) ++zerocnt;
1082 
1083  b -= zerocnt;
1084 
1085  if(zerocnt == 0){
1086  for(int s = 0; s < 4; ++s){
1087  uncompressed[curu] = curADC;
1088  ++curu;
1089  ++numu;
1090  if(curu > uncompressed.size()-1) break;
1091  }
1092  --b;
1093  }
1094  else if(zerocnt == 1){
1095  uncompressed[curu] = curADC;
1096  ++curu;
1097  ++numu;
1098  --b;
1099  }
1100  else if(zerocnt == 2){
1101  curADC += 1;
1102  uncompressed[curu] = curADC;
1103  ++curu;
1104  ++numu;
1105  --b;
1106  }
1107  else if(zerocnt == 3){
1108  curADC -= 1;
1109  uncompressed[curu] = curADC;
1110  ++curu;
1111  ++numu;
1112  --b;
1113  }
1114  else if(zerocnt == 4){
1115  curADC += 2;
1116  uncompressed[curu] = curADC;
1117  ++curu;
1118  ++numu;
1119  --b;
1120  }
1121  else if(zerocnt == 5){
1122  curADC -= 2;
1123  uncompressed[curu] = curADC;
1124  ++curu;
1125  ++numu;
1126  --b;
1127  }
1128  else if(zerocnt == 6){
1129  curADC += 3;
1130  uncompressed[curu] = curADC;
1131  ++curu;
1132  ++numu;
1133  --b;
1134  }
1135  else if(zerocnt == 7){
1136  curADC -= 3;
1137  uncompressed[curu] = curADC;
1138  ++curu;
1139  ++numu;
1140  --b;
1141  }
1142 
1143  if(curu > uncompressed.size() - 1) break;
1144 
1145  }// end loop over bits
1146 
1147  if(curu > uncompressed.size() - 1) break;
1148 
1149  }// end if this entry in the vector is encoded
1150 
1151  }// end loop over entries in adc
1152 
1153  return;
1154  }
1155 
1156  //--------------------------------------------------------
1157  // need to decrement the bit you are looking at to determine the deltas as that is how
1158  // the bits are set
1159  int ADCStickyCodeCheck(const short adc_value,
1160  const int pedestal,
1161  bool fADCStickyCodeFeature){
1162 
1163  int adc_return_value = std::abs(adc_value - pedestal);
1164 
1165  if(!fADCStickyCodeFeature){
1166  return adc_return_value;
1167  }
1168  // if DUNE 35t ADC sticky code feature is enabled in simulation, skip over ADC codes with LSBs of 0x00 or 0x3f
1169  unsigned int sixlsbs = adc_value & onemask;
1170 
1171  if((sixlsbs==onemask || sixlsbs==0) && std::abs(adc_value - pedestal) < 64){
1172  adc_return_value = 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
1173  }
1174  return adc_return_value;
1175  }
1176 
1177 }
void CompressHuffman(std::vector< short > &adc)
Definition: raw.cxx:823
Huffman Encoding.
Definition: RawTypes.h:10
Float_t s
Definition: plot.C:23
enum raw::_compress Compress_t
void UncompressHuffman(const std::vector< short > &adc, std::vector< short > &uncompressed)
Definition: raw.cxx:1033
const unsigned int onemask
Definition: raw.h:127
Zero Suppression followed by Huffman Encoding.
Definition: RawTypes.h:12
Raw data description.
Definition: RawTypes.h:6
Float_t tmp
Definition: plot.C:37
no compression
Definition: RawTypes.h:9
Zero Suppression algorithm.
Definition: RawTypes.h:11
int ADCStickyCodeCheck(const short adc_value, const int pedestal, bool fADCStickyCodeFeature)
Definition: raw.cxx:1159
Collect all the RawData header files together.
void ZeroUnsuppression(const std::vector< short > &adc, std::vector< short > &uncompressed)
Definition: raw.cxx:696
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void Compress(std::vector< short > &adc, raw::Compress_t compress)
Compresses a raw data buffer.
Definition: raw.cxx:20
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:756
void ZeroSuppression(std::vector< short > &adc, unsigned int &zerothreshold)
Definition: raw.cxx:153
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33