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) {
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>
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();
225 const uint_fast16_t end = channel.
offset() + channel.
length();
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()) <<
".";
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) {
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};
274 const uint_fast16_t end = channel.
offset() + channel.
length();
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>
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
FEDReadoutMode readoutMode() const
bool checkChannelLengthsMatchBufferLength() const
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_BOTBOT
bool feOverflow(const uint8_t internalFEUnitNum) const
const uint8_t * data() const
bool feGoodWithoutAPVEmulatorCheck(const uint8_t internalFEUnitNum) 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
StatusCode unpackRawW(const FEDChannel &channel, OUT &&out, uint8_t bits_shift=0)
const FEDFEHeader * feHeader() const
FEDBuffer(const FEDRawData &fedBuffer, const bool allowBadBuffer=false)
uint8_t internalFEDChannelNum(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum)
bool checkFEUnitAPVAddresses() const
uint16_t calculateFEUnitLength(const uint8_t internalFEUnitNumber) const
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)
uint8_t nFEUnitsPresent() const
bool checkFEUnitLengths() const
uint16_t getADC_B1(const uint8_t *data, uint_fast16_t wOffset, uint_fast8_t bOffset)
std::string toString(fedchannelunpacker::StatusCode status)
bool majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const
virtual bool doCorruptBufferChecks() 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
bool checkChannelPacketCodes() const
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_
static const uint16_t FEUNITS_PER_FED
bool checkFEPayloadsPresent() const
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)
A Digi for the silicon strip detector, containing both strip and adc information, and suitable for st...
bool checkAllChannelStatusBits() const
static const uint8_t PACKET_CODE_VIRGIN_RAW8_TOPBOT
uint8_t getCorrectPacketCode() const
bool channelGood(const uint8_t internalFEDannelNum, const bool doAPVeCheck) 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)
bool isZeroSuppressed(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
static const uint16_t FEDCH_PER_FEUNIT
bool checkStatusBits(const uint8_t internalFEDChannelNum) const
bool checkChannelLengths() const
std::unique_ptr< FEDFEHeader > feHeader_
StatusCode unpackRawB(const FEDChannel &channel, OUT &&out)
bool isNonLiteZS(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
virtual bool channelGood(const uint8_t internalFEDChannelNum) const
char data[epos_bytes_allocation]
static const uint16_t FEDCH_PER_FED
uint16_t getADC_B2(const uint8_t *data, uint_fast16_t wOffset, uint_fast8_t bOffset)
bool feGood(const uint8_t internalFEUnitNum) const
FEDBufferStatusCode preconstructCheckFEDBuffer(const FEDRawData &fedBuffer, bool allowBadBuffer=false)
uint16_t readoutOrder(uint16_t physical_order)
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
void print(std::ostream &os) const override
FEDBufferStatusCode preconstructCheckFEDBufferBase(const FEDRawData &fedBuffer, bool checkRecognizedFormat=true)
A Digi for the silicon strip detector, containing only adc information, and suitable for storing raw ...
bool fePresent(uint8_t internalFEUnitNum) const
static const uint8_t PACKET_CODE_VIRGIN_RAW
StatusCode unpackProcessedRaw(const FEDChannel &channel, OUT &&out)
uint8_t packetCode(bool legacy=false, const uint8_t internalFEDChannelNum=0) const