29#include <fairlogger/Logger.h>
32#define MCH_DECODER_MAX_ERROR_COUNT 100
45static constexpr uint32_t bcRollOver = (1 << 20);
46static constexpr uint32_t twentyBitsAtOne = 0xFFFFF;
50static std::array<int, 64> refManu2ds_st345_v5 = {
51 63, 62, 61, 60, 59, 57, 56, 53, 51, 50, 47, 45, 44, 41, 38, 35,
52 36, 33, 34, 37, 32, 39, 40, 42, 43, 46, 48, 49, 52, 54, 55, 58,
53 7, 8, 5, 2, 6, 1, 3, 0, 4, 9, 10, 15, 17, 18, 22, 25,
54 31, 30, 29, 28, 27, 26, 24, 23, 20, 21, 16, 19, 12, 14, 11, 13};
57static std::array<int, 64> refManu2ds_st345_v2 = {
58 62, 61, 63, 60, 59, 55, 58, 57, 56, 54, 50, 46, 42, 39, 37, 41,
59 35, 36, 33, 34, 32, 38, 43, 40, 45, 44, 47, 48, 49, 52, 51, 53,
60 7, 6, 5, 4, 2, 3, 1, 0, 9, 11, 13, 15, 17, 19, 21, 23,
61 31, 30, 29, 28, 27, 26, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8};
63#define refManu2ds_st345 refManu2ds_st345_v5
66static std::array<int, 64> refDs2manu_st345;
77 return refDs2manu_st345[
i];
82static void patchPage(gsl::span<const std::byte> rdhBuffer,
bool verbose)
84 auto& rdhAny = *
reinterpret_cast<RDH*
>(
const_cast<std::byte*
>(&(rdhBuffer[0])));
86 auto existingFeeId = o2::raw::RDHUtils::getFEEID(rdhAny);
87 if (existingFeeId == 0) {
91 auto cruId = o2::raw::RDHUtils::getCRUID(rdhAny) & 0xFF;
92 auto endpoint = o2::raw::RDHUtils::getEndPointID(rdhAny);
93 auto flags = o2::raw::RDHUtils::getCRUID(rdhAny) & 0xFF00;
104 if (d1.
getTime() == d2.getTime()) {
105 if (d1.
getDetID() == d2.getDetID()) {
106 return d1.
getPadID() < d2.getPadID();
108 return d1.
getDetID() < d2.getDetID();
110 return (d1.
getTime() < d2.getTime());
115 return fmt::format(
"DE {:4d} PADID {:5d} ADC {:5d} TIME {} BX {}",
127static bool isValidDeID(
int deId)
129 for (
auto id :
o2::mch::constants::deIdsForAllMCH) {
155 return digit ==
other.digit && info ==
other.info;
161 LOGP(info,
"[TimeFrameStartRecord::update()] new {}/{} current {}/{} prev {}/{} valid {}",
162 orbit, bunchCrossing, mOrbit, mBunchCrossing, mOrbitPrev, mBunchCrossingPrev, mValid);
168 mBunchCrossing = bunchCrossing;
174 if (mOrbit ==
orbit) {
181 if (
check(
orbit, bunchCrossing, mOrbitPrev, mBunchCrossingPrev, verbose)) {
183 mBunchCrossing = bunchCrossing;
190 bool valid =
check(
orbit, bunchCrossing, mOrbit, mBunchCrossing, verbose);
192 bool replace = valid || (mOrbitPrev < 0) || (mValid ==
false);
196 mBunchCrossingPrev = mBunchCrossing;
199 mBunchCrossing = bunchCrossing;
206 LOGP(info,
"[TimeFrameStartRecord::update()] set to {}/{} prev {}/{} valid {}",
207 mOrbit, mBunchCrossing, mOrbitPrev, mBunchCrossingPrev, mValid);
216 LOGP(info,
"[TimeFrameStartRecord::check()] current {}/{} ref {}/{}",
orbit,
bc, orbitRef, bcRef);
223 int64_t dOrbit =
orbit - orbitRef;
225 LOGP(info,
"[TimeFrameStartRecord::check()] dOrbit{}", dOrbit);
227 int64_t bcExpected = dOrbit * bcInOrbit + bcRef;
229 uint64_t bcExpected20bits = bcExpected & twentyBitsAtOne;
231 bool result = (bcExpected20bits ==
bc);
234 LOGP(info,
" dOrbit {} expected {} expected20bits {} bc {} valid {}", dOrbit, bcExpected, bcExpected20bits,
bc,
result);
243 std::string mapCRUfile, std::string mapFECfile,
246 uint32_t nofOrbitsPerTF)
247 : mChannelHandler(channelHandler), mRdhHandler(rdhHandler), mMapCRUfile(mapCRUfile), mMapFECfile(mapFECfile), mDs2manu(
ds2manu), mDebug(verbose), mUseDummyElecMap(
useDummyElecMap), mTimeRecoMode(timeRecoMode), mOrbitsInTF(nofOrbitsPerTF)
254 for (
auto err : mErrorMap) {
255 LOGP(warning,
"{} ({} time{}) [{} TFs seen]", err.first, err.second,
256 err.second > 1 ?
"s" :
"", tfcount);
264 mFirstOrbitInTF =
orbit;
272 std::cout <<
"\n\n============================\nStart of new buffer\n";
275 size_t pageStart = 0;
277 RDH* rdh =
reinterpret_cast<RDH*
>(
const_cast<std::byte*
>(&(
buf[pageStart])));
279 if (pageStart == 0) {
280 std::cout <<
"+++\n[decodeBuffer]" << std::endl;
282 std::cout <<
"---\n[decodeBuffer]" << std::endl;
287 auto rdhHeaderSize = o2::raw::RDHUtils::getHeaderSize(rdh);
288 if (rdhHeaderSize != 64) {
291 auto pageSize = o2::raw::RDHUtils::getOffsetToNext(rdh);
293 gsl::span<const std::byte> page(
reinterpret_cast<const std::byte*
>(rdh), pageSize);
296 }
catch (
const std::exception& e) {
301 pageStart += pageSize;
305 std::cout <<
"[decodeBuffer] mOrbits size: " << mOrbits.size() << std::endl;
307 std::cout <<
"[decodeBuffer] mDigits size: " << mDigits.size() << std::endl;
315void DataDecoder::dumpDigits()
317 for (
size_t di = 0;
di < mDigits.size();
di++) {
318 auto& d = mDigits[
di];
319 auto detID = d.getDetID();
320 auto padID = d.getPadID();
325 bool bend =
segment.isBendingPad(padID);
326 float X =
segment.padPositionX(padID);
327 float Y =
segment.padPositionY(padID);
328 uint32_t
orbit = d.getOrbit();
329 uint32_t bunchCrossing = d.getBunchCrossing();
330 uint32_t sampaTime = d.getSampaTime();
331 std::cout << fmt::format(
" DE {:4d} PAD {:5d} ADC {:6d} TIME ({} {} {:4d})",
332 detID, padID, d.getADC(),
orbit, bunchCrossing, sampaTime);
333 std::cout << fmt::format(
"\tC {} PAD_XY {:+2.2f} , {:+2.2f}", (bend ? (
int)0 : (
int)1), X, Y);
334 std::cout << std::endl;
340void dumpOrbits(
const std::unordered_set<OrbitInfo, OrbitInfoHash>& mOrbits)
342 std::set<OrbitInfo> ordered_orbits(mOrbits.begin(), mOrbits.end());
343 for (
auto o : ordered_orbits) {
344 std::cout <<
" FEEID " <<
o.getFeeID() <<
" LINK " << (
int)
o.getLinkID() <<
" ORBIT " <<
o.getOrbit() << std::endl;
350bool DataDecoder::getMergerChannelId(
const DsElecId& dsElecId,
DualSampaChannelId channel, uint32_t& chId, uint32_t& boardId)
352 static constexpr uint32_t sChannelsInOneDs = 64;
353 static constexpr uint32_t sDsInOneSolar = 40;
354 static constexpr uint32_t sChannelsInOneSolar = sChannelsInOneDs * sDsInOneSolar;
355 auto solarId = dsElecId.solarId();
356 uint32_t dsId =
static_cast<uint32_t
>(dsElecId.elinkGroupId()) * 5 + dsElecId.elinkIndexInGroup();
357 if (solarId > DataDecoder::sMaxSolarId || dsId >= 40 || channel >= 64) {
361 boardId = solarId * sDsInOneSolar + dsId;
362 chId = boardId * sChannelsInOneDs + channel;
383bool DataDecoder::mergeDigits(uint32_t mergerChannelId, uint32_t mergerBoardId, uint64_t mergerChannelBitmask,
o2::mch::raw::SampaCluster& sc)
385 uint32_t BCROLLOVER = (mTimeRecoMode ==
TimeRecoMode::BCReset) ? (mBcInOrbit * mOrbitsInTF) : (1 << 20);
386 static constexpr uint32_t ONEADCCLOCK = 4;
387 static constexpr uint32_t MAXNOFSAMPLES = 0x3FF;
388 static constexpr uint32_t TWENTYBITSATONE = 0xFFFFF;
396 if ((mMergerRecordsReady[mergerBoardId] & mergerChannelBitmask) == 0) {
400 auto& mergerCh = mMergerRecords[mergerChannelId];
405 if (bcStart < mergerCh.bcEnd) {
406 bcStart += BCROLLOVER;
411 if ((bcStart - mergerCh.bcEnd) != ONEADCCLOCK) {
416 auto& digit = mDigits[mergerCh.digitId].digit;
418 digit.setADC(digit.getADC() + sc.
sum());
419 uint32_t newNofSamples = digit.getNofSamples() + sc.
nofSamples();
420 if (newNofSamples > MAXNOFSAMPLES) {
421 newNofSamples = MAXNOFSAMPLES;
423 digit.setNofSamples(newNofSamples);
426 mergerCh.bcEnd = (bcStart & TWENTYBITSATONE) + (sc.
nofSamples() - 1) * 4;
433void DataDecoder::updateMergerRecord(uint32_t mergerChannelId, uint32_t mergerBoardId, uint64_t mergerChannelBitmask, uint32_t digitId)
435 auto& mergerCh = mMergerRecords[mergerChannelId];
436 auto& digit = mDigits[digitId];
437 mergerCh.digitId = digitId;
438 mergerCh.bcEnd = digit.info.bunchCrossing + (digit.info.sampaTime + digit.digit.getNofSamples() - 1) * 4;
439 mMergerRecordsReady[mergerBoardId] |= mergerChannelBitmask;
441 std::cout << fmt::format(
"[updateMergerRecord] updated S{}-DS{}-CHIP{} time {}-{}-{} cs {}",
442 (
int)digit.info.solar, (
int)digit.info.ds, (
int)digit.info.chip,
443 (
int)digit.info.orbit, (
int)digit.info.bunchCrossing, (
int)digit.info.sampaTime, (
int)digit.digit.getNofSamples())
450bool DataDecoder::getPadMapping(
const DsElecId& dsElecId,
DualSampaChannelId channel,
int& deId,
int& dsIddet,
int& padId)
456 if (
auto opt = mElec2Det(dsElecId); opt.has_value()) {
457 DsDetId dsDetId = opt.value();
458 dsIddet = dsDetId.dsId();
459 deId = dsDetId.deId();
463 auto ch = fmt::format(
"{}-CH{:02d}", s, channel);
464 std::cout << ch <<
" "
465 <<
"deId " << deId <<
" dsIddet " << dsIddet << std::endl;
468 if (deId < 0 || dsIddet < 0 || !isValidDeID(deId)) {
469 auto msg = fmt::format(
"got invalid DsDetId from dsElecId={}",
asString(dsElecId));
475 padId =
segment.findPadByFEE(dsIddet,
int(channel));
487 int deId, dsIddet, padId;
488 if (!getPadMapping(dsElecId, channel, deId, dsIddet, padId)) {
492 uint32_t digitadc = sc.
sum();
496 auto ch = fmt::format(
"{}-CH{:02d}", s, channel);
497 LOG(info) << ch <<
" "
498 << fmt::format(
"PAD ({:04d} {:04d} {:04d})\tADC {:06d} TIME ({} {} {:02d}) SIZE {} END {}",
505 LOGP(alarm,
"got invalid padId from dsElecId={} dualSampaId={} channel={}",
asString(dsElecId), dsIddet, channel);
512 digit.
info.
ds = dsElecId.elinkId();
518 mDigits.emplace_back(digit);
521 RawDigit& lastDigit = mDigits.back();
522 LOGP(info,
"DIGIT STORED: ORBIT {} ADC {} DE {} PADID {} TIME {} BXCOUNT {}",
531 return solar * 40 * 2 +
ds * 2 + chip;
538 if (chipId < DataDecoder::sReadoutChipsNum) {
539 mTimeFrameStartRecords[chipId].update(mFirstOrbitInTF, bcTF);
545void DataDecoder::decodePage(gsl::span<const std::byte> page)
547 uint8_t isStopRDH = 0;
552 auto heartBeatHandler = [&](
DsElecId dsElecId, uint8_t chip, uint32_t bunchCrossing) {
554 auto solar = dsElecId.
solarId();
559 LOGP(info,
"HeartBeat: {}-CHIP{} -> {}/{}",
560 s, chip, mFirstOrbitInTF, bunchCrossing);
563 if (chipId >= DataDecoder::sReadoutChipsNum) {
567 mHBPackets.emplace_back(solar,
ds, chip, bunchCrossing);
570 bool isOk = mTimeFrameStartRecords[chipId].update(mFirstOrbitInTF, bunchCrossing);
573 LOGP(warning,
"Bad HeartBeat packet received: {}-CHIP{} {}/{} (last {}/{})",
574 s, chip, mFirstOrbitInTF, bunchCrossing, mTimeFrameStartRecords[chipId].mOrbitPrev, mTimeFrameStartRecords[chipId].mBunchCrossingPrev);
582 if (mChannelHandler) {
583 mChannelHandler(dsElecId, channel, sc);
587 LOGP(error,
"using ds2manu");
588 channel =
ds2manu(
int(channel));
591 uint32_t mergerChannelId;
592 uint32_t mergerBoardId;
593 if (!getMergerChannelId(dsElecId, channel, mergerChannelId, mergerBoardId)) {
594 LOGP(error,
"dsElecId={} is out-of-bounds",
asString(dsElecId));
597 uint64_t mergerChannelBitmask = getMergerChannelBitmask(channel);
599 if (mergeDigits(mergerChannelId, mergerBoardId, mergerChannelBitmask, sc)) {
603 if (!addDigit(dsElecId, channel, sc)) {
607 updateMergerRecord(mergerChannelId, mergerBoardId, mergerChannelBitmask, mDigits.size() - 1);
610 auto errorHandler = [&](DsElecId dsElecId,
616 auto solarId = dsElecId.solarId();
617 auto dsId = dsElecId.elinkId();
621 patchPage(page, mDebug);
623 auto& rdhAny = *
reinterpret_cast<RDH*
>(
const_cast<std::byte*
>(&(page[0])));
624 mOrbit = o2::raw::RDHUtils::getHeartBeatOrbit(rdhAny);
626 LOGP(info,
"[decodeBuffer] mOrbit set to {}", mOrbit);
630 mRdhHandler(&rdhAny);
634 mOrbits.emplace(page);
637 DecodedDataHandlers handlers;
638 handlers.sampaChannelHandler = channelHandler;
639 handlers.sampaHeartBeatHandler = heartBeatHandler;
640 handlers.sampaErrorHandler = errorHandler;
650bool DataDecoder::getTimeFrameStartRecord(
const RawDigit& digit, uint32_t& orbitTF, uint32_t& bcTF)
652 static constexpr uint32_t twentyBitsAtOne = 0xFFFFF;
655 orbitTF = mFirstOrbitInTF;
657 auto& d = digit.
digit;
658 auto& info = digit.
info;
660 auto chipId =
getChipId(info.solar, info.ds, info.chip);
661 auto& tfStart = mTimeFrameStartRecords[chipId];
663 if (tfStart.mOrbit < 0) {
665 LOGP(alarm,
"Missing TF start record for S{}-J{}-DS{}-CHIP{}", info.solar, info.ds / 5 + 1, info.ds % 5, info.chip);
671 if (tfStart.mValid ==
false) {
673 LOGP(alarm,
"Invalid TF start record for S{}-J{}-DS{}-CHIP{}", info.solar, info.ds / 5 + 1, info.ds % 5, info.chip);
679 uint32_t orbitHBP = tfStart.mOrbit;
681 bcTF = tfStart.mBunchCrossing;
683 if (orbitHBP != orbitTF) {
685 bcTF += (orbitTF - orbitHBP) * mBcInOrbit;
687 bcTF &= twentyBitsAtOne;
691 tfStart.update(orbitTF, bcTF);
703 int64_t dOrbit =
static_cast<int64_t
>(orbitDigit) -
static_cast<int64_t
>(orbitStart);
708 int64_t dBcMin = (dOrbit - 50) * bcInOrbit;
709 int64_t dBcMax = (dOrbit + 3) * bcInOrbit;
712 int64_t dBc =
static_cast<int64_t
>(bcDigit) -
static_cast<int64_t
>(bcStart);
718 }
else if (dBc > dBcMax) {
724 return static_cast<int32_t
>(dBc);
733 auto setDigitTime = [&](
Digit& d, int32_t tfTime) {
737 for (
auto& digit : mDigits) {
738 auto& d = digit.
digit;
739 auto& info = digit.
info;
743 int32_t tfTime = timeInvalid;
745 auto orbitDigit = info.
orbit;
746 auto bcDigit = info.getBXTime();
748 if (getTimeFrameStartRecord(digit, orbitTF, bcTF)) {
749 int solar = info.solar;
751 int chip = info.chip;
755 setDigitTime(d, tfTime);
756 info.tfTime = tfTime;
766 int64_t dOrbitRDH =
static_cast<int64_t
>(orbitDigit) -
static_cast<int64_t
>(orbitStart);
769 int64_t dBc =
static_cast<int64_t
>(bcDigit) -
static_cast<int64_t
>(bcStart);
770 int64_t dOrbitSampa = dBc / mBcInOrbit;
772 if (dOrbitSampa > (dOrbitRDH + 1)) {
775 dBc -= mBcInOrbit * mOrbitsInTF;
778 return static_cast<int32_t
>(dBc);
787 auto setDigitTime = [&](
Digit& d, int32_t tfTime) {
791 for (
auto& digit : mDigits) {
792 auto& d = digit.
digit;
793 auto& info = digit.
info;
795 uint32_t orbitTF = mFirstOrbitInTF;
797 int32_t tfTime = timeInvalid;
799 auto orbitDigit = info.orbit;
800 auto bcDigit = info.getBXTime();
804 if (mDebug && tfTime < (-2 * mBcInOrbit)) {
805 int solar = info.solar;
807 int chip = info.chip;
808 std::cout << fmt::format(
"Out-of-time digit: S{} DS{} CHIP{} TF {}/{} DIGIT {}/{} TIME {}",
809 solar,
ds, chip, orbitTF, bcTF, orbitDigit, bcDigit, tfTime)
813 setDigitTime(d, tfTime);
814 info.tfTime = tfTime;
822 switch (mTimeRecoMode) {
830 LOGP(error,
"Digit time reconstruction mode undefined");
837static std::string readFileContent(std::string&
filename)
842 while (std::getline(in, s)) {
851void DataDecoder::initElec2DetMapper(std::string
filename)
854 if (mUseDummyElecMap) {
855 LOGP(warning,
"[initElec2DetMapper] Using dummy electronic mapping");
861 LOGP(info,
"[initElec2DetMapper] filename={}",
filename);
869void DataDecoder::initFee2SolarMapper(std::string
filename)
872 if (mUseDummyElecMap) {
873 LOGP(warning,
"[initFee2SolarMapper] Using dummy electronic mapping");
879 LOGP(info,
"[initFee2SolarMapper] filename={}",
filename);
887void DataDecoder::init()
889 for (
int i = 0;
i < 64;
i++) {
890 for (
int j = 0;
j < 64;
j++) {
894 refDs2manu_st345[
i] =
j;
899 initFee2SolarMapper(mMapCRUfile);
900 initElec2DetMapper(mMapFECfile);
904 mTimeFrameStartRecords.resize(sReadoutChipsNum);
905 std::fill(mTimeFrameStartRecords.begin(), mTimeFrameStartRecords.end(), TimeFrameStartRecord());
907 mMergerRecords.resize(sReadoutChannelsNum);
908 mMergerRecordsReady.resize(sReadoutBoardsNum);
921 memset(mMergerRecordsReady.data(), 0,
sizeof(uint64_t) * mMergerRecordsReady.size());
#define MCH_DECODER_MAX_ERROR_COUNT
Definition of the decoder for the MCH data.
Header to collect LHC related constants.
int ds2manu(int deId, int ch)
int manu2ds(int deId, int ch)
MCH decoder error implementation.
MCH digit implementation.
void logErrorMap(int tfcount) const
send all messages from our error map to the infologger
void computeDigitsTimeBCRst()
Compute the time of all the digits that have been decoded in the current TimeFrame.
void computeDigitsTimeHBPackets()
Compute the time of all the digits that have been decoded in the current TimeFrame.
static constexpr int32_t tfTimeInvalid
static int32_t getDigitTimeHBPackets(uint32_t orbitTF, uint32_t bcTF, uint32_t orbitDigit, uint32_t bcDigit)
Helper function for computing the digit time relative to the beginning of the TimeFrame.
void setFirstOrbitInTF(uint32_t orbit)
int32_t getDigitTimeBCRst(uint32_t orbitTF, uint32_t bcTF, uint32_t orbitDigit, uint32_t bcDigit)
static uint64_t getChipId(uint32_t solar, uint32_t ds, uint32_t chip)
Convert a Solar/Ds/Chip triplet into an unique chip index.
void updateTimeFrameStartRecord(uint64_t chipId, uint32_t mFirstOrbitInTF, uint32_t bcTF)
For a given SAMPA chip, update the information about the BC counter value at the beginning of the Tim...
DataDecoder(SampaChannelHandler channelHandler, RdhHandler rdhHandler, std::string mapCRUfile, std::string mapFECfile, bool ds2manu, bool verbose, bool useDummyElecMap, TimeRecoMode timeRecoMode=TimeRecoMode::HBPackets, uint32_t nofOrbitsPerTF=32)
bool decodeBuffer(gsl::span< const std::byte > buf)
constexpr uint8_t elinkId() const
constexpr uint16_t solarId() const
solarId is an identifier that uniquely identify a solar board
GLenum GLuint GLenum GLsizei const GLchar * buf
constexpr int LHCMaxBunches
void check(const std::vector< std::string > &arguments, const std::vector< ConfigParamSpec > &workflowOptions, const std::vector< DeviceSpec > &deviceSpecs, CheckMatrix &matrix)
O2MCHMAPPINGIMPL3_EXPORT const Segmentation & segmentation(int detElemId)
std::function< std::optional< DsDetId >(DsElecId)> createElec2DetMapper< ElectronicMapperGenerated >(uint64_t)
FeeLink2SolarMapper createFeeLink2SolarMapper< ElectronicMapperString >()
std::function< void(o2::header::RDHAny *)> RdhHandler
std::function< std::optional< uint16_t >(FeeLinkId)> createFeeLink2SolarMapper< ElectronicMapperGenerated >()
@ ErrorNonRecoverableDecodingError
std::string errorCodeAsString(uint32_t code)
void dumpOrbits(const std::unordered_set< OrbitInfo, OrbitInfoHash > &mOrbits)
Elec2DetMapper createElec2DetMapper< ElectronicMapperString >(uint64_t)
std::function< void(DsElecId dsId, DualSampaChannelId channel, SampaCluster)> SampaChannelHandler
std::function< std::optional< DsDetId >(DsElecId)> createElec2DetMapper< ElectronicMapperDummy >(uint64_t timestamp)
uint6_t DualSampaChannelId
PageDecoder createPageDecoder(RawBuffer rdhBuffer, DecodedDataHandlers decodedDataHandlers)
will be called for each decoded Sampa packet and in case of decoding errors
std::string asString(const SampaCluster &sc)
std::function< std::optional< uint16_t >(FeeLinkId)> createFeeLink2SolarMapper< ElectronicMapperDummy >()
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
bool operator<(const observer_ptr< W1 > &p1, const observer_ptr< W2 > &p2)
std::ostream & operator<<(std::ostream &stream, o2::InteractionRecord const &ir)
auto getSampaTime() const
bool operator==(const RawDigit &) const
auto getBunchCrossing() const
Structure storing the raw SAMPA information.
bool operator==(const SampaInfo &) const
uint32_t bunchCrossing
bit 0 to 9: sampa time
uint32_t orbit
bit 30 to 31: reserved
bool check(int32_t orbit, uint32_t bc, int32_t orbitRef, uint32_t bcRef, bool verbose=false)
bool update(uint32_t orbit, uint32_t bunchCrossing, bool verbose=false)
store the new orbit/bc pair, and copy the existing one in the "*Prev" data members
static std::string sCruMap
static std::string sFecMap
Piece of data for one Sampa channel.
uint32_t sum() const
sum returns the total charge in the cluster
uint16_t nofSamples() const
static void printRDH(const RDHv4 &rdh)
static void setFEEID(RDHv4 &rdh, uint16_t v)
static constexpr int getVersion()
get numeric version of the RDH
const bool useDummyElecMap
VectorOfTObjectPtrs other
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
uint64_t const void const *restrict const msg