AlcapDAQ  1
fadc_compress.cpp
Go to the documentation of this file.
1 //
3 // 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 
17 
18 const int num_fadc_channels = 4;
19 
21 {
22  huffman_optimize_tree(&fadc_run_huffman);
23  huffman_optimize_tree(&fadc_small_huffman);
24 
25  save_huffman("/Compression/Lossless/FADC/Huffman/Run", &fadc_run_huffman);
26  save_huffman("/Compression/Lossless/FADC/Huffman/Small", &fadc_small_huffman);
27 }
28 
29 void fadc_load()
30 {
31  huffman_init_default(&fadc_run_huffman, 32);
32  huffman_init_default(&fadc_small_huffman, 9);
33 
34  load_huffman("/Compression/Lossless/FADC/Huffman/Run", &fadc_run_huffman);
35  load_huffman("/Compression/Lossless/FADC/Huffman/Small", &fadc_small_huffman);
36 
37  int size = sizeof(BOOL);
38  db_get_value(hDB, 0, "/Compression/Lossless/FADC/Enabled", &should_compress_fadc,
39  &size, TID_BOOL, TRUE);
40 }
41 
42 int encode_fadc(fadc_word * input, int input_size, io_buffer * output)
43 {
44  // Encode the flash ADC data by
45  // 1. Splitting the four channels.
46  // 2. Taking successive differences between samples within a channel.
47  // 3. Run-length encoding the differences.
48  // 4. Huffman coding the results.
49 
50  int num_fadc_samples = input_size;
51 
52  int diffs[ /*num_fadc_samples */ 1024];
53 
54  for (int chan = 0; chan < num_fadc_channels; chan++) {
55  int prev_sample = 0;
56 
57  for (int i = 0; i < num_fadc_samples; i++) {
58  diffs[i] = ((int) input[i].channel[chan]) - prev_sample;
59  prev_sample = input[i].channel[chan];
60  }
61 
62  for (int i = 0; i < num_fadc_samples; i++) {
63 
64  if (diffs[i] == 0) {
65  // count the run length
66  int run_length = 0;
67  while (i + run_length < num_fadc_samples && run_length < 31) {
68  if (diffs[i + run_length] == 0) {
69  run_length++;
70  } else {
71  break;
72  }
73  }
74 
75  i += run_length - 1;
76 
77  io_buffer_put(output, 0, 1);
78  huffman_put_symbol(&fadc_run_huffman, output, run_length);
79  } else if (diffs[i] <= 4 && diffs[i] >= -4) {
80  io_buffer_put(output, 2, 2);
81  huffman_put_symbol(&fadc_small_huffman, output, diffs[i] + 4);
82  } else {
83  io_buffer_put(output, 3, 2);
84  io_buffer_put(output, diffs[i] + 256, 9);
85  }
86  }
87  }
88 
89  return flush_output_buffer(output);
90 }
91 
92 int fadc_compress(fadc_word * input, int input_size, unsigned char *output, int userParam)
93 {
94  input_size /= sizeof(fadc_word);
95 
97 
98  io_buffer output_buffer;
99 
100  // store size of input data
101  int *uncompressed_size_p = (int *) output;
102  *uncompressed_size_p = input_size;
103  output += sizeof(int);
104 
105  // reserve space for the size of the compressed data
106  int *compressed_time_size_p = (int *) output;
107  output += sizeof(int);
108 
109  // compress samples
110  start_output_buffer(&output_buffer, output);
111  int compressed_size = encode_fadc(input, input_size, &output_buffer);
112  output += compressed_size;
113 
114  // store size of compressed times
115  *compressed_time_size_p = compressed_size;
116 
117  return compressed_size + 2 * sizeof(int);
118 }
119 
120 int decode_fadc(io_buffer * input, fadc_word * output, int input_size)
121 {
122  int num_fadc_samples = input_size;
123 
124  int diffs[ /*num_fadc_samples */ 1024];
125 
126  for (int chan = 0; chan < num_fadc_channels; chan++) {
127 
128  for (int i = 0; i < num_fadc_samples; i++) {
129  int type_code_1 = io_buffer_get(input, 1);
130  if (type_code_1 == 0) {
131  int run_length = huffman_get_symbol(&fadc_run_huffman, input);
132 
133  for (int j = 0; j < run_length; j++) {
134  diffs[i + j] = 0;
135  }
136 
137  i += run_length - 1;
138 
139  if (i < 0 || i >= num_fadc_samples) {
140  printf("WTF?\n");
141  }
142 
143 
144  } else {
145  int type_code_2 = io_buffer_get(input, 1);
146  if (type_code_2 == 0) {
147  diffs[i] = huffman_get_symbol(&fadc_small_huffman, input) - 4;
148  } else {
149  diffs[i] = io_buffer_get(input, 9) - 256;
150  }
151  }
152  }
153 
154  int prev_sample = 0;
155 
156  for (int i = 0; i < num_fadc_samples; i++) {
157  output[i].channel[chan] = prev_sample + diffs[i];
158  prev_sample = output[i].channel[chan];
159  }
160  }
161 
162  return num_fadc_samples;
163 }
164 
165 int fadc_expand(unsigned char *input, int input_size, fadc_word * output, int userParam)
166 {
167  //
168  // Uncompress the data produced by caen_compress().
169  //
170 
171  rle_bits_setup();
172 
173  // Get uncompressed data size
174  int *uncompressed_size_p = (int *) input;
175  int uncompressed_size = *uncompressed_size_p;
176  input += sizeof(int);
177  input_size -= sizeof(int);
178 
179  // Get size of compressed data
180  int *compressed_size_p = (int *) input;
181  int compressed_size = *compressed_size_p;
182  input += sizeof(int);
183  input_size -= sizeof(int);
184 
185  // Uncompress data
186  io_buffer input_buffer;
187  start_input_buffer(&input_buffer, input);
188  decode_fadc(&input_buffer, output, uncompressed_size);
189  input += compressed_size;
190  input_size -= compressed_size;
191 
192  return uncompressed_size * sizeof(fadc_word);
193 }