AlcapDAQ  1
Functions | Variables
tdc400_compress.cpp File Reference
#include <stdio.h>
#include <stdlib.h>
#include "midas.h"
#include "mucap_compress.h"
#include "mucap_structures.h"

Go to the source code of this file.

Functions

void tdc400_optimize ()
 
void tdc400_load ()
 
void binary_print (unsigned char c)
 
void event_display (tdc400_word *input, int length)
 
int encode_times (tdc400_word *input, int input_size, io_buffer *output)
 
void decode_times (io_buffer *input, tdc400_word *output)
 
int encode_bits (tdc400_word *input, int input_size, io_buffer *output)
 
void decode_bits (io_buffer *input, tdc400_word *output, int output_size)
 
int tdc400_compress (tdc400_word *input, int input_size, unsigned char *output, int userParam)
 
int tdc400_expand (unsigned char *input, int input_size, tdc400_word *output, int userParam)
 

Variables

huffman_table bits_huffman [2]
 
huffman_table time_huffman
 
BOOL should_compress_tdc400 = TRUE
 

Function Documentation

void binary_print ( unsigned char  c)

Definition at line 45 of file tdc400_compress.cpp.

References i, and printf().

Referenced by event_display().

46 {
47  for (int i = 0; i < 8; i++) {
48  if (c & 0x80) {
49  printf("X");
50  } else {
51  printf(".");
52  }
53 
54  c = c << 1;
55  }
56 }
void decode_bits ( io_buffer input,
tdc400_word output,
int  output_size 
)

Definition at line 191 of file tdc400_compress.cpp.

References i, rle_get(), s, and tdc400_byte().

192 {
193  rle_state s = { 1, 0, {128, 128}, 0, bits_huffman };
194 
195  for (int i = 0; i < output_size; i++) {
196  for (int j = 0; j < 6; j++) {
197  int b = rle_get(input, &s);
198  if (b >= 0) {
199  tdc400_byte(output[i], j) = (unsigned char) b;
200  } else {
201  return;
202  }
203  }
204  }
205 }
void decode_times ( io_buffer input,
tdc400_word output 
)

Definition at line 133 of file tdc400_compress.cpp.

References huffman_get_symbol(), i, io_buffer_get(), io_buffer::num_codes, and tdc400_word::time.

134 {
135  //
136  // Reverse the encoding performed by encode_times.
137  //
138 
139  int num_words_in = input->num_codes / 2;
140  int output_size = 0;
141  unsigned short prev_run_time = 0;
142 
143  for (int i = 0; i < num_words_in; i++) {
144  int first_time_length_flag = io_buffer_get(input, 1);
145  unsigned short first_time;
146  if (first_time_length_flag) {
147  first_time = io_buffer_get(input, 16);
148  } else {
149  first_time = io_buffer_get(input, 8);
150  }
151 
152  int run_length = huffman_get_symbol(&time_huffman, input);
153 
154  for (int j = 0; j < run_length; j++) {
155  output[output_size++].time = first_time + prev_run_time + j;
156  }
157 
158  prev_run_time += first_time;
159  }
160 }
int encode_bits ( tdc400_word input,
int  input_size,
io_buffer output 
)

Definition at line 162 of file tdc400_compress.cpp.

References flush_rle(), i, rle_put(), s, and tdc400_byte().

163 {
164  //
165  // Perform bitwise run-length encoding on the bit mask portion of
166  // the TDC400 data. For example, the following bit pattern:
167  //
168  // t 000000000011100000000000000000000000000000000000
169  // t+1 000000000000110000000000000000000000000000000000
170  //
171  // which is not altogether improbable, would be encoded as
172  //
173  // 10, 3, 47, 2, 34
174  //
175  // Then, store Huffman codes for the run lengths. Use a separate
176  // Huffman table for the "zero" runs and the "one" runs.
177  //
178 
179  rle_state s = { 0, 0, {128, 128}, 0, bits_huffman };
180 
181  for (int i = 0; i < input_size; i++) {
182  for (int j = 0; j < 6; j++) {
183  unsigned char b = tdc400_byte(input[i], j);
184  rle_put(b, &s, output);
185  }
186  }
187 
188  return flush_rle(&s, output);
189 }
int encode_times ( tdc400_word input,
int  input_size,
io_buffer output 
)

