AlcapDAQ  1
stck_compress.cpp
Go to the documentation of this file.
1 //
3 // Compression of "stacked" TPC data.
4 //
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 
10 #include "midas.h"
11 
12 #include "mucap_compress.h"
13 #include "mucap_structures.h"
14 
15 void myprint_TPCstack_interval(stack_elt *stackArray, long index1, long index2);
16 void print_TPCstack_interval(stack_elt *stackArray, long index1, long index2);
17 
21 
23 {
24  huffman_optimize_tree(&stck_time_huffman);
25  huffman_optimize_tree(&stck_bits_huffman[0]);
26  huffman_optimize_tree(&stck_bits_huffman[1]);
27 
28  save_huffman("/Compression/Lossless/STCK/Huffman/Bits 0", &stck_bits_huffman[0]);
29  save_huffman("/Compression/Lossless/STCK/Huffman/Bits 1", &stck_bits_huffman[1]);
30 }
31 
32 void stck_load()
33 {
34  huffman_init_default(&stck_time_huffman, 129);
35  huffman_init_default(&stck_bits_huffman[0], 129);
36  huffman_init_default(&stck_bits_huffman[1], 129);
37 
38  load_huffman("/Compression/Lossless/STCK/Huffman/Bits 0", &stck_bits_huffman[0]);
39  load_huffman("/Compression/Lossless/STCK/Huffman/Bits 1", &stck_bits_huffman[1]);
40 
41  int size = sizeof(BOOL);
42  db_get_value(hDB, 0, "/Compression/Lossless/STCK/Enabled", &should_compress_stck,
43  &size, TID_BOOL, TRUE);
44 }
45 
46 int encode_times(stack_elt * input, int input_size, io_buffer * output)
47 {
48  //
49  // Perform a variant of run-length encoding on the times in the STCK
50  // data, which are the most significant 16 bits in every 64 bit word.
51  //
52  // Times come in sequences of consecutive words, with sequences separated
53  // by a "-1" time; generally there are a whole lot of words, many of which
54  // are entirely zero padding. We store the time of the start of the block
55  // followed by the number of elements in the block.
56  //
57 
58  int run_length = 0;
59  int prev_time = 0;
60  unsigned short prev_run_time = 0;
61 
62  for (int i = 0; i < input_size; i++) {
63  if (input[i].time != -1.0) {
64  if(run_length == 0) {
65  int this_time = (int) ((input[i].time+0.1)/200);
66  int this_run_time_diff = this_time - prev_run_time;
67  if (this_run_time_diff < 2048) {
68  io_buffer_put(output, this_run_time_diff, 12);
69  } else {
70  io_buffer_put(output, (1 << 22) | this_run_time_diff, 23);
71  }
72  output->num_codes++;
73 
74  prev_run_time = this_time;
75  }
76  run_length++;
77  } else {
78  if (run_length != 0) {
79  if(run_length < 256) {
80  io_buffer_put(output, run_length, 9);
81  } else {
82  io_buffer_put(output, (1 << 19) | run_length, 20);
83  }
84  run_length = 0;
85  }
86  }
87  }
88 
89  if (run_length != 0) {
90  if(run_length < 256) {
91  io_buffer_put(output, run_length, 9);
92  } else {
93  io_buffer_put(output, (1 << 19) | run_length, 20);
94  }
95  run_length = 0;
96  }
97 
98  return flush_output_buffer(output);
99 }
100 
101 void decode_times(io_buffer * input, stack_elt * output)
102 {
103  //
104  // Reverse the encoding performed by encode_times.
105  //
106 
107  int num_words_in = input->num_codes;
108  int output_size = 0;
109  unsigned short prev_run_time = 0;
110 
111  for (int i = 0; i < num_words_in; i++) {
112  int first_time_length_flag = io_buffer_get(input, 1);
113  int first_time;
114  if (first_time_length_flag) {
115  first_time = io_buffer_get(input, 22);
116  } else {
117  first_time = io_buffer_get(input, 11);
118  }
119 
120  int run_length_flag = io_buffer_get(input, 1);
121  int run_length;
122  if (run_length_flag) {
123  run_length = io_buffer_get(input, 19);
124  } else {
125  run_length = io_buffer_get(input, 8);
126  }
127 
128  output[output_size++].time = -1;
129  for (int j = 0; j < run_length; j++) {
130  output[output_size++].time = (first_time + prev_run_time + j)*200;
131  }
132 
133  prev_run_time += first_time;
134  }
135 }
136 
137 int encode_bits(stack_elt * input, int input_size, io_buffer * output)
138 {
139  //
140  // the STCK data. For example, the following bit pattern:
141  //
142  // t 000000000011100000000000000000000000000000000000
143  // t+1 000000000000110000000000000000000000000000000000
144  //
145  // which is not altogether improbable, would be encoded as
146  //
147  // 10, 3, 47, 2, 34
148  //
149  // Then, store Huffman codes for the run lengths. Use a separate
150  // Huffman table for the "zero" runs and the "one" runs.
151  //
152 
153  rle_state s = { 0, 0, {128, 128}, 1, stck_bits_huffman };
154 
155  for(int i = 0; i < 3; i++) {
156  for (int j = 0; j < input_size; j++) {
157  for (int k = 0; k < 6; k++) {
158  unsigned char b = input[j].thr[i].Aword[k] & 0xff;
159  rle_put(b, &s, output);
160  b = (input[j].thr[i].Aword[k] >> 8) & 0xff;
161  rle_put(b, &s, output);
162  }
163  }
164 
165  for (int j = 0; j < input_size; j++) {
166  for (int k = 0; k < 3; k++) {
167  unsigned char b = input[j].thr[i].Sword[k] & 0xff;
168  rle_put(b, &s, output);
169  b = (input[j].thr[i].Sword[k] >> 8) & 0xff;
170  rle_put(b, &s, output);
171  }
172  }
173  }
174 
175  return flush_rle(&s, output);
176 }
177 
178 void decode_bits(io_buffer * input, stack_elt * output, int output_size)
179 {
180  rle_state s = { 1, 0, {128, 128}, 1, stck_bits_huffman };
181 
182  for(int i = 0; i < 3; i++) {
183  for (int j = 0; j < output_size; j++) {
184  for (int k = 0; k < 6; k++) {
185  int b1 = rle_get(input, &s);
186  int b2 = rle_get(input, &s);
187  if(b1 >= 0 && b2 >= 0) {
188  output[j].thr[i].Aword[k] = (b2 << 8) | b1;
189  } else {
190  return;
191  }
192  }
193  }
194 
195  for (int j = 0; j < output_size; j++) {
196  for (int k = 0; k < 3; k++) {
197  int b1 = rle_get(input, &s);
198  int b2 = rle_get(input, &s);
199  if(b1 >= 0 && b2 >= 0) {
200  output[j].thr[i].Sword[k] = (b2 << 8) | b1;
201  } else {
202  return;
203  }
204  }
205  }
206 
207  for (int j = 0; j < output_size; j++) {
208  bool bit = 0;
209  for(int k = 0; k < 6; k++) {
210  bit = bit || (output[j].thr[i].Aword[k] != 0);
211  }
212  for(int k = 0; k < 3; k++) {
213  bit = bit || (output[j].thr[i].Sword[k] != 0);
214  }
215  output[j].thrbits[i] = bit;
216  }
217  }
218 }
219 
220 int stck_compress(stack_elt * input, int input_size,
221  unsigned char *output, int userParam)
222 {
223  //
224  // Carry out lossless compression on the stacked TPC data.
225  //
226 
227  input_size /= sizeof(stack_elt);
228 
229  //myprint_TPCstack_interval(input, 0, input_size-1);
230 
231  rle_bits_setup();
232 
233  io_buffer output_buffer;
234 
235  // store size of input data
236  int *uncompressed_size_p = (int *) output;
237  *uncompressed_size_p = input_size;
238  output += sizeof(int);
239 
240  // reserve space for the size of the compressed times
241  int *compressed_time_size_p = (int *) output;
242  output += sizeof(int);
243 
244  // compress times
245  start_output_buffer(&output_buffer, output);
246  int compressed_time_size =
247  encode_times(input, input_size, &output_buffer);
248  output += compressed_time_size;
249 
250  // store size of compressed times
251  *compressed_time_size_p = compressed_time_size;
252 
253  // reserve space for the size of the compressed bit patterns
254  int *compressed_bits_size_p = (int *) output;
255  output += sizeof(int);
256 
257  // compress bit patterns
258  start_output_buffer(&output_buffer, output);
259  int compressed_bits_size =
260  encode_bits(input, input_size, &output_buffer);
261  output += compressed_time_size;
262 
263  // store size of compressed bit patterns
264  *compressed_bits_size_p = compressed_bits_size;
265 
266  return compressed_time_size + compressed_bits_size + 3 * sizeof(int);
267 }
268 
269 int stck_expand(unsigned char *input, int input_size,
270  stack_elt * output, int userParam)
271 {
272  //
273  //
274  // Uncompress the data produced by stck_compress().
275  //
276 
277  rle_bits_setup();
278 
279  // Get uncompressed data size
280  int *uncompressed_size_p = (int *) input;
281  int uncompressed_size = *uncompressed_size_p;
282  input += sizeof(int);
283  input_size -= sizeof(int);
284 
285  // Get size of compressed time data
286  int *compressed_time_size_p = (int *) input;
287  int compressed_time_size = *compressed_time_size_p;
288  input += sizeof(int);
289  input_size -= sizeof(int);
290 
291  // Uncompress times
292  io_buffer input_buffer;
293  start_input_buffer(&input_buffer, input);
294  decode_times(&input_buffer, output);
295  input += compressed_time_size;
296  input_size -= compressed_time_size;
297 
298  // Get size of compressed bit patterns
299  int *compressed_bits_size_p = (int *) input;
300  int compressed_bits_size = *compressed_bits_size_p;
301  input += sizeof(int);
302  input_size -= sizeof(int);
303 
304  // Uncompress bit patterns
305  start_input_buffer(&input_buffer, input);
306  decode_bits(&input_buffer, output, uncompressed_size);
307 
308  //myprint_TPCstack_interval(output, 0, uncompressed_size-1);
309 
310  return uncompressed_size * sizeof(stack_elt);
311 }
312 
314  long index1,
315  long index2)
316 {
317  for(int i = index1; i <= index2; i++) {
318 #if 0
319  printf("%f: \n", stackArray[i].time);
320  for(int j = 0; j < 3; j++) {
321  printf(" | %d | ", stackArray[i].thrbits[j]);
322  for(int k = 0; k < 6; k++) {
323  printf("0x%08x ", stackArray[i].thr[j].Aword[k]);
324  }
325  printf("* ");
326  for(int k = 0; k < 3; k++) {
327  printf("0x%08x ", stackArray[i].thr[j].Sword[k]);
328  }
329  printf("\n");
330  }
331 #endif
332 
333  printf("%f: \n", stackArray[i].time);
334  for(int j = 0; j < sizeof(stack_elt); j++) {
335  printf("%d ", ((char *) &stackArray[i])[j]);
336  }
337  printf("\n");
338  }
339 }
340 
342  long index1,
343  long index2)
344 {
345  // Everything OK, so print requested section of STCK bank
346  for (int index=index1; index<=index2; index++) {
347  if (stackArray[index].time > 0) {
348  // Anodes
349  for (int section=1; section<=5; section++) {
350  for (int anode=0; anode<16; anode++) {
351  if (stackArray[index].thr[2].Aword[section-1] & (1 << anode)) {
352  printf("*");
353  } else {
354  if (stackArray[index].thr[1].Aword[section-1] & (1 << anode)) {
355  printf("#");
356  } else {
357  if (stackArray[index].thr[0].Aword[section-1] & (1 << anode)) {
358  printf(".");
359  } else {
360  printf("0");
361  }
362  }
363  }
364  }
365  } // End loop over anodes
366 
367  // Strips
368  printf(" ");
369  for (int section=1; section<=3; section++) {
370  int maxstrip;
371  if (section == 3) {
372  maxstrip=3;
373  } else {
374  maxstrip=16;
375  }
376  for (int strip=0; strip<maxstrip; strip++) {
377  if (stackArray[index].thr[2].Sword[section-1] & (1 << strip)) {
378  printf("*");
379  } else {
380  if (stackArray[index].thr[1].Sword[section-1] & (1 << strip)) {
381  printf("#");
382  } else {
383  if (stackArray[index].thr[0].Sword[section-1] & (1 << strip)) {
384  printf(".");
385  } else {
386  printf("0");
387  }
388  }
389  }
390  }
391  } // End loop over strips
392 
393  printf(" [%d].time = %0.0f ns\n",index,stackArray[index].time);
394  } else {
395  if (index != index2) {
396  printf(" |10 |20 |30 |40 |50 ");
397  printf("|60 |70 |76\n");
398  }
399  printf("----------------------------------------------------------");
400  printf("----------------------------------------------------------");
401  printf(" [%d].time = %0.0f\n", index, stackArray[index].time);
402  }
403  }
404 }