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 virtual bool channelGood(
const uint8_t internalFEDannelNum,
const bool doAPVeCheck =
true)
const;
73 virtual bool doChecks(
bool doCRC =
true)
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();
175 namespace fedchannelunpacker {
180 template <u
int8_t num_words>
183 return (
data[
offset ^ 7] + (num_words == 2 ? ((
data[(
offset + 1) ^ 7] & 0x03) << 8) : 0)) << bits_shift;
186 template <u
int16_t mask>
187 uint16_t
getADC_B2(
const uint8_t*
data, uint_fast16_t wOffset, uint_fast8_t bOffset) {
189 return (((
data[wOffset ^ 7]) << bOffset) + (
data[(wOffset + 1) ^ 7] >> (
BITS_PER_BYTE - bOffset))) & mask;
191 template <u
int16_t mask>
192 uint16_t
getADC_B1(
const uint8_t*
data, uint_fast16_t wOffset, uint_fast8_t bOffset) {
198 template <u
int8_t num_bits,
typename OUT>
200 constexpr
auto num_words = num_bits / 8;
201 static_assert(((num_bits % 8) == 0) && (num_words > 0) && (num_words < 3));
202 if ((num_words > 1) && ((channel.
length() - 3) % num_words)) {
203 LogDebug(
"FEDBuffer") <<
"Channel length is invalid. Raw channels have 3 header bytes and " << num_words
204 <<
" bytes per sample. "
205 <<
"Channel length is " << uint16_t(channel.
length()) <<
".";
208 const uint8_t*
const data = channel.
data();
217 template <u
int_fast8_t num_bits,
typename OUT>
219 static_assert(num_bits <= 16,
"Word length must be between 0 and 16.");
220 if (channel.
length() & 0xF000) {
221 LogDebug(
"FEDBuffer") <<
"Channel length is invalid. Channel length is " << uint16_t(channel.
length()) <<
".";
224 constexpr uint16_t mask = (1 << num_bits) - 1;
225 const uint8_t*
const data = channel.
data();
226 const uint_fast16_t chEnd = channel.
offset() + channel.
length();
227 uint_fast16_t wOffset = channel.
offset() + 3;
228 uint_fast8_t bOffset = 0;
229 while (((wOffset + 1) < chEnd) || ((chEnd - wOffset) *
BITS_PER_BYTE - bOffset >= num_bits)) {
246 template <u
int8_t num_bits,
typename OUT>
248 const FEDChannel& channel,
OUT&&
out, uint8_t headerLength, uint16_t stripStart, uint8_t bits_shift = 0) {
249 constexpr
auto num_words = num_bits / 8;
250 static_assert(((num_bits % 8) == 0) && (num_words > 0) && (num_words < 3));
251 if (channel.
length() & 0xF000) {
252 LogDebug(
"FEDBuffer") <<
"Channel length is invalid. Channel length is " << uint16_t(channel.
length()) <<
".";
255 const uint8_t*
const data = channel.
data();
257 uint_fast8_t firstStrip{0}, nInCluster{0}, inCluster{0};
260 if (inCluster == nInCluster) {
265 const uint_fast8_t newFirstStrip =
data[(
offset++) ^ 7];
266 if (newFirstStrip < (firstStrip + inCluster)) {
267 LogDebug(
"FEDBuffer") <<
"First strip of new cluster is not greater than last strip of previous cluster. "
268 <<
"Last strip of previous cluster is " << uint16_t(firstStrip + inCluster) <<
". "
269 <<
"First strip of new cluster is " << uint16_t(newFirstStrip) <<
".";
272 firstStrip = newFirstStrip;
284 template <u
int_fast8_t num_bits,
typename OUT>
286 constexpr uint16_t mask = (1 << num_bits) - 1;
287 if (channel.
length() & 0xF000) {
288 LogDebug(
"FEDBuffer") <<
"Channel length is invalid. Channel length is " << uint16_t(channel.
length()) <<
".";
291 const uint8_t*
const data = channel.
data();
292 uint_fast16_t wOffset = channel.
offset() + headerLength;
293 uint_fast8_t bOffset{0}, firstStrip{0}, nInCluster{0}, inCluster{0};
294 const uint_fast16_t chEnd = channel.
offset() + channel.
length();
295 while (((wOffset + 1) < chEnd) ||
296 ((inCluster != nInCluster) && ((chEnd - wOffset) *
BITS_PER_BYTE - bOffset >= num_bits))) {
297 if (inCluster == nInCluster) {
298 if (wOffset + 2 >= chEnd) {
306 const uint_fast8_t newFirstStrip =
data[(wOffset++) ^ 7];
307 if (newFirstStrip < (firstStrip + inCluster)) {
308 LogDebug(
"FEDBuffer") <<
"First strip of new cluster is not greater than last strip of previous cluster. "
309 <<
"Last strip of previous cluster is " << uint16_t(firstStrip + inCluster) <<
". "
310 <<
"First strip of new cluster is " << uint16_t(newFirstStrip) <<
".";
313 firstStrip = newFirstStrip;
314 nInCluster =
data[(wOffset++) ^ 7];
321 *
out++ =
SiStripDigi(stripStart + firstStrip + inCluster, getADC_B2<mask>(
data, wOffset, bOffset));
324 *
out++ =
SiStripDigi(stripStart + firstStrip + inCluster, getADC_B1<mask>(
data, wOffset, bOffset));
336 return (4 * ((static_cast<uint16_t>((static_cast<float>(physical_order) / 8.0))) % 4) +
337 static_cast<uint16_t>(static_cast<float>(physical_order) / 32.0) + 16 * (physical_order % 8));
400 template <
typename OUT>
402 return detail::unpackRawW<16>(channel,
out);
404 template <
typename OUT>
406 return detail::unpackRawW<16>(channel,
out);
409 template <
typename OUT>
411 std::vector<SiStripRawDigi>
samples;
415 st = detail::unpackRawW<16>(channel, std::back_inserter(
samples));
418 st = detail::unpackRawB<10>(channel, std::back_inserter(
samples));
421 st = detail::unpackRawW<8>(
425 for (uint_fast16_t
i{0};
i !=
samples.size(); ++
i) {
426 const auto physical =
i % 128;
428 + (
i >= 128 ? 1 : 0));
434 template <
typename OUT>
442 uint8_t packetCode = 0) {
446 return detail::unpackZSB<10>(channel,
out, (isNonLite ? 7 : 2), stripStart);
448 return detail::unpackZSW<16>(channel,
out, 7, stripStart);
450 uint8_t bits_shift = 0;
464 auto st = detail::unpackZSW<8>(channel,
out, (isNonLite ? 7 : 2), stripStart, bits_shift);
476 #endif //ndef EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H