AlcapDAQ  1
nfadc_compress.cpp
Go to the documentation of this file.
1 //
3 // New Louvain/Berkeley Flash ADC compression
4 //
6 
7 #include <stdio.h>
8 
9 #include "midas.h"
10 
11 #include "mucap_compress.h"
12 #include "mucap_structures.h"
13 
15 
16 const int num_nfadc_channels = 4;
17 
18 void nfadc_dump(int num_fadc_words, unsigned char *data);
19 
21 {
22 }
23 
24 void nfadc_load()
25 {
26  int size = sizeof(BOOL);
27  db_get_value(hDB, 0, "/Compression/Lossless/NFADC/Enabled", &should_compress_nfadc,
28  &size, TID_BOOL, TRUE);
29 }
30 
31 int encode_nfadc(unsigned char * input, int input_size, io_buffer * output, int boardNumber)
32 {
33  int num_words = input_size/10;
34 
35  // first deal with the timestamps
36  int run_length = 0;
37  int last_timestamp = -2;
38  int last_adc = -2;
39  int island_adc = 0;
40  int island_timestamp = -1;
41  int last_island_timestamp = 0;
42  for(int j = 0; j < num_words; j++) {
43 
44  int adc = (input[j*10+0] >> 7) & 0x01;
45 
46  int timestamp = ((input[j*10+0] & 0x7f) << 20) |
47  (input[j*10+1] << 12) |
48  (input[j*10+2] << 4) |
49  (input[j*10+3] >> 4);
50  if(boardNumber < 128) {
51  timestamp /= 2;
52  }
53 
54  if(timestamp != last_timestamp + 1 || adc != last_adc || run_length == 255) {
55  if(island_timestamp != -1) {
56  io_buffer_put(output, island_adc, 1);
57  io_buffer_put(output, island_timestamp, 27);
58  io_buffer_put(output, run_length, 8);
59  }
60 
61  island_adc = adc;
62  island_timestamp = timestamp;
63  run_length = 0;
64  }
65 
66  last_adc = adc;
67  last_timestamp = timestamp;
68  run_length++;
69  }
70 
71  // final run
72  if(island_timestamp != -1) {
73  io_buffer_put(output, island_adc, 1);
74  io_buffer_put(output, island_timestamp, 27);
75  io_buffer_put(output, run_length, 8);
76  }
77 
78  // now the FADC codes
79  int lastSample = 0;
80  for(int j = 0; j < num_words; j++) {
81  int sample[4];
82  bool overflowB0 = ((input[j*10+3] & 0x08) != 0);
83  bool overflowA0 = ((input[j*10+3] & 0x04) != 0);
84  bool overflowB1 = ((input[j*10+3] & 0x02) != 0);
85  bool overflowA1 = ((input[j*10+3] & 0x01) != 0);
86  sample[3] = (overflowB0 << 12) | (input[j*10+4] << 4) | (input[j*10+5] >> 4);
87  sample[2] = (overflowA0 << 12) | ((input[j*10+5] & 0xf) << 8) | (input[j*10+6]);
88  sample[1] = (overflowB1 << 12) | (input[j*10+7] << 4) | (input[j*10+8] >> 4);
89  sample[0] = (overflowA1 << 12) | ((input[j*10+8] & 0xf) << 8) | (input[j*10+9]);
90 
91  for(int k = 0; k < 4; k++) {
92  int diff = sample[k] - lastSample;
93  lastSample = sample[k];
94 
95 
96  if(diff <= 7 && diff >= -7) {
97  io_buffer_put(output, diff+8, 4);
98  } else {
99  io_buffer_put(output, 0, 4);
100  io_buffer_put(output, sample[k], 13);
101  }
102  }
103  }
104 
105  return flush_output_buffer(output);
106 }
107 
108 int nfadc_compress(unsigned char *input, int input_size, unsigned char *output, int userParam)
109 {
110  io_buffer output_buffer;
111 
112  // store size of input data
113  int *uncompressed_size_p = (int *) output;
114  *uncompressed_size_p = input_size;
115  output += sizeof(int);
116 
117  // compress samples
118  start_output_buffer(&output_buffer, output);
119  int compressed_size = encode_nfadc(input, input_size, &output_buffer, userParam);
120  output += compressed_size;
121 
122  return compressed_size + sizeof(int);
123 }
124 
125 int decode_nfadc(io_buffer * input, unsigned char * output, int input_size, int boardNumber)
126 {
127  int num_fadc_words = input_size/10;
128 
129  // first retrieve the timestamps
130  int j = 0;
131  while(j < num_fadc_words) {
132 
133  int adc = io_buffer_get(input, 1);
134  int timestamp = io_buffer_get(input, 27);
135  int run_length = io_buffer_get(input, 8);
136 
137  for(int k = 0; k < run_length; k++) {
138  int t2 = timestamp + k;
139  if(boardNumber < 128) {
140  t2 *= 2;
141  }
142  output[(j+k)*10+0] = (adc << 7) | ((t2 >> 20) & 0x7f);
143  output[(j+k)*10+1] = (t2 >> 12) & 0xff;
144  output[(j+k)*10+2] = (t2 >> 4) & 0xff;
145  output[(j+k)*10+3] = (t2 & 0xf) << 4;
146  }
147  j += run_length;
148 
149  }
150 
151  // now the FADC codes
152  int lastSample = 0;
153  for(int j = 0; j < num_fadc_words; j++) {
154  int sample[4];
155  for(int k = 0; k < 4; k++) {
156  int encodedDiff = io_buffer_get(input, 4) & 0xf;
157  if(encodedDiff == 0) {
158  sample[k] = io_buffer_get(input, 13) & 0x1fff;
159  } else {
160  sample[k] = lastSample + encodedDiff - 8;
161  }
162  lastSample = sample[k];
163  }
164 
165  int overflows = ((sample[0] & 0x1000) ? 0x01 : 0) |
166  ((sample[1] & 0x1000) ? 0x02 : 0) |
167  ((sample[2] & 0x1000) ? 0x04 : 0) |
168  ((sample[3] & 0x1000) ? 0x08 : 0);
169  output[j*10+3] |= overflows;
170  output[j*10+4] = (sample[3] >> 4) & 0xff;
171  output[j*10+5] = ((sample[3] & 0xf) << 4) | ((sample[2] >> 8) & 0xf);
172  output[j*10+6] = (sample[2] & 0xff);
173  output[j*10+7] = (sample[1] >> 4) & 0xff;
174  output[j*10+8] = ((sample[1] & 0xf) << 4) | ((sample[0] >> 8) & 0xf);
175  output[j*10+9] = (sample[0] & 0xff);
176  }
177 
178  return input_size;
179 }
180 
181 int nfadc_expand(unsigned char *input, int input_size, unsigned char * output, int userParam)
182 {
183  //
184  // Uncompress the data produced by nfadc_compress().
185  //
186 
187  // Get uncompressed data size
188  int *uncompressed_size_p = (int *) input;
189  int uncompressed_size = *uncompressed_size_p;
190  input += sizeof(int);
191  input_size -= sizeof(int);
192 
193  // Uncompress data
194  io_buffer input_buffer;
195  start_input_buffer(&input_buffer, input);
196  decode_nfadc(&input_buffer, output, uncompressed_size, userParam);
197 
198  return uncompressed_size;
199 }
200 
201 void nfadc_dump(int num_fadc_words, unsigned char *data)
202 {
203  for(int i = 0; i < num_fadc_words; i++) {
204  printf("%d: ", i);
205  for(int j = 0; j < 10; j++) {
206  printf("%02x ", data[i*10+j]);
207  }
208  printf("\n");
209  }
210 }