Definition at line 74 of file tdc400_compress.cpp.

References event_display(), flush_output_buffer(), huffman_put_symbol(), i, io_buffer_put(), io_buffer::num_codes, and tdc400_word::time.

75 {
76  //
77  // Perform a variant of run-length encoding on the times in the TDC400
78  // data, which are the most significant 16 bits in every 64 bit word.
79  //
80  // Times typically come in blocks of consecutive words, where the
81  // block
82  // length is generally of order 20. We will store the time of the
83  // start of the block followed by the number of elements in the block.
84  //
85  // More precisely, this is what we do:
86  // - Take the difference of the first time of the current block
87  // from the first time of the previous block.
88  // - If the difference is less than 256, store a 0; otherwise, store a 1
89  //
90  // - Store either 8 or 16 bits of time difference information.
91  // - Store Huffman-coded run length.
92  //
93 
94  int run_length = 1;
95  unsigned short prev_time = 0;
96  unsigned short prev_run_time = 0;
97 
98  for (int i = 0; i < input_size; i++) {
99  unsigned short this_time = input[i].time;
100 
101  if (this_time == prev_time + 1 && i != 0 && run_length < 127) {
102  run_length++;
103  } else {
104  if (i != 0) {
105 #if 0
106  if (run_length >= 8) {
107  event_display(&input[i - run_length], run_length);
108  }
109 #endif
110  huffman_put_symbol(&time_huffman, output, run_length);
111  }
112  run_length = 1;
113 
114  unsigned short this_run_time_diff = this_time - prev_run_time;
115  if (this_run_time_diff < 256) {
116  io_buffer_put(output, this_run_time_diff, 9);
117  } else {
118  io_buffer_put(output, 0x00010000 | this_run_time_diff, 17);
119  }
120  output->num_codes++;
121 
122  prev_run_time = this_time;
123  }
124 
125  prev_time = this_time;
126  }
127 
128  huffman_put_symbol(&time_huffman, output, run_length);
129 
130  return flush_output_buffer(output);
131 }
void event_display ( tdc400_word input,
int  length 
)

Definition at line 58 of file tdc400_compress.cpp.

References binary_print(), i, length, printf(), tdc400_byte(), and time.

Referenced by encode_times().

59 {
60  for (int i = 0; i < length; i++) {
61  printf("%d ", input[i].time);
62 
63  for (int j = 0; j < 6; j++) {
64  binary_print(tdc400_byte(input[i], j));
65  printf(" ");
66  }
67 
68  printf("\n");
69  }
70 
71  printf("------------------------------------------------------------\n");
72 }
int tdc400_compress ( tdc400_word input,
int  input_size,
unsigned char *  output,
int  userParam 
)

Definition at line 207 of file tdc400_compress.cpp.

References encode_bits(), encode_times(), rle_bits_setup(), and start_output_buffer().

Referenced by compress_event().

