12#ifndef O2_MCH_RAW_BARE_ELINK_DECODER_H
13#define O2_MCH_RAW_BARE_ELINK_DECODER_H
20#include <fmt/format.h>
21#include <fmt/printf.h>
41template <
typename CHARGESUM>
57 void append(
bool bit0,
bool bit1);
77 enum class State :
int {
87 void appendOneBit(
bool bit);
88 void changeState(State newState,
int newCheckpoint);
89 void changeToReadingData();
90 void clear(
int checkpoint);
92 void handlReadClusterSum();
94 void handleReadClusterSum();
95 void handleReadData();
96 void handleReadSample();
97 void handleReadTimestamp();
98 void oneLess10BitWord();
104 template <
typename T>
129 std::vector<uint16_t> mSamples;
140template <
typename CHARGESUM>
144 mDecodedDataHandlers{decodedDataHandlers},
151 mNofHeaderParityErrors{},
153 mNof10BitsWordsToRead{},
159 mState{State::LookingForSync},
164template <
typename CHARGESUM>
169 mBitBuffer += bit * mMask;
172 if (mMask == mCheckpoint) {
177template <
typename CHARGESUM>
184template <
typename CHARGESUM>
188 clear(newCheckpoint);
191template <
typename CHARGESUM>
192void BareElinkDecoder<CHARGESUM>::clear(
int checkpoint)
195 mCheckpoint =
static_cast<uint64_t>(1) << checkpoint;
204template <
typename CHARGESUM>
205void BareElinkDecoder<CHARGESUM>::findSync()
207 assert(mState == State::LookingForSync);
213 changeState(State::LookingForHeader,
HEADERSIZE);
217template <
typename CHARGESUM>
218void BareElinkDecoder<CHARGESUM>::handleHeader()
220 assert(mState == State::LookingForHeader);
222 mSampaHeader.uint64(mBitBuffer);
226 if (mSampaHeader.hasError()) {
230 switch (mSampaHeader.packetType()) {
240 mNof10BitsWordsToRead = mSampaHeader.nof10BitWords();
241 changeState(State::ReadingNofSamples, 10);
248 if (mSampaHeader.isHeartbeat()) {
250 changeState(State::LookingForHeader,
HEADERSIZE);
256 throw std::logic_error(
"that should not be possible");
261template <
typename CHARGESUM>
262void BareElinkDecoder<CHARGESUM>::handleReadClusterSum()
264 mClusterSum = mBitBuffer;
268 if (mNof10BitsWordsToRead) {
269 changeState(State::ReadingNofSamples, 10);
271 changeState(State::LookingForHeader,
HEADERSIZE);
275template <
typename CHARGESUM>
276void BareElinkDecoder<CHARGESUM>::handleReadData()
278 assert(mState == State::ReadingTimestamp || mState == State::ReadingSample);
279 if (mState == State::ReadingTimestamp) {
280 mTimestamp = mBitBuffer;
283 changeToReadingData();
286template <
typename CHARGESUM>
287void BareElinkDecoder<CHARGESUM>::handleReadSample()
289 mSamples.push_back(mBitBuffer);
290 if (mNofSamples > 0) {
295 changeToReadingData();
298 if (mNof10BitsWordsToRead) {
299 changeState(State::ReadingNofSamples, 10);
301 changeState(State::LookingForHeader,
HEADERSIZE);
306template <
typename CHARGESUM>
307void BareElinkDecoder<CHARGESUM>::handleReadTimestamp()
309 assert(mState == State::ReadingNofSamples);
311 mNofSamples = mBitBuffer;
312 mClusterSize = mNofSamples;
313 changeState(State::ReadingTimestamp, 10);
316template <
typename CHARGESUM>
319 return static_cast<int>(std::floor(log2(1.0 * mMask)) + 1);
322template <
typename CHARGESUM>
326 case State::LookingForSync:
327 return "LookingForSync";
329 case State::LookingForHeader:
330 return "LookingForHeader";
332 case State::ReadingNofSamples:
333 return "ReadingNofSamples";
335 case State::ReadingTimestamp:
336 return "ReadingTimestamp";
338 case State::ReadingSample:
339 return "ReadingSample";
341 case State::ReadingClusterSum:
342 return "ReadingClusterSum";
347template <
typename CHARGESUM>
348void BareElinkDecoder<CHARGESUM>::oneLess10BitWord()
350 if (mNof10BitsWordsToRead > 0) {
351 --mNof10BitsWordsToRead;
356template <
typename CHARGESUM>
357void BareElinkDecoder<CHARGESUM>::process()
360 case State::LookingForSync:
363 case State::LookingForHeader:
366 case State::ReadingNofSamples:
367 handleReadTimestamp();
369 case State::ReadingTimestamp:
372 case State::ReadingSample:
375 case State::ReadingClusterSum:
376 handleReadClusterSum();
381template <
typename CHARGESUM>
382void BareElinkDecoder<CHARGESUM>::softReset()
387template <
typename CHARGESUM>
391 mState = State::LookingForSync;
394template <
typename CHARGESUM>
397 os << fmt::format(
"ID{:2d} cruId {:2d} sync {:6d} cp 0x{:6x} mask 0x{:6x} state {:17s} len {:6d} nseen {:6d} errH {:6} errP {:6} head {:6d} n10w {:6d} nsamples {:6d} mode {} bbuf {:s}",
398 e.mLinkId,
e.mCruId,
e.mNofSync,
e.mCheckpoint,
e.mMask,
400 e.len(),
e.mNofBitSeen,
403 e.mNofHeaderParityErrors,
404 e.mNof10BitsWordsToRead,
406 (
e.mClusterSumMode ?
"CLUSUM" :
"SAMPLE"),
411template <
typename CHARGESUM>
412void BareElinkDecoder<CHARGESUM>::sendHBPacket()
416 handler(mDsId, mSampaHeader.chipAddress() % 2, mSampaHeader.bunchCrossingCounter());
unsigned short int uint16_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to process
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char e
Main element of the MCH Bare Raw Data Format decoder.
BareElinkDecoder(DsElecId dsId, DecodedDataHandlers decodedDataHandlers)
int len() const
Current number of bits we're holding.
void append(bool bit0, bool bit1)
Append two bits (from the same dual sampa, one per sampa) to the Elink.
friend std::ostream & operator<<(std::ostream &os, const o2::mch::raw::BareElinkDecoder< T > &e)
GLuint const GLchar * name
constexpr uint64_t sampaSyncWord
@ DataTriggerTooEarlyNumWords
@ DataTruncatedTriggerTooEarly
std::string bitBufferString(const std::bitset< 50 > &bs, int imax)
std::function< void(DsElecId dsId, uint8_t chip, uint20_t bunchCrossing)> SampaHeartBeatHandler
std::ostream & operator<<(std::ostream &stream, o2::InteractionRecord const &ir)