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();
142 printHex(&headerTypeNibble, 1, msg);
175 return feHeader_->checkChannelStatusBits(internalFEDChannelNum);
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) {
210 return (data[wOffset ^ 7] >> (
BITS_PER_BYTE - bOffset)) & mask;
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};
275 while (offset != end) {
276 if (inCluster == nInCluster) {
277 if (offset + 2 >= end) {
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;
289 nInCluster = data[(offset++) ^ 7];
292 *
out++ =
SiStripDigi(stripStart + firstStrip + inCluster, getADC_W<num_words>(data, offset, bits_shift));
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;
430 samples.reserve((channel.
length() - 3) / 2);
431 st = detail::unpackRawW<16>(channel, std::back_inserter(samples));
433 samples.reserve((channel.
length() - 3) * 10 / 8);
434 st = detail::unpackRawB<10>(channel, std::back_inserter(samples));
436 samples.reserve(channel.
length() - 3);
437 st = detail::unpackRawW<8>(
440 if (!samples.empty()) {
441 for (uint_fast16_t
i{0};
i != samples.size(); ++
i) {
442 const auto physical =
i % 128;
444 + (
i >= 128 ? 1 : 0));
445 *
out++ = samples[readout];
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
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_BOTBOT
bool checkFEUnitLengths() const
bool checkStatusBits(const uint8_t internalFEDChannelNum) const
StatusCode unpackZeroSuppressed(const FEDChannel &channel, OUT &&out, uint16_t stripStart, bool isNonLite, FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID, uint8_t packetCode=0)
std::string checkSummary() const override
virtual bool doCorruptBufferChecks() const
bool checkFEPayloadsPresent() const
StatusCode unpackRawW(const FEDChannel &channel, OUT &&out, uint8_t bits_shift=0)
FEDReadoutMode readoutMode() const
FEDBuffer(const FEDRawData &fedBuffer, const bool allowBadBuffer=false)
uint8_t internalFEDChannelNum(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum)
bool isScopeMode(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
FEDBufferStatusCode findChannels()
StatusCode unpackZSW(const FEDChannel &channel, OUT &&out, uint8_t headerLength, uint16_t stripStart, uint8_t bits_shift=0)
const FEDFEHeader * feHeader() const
uint16_t getADC_B1(const uint8_t *data, uint_fast16_t wOffset, uint_fast8_t bOffset)
std::string toString(fedchannelunpacker::StatusCode status)
bool feGoodWithoutAPVEmulatorCheck(const uint8_t internalFEUnitNum) const
bool fePresent_[FEUNITS_PER_FED]
StatusCode unpackZSB(const FEDChannel &channel, OUT &&out, uint8_t headerLength, uint16_t stripStart)
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_TOPBOT
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED10
void setLegacyMode(bool legacy)
static const uint8_t PACKET_CODE_VIRGIN_RAW10
bool isProcessedRaw(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
const uint8_t * payloadPointer_
bool fePresent(uint8_t internalFEUnitNum) const
bool majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const
static const uint16_t FEUNITS_PER_FED
uint16_t getADC_W(const uint8_t *data, uint_fast16_t offset, uint8_t bits_shift)
constexpr uint16_t BITS_PER_BYTE
bool isVirginRaw(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
StatusCode unpackVirginRaw(const FEDChannel &channel, OUT &&out, uint8_t packetCode)
uint8_t packetCode(bool legacy=false, const uint8_t internalFEDChannelNum=0) const
A Digi for the silicon strip detector, containing both strip and adc information, and suitable for st...
bool channelGood(const uint8_t internalFEDannelNum, const bool doAPVeCheck) const
static const uint8_t PACKET_CODE_VIRGIN_RAW8_TOPBOT
bool checkChannelPacketCodes() const
StatusCode unpackScope(const FEDChannel &channel, OUT &&out)
static const uint8_t PACKET_CODE_VIRGIN_RAW8_BOTBOT
void printHex(const void *pointer, const size_t length, std::ostream &os)
uint8_t nFEUnitsPresent() const
bool isZeroSuppressed(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
static const uint16_t FEDCH_PER_FEUNIT
std::unique_ptr< FEDFEHeader > feHeader_
bool checkFEUnitAPVAddresses() const
StatusCode unpackRawB(const FEDChannel &channel, OUT &&out)
const uint8_t * data() const
uint8_t getCorrectPacketCode() const
bool checkChannelLengthsMatchBufferLength() const
bool isNonLiteZS(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
char data[epos_bytes_allocation]
static const uint16_t FEDCH_PER_FED
bool checkAllChannelStatusBits() const
uint16_t getADC_B2(const uint8_t *data, uint_fast16_t wOffset, uint_fast8_t bOffset)
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
virtual bool channelGood(const uint8_t internalFEDChannelNum) const
uint16_t calculateFEUnitLength(const uint8_t internalFEUnitNumber) const
FEDBufferStatusCode preconstructCheckFEDBuffer(const FEDRawData &fedBuffer, bool allowBadBuffer=false)
uint16_t readoutOrder(uint16_t physical_order)
bool checkChannelLengths() const
void print(std::ostream &os) const override
FEDBufferStatusCode preconstructCheckFEDBufferBase(const FEDRawData &fedBuffer, bool checkRecognizedFormat=true)
bool feGood(const uint8_t internalFEUnitNum) const
A Digi for the silicon strip detector, containing only adc information, and suitable for storing raw ...
static const uint8_t PACKET_CODE_VIRGIN_RAW
StatusCode unpackProcessedRaw(const FEDChannel &channel, OUT &&out)
bool feOverflow(const uint8_t internalFEUnitNum) const