209 {
210  //
211  // Carry out lossless compression on the TPC data recorded by a
212  // single TDC400.
213  //
214 
215  input_size /= sizeof(tdc400_word);
216 
217  rle_bits_setup();
218 
219  io_buffer output_buffer;
220 
221  // store size of input data
222  int *uncompressed_size_p = (int *) output;
223  *uncompressed_size_p = input_size;
224  output += sizeof(int);
225 
226  // reserve space for the size of the compressed times
227  int *compressed_time_size_p = (int *) output;
228  output += sizeof(int);
229 
230  // compress times
231  start_output_buffer(&output_buffer, output);
232  int compressed_time_size =
233  encode_times(input, input_size, &output_buffer);
234  output += compressed_time_size;
235 
236  // store size of compressed times
237  *compressed_time_size_p = compressed_time_size;
238 
239  // reserve space for the size of the compressed bit patterns
240  int *compressed_bits_size_p = (int *) output;
241  output += sizeof(int);
242 
243  // compress bit patterns
244  start_output_buffer(&output_buffer, output);
245  int compressed_bits_size =
246  encode_bits(input, input_size, &output_buffer);
247  output += compressed_time_size;
248 
249  // store size of compressed bit patterns
250  *compressed_bits_size_p = compressed_bits_size;
251 
252  return compressed_time_size + compressed_bits_size + 3 * sizeof(int);
253 }
int tdc400_expand ( unsigned char *  input,
int  input_size,
tdc400_word output,
int  userParam 
)

Definition at line 255 of file tdc400_compress.cpp.

References decode_bits(), decode_times(), rle_bits_setup(), and start_input_buffer().

Referenced by expand_event().

257 {
258  //
259  // Uncompress the data produced by tdc400_compress().
260  //
261 
262  rle_bits_setup();
263 
264  // Get uncompressed data size
265  int *uncompressed_size_p = (int *) input;
266  int uncompressed_size = *uncompressed_size_p;
267  input += sizeof(int);
268  input_size -= sizeof(int);
269 
270  // Get size of compressed time data
271  int *compressed_time_size_p = (int *) input;
272  int compressed_time_size = *compressed_time_size_p;
273  input += sizeof(int);
274  input_size -= sizeof(int);
275 
276  // Uncompress times
277  io_buffer input_buffer;
278  start_input_buffer(&input_buffer, input);
279  decode_times(&input_buffer, output);
280  input += compressed_time_size;
281  input_size -= compressed_time_size;
282 
283  // Get size of compressed bit patterns
284  int *compressed_bits_size_p = (int *) input;
285  int compressed_bits_size = *compressed_bits_size_p;
286  input += sizeof(int);
287  input_size -= sizeof(int);
288 
289  // Uncompress bit patterns
290  start_input_buffer(&input_buffer, input);
291  decode_bits(&input_buffer, output, uncompressed_size);
292 
293  return uncompressed_size * sizeof(tdc400_word);
294 }
void tdc400_load ( )

Definition at line 30 of file tdc400_compress.cpp.

References hDB, huffman_init_default(), load_huffman(), should_compress_tdc400, size, and TRUE.

Referenced by compress_load_all().

31 {
35 
36  load_huffman("/Compression/Lossless/TDC400/Huffman/Time", &time_huffman);
37  load_huffman("/Compression/Lossless/TDC400/Huffman/Bits 0", &bits_huffman[0]);
38  load_huffman("/Compression/Lossless/TDC400/Huffman/Bits 1", &bits_huffman[1]);
39 
40  int size = sizeof(BOOL);
41  db_get_value(hDB, 0, "/Compression/Lossless/TDC400/Enabled", &should_compress_tdc400,
42  &size, TID_BOOL, TRUE);
43 }
void tdc400_optimize ( )

Definition at line 19 of file tdc400_compress.cpp.

References huffman_optimize_tree(), and save_huffman().

Referenced by compress_optimize_all().

20 {
24 
25  save_huffman("/Compression/Lossless/TDC400/Huffman/Time", &time_huffman);
26  save_huffman("/Compression/Lossless/TDC400/Huffman/Bits 0", &bits_huffman[0]);
27  save_huffman("/Compression/Lossless/TDC400/Huffman/Bits 1", &bits_huffman[1]);
28 }

Variable Documentation

huffman_table bits_huffman[2]

Definition at line 15 of file tdc400_compress.cpp.

BOOL should_compress_tdc400 = TRUE

Definition at line 17 of file tdc400_compress.cpp.

Referenced by compress_event(), and tdc400_load().

huffman_table time_huffman

Definition at line 16 of file tdc400_compress.cpp.