1 #ifndef EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H
2 #define EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H
56 void print(std::ostream& os)
const override;
59 bool feGood(
const uint8_t internalFEUnitNum)
const;
64 bool fePresent(uint8_t internalFEUnitNum)
const;
67 bool channelGood(
const uint8_t internalFEDannelNum,
const bool doAPVeCheck)
const;
92 bool checkStatusBits(
const uint8_t internalFEUnitNum,
const uint8_t internalChannelNum)
const;
136 const auto hdr_type = hdr.headerType();
139 std::ostringstream
msg;
140 msg <<
"Header type is invalid. Header type nibble is ";
141 const auto headerTypeNibble = hdr.headerTypeNibble();
191 namespace fedchannelunpacker {
196 template <u
int8_t num_words>
199 return (
data[
offset ^ 7] + (num_words == 2 ? ((
data[(
offset + 1) ^ 7] & 0x03) << 8) : 0)) << bits_shift;
202 template <u
int16_t mask>
203 uint16_t
getADC_B2(
const uint8_t*
data, uint_fast16_t wOffset, uint_fast8_t bOffset) {
205 return (((
data[wOffset ^ 7]) << bOffset) + (
data[(wOffset + 1) ^ 7] >> (
BITS_PER_BYTE - bOffset))) & mask;
207 template <u
int16_t mask>
208 uint16_t
getADC_B1(
const uint8_t*
data, uint_fast16_t wOffset, uint_fast8_t bOffset) {
214 template <u
int8_t num_bits,
typename OUT>
216 constexpr
auto num_words = num_bits / 8;
217 static_assert(((num_bits % 8) == 0) && (num_words > 0) && (num_words < 3));
218 if ((num_words > 1) && ((channel.
length() - 3) % num_words)) {
219 LogDebug(
"FEDBuffer") <<
"Channel length is invalid. Raw channels have 3 header bytes and " << num_words
220 <<
" bytes per sample. "
221 <<
"Channel length is " << uint16_t(channel.
length()) <<
".";
224 const uint8_t*
const data = channel.
data();
233 template <u
int_fast8_t num_bits,
typename OUT>
235 static_assert(num_bits <= 16,
"Word length must be between 0 and 16.");
236 if (channel.
length() & 0xF000) {
237 LogDebug(
"FEDBuffer") <<
"Channel length is invalid. Channel length is " << uint16_t(channel.
length()) <<
".";
240 constexpr uint16_t mask = (1 << num_bits) - 1;
241 const uint8_t*
const data = channel.
data();
242 const uint_fast16_t chEnd = channel.
offset() + channel.
length();
243 uint_fast16_t wOffset = channel.
offset() + 3;
244 uint_fast8_t bOffset = 0;
245 while (((wOffset + 1) < chEnd) || ((chEnd - wOffset) *
BITS_PER_BYTE - bOffset >= num_bits)) {
262 template <u
int8_t num_bits,
typename OUT>
264 const FEDChannel& channel,
OUT&&
out, uint8_t headerLength, uint16_t stripStart, uint8_t bits_shift = 0) {
265 constexpr
auto num_words = num_bits / 8;
266 static_assert(((num_bits % 8) == 0) && (num_words > 0) && (num_words < 3));
267 if (channel.
length() & 0xF000) {
268 LogDebug(
"FEDBuffer") <<
"Channel length is invalid. Channel length is " << uint16_t(channel.
length()) <<
".";
271 const uint8_t*
const data = channel.
data();
273 uint_fast8_t firstStrip{0}, nInCluster{0}, inCluster{0};
276 if (inCluster == nInCluster) {
281 const uint_fast8_t newFirstStrip =
data[(
offset++) ^ 7];
282 if (newFirstStrip < (firstStrip + inCluster)) {
283 LogDebug(
"FEDBuffer") <<
"First strip of new cluster is not greater than last strip of previous cluster. "
284 <<
"Last strip of previous cluster is " << uint16_t(firstStrip + inCluster) <<
". "
285 <<
"First strip of new cluster is " << uint16_t(newFirstStrip) <<
".";
288 firstStrip = newFirstStrip;
300 template <u
int_fast8_t num_bits,
typename OUT>
302 constexpr uint16_t mask = (1 << num_bits) - 1;
303 if (channel.
length() & 0xF000) {
304 LogDebug(
"FEDBuffer") <<
"Channel length is invalid. Channel length is " << uint16_t(channel.
length()) <<
".";
307 const uint8_t*
const data = channel.
data();
308 uint_fast16_t wOffset = channel.
offset() + headerLength;
309 uint_fast8_t bOffset{0}, firstStrip{0}, nInCluster{0}, inCluster{0};
310 const uint_fast16_t chEnd = channel.
offset() + channel.
length();
311 while (((wOffset + 1) < chEnd) ||
312 ((inCluster != nInCluster) && ((chEnd - wOffset) *
BITS_PER_BYTE - bOffset >= num_bits))) {
313 if (inCluster == nInCluster) {
314 if (wOffset + 2 >= chEnd) {
322 const uint_fast8_t newFirstStrip =
data[(wOffset++) ^ 7];
323 if (newFirstStrip < (firstStrip + inCluster)) {
324 LogDebug(
"FEDBuffer") <<
"First strip of new cluster is not greater than last strip of previous cluster. "
325 <<
"Last strip of previous cluster is " << uint16_t(firstStrip + inCluster) <<
". "
326 <<
"First strip of new cluster is " << uint16_t(newFirstStrip) <<
".";
329 firstStrip = newFirstStrip;
330 nInCluster =
data[(wOffset++) ^ 7];
337 *
out++ =
SiStripDigi(stripStart + firstStrip + inCluster, getADC_B2<mask>(
data, wOffset, bOffset));
340 *
out++ =
SiStripDigi(stripStart + firstStrip + inCluster, getADC_B1<mask>(
data, wOffset, bOffset));
352 return (4 * ((static_cast<uint16_t>((static_cast<float>(physical_order) / 8.0))) % 4) +
353 static_cast<uint16_t>(static_cast<float>(physical_order) / 32.0) + 16 * (physical_order % 8));
416 template <
typename OUT>
418 return detail::unpackRawW<16>(channel,
out);
420 template <
typename OUT>
422 return detail::unpackRawW<16>(channel,
out);
425 template <
typename OUT>
427 std::vector<SiStripRawDigi>
samples;
431 st = detail::unpackRawW<16>(channel, std::back_inserter(
samples));
434 st = detail::unpackRawB<10>(channel, std::back_inserter(
samples));
437 st = detail::unpackRawW<8>(
441 for (uint_fast16_t
i{0};
i !=
samples.size(); ++
i) {
442 const auto physical =
i % 128;
444 + (
i >= 128 ? 1 : 0));
450 template <
typename OUT>
458 uint8_t packetCode = 0) {
462 return detail::unpackZSB<10>(channel,
out, (isNonLite ? 7 : 2), stripStart);
464 return detail::unpackZSW<16>(channel,
out, 7, stripStart);
466 uint8_t bits_shift = 0;
480 auto st = detail::unpackZSW<8>(channel,
out, (isNonLite ? 7 : 2), stripStart, bits_shift);
492 #endif //ndef EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H