AlcapDAQ  1
hits_compress.cpp
Go to the documentation of this file.
1 //
3 // HITS bank compression (for use with "skimmed" data)
4 //
6 
7 #include <stdio.h>
8 #include <assert.h>
9 
10 #include "midas.h"
11 
12 #include "mucap_compress.h"
13 #include "mucap_structures.h"
14 
17 
19 {
20  huffman_optimize_tree(&hits_parameter_huffman);
21  save_huffman("/Compression/Lossless/HITS/Huffman/Parameter", &hits_parameter_huffman);
22 }
23 
24 void hits_load()
25 {
26  huffman_init_default(&hits_parameter_huffman, 322);
27  load_huffman("/Compression/Lossless/HITS/Huffman/Parameter", &hits_parameter_huffman);
28 
29  int size = sizeof(BOOL);
30  db_get_value(hDB, 0, "/Compression/Lossless/HITS/Enabled", &should_compress_hits,
31  &size, TID_BOOL, TRUE);
32 }
33 
34 int encode_hits(channel_hit * input, int input_size, io_buffer * output,
35  int *uncompressed_size_p)
36 {
37  int prev_time = 0;
38  int prev_parameter = 0;
39 
40  for (int i = 0; i < input_size; i++) {
41  //printf("par %d time %f\n", input[i].parameter, input[i].time);
42 
43  int parameter = input[i].parameter;
44  int parameter_diff = parameter - prev_parameter + 161;
45  if(parameter_diff <= 0 || parameter_diff >= 322) {
46  parameter_diff = 0;
47  }
48  huffman_put_symbol(&hits_parameter_huffman, output, parameter_diff);
49  if(parameter_diff == 0) {
50  io_buffer_put(output, parameter, 13);
51  }
52 
53  int time = (int) ((input[i].time+0.01)/1.25);
54  int time_diff = time - prev_time;
55  assert (time_diff >= 0);
56 
57  if (time_diff < 64) {
58  io_buffer_put(output, 0, 1);
59  io_buffer_put(output, time_diff & 0x3f, 6);
60  } else if (time_diff < 4096) {
61  io_buffer_put(output, 2, 2);
62  io_buffer_put(output, time_diff & 0xfff, 12);
63  } else {
64  io_buffer_put(output, 3, 2);
65  io_buffer_put(output, time_diff, 29);
66  }
67 
68  prev_time = time;
69  prev_parameter = parameter;
70  }
71 
72  *uncompressed_size_p = input_size;
73 
74  return flush_output_buffer(output);
75 }
76 
77 int hits_compress(channel_hit * input, int input_size, unsigned char *output, int userParam)
78 {
79  input_size /= sizeof(channel_hit);
80 
82 
83  io_buffer output_buffer;
84 
85  // reserve space for size of uncompressed data (may be different from
86  // input size, since some hits may be stripped)
87  int *uncompressed_size_p = (int *) output;
88  output += sizeof(int);
89 
90  // reserve space for the size of the compressed data
91  int *compressed_time_size_p = (int *) output;
92  output += sizeof(int);
93 
94  // compress times
95  start_output_buffer(&output_buffer, output);
96  int compressed_time_size =
97  encode_hits(input, input_size, &output_buffer, uncompressed_size_p);
98  output += compressed_time_size;
99 
100  // store size of compressed times
101  *compressed_time_size_p = compressed_time_size;
102 
103  return compressed_time_size + 2 * sizeof(int);
104 }
105 
106 void decode_hits(io_buffer * input, channel_hit * output)
107 {
108  int prev_time = 0;
109  int prev_parameter = 0;
110 
111  int i = 0;
112  while (1) {
113 
114  int parameter = 0;
115  int parameter_diff = huffman_get_symbol(&hits_parameter_huffman, input);
116  if (parameter_diff < 0) {
117  break;
118  } else if(parameter_diff == 0) {
119  parameter = io_buffer_get(input, 13);
120  } else {
121  parameter = prev_parameter + parameter_diff - 161;
122  }
123  output[i].parameter = parameter;
124 
125  int time_length_flag1 = io_buffer_get(input, 1);
126  int time_diff;
127  if (time_length_flag1 == 0) {
128  time_diff = io_buffer_get(input, 6);
129  } else {
130  int time_length_flag2 = io_buffer_get(input, 1);
131  if (time_length_flag2 == 0) {
132  time_diff = io_buffer_get(input, 12);
133  } else {
134  time_diff = io_buffer_get(input, 29);
135  }
136  }
137 
138  output[i].time = (prev_time + time_diff) * 1.25;
139  prev_time = prev_time + time_diff;
140  prev_parameter = parameter;
141 
142  //printf("par %d time %f\n", output[i].parameter, output[i].time);
143 
144  i++;
145  }
146 }
147 
148 int hits_expand(unsigned char *input, int input_size, channel_hit * output, int userParam)
149 {
150  //
151  // Uncompress the data produced by hits_compress().
152  //
153 
154  rle_bits_setup();
155 
156  // Get uncompressed data size
157  int *uncompressed_size_p = (int *) input;
158  int uncompressed_size = *uncompressed_size_p;
159  input += sizeof(int);
160  input_size -= sizeof(int);
161 
162  // Get size of compressed time data
163  int *compressed_time_size_p = (int *) input;
164  int compressed_time_size = *compressed_time_size_p;
165  input += sizeof(int);
166  input_size -= sizeof(int);
167 
168  // Uncompress times
169  io_buffer input_buffer;
170  start_input_buffer(&input_buffer, input);
171  decode_hits(&input_buffer, output);
172  input += compressed_time_size;
173  input_size -= compressed_time_size;
174 
175  return uncompressed_size * sizeof(channel_hit);
176 }