Orion
high-rate readout
decoder.hpp
1 #pragma once
2 
3 #include <bit>
4 #include <bitset>
5 #include <concepts>
6 #include <cstdint>
7 #include <iostream>
8 #include <type_traits>
9 
10 #include "itk/logger.hpp"
11 #include "itk/itkpix/geo/geometry.hpp"
13 
14 #include "bintree.hpp"
15 #include "bitstream.hpp"
16 #include "print_utils.hpp"
17 
18 
19 
20 namespace itk::itkpix::endec::codec {
21 
22 [[maybe_unused]] static inline print<false> logger;
23 
24 extern itk::Logger log;
25 
34 // using Hit = itk::pixel::datafmt::Hit;
35 using Options = itk::itkpix::endec::Options;
36 
37 //template <typename T, itkpix::concepts::DecoderOutput<Hit> OutPut, bool EnableLogging = false>
38 template <itk::itkpix::endec::concepts::EventCallback OutPut, bool EnableLogging = false>
40 // using ItkChip = itkpix::frontend::ItkChip;
41  static inline print<EnableLogging> logger;
42 
43  public:
44  StreamDecoder(const std::span<const uint64_t> data_, OutPut &proc, Options opt = Options())
45  : data(data_, opt.en_chip_id ? 3 : 1), out(proc), options(opt) {}
46 
47  ~StreamDecoder() = default;
48 
66  void decode() {
67  uint64_t ccol = 999999;
68  uint64_t tag;
69  uint64_t qrow = 0;
70  bool is_neighbor = false;
71  bool is_last = true;
72 
73  auto fetch_ccol = [&]() mutable -> bool {
74  bool result;
75  std::tie(result, ccol) = data.fetch(6);
76  logger.ccol(ccol);
77  if ((ccol >> 3) == 0b111) { // internal tag
78  auto [result1, intTag] = data.fetch(5);
79  intTag |= ((ccol & 0b111) << 5);
80  bool result2;
81  std::tie(result2, ccol) = data.fetch(6);
82  logger.internal_tag(intTag);
83  out.evt_init(intTag);
84  }
85  if (ccol == 0) return false;
86  return result;
87  };
88 
89  auto fetch_ctrl = [&]() mutable -> bool {
90  auto [result, ctrl] = data.fetch(2);
91  is_last = (ctrl & 2) == 2;
92  is_neighbor = (ctrl & 1) == 1;
93  logger.ctrl(ctrl);
94  return result;
95  };
96 
97  auto fetch_hitmap = [&]() -> bool {
98  auto [result, hit_map] = data.prefetch(30);
99  uint32_t decoded{};
100  auto len = BinaryTreeLUT::decode(hit_map, decoded);
101  data.advance(len);
102  logger.hitmap(hit_map >> (30 - len), len, decoded);
103  // auto hits = std::popcount(decoded);
104 
105  auto hits = BinaryTreeLUT::hit_lut_length[decoded];
106  auto [result1, tots] = data.fetch(hits * 4);
107  logger.tot(tots, hits);
108  // printf("hitmap: %04x, totmap: %016lx\n", decoded, tots);
109 
110  int hit_count = hits;
111  auto h = BinaryTreeLUT::hit_lut[decoded];
112 
113  uint16_t col_base = (ccol - 1) * itk::itkpix::geo::NumQColPix;
114  uint16_t row_base = qrow * itk::itkpix::geo::NumQRowPix;
115  for (int i = 0; i < hits; ++i) {
116  uint16_t col = col_base + uint16_t(h[i].first);
117  uint16_t row = row_base + uint16_t(h[i].second);
118  hit_count--;
119  uint16_t tot = ((tots >> (hit_count * 4)) & 0xf);
120  //tot++; // tot from 1..16
121  // hit_cache[i] = {col, row, tot};
122  out.add_hit(col, row, tot);
123  }
124  // out.add_hits(hit_cache.data(), hits);
125  return result;
126  };
127 
128  bool result;
129  std::tie(result, tag) = data.fetch(8);
130  logger.tag(tag);
131  out.evt_init(tag);
132  while (data.left() > 6 && ccol != 0) {
133  if (is_last) {
134  auto success = fetch_ccol();
135  if (!success) break;
136  }
137  fetch_ctrl();
138  if (!is_neighbor) {
139  bool result;
140  std::tie(result, qrow) = data.fetch(8);
141  logger.qrow(qrow);
142  } else {
143  qrow++;
144  }
145  fetch_hitmap();
146  }
147  }
148 
149  std::size_t bits_processed() const { return data.index(); }
150 
151 private:
152  static inline constexpr uint64_t bit_mask(std::size_t n) { return (uint64_t(1) << n) - 1; }
153 
154  BitStreamReader<const std::span<uint64_t>> data;
155  OutPut &out;
156  const Options options;
157 };
158 
159 
160 } // itk::itkpix::endec::codec
161 
162 
163 namespace itk::itkpix::endec::codec {
164 
165 extern itk::Logger log;
166 
167 template<typename Callback, int cb_type = 0>
168 class DecCore {
169 public:
170  using EventCallback = Callback;
171 
172  DecCore(Options opt, EventCallback& cb_evt)
173  : opt(opt), cb_evt(cb_evt) {
174  log.trace("slac.DecCore(opt, evt)");
175  }
176 
177  inline void initialize() {
178  log.trace("slac.initialize");
179  }
180  inline void finalize() {
181  log.trace("slac.finalize");
182  }
183  inline void decode(uint64_t data64) {
184  log.warn("not implemented | slac.decode(data64: 0x{:016x})", data64);
185  }
186  inline void decode(const uint8_t *buff, size_t size) {
187  auto data = std::span<const uint8_t>{buff, size};
188  decode(data);
189  }
190  inline void decode(const uint64_t *buff64, size_t size64) {
191  auto data64 = std::span<const uint64_t>{buff64, size64};
192  decode(data64);
193  }
194 
195  inline void decode(const std::span<const uint8_t> buff) {
196  log.trace("slac.decode(buff) | size64: {}", buff.size());
197  for (auto data : buff) {
198  log.trace(" 0x{:02x}", data);
199  }
200  }
201  inline void decode(const std::span<const uint64_t> buff64) {
202  //log.info("wittgen.decode(buff64) | size64: {}", buff64.size());
203  //for (auto data64 : buff64) {
204  // log.info(" 0x{:016x}", data64);
205  //}
206 
207  StreamDecoder<EventCallback> dec(buff64, cb_evt, opt);
208  dec.decode();
209  }
210 
211  Options opt;
212  EventCallback& cb_evt;
213 };
214 
215 } // itk::itkpix::endec::codec
Definition: test_enc_dec.cpp:117
Definition: decoder.hpp:168
Decode a ITK pixel data stream.
Definition: decoder.hpp:39
void decode()
Decode the ITK pixel data stream.
Definition: decoder.hpp:66
Logger class definition, wrapper around CoreLogger, adds templated methods for different logging leve...
Definition: logger.hpp:108
void trace(fmt::format_string< Args... > fmt, Args &&...args)
Logs a message with trace level.
Definition: logger.hpp:132
void warn(fmt::format_string< Args... > fmt, Args &&...args)
Logs a message with warning level.
Definition: logger.hpp:156
uint16_t size
Definition: fragheader.hpp:5
Templates for ITkPix Decoder Core.
Logger definitions.
Common encoder/decoder options.
Definition: options.hpp:10
Definition: print_utils.hpp:10