5 #ifndef artdaq_dune_Overlays_FelixComp_hh 6 #define artdaq_dune_Overlays_FelixComp_hh 16 #include <unordered_map> 21 #include "artdaq-core/Data/Fragment.hh" 65 std::unordered_map<uint16_t, Node*>
nodes;
72 if (loc->
left == NULL) {
73 std::cout <<
"Node with value " << loc->
value <<
", frequency " 75 << std::bitset<32>(loc->
huffcode) <<
" length " 87 std::ofstream ofile(filename);
89 ofile <<
"Value\tFrequency\tCode\tLength\n";
90 std::vector<Node*> local_nlist;
95 local_nlist.push_back(n);
98 std::sort(local_nlist.begin(), local_nlist.end());
100 for(
unsigned i = 0; i < local_nlist.size(); ++i) {
101 Node*
n = local_nlist[i];
102 if(n->
value > (1<<16)/2) {
105 if(n->
value > 1000)
continue;
116 if (loc->
left == NULL) {
132 std::unordered_map<uint16_t, Node*>
make_tree(std::vector<Node> nodevec) {
134 std::sort(nodevec.begin(), nodevec.end());
136 const unsigned totlen = 2 * nodevec.size() - 1;
138 nodelist =
new Node[totlen];
142 for (
unsigned i = 0; i < totlen - nodevec.size(); ++i) {
148 Node* sec_lowest = lowest + 1;
152 for (
Node*
n = nodelist;
n != nodelist + nodevec.size() + i; ++
n) {
160 }
else if (
n->frequency < sec_lowest->
frequency &&
n != lowest) {
174 Node* newNode = &nodelist[nodevec.size() + i];
175 newNode->
left = lowest;
176 newNode->
right = sec_lowest;
183 root = &nodelist[totlen - 1];
194 uint32_t comp_method : 2, unique_values : 14, num_frames : 16;
217 : input(data), input_length(num_frames * sizeof(
dune::
FelixFrame)) {}
219 : input(frag.dataBeginBytes()), input_length(frag.dataSizeBytes()) {}
227 MetaData meta = {1, 0, (uint32_t)num_frames};
228 out.resize(
sizeof(meta));
229 memcpy(&out[0], &meta,
sizeof(meta));
235 std::vector<uint8_t> bad_headers(num_frames/8 + 1);
237 for (
unsigned i = 1; i < num_frames; ++i) {
238 bool check_failed =
false;
241 check_failed |= frame_()->sof() ^ frame_(i)->sof();
242 check_failed |= frame_()->version() ^ frame_(i)->version();
243 check_failed |= frame_()->fiber_no() ^ frame_(i)->fiber_no();
244 check_failed |= frame_()->crate_no() ^ frame_(i)->crate_no();
245 check_failed |= frame_()->slot_no() ^ frame_(i)->slot_no();
246 check_failed |= frame_()->mm() ^ frame_(i)->mm();
247 check_failed |= frame_()->oos() ^ frame_(i)->oos();
248 check_failed |= frame_()->wib_errors() ^ frame_(i)->wib_errors();
249 check_failed |= frame_()->z() ^ frame_(i)->z();
252 (uint64_t)(frame_()->timestamp() + 25 * i) ^ frame_(i)->timestamp();
255 for (
unsigned j = 0; j < 4; ++j) {
256 check_failed |= frame_()->s1_error(j) ^ frame_(i)->s1_error(j);
257 check_failed |= frame_()->s2_error(j) ^ frame_(i)->s2_error(j);
258 check_failed |= frame_()->checksum_a(j) ^ frame_(i)->checksum_a(j);
259 check_failed |= frame_()->checksum_b(j) ^ frame_(i)->checksum_b(j);
261 frame_()->error_register(j) ^ frame_(i)->error_register(j);
262 for (
unsigned h = 0;
h < 8; ++
h) {
263 check_failed |= frame_()->hdr(j,
h) ^ frame_(i)->hdr(j,
h);
267 (uint16_t)(frame_()->coldata_convert_count(j) + 25 * i) ^
268 frame_(i)->coldata_convert_count(j);
273 bad_headers[i/8] |= 1 << (i%8);
287 size_t tail = out.size();
288 out.resize(tail + num_frames/8+1);
289 memcpy(&out[tail], &bad_headers[0], bad_headers.size());
295 memcpy(&out[tail], frame_()->wib_header(),
sizeof(
WIBHeader));
296 memcpy(&out[tail +
sizeof(
WIBHeader)], frame_()->coldata_header(0),
306 for(
unsigned i = 1; i < num_frames; ++i) {
307 bool check_failed = (bad_headers[i / 8] >> (7 - (i % 8))) & 1;
308 if(!check_failed) {
continue; }
313 memcpy(&out[tail], frame_(i)->wib_header(),
sizeof(
WIBHeader));
314 for(
unsigned j = 0; j < 4; ++j) {
315 memcpy(&out[tail +
sizeof(
WIBHeader)], frame_(i)->coldata_header(j),
324 std::unordered_map<adc_t, uint32_t> freq_table;
325 for (
unsigned vi = 0; vi < frame_()->num_ch_per_frame; ++vi) {
326 freq_table[frame_(0)->channel(vi)]++;
327 for (
unsigned fri = 1; fri < num_frames; ++fri) {
329 adc_t curr_val = frame_(fri)->channel(vi) - frame_(fri - 1)->channel(vi);
331 adc_t curr_val = frame_(fri)->channel(vi);
333 freq_table[curr_val]++;
343 size_t tail = out.size();
344 out.resize(tail + freq_table.size() * (
sizeof(
adc_t) + 4));
345 for (
auto p : freq_table) {
346 memcpy(&out[tail], &
p.first,
sizeof(
p.first));
347 memcpy(&out[tail +
sizeof(
p.first)], &
p.second,
sizeof(
p.second));
348 tail +=
sizeof(
p.first) +
sizeof(
p.second);
353 std::vector<HuffTree::Node>
nodes;
355 const unsigned num_vals = num_frames * frame_()->num_ch_per_frame;
356 for (
auto p : freq_table) {
358 curr_node.
value =
p.first;
360 nodes.push_back(curr_node);
362 entropy += (double)
p.second / num_vals * log((
double)num_vals /
p.second);
373 const size_t tail = out.size();
374 out.resize(tail +
sizeof(
adc_t) * num_frames * 256);
376 unsigned rec_bits = 0;
377 const char*
dest = &out[0] + tail;
379 for(
unsigned j = 0; j < 256; ++j) {
380 adc_t curr_val = frame_(0)->channel(j);
381 *(
unsigned long*)(dest + (rec_bits/8)) |= hufftree(curr_val)->huffcode << (rec_bits%8);
382 rec_bits += hufftree(curr_val)->hufflength;
384 for (
unsigned i = 1; i < num_frames; ++i) {
386 adc_t curr_val = frame_(i)->channel(j) - frame_(i - 1)->channel(j);
388 adc_t curr_val = frame_(i)->channel(j);
392 *(uint64_t*)(dest + (rec_bits/8)) |= hufftree(curr_val)->huffcode << (rec_bits%8);
393 rec_bits += hufftree(curr_val)->hufflength;
397 out.resize(tail + rec_bits / 8 + 1);
417 generate_Huff_tree(out);
447 const char* src = buff.data();
453 result.resizeBytes(num_frames *
sizeof(
FelixFrame));
460 std::vector<uint8_t> bad_headers(num_frames/8+1);
461 memcpy(&bad_headers[0], src, num_frames/8+1);
462 src += num_frames / 8 + 1;
467 std::vector<const ColdataHeader*> chead(4);
468 for(
unsigned i = 0; i < 4; ++i) {
472 size_t bad_header_counter = 0;
473 for (
unsigned i = 0; i < num_frames; ++i) {
475 std::vector<const ColdataHeader*> curr_chead(4);
477 bool bad_header = (bad_headers[i / 8] >> (7 - (1 % 8))) & 1;
479 ++bad_header_counter;
481 std::cout <<
"BAD HEADER\n";
483 src + bad_header_counter * sizeof_header_set);
484 for (
unsigned j = 0; j < 4; ++j) {
486 src + bad_header_counter * sizeof_header_set +
492 for(
unsigned j = 0; j < 4; ++j) {
493 curr_chead[j] = chead[j];
497 (frame + i)->set_sof(curr_whead->
sof);
498 (frame + i)->set_version(curr_whead->
version);
499 (frame + i)->set_fiber_no(curr_whead->
fiber_no);
500 (frame + i)->set_crate_no(curr_whead->
crate_no);
501 (frame + i)->set_slot_no(curr_whead->
slot_no);
502 (frame + i)->set_mm(curr_whead->
mm);
503 (frame + i)->set_oos(curr_whead->
oos);
504 (frame + i)->set_wib_errors(curr_whead->
wib_errors);
505 (frame + i)->set_timestamp(curr_whead->
timestamp() + i * 25);
506 (frame + i)->set_wib_counter(curr_whead->
wib_counter());
507 (frame + i)->set_z(curr_whead->
z);
508 for(
unsigned j = 0; j < 4; ++j) {
509 (frame + i)->set_s1_error(j, curr_chead[j]->s1_error);
510 (frame + i)->set_s2_error(j, curr_chead[j]->s2_error);
511 (frame + i)->set_coldata_convert_count(
512 j, curr_chead[j]->coldata_convert_count + i * 25);
513 (frame + i)->set_error_register(j, curr_chead[j]->error_register);
516 src += (bad_header_counter+1) * sizeof_header_set;
519 std::unordered_map<uint16_t, unsigned> freq_table;
520 for (
unsigned i = 0; i < unique_values; ++i) {
521 const uint16_t* v =
reinterpret_cast<uint16_t
const*
>(src);
523 reinterpret_cast<uint32_t
const*
>(src +
sizeof(uint16_t));
525 src +=
sizeof(uint16_t) +
sizeof(uint32_t);
527 std::vector<HuffTree::Node>
nodes;
528 for (
auto p : freq_table) {
530 curr_node.
value =
p.first;
532 nodes.push_back(curr_node);
538 size_t bits_read = 0;
539 for (
unsigned i = 0; i < num_frames * 256; ++i) {
542 while (pnode->
left != NULL) {
543 if (*src >> (bits_read % 8) & 1) {
544 pnode = pnode->
right;
550 if (bits_read % 8 == 0) {
557 if (i % num_frames != 0) {
558 found_val += (frame + i % num_frames - 1)->
channel(i / num_frames);
561 (frame + i % num_frames)->set_channel(i / num_frames, found_val);
void generate_Huff_tree(std::vector< char > &out)
void header_reduce(std::vector< char > &out)
void store_metadata(std::vector< char > &out)
artdaq::Fragment FelixDecompress(const std::vector< char > &buff)
bool valuecomp(const Node &one, const Node &other) const
void operator=(const Node &other)
std::unordered_map< uint16_t, Node * > nodes
FelixFrame const * frame_(const size_t &frame_num=0) const
std::unordered_map< uint16_t, Node * > make_tree(std::vector< Node > nodevec)
std::vector< char > FelixCompress(const dune::FelixFragment &frag)
FelixCompressor(const dune::FelixFragment &frag)
const size_t input_length
void printFile(std::string &filename)
Node * operator()(const uint16_t value)
void compress_copy(std::vector< char > &out)
FelixCompressor(const uint8_t *data, const size_t num_frames=10000)
void generate_codes(Node *loc, size_t buff=0, uint8_t len=0)
bool operator<(const Node &other) const
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
void ADC_compress(std::vector< char > &out)