19 template<u
int8_t sys_ver>
22 auto flag = (frame >> 15) & 0x3;
33 template<u
int8_t sys_ver>
45 template<u
int8_t sys_ver>
48 if (flags &
static_cast<std::uint16_t
>(fles::MicrosliceFlags::CrcValid)) {
51 if (flags &
static_cast<std::uint16_t
>(fles::MicrosliceFlags::OverflowFlim)) {
54 if (flags &
static_cast<std::uint16_t
>(fles::MicrosliceFlags::OverflowUser)) {
57 if (flags &
static_cast<std::uint16_t
>(fles::MicrosliceFlags::DataError)) {
66 template<u
int8_t sys_ver>
70 assert(*nadcbits >= 9);
82 std::int16_t sample = 0x07f;
85 sample &= (*adcbuffer >> (*nadcbits + 2));
96 template<u
int8_t sys_ver>
100 assert(*nadcbits >= 9);
106 std::int16_t temp = 0x1ff;
107 temp &= (*adcbuffer >> (*nadcbits));
112 std::int16_t sample = (temp & 0x0100) ? (temp | 0xff00) : temp;
120 template<u
int8_t sys_ver>
124 size_t mask = 0x000FFFFF;
132 if (((frame & mask) >> 18) == 3)
136 if (((frame & mask) >> 17) == 2)
140 if (((frame & mask) >> 17) == 3)
142 digestBufInfoFlags(frame);
145 if (((frame & mask) >> 17) == 4)
149 if (((frame & mask) >> 17) == 5)
155 L_(error) <<
"UnpackMS::GetInfoType] unknown type!";
163 template<u
int8_t sys_ver>
166 std::uint32_t checkframe = frame;
167 checkframe &= 0xffffff;
168 if ((checkframe >> 21) == 1)
172 else if ((checkframe >> 22) == 1)
176 else if ((checkframe >> 20) == 1)
180 else if ((checkframe >> 22) == 3)
184 else if (0 < (checkframe >> 18) && (checkframe >> 18) <= 3) {
187 else if (checkframe == 0)
200 template<u
int8_t sys_ver>
203 if ((frame & 0xf) > 0)
207 std::uint8_t tsmsb[3];
208 for (uint iepoch = 0; iepoch < 3; ++iepoch) {
209 tsmsb[iepoch] =
static_cast<std::uint8_t
>((frame >> (4 + 6 * iepoch) & 0x3f));
214 if (tsmsb[0] == tsmsb[1] || tsmsb[0] == tsmsb[2])
return tsmsb[0];
218 if (tsmsb[1] == tsmsb[2])
return tsmsb[1];
229 template<u
int8_t sys_ver>
240 auto triggerType = GetDigiTriggerType(rawTriggerType);
242 int32_t errClass = 0;
247 const uint32_t asicAddress = elinkPar.
fAddress;
253 uint64_t time = (fw.timestamp - fw.prec_time) * fAsicClockCycle + fMsStartTimeRel;
256 auto energy = fw.maxAdc * fParams.fMaxAdcToEnergyCal;
259 int32_t uniqueModuleId = asicAddress / 1000;
270 template<u
int8_t sys_ver>
275 auto triggerType = GetDigiTriggerType(rawTriggerType);
278 int32_t errClass = 0;
283 const uint32_t asicAddress = elinkPar.
fAddress;
295 uint64_t currentTimeshift = GetBinTimeShift(raw.
GetSamples());
299 time = time > currentTimeshift ? time - currentTimeshift : 0;
304 auto maxadc = GetMaxAdcValue(raw.
GetSamples());
307 auto energy = maxadc * fParams.fMaxAdcToEnergyCal;
310 int32_t uniqueModuleId = asicAddress / 1000;
323 template<u
int8_t sys_ver>
325 std::uint16_t elinkId, std::uint8_t istream,
MsContext& ctx)
const
327 auto chId =
static_cast<std::uint8_t
>(((frame >> 17) & 0xf));
328 auto timestamp =
static_cast<std::uint8_t
>((frame >> 9) & 0xff);
329 bool multihit = ((frame >> 8) & 0x1);
330 auto hitType =
static_cast<std::uint8_t
>((frame >> 6) & 0x3);
331 std::uint8_t nsamples = 0;
333 std::vector<std::int16_t> samples = std::vector<std::int16_t>(0);
338 return CbmTrdRawMessageSpadic(chId, elinkId, crobId, criId, hitType, nsamples, multihit, fulltime, samples);
342 std::uint8_t crobId, std::uint16_t elinkId,
343 std::uint8_t istream, MsContext& ctx)
const;
347 template<u
int8_t sys_ver>
366 template<u
int8_t sys_ver>
370 assert(samples->size() >= fPeakingBinMin);
374 auto itbegin = std::next(samples->begin(), fPeakingBinMin);
377 auto nsamples = samples->size();
378 auto peakingBinMax = (nsamples - 1) > fPeakingBinMax ? fPeakingBinMax : nsamples;
379 auto itend = std::next(samples->begin(), peakingBinMax);
382 auto itmax = std::max_element(itbegin, itend);
385 float_t charge =
static_cast<float_t
>(*itmax) - GetBaseline(samples);
390 return charge > 0 ? charge : 0;
396 template<u
int8_t sys_ver>
401 if (fParams.fUseBaselineAvg)
402 return samples->at(0);
404 float_t baseline = 0.0;
405 auto itend = samples->begin() + fNrOfPresamples;
406 if (itend > samples->end()) itend = samples->end();
407 for (
auto isample = samples->begin(); isample < itend; isample++) {
408 baseline += *isample;
410 baseline /= fNrOfPresamples;
418 template<std::u
int8_t sys_ver>
420 const fles::MicrosliceDescriptor& msDescr,
421 const uint64_t tTimeslice)
const
427 digestMsFlags(msDescr.flags, std::get<1>(result));
429 size_t fMsStartTimeRel = (msDescr.idx - tTimeslice);
434 auto mssize = msDescr.size;
435 std::uint32_t nwords = mssize / bytes;
439 for (std::uint32_t iword = 0; iword < nwords; ++iword) {
443 std::get<0>(result).push_back(makeDigi(fw, fMsStartTimeRel));
450 const fles::MicrosliceDescriptor& msDescr,
451 const uint64_t tTimeslice)
const;
457 const fles::MicrosliceDescriptor& msDescr,
458 const uint64_t tTimeslice)
const
470 std::int8_t currTsMsb = 0;
477 auto mssize = msDescr.size;
480 std::uint8_t crobId = 0;
481 auto criId = msDescr.eq_id;
484 digestMsFlags(msDescr.flags, std::get<1>(result));
487 std::uint32_t nwords = mssize / fBytesPerWord;
490 const auto mscontent =
reinterpret_cast<const size_t*
>(msContent);
492 std::get<0>(result).reserve(nwords);
495 for (std::uint32_t istream = 0; istream < fStreamsPerWord; istream++) {
497 for (std::uint32_t iword = 0; iword < nwords; ++iword) {
499 size_t word =
static_cast<size_t>(mscontent[iword]);
502 std::uint32_t frame = (word >> (32 * istream)) & 0xffffffff;
505 auto kWordtype = getMessageType(frame);
509 auto elinkId = (frame >> 24) & 0x3f;
513 auto tsmsb = getTsMsb(frame, std::get<1>(result));
514 if (((tsmsb - currTsMsb) & 0x3f) == 1 || currTsMsb == -1) ctx.
fNrTsMsbVec.at(istream)++;
516 std::get<1>(result).fNumEpochMsgs++;
528 size_t nadcbitstotal = 6;
530 size_t adcbuffer = frame & 0x3f;
536 word =
static_cast<size_t>(mscontent[iword]);
537 frame = (word >> (32 * istream)) & 0xffffffff;
545 elinkId = (frame >> 24) & 0x3f;
547 std::get<1>(result).fNumElinkMis++;
552 adcbuffer |=
static_cast<size_t>((frame & 0x3fffff));
557 while (nadcbits >= 9) {
560 if (isample == 0 && fParams.fUseBaselineAvg)
561 raw.
SetSample(extractAvgSample(&adcbuffer, &nadcbits), isample);
563 raw.
SetSample(extractSample(&adcbuffer, &nadcbits), isample);
567 word =
static_cast<size_t>(mscontent[iword]);
568 frame = (word >> (32 * istream)) & 0xffffffff;
573 elinkId = (frame >> 24) & 0x3f;
575 std::get<1>(result).fNumElinkMis++;
579 std::uint8_t nsamplesindicator = (frame >> 18) & 0x3;
581 std::uint64_t nreqsamples = (nadcbitstotal + 18) / 9;
582 std::uint8_t nn = nreqsamples % 4;
583 for (std::uint8_t itest = 0; itest < 3; itest++) {
584 if (nn == nsamplesindicator || nreqsamples == 0)
break;
586 nn = nreqsamples % 4;
591 if (nreqsamples >= isample) {
593 std::int8_t nrequiredbits = (nreqsamples - isample) * 9 - nadcbits;
594 adcbuffer <<= nrequiredbits;
597 adcbuffer |=
static_cast<size_t>((frame & 0x3ffff) >> (18 - nrequiredbits));
598 nadcbits += nrequiredbits;
600 while (nadcbits >= 9) {
602 raw.
SetSample(extractSample(&adcbuffer, &nadcbits), isample);
607 std::get<1>(result).fNumCorruptEom++;
609 std::get<1>(result).fNumCreatedRawMsgs++;
614 if (isample > 0) std::get<0>(result).push_back(makeDigi(raw, ctx));
619 std::get<1>(result).fNumMissingEom++;
624 std::get<1>(result).fNumWildRda++;
628 std::get<1>(result).fNumWildEom++;
632 std::get<1>(result).fNumCreatedInfoMsgs++;
633 digestInfoMsg(frame);
638 if (iword != (nwords - 1) || (istream != (fStreamsPerWord - 1))) {
639 std::get<1>(result).fNumWildNul++;
644 std::get<1>(result).fNumUnknownWords++;
void SetTriggerType(const eTriggerType triggerType)
Set digi trigger type.
Base class for storing raw information which comes from the Spadic v2.2 trough flib or from a tsa fil...
std::uint64_t GetFullTime() const
const std::vector< std::int16_t > * GetSamples() const
void IncNrSamples()
increase the number of samples stored in this raw message by one
std::uint8_t GetChannelId() const
void SetSample(std::int16_t value, std::uint8_t pos)
std::uint8_t GetCrobId() const
std::uint8_t GetHitType() const
std::uint8_t GetElinkId() const
std::tuple< std::vector< Digi_t >, Monitor_t, Aux_t > Result_t
float_t GetBaseline(const std::vector< std::int16_t > *samples) const
Get the Baseline value The digi charge is an unsigned. Hence, we need to get the baseline to 0.
Spadic::MsMessageType getMessageType(const std::uint32_t frame) const
Identify the message type of a given 32bit frame inside a Microslice.
CbmTrdDigi makeDigi(CbmTrdRawMessageSpadic raw, MsContext &ctx) const
Create an actual digi from the raw message.
Spadic::MsInfoType getInfoType(const std::uint32_t frame) const
Identify the InfoType of a 64bit InfoMessage word inside a Microslice.
std::float_t GetMaxAdcValue(const std::vector< std::int16_t > *samples) const
Get the MaxAdc value.
std::int16_t extractSample(size_t *adcbuffer, size_t *nadcbits) const
Extract one adc sample from a given adcbuffer.
CbmTrdRawMessageSpadic makeRaw(const std::uint32_t frame, std::uint16_t criId, std::uint8_t crobId, std::uint16_t elinkId, std::uint8_t istream, MsContext &ctx) const
Create a CbmTrdRawMessageSpadic from the hit message input.
Spadic::MsInfoType digestBufInfoFlags(const std::uint32_t frame) const
Digest the aditional flags stored in the 4 "cccc" bits of the EPO messages.
static CbmTrdDigi::eTriggerType GetDigiTriggerType(Spadic::eTriggerType tt)
Get the Digi Trigger Type from the raw message triggertype.
void digestInfoMsg(const std::uint32_t frame) const
Digest a info message run all default information forwarding from the msg.
std::float_t extractAvgSample(size_t *adcbuffer, size_t *nadcbits) const
Extract the baseline average sample from a given adcbuffer. Depending on the Spadic settings sample-0...
Result_t operator()(const uint8_t *msContent, const fles::MicrosliceDescriptor &msDescr, const uint64_t tTimeslice) const override
Algorithm execution.
std::uint8_t getTsMsb(const std::uint32_t frame, UnpackMonitorData &monitor) const
Get the ts_msb information from the TS_MSB(kEPO) frame. We take the first of the 3 The 3 redundant TS...
void digestMsFlags(const std::uint16_t flags, UnpackMonitorData &monitor) const
Digest the flags of the currently unpacked µSlice.
@ kUNU
Unused request. 100. .... .... .... cccc.
@ kChannelBufM
Channel buffer full and multihit from kEPO msg.
@ kChannelBuf
Channel buffer full from kEPO msg.
@ kBOM
Buffer overflow count. 11nn nnnn nnnn nnnn cccc.
@ kMIS
Missing request. 101. .... .... .... ....
@ kOrdFifoBuf
Multi-hit but ordering buffer full from kEPO msg.
@ kBUF
Buffer full. 011b b... .... .... cccc.
@ kMSB
Message build error. 010. .... .... .... cccc.
@ kNeigh
Neighbor trigger.
@ kSandN
Self and neighbor trigger at the same time.
@ kEPO
Epoch Marker or TS_MSB depending on the hitmessage version.
constexpr std::uint8_t BytesPerWord()
TRD Unpacking parameters for one CROB.
std::vector< UnpackElinkPar > fElinkParams
Parameters for each eLink.
TRD Unpacking parameters for one eLink.
std::vector< uint32_t > fChanAddress
CbmTrdAddress for different channels.
uint32_t fAddress
Asic address.
uint64_t fTimeOffset
Time calibration parameter.
std::vector< std::uint8_t > fNrTsMsbVec
Counter for the ts_msb used to reconstruct the time.
size_t fLastFulltime
Time of the last succesful digest hit message.
size_t fMsStartTimeRelCC
Start time of the current µSlice relative to the Timeslice start time in Spadic CC.
Monitoring data for TRD unpacking.
size_t fNumOverflowFlimFlags
counter for inf/error flags from the µSlices
size_t fNumCrcValidFlags
counter for inf/error flags from the µSlices
size_t fNumNonMajorTsMsb
Counter for the ts_msb used to reconstruct the time.
size_t fNumOverflowUserFlags
counter for inf/error flags from the µSlices
size_t fNumDataErrorFlags
counter for inf/error flags from the µSlices