6#include "BmnADCDigit.h"
7#include "BmnAbstractTDCDigit.h"
9#include "BmnHRBDigit.h"
10#include "BmnHgndRaw.h"
11#include "BmnMSCDigit.h"
12#include "BmnMSCZSDigit.h"
15#include "BmnTDCDigit.h"
16#include "BmnTQDCADCDigit.h"
17#include "BmnVspRawDigit.h"
19#include "StorableTimeslice.h"
20#include "StsXyterMessage.h"
22using namespace std::chrono;
56 fRawTree =
new TTree((TString)
"BMN_RAW" + ext, (TString)
"BMN_RAW" + ext);
58 fRawTreeSpills =
new TTree((TString)
"BMN_RAW_SPILLS" + ext, (TString)
"BMN_RAW_SPILLS" + ext);
61 sync =
new TClonesArray(BmnSyncDigit::Class());
62 adc32 =
new TClonesArray(BmnADCDigit::Class());
63 adc64 =
new TClonesArray(BmnADCDigit::Class());
64 adc128 =
new TClonesArray(BmnADCDigit::Class());
65 adc =
new TClonesArray(BmnADCDigit::Class());
66 vsp =
new TClonesArray(BmnVspRawDigit::Class());
67 tdc =
new TClonesArray(BmnTDCDigit::Class());
68 tqdc_adc =
new TClonesArray(BmnTQDCADCDigit::Class());
69 tqdc_tdc =
new TClonesArray(BmnTDCDigit::Class());
70 tdc_hgnd =
new TClonesArray(BmnAbstractTDCDigit::Class());
71 hrb =
new TClonesArray(BmnHRBDigit::Class());
96void BmnConverterThread::WriteSpill(Int_t spillId)
99 TTree* tree =
new TTree(
"BMN_RAW",
"BMN_RAW");
100 TTree* treeSpills =
new TTree(
"BMN_RAW_SPILLS",
"BMN_RAW_SPILLS");
102 tree->Branch(
"SYNC", &
sync);
103 tree->Branch(
"ADC32", &
adc32);
104 tree->Branch(
"ADC64", &
adc64);
105 tree->Branch(
"ADC128", &
adc128);
106 tree->Branch(
"ADC", &
adc);
107 tree->Branch(
"VSP_RAW", &
vsp);
108 tree->Branch(
"TDC", &
tdc);
109 tree->Branch(
"TQDC_ADC", &
tqdc_adc);
110 tree->Branch(
"TQDC_TDC", &
tqdc_tdc);
111 tree->Branch(
"TDC_HGND", &
tdc_hgnd);
112 tree->Branch(
"HRB", &
hrb);
113 treeSpills->Branch(
"MSC", &
msc);
114 treeSpills->Branch(
"T0Raw", &
t0raw);
115 for (
size_t j = 0; j < vecTree->size(); j++) {
116 if ((*vecTree)[j].first == spillId) {
117 if ((*vecTree)[j].second.first ==
threadId) {
118 fRawTree->GetEntry((*vecTree)[j].second.second);
123 for (
size_t j = 0; j < vecTreeSpills->size(); j++) {
124 if ((*vecTreeSpills)[j].first == spillId) {
125 if ((*vecTreeSpills)[j].second.first ==
threadId) {
134void BmnConverterThread::Calculate()
138 ProcessEvent(
rawData, dataLen);
143 ConvertStatEvent(
rawData, dataLen);
148 LOGF(debug2,
"Calculate task %d in id %d done",
taskId,
threadId);
169 LOGF(info,
"thread file closed");
182 std::memcpy(
rawData, data,
sizeof(UInt_t) * len);
184 fCurEvent.
fRunId = fRunId;
200BmnStatus BmnConverterThread::ConvertStatEvent(UInt_t*
d, UInt_t& len)
203 ProcessEvent(
d, len);
216BmnStatus BmnConverterThread::ProcessEvent(UInt_t*
d, UInt_t len)
221 LOG(info) <<
"Converted event #" << fCurEvent.
fEventId;
229 Bool_t recognized = kTRUE;
230 DeviceHeader* dh =
reinterpret_cast<DeviceHeader*
>(
d + idx);
234 UInt_t serial = dh->Serial;
235 uint8_t
id = dh->DeviceId;
237 UInt_t payload = dh->GetNWords();
239 if (payload > 2000000) {
240 LOGF(warn,
"Event %d:\n serial = 0x%06X\n id = Ox%02X\n payload = %d", fCurEvent.
fEventId, serial,
id,
245 LOGF(debug4,
"STAT iev %7d idx %6u/%6u idev %02X serial 0x%08X payload %4u", fCurEvent.
fEventId, idx,
246 len,
id, serial, payload);
249 FillTQDC_E(&
d[idx], serial, payload);
253 FillTDC72VXS(&
d[idx], serial, payload,
id);
256 FillTTVXS(&
d[idx], serial, payload);
259 ProcessGenericDevice(&
d[idx], dh);
264 FillMSC16VE_E(&
d[idx], dh);
268 BmnConverterTools::Process_ADC64<Short_t>(&
d[idx], payload, serial,
269 [&](Int_t n_samples) -> TClonesArray* {
288 BmnConverterTools::Process_ADC64<UShort_t>(&
d[idx], payload, serial,
289 [&](Int_t n_samples) -> TClonesArray* {
return adc; });
293 Process_FVME(&
d[idx], payload, serial, trigInfo);
296 Process_HRB(&
d[idx], payload, serial);
299 FillUT24VE_TRC(&
d[idx], serial, payload);
302 FillVirtualDevice(&
d[idx], dh);
309 if (payload + idx > len) {
311 "Error in the event #%d: 0x%08X : %2X device payload length mismatch! pauload %5u idx/len: %5u/%5u \n",
312 fCurEvent.
fEventId, serial,
id, payload, idx, len);
339BmnStatus BmnConverterThread::Process_FVME(UInt_t*
d, UInt_t len, UInt_t serial,
BmnTrigInfo& spillInfo)
349 for (UInt_t
i = 0;
i < len;
i++) {
367 modId = (
d[
i] >> 16) & 0x7F;
368 slot = (
d[
i] >> 23) & 0x1F;
375 if (!((
d[
i] >> 16) & 0x1))
377 if (!((
d[
i] >> 17) & 0x1))
379 if (!((
d[
i] >> 18) & 0x1))
381 if (!((
d[
i] >> 19) & 0x1))
394 FillTDC(
d, serial, slot, modId,
i);
398 FillTQDC(
d, serial, slot, modId,
i);
401 FillMSC(
d, serial, slot,
i);
404 FillFVME2TMWR(
d, serial,
i, len);
407 FillU40VE(
d, slot,
i, spillInfo);
416BmnStatus BmnConverterThread::Process_HRB(UInt_t*
d, UInt_t len, UInt_t serial)
422 UInt_t nSmpl = (len - 3) / nWords;
424 for (UInt_t iSmpl = 0; iSmpl < nSmpl; ++iSmpl) {
425 for (UInt_t iWord = 0; iWord < nWords; ++iWord) {
426 UInt_t word32 =
d[3 + iWord + iSmpl * nWords];
427 for (Int_t iCh = 0; iCh < 32; ++iCh) {
428 if (word32 & BIT(iCh)) {
429 TClonesArray& ar_hrb = *
hrb;
430 new (ar_hrb[
hrb->GetEntriesFast()])
BmnHRBDigit(serial, iCh + 32 * iWord, iSmpl, tH, tL);
441 UInt_t
type =
d[idx] >> 28;
443 Bool_t countersDone = kFALSE;
453 if (type ==
kWORDAUX && !countersDone) {
462 countersDone = kTRUE;
472BmnStatus BmnConverterThread::FillTDC(UInt_t*
d, UInt_t serial, UInt_t slot, UInt_t modId, UInt_t& idx)
474 UInt_t
type =
d[idx] >> 28;
477 LOGF(warning,
"TDC (modID 0x%02X serial 0x%08X slot %d tdcID %d) error flags: 0x%04X", modId, serial, slot,
478 ((
d[idx] >> 24) & 0xF), (
d[idx] & ((1 << 15) - 1)));
479 if ((
d[idx] & BIT(12)) || (
d[idx] & BIT(13))) {
480 LOGF(warning,
"TDC data loss in 0x%08X ", serial);
485 UInt_t tdcId = (
d[idx] >> 24) & 0xF;
487 (modId ==
kTDC64V) ? (
d[idx] & 0x7FFFF) : ((
d[idx] & 0x7FFFF) << 2) | ((
d[idx] & 0x180000) >> 19);
488 UInt_t channel = (modId ==
kTDC64V) ? (
d[idx] >> 19) & 0x1F : (
d[idx] >> 21) & 0x7;
490 TClonesArray& ar_tdc = *
tdc;
491 new (ar_tdc[
tdc->GetEntriesFast()])
494 LOGF(debug4,
"tdc %08X : %d channel %d", serial, slot, channel);
502BmnStatus BmnConverterThread::FillTQDC(UInt_t*
d, UInt_t serial, UInt_t slot, UInt_t modId, UInt_t& idx)
504 UInt_t
type =
d[idx] >> 28;
505 UShort_t trigTimestamp = 0;
506 UShort_t adcTimestamp = 0;
507 UShort_t tdcTimestamp = 0;
511 Bool_t inADC = kFALSE;
514 LOGF(warning,
"TDC (serial 0x%08X slot %d tdcID %d) error flags: 0x%04X", serial, slot,
515 ((
d[idx] >> 24) & ((1 << 4) - 1)), (
d[idx] & ((1 << 15) - 1)));
516 if ((
d[idx] & BIT(12)) || (
d[idx] & BIT(13))) {
517 LOGF(warning,
"TQDC data loss in 0x%08X ", serial);
521 UInt_t mode = (
d[idx] >> 26) & 0x3;
524 channel = (
d[idx] >> 19) & 0x1F;
525 UInt_t time = ((
d[idx] & 0x7FFFF) << 2) | ((
d[idx] >> 24) & 0x3);
527 new ((*tqdc_tdc)[
tqdc_tdc->GetEntriesFast()])
530 }
else if ((type == 4) && (mode != 0)) {
531 channel = (
d[idx] >> 19) & 0x1F;
532 if (
d[idx] & BIT(16)) {
533 adcTimestamp =
d[idx] & 0xFFFF;
536 trigTimestamp =
d[idx] & 0xFFFF;
539 tdcTimestamp =
d[idx] & 0xFFF;
548 Short_t
val = (
d[idx] & ((1 << 14) - 1)) - (1 << (14 - 1));
549 valI[iSampl++] =
val;
551 new ((*tqdc_adc)[
tqdc_adc->GetEntriesFast()])
552 BmnTQDCADCDigit(serial, channel, slot, iSampl, valI, trigTimestamp, adcTimestamp);
559 type =
d[++idx] >> 28;
564BmnStatus BmnConverterThread::FillBlockADC(UInt_t*
d, UInt_t serial, uint8_t channel, uint16_t& len, TClonesArray* ar)
567 const uint8_t NBytesInSample = 2;
569 while (iWord < len) {
570 uint16_t adcTS =
d[iWord] & (BIT(16) - 1);
571 uint16_t SigLen =
d[iWord] >> 16;
572 uint16_t NSamples = SigLen / NBytesInSample;
575 if (iWord + NSampleWords + 1 > len) {
576 printf(
"Error! TQDC ADC wrong payload length! iWord %u SigLen %u len %u\n", iWord, SigLen, len);
579 uint16_t iSampleWord = 0;
580 while (iSampleWord++ < NSampleWords) {
581 int16_t adcLo =
static_cast<int16_t
>(
d[iWord + iSampleWord] & (BIT(16) - 1));
582 int16_t adcHi =
static_cast<int16_t
>(
d[iWord + iSampleWord] >> 16);
584 valI[iSampleWord * 2 - 2] = adcLo;
585 valI[iSampleWord * 2 - 1] = adcHi;
589 new ((*ar)[ar->GetEntriesFast()])
BmnTQDCADCDigit(serial, channel, 0, NSamples, valI, 0, adcTS);
590 iWord += iSampleWord;
595BmnStatus BmnConverterThread::FillBlockTDC(UInt_t*
d, UInt_t serial, uint16_t& len, TClonesArray* ar, UInt_t modid = 0)
599 uint16_t tdcLine = 0;
600 while (tdcLine < len) {
601 UInt_t word =
d[tdcLine];
602 UInt_t bt = word >> 28;
619 uint8_t channel = (word >> 21) & (BIT(7) - 1);
621 UInt_t time = word & (BIT(21) - 1);
624 new ((*ar)[ar->GetEntriesFast()])
629 LOGF(warning,
"TDC (serial 0x%08X tdcID %d) error flags: 0x%04X %s", serial,
630 ((word >> 24) & ((1 << 4) - 1)), (word & ((1 << 15) - 1)),
631 ((word & BIT(12)) || (word & BIT(13))) ?
"data lost" :
"");
639BmnStatus BmnConverterThread::FillTQDC_E(UInt_t*
d, UInt_t serial, UInt_t& len)
645 MStreamTAI* ms0 =
reinterpret_cast<MStreamTAI*
>(
d + index);
647 FillWR(serial, fCurEvent.
fEventId, ms0->Sec, ms0->NSec);
652 while (index < len) {
653 TqdcDataHeader* th =
reinterpret_cast<TqdcDataHeader*
>(
d + index);
658 switch (th->DataType) {
660 FillBlockTDC(
d + index, serial, blockLen,
tqdc_tdc);
663 FillBlockADC(
d + index, serial, th->Chan, blockLen,
tqdc_adc);
666 printf(
"Wrong TQDC data type %u !\n", th->DataType);
674BmnStatus BmnConverterThread::FillTDC72VXS(UInt_t*
d, UInt_t serial, UInt_t& len, UInt_t modid = 0)
680 MStreamTAI* ms0 =
reinterpret_cast<MStreamTAI*
>(
d + index);
682 FillWR(serial, fCurEvent.
fEventId, ms0->Sec, ms0->NSec);
686 while (index < len) {
687 uint8_t dtype =
d[index] >> 28;
688 bool overflow =
d[index] & BIT(16);
694 FillBlockTDC(
d + index, serial, blockLen,
tdc, modid);
699 printf(
"Wrong VXS data type %u !\n", dtype);
707BmnStatus BmnConverterThread::FillTTVXS(UInt_t*
d, UInt_t serial, UInt_t& len)
713 MStreamTAI* ms0 =
reinterpret_cast<MStreamTAI*
>(
d + index);
716 FillWR(serial, fCurEvent.
fEventId, ms0->Sec, ms0->NSec);
720 while (index < len) {
721 uint8_t dtype =
d[index] >> 28;
722 bool overflow =
d[index] & BIT(16);
736 printf(
"Wrong TTVXS data type %u !\n", dtype);
744BmnStatus BmnConverterThread::ProcessGenericDevice(UInt_t*
d, DeviceHeader* dev_hdr)
748 return MapVSP(
d, dev_hdr);
750 return FillTDC250HGND(
d, dev_hdr->Serial, dev_hdr->Len);
752 LOGF(error,
"BmnRawSource::ProcessGenericDevice: Unknown device serial 0x%08X", dev_hdr->Serial);
757BmnStatus BmnConverterThread::FillTDC250HGND(UInt_t*
d, UInt_t serial, UInt_t len)
762 uint16_t* words =
reinterpret_cast<uint16_t*
>(
d);
763 size_t total_words = len /
sizeof(uint16_t);
765 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug4)) {
766 for (
size_t i = 0;
i < total_words; ++
i)
767 LOGF(debug4,
"0x%04x", words[
i]);
771 std::vector<uint16_t> event_words;
772 std::unique_ptr<BmnHgndRaw::FIFO_block> event;
774 while (index < total_words) {
775 uint16_t* word = words + index;
777 LOGF(error,
"BmnRawSource::FillTDC250HGND: Wrong header 0x%04X", *word);
784 LOGF(debug4,
"Event type %d, 16bit words %d (index=%zu, total=%zu)", (uint32_t)event_type, event_length, index,
787 if (index + event_length > total_words) {
788 LOGF(error,
"BmnRawSource::FillTDC250HGND: Event block overruns buffer");
792 event_words.assign(word, word + event_length);
793 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug4)) {
794 for (
size_t i = 0;
i < event_words.size(); ++
i) {
795 LOGF(debug4,
"0x%04x", event_words[
i]);
799 if (event_type == BmnHgndRaw::Block::EventPacketVersion::V1) {
800 event = std::make_unique<BmnHgndRaw::Event_type_1>(event_words);
801 }
else if (event_type == BmnHgndRaw::Block::EventPacketVersion::V2) {
802 event = std::make_unique<BmnHgndRaw::Event_type_2>(event_words);
803 if (!event->validate()) {
804 LOGF(error,
"BmnRawSource::FillTDC250HGND: Event block validation failed");
810 LOGF(error,
"BmnRawSource::FillTDC250HGND: Event cast to Event_type_2 failed");
814 uint8_t trise_100ps = ev2->TDC_rise_time;
815 uint8_t tfall_100ps = ev2->TDC_falling_time;
816 int64_t time_sec = ev2->timestamp >> 31;
817 time_sec -= tai_utc_dif;
818 uint64_t time_nsec = ((ev2->timestamp & 0x7ffffff0) >> 4) * 32;
819 uint16_t time_100ps =
820 (ev2->timestamp & 0xf) * 32 + trise_100ps;
821 uint16_t plen_100ps =
822 (ev2->pulse_length + 1) * 32 + tfall_100ps - trise_100ps;
824 LOGF(debug4,
"ch_num = 0x%02X", ev2->channel_number);
825 LOGF(debug4,
"timestamp = 0x%016lX", ev2->timestamp);
826 LOGF(debug4,
"time_sec = 0x%08X", time_sec);
827 LOGF(debug4,
"time_nsec = 0x%08X", time_nsec);
828 LOGF(debug4,
"trise_100ps = 0x%02X", trise_100ps);
829 LOGF(debug4,
"tfall_100ps = 0x%02X", tfall_100ps);
830 LOGF(debug4,
"time_100ps = 0x%04X", time_100ps);
831 LOGF(debug4,
"plen_100ps = 0x%04X", plen_100ps);
832 LOGF(debug4,
"global_ch = 0x%04X", ev2->channel_number_global);
834 new ((*tdc_hgnd)[
tdc_hgnd->GetEntriesFast()])
835 BmnAbstractTDCDigit(serial, ev2->channel_number_global, time_sec, time_nsec, time_100ps, plen_100ps);
837 LOGF(error,
"BmnRawSource::FillTDC250HGND: Wrong event type");
841 index += event_length;
847BmnStatus BmnConverterThread::MapVSP(UInt_t*
d, DeviceHeader* dev_hdr)
849 LOGF(debug,
"MapVSP");
850 if (dev_hdr->GetNWords() < 3) {
851 LOGF(warning,
"Empty VSP block");
854 uint8_t iComp = (dev_hdr->Serial & 0xFF000000) >> 24;
859BmnStatus BmnConverterThread::FillVSP(TClonesArray* ar)
861 LOGF(debug,
"FillVSP");
862 const uint8_t kuMaxComps = 10;
863 uint16_t fvuCurrentTsMsbCycle[kuMaxComps] = {};
864 uint64_t fvulCurrentTsMsb[kuMaxComps] = {};
870 for (uint8_t iw01 = 0; iw01 < nComp; iw01++)
871 (*stti).append_component(1);
874 uint8_t iw01 = el.first;
875 auto* mslice_descr = el.second;
879 for (uint8_t uw02 = 0; uw02 < nComp; uw02++) {
883 uint16_t fuCurrentEquipmentId =
static_cast<uint16_t
>(msd.
eq_id);
884 uint16_t fusCurrentDpbIdx =
static_cast<uint32_t
>(fuCurrentEquipmentId & 0xFFFF);
887 uint64_t tgn = msd.
idx;
889 LOGF(warning,
"!!! Misplaced VSP event! tgn = %lu while EventId = %u !!!\n", tgn, fCurEvent.
fEventId);
890 uint32_t tgNev =
static_cast<uint32_t
>(tgn);
899 uint32_t uNbMessages = 0;
901 uint64_t uiTrgTimeFLES = 0;
902 uint64_t uiHitTimeFLES = 0;
905 static const uint32_t kuBytesPerMessage = 4;
907 uNbMessages = (size - (size % kuBytesPerMessage)) / kuBytesPerMessage;
910 const uint32_t* pInBuff =
reinterpret_cast<const uint32_t*
>((*stti).content(uw02, 0));
913 uint64_t uiTrgTime_TsMsb = 0;
914 uint64_t uiHitTime_TsMsb = 0;
915 uint64_t uiTrgTime_Epoch = 0;
917 uint16_t uiTsMsbMessageNumber = 0;
918 uint16_t uiEpochMessageNumber = 0;
920 uint16_t usHitMissedEvts = 0;
921 if (uNbMessages == 0)
925 for (uint32_t uIdx = 0; uIdx < uNbMessages; ++uIdx) {
927 uint32_t ulData =
static_cast<uint32_t
>(pInBuff[uIdx]);
935 uiEpochMessageNumber++;
937 if (uiEpochMessageNumber == 1)
938 uiTrgTime_Epoch = mess.GetEpochVal();
940 printf(
"fles WARNING: more than one EPOCH message in event tgN = %lu, exactly: %u\n", tgn,
941 uiEpochMessageNumber);
945 uiTsMsbMessageNumber++;
946 uint64_t uVal = mess.GetTsMsbValBinning();
947 if (uVal < fvulCurrentTsMsb[uw02]) {
948 printf(
"TsMsbCycle: event trigger# %u", tgNev);
949 printf(
"\tDPB: %u, Old TsMsb= %lu, new TsMsb=%lu, Old MsbCy=%u\n", uw02, fvulCurrentTsMsb[uw02],
950 uVal, fvuCurrentTsMsbCycle[uw02]);
952 if ((fvulCurrentTsMsb[uw02] - uVal) > 10000000)
953 fvuCurrentTsMsbCycle[uw02]++;
956 fvulCurrentTsMsb[uw02] = uVal;
957 uiHitTime_TsMsb = uVal << 10;
958 uiHitTime_TsMsb +=
static_cast<uint64_t
>(stsxyter::kulTsCycleNbBinsBinning)
959 * fvuCurrentTsMsbCycle[uw02];
960 if (uiTsMsbMessageNumber == 1) {
962 uiHitTime_TsMsb & 0xFFE0000000;
967 uint16_t usRawTs =
static_cast<uint16_t
>(mess.GetHitTimeBinning());
968 uiHitTimeFLES = uiHitTime_TsMsb +
static_cast<uint64_t
>(usRawTs);
969 uint16_t usElinkIdx = mess.GetLinkIndexHitBinning();
970 uint16_t usChan = mess.GetHitChannel();
971 uint16_t usRawAdc = mess.GetHitAdc();
973 if (mess.IsHitMissedEvts())
975 dig->
AppendHit(uiHitTimeFLES, usElinkIdx, usChan, usRawAdc);
984 uiTrgTimeFLES = uiTrgTime_TsMsb + uiTrgTime_Epoch;
991BmnStatus BmnConverterThread::FillMSC16VE_E(UInt_t*
d, DeviceHeader* dev_hdr)
995 const uint32_t len = dev_hdr->GetNWords();
996 MSC16VE_EHeader* ms =
reinterpret_cast<MSC16VE_EHeader*
>(
d);
999 if (ms->Hdr.Len > (len - 1)) {
1000 LOGF(error,
"MSC header payload length mismatch!");
1006 Bool_t hasValues = kFALSE;
1007 std::array<uint8_t, MSC_N_COUNTERS> cntrs = {};
1008 switch (ms->GetVersion()) {
1010 const uint8_t NumsInWord = 4;
1011 while (index < len) {
1012 uint8_t
type =
d[index] >> 28;
1016 UInt_t ext_cond = (
d[index] >> 24) & (BIT(4) - 1);
1017 UInt_t sliceNum = (
d[index]) & (BIT(24) - 1);
1018 auto sc_time_shift = ms->SliceInt * sliceNum * 1ns;
1019 SysPoint p{(ms->Tai.Sec - tai_utc_dif) * 1s + ms->Tai.NSec * 1ns + sc_time_shift};
1020 LOGF(debug,
"MSC ext_cond %2u sliceNum %7u time %s", ext_cond, sliceNum,
1022 new ((*msc)[
msc->GetEntriesFast()])
1028 for (uint8_t
i = 0;
i < NumsInWord;
i++) {
1029 UInt_t cnt = (
d[index] >> (
i * ms->NCntrBits)) & (BIT(ms->NCntrBits) - 1);
1030 cntrs[
type * NumsInWord +
i] = cnt;
1039 UInt_t missing_hits =
d[index++];
1041 LOGF(info,
"missing_hits %3u !!!", missing_hits);
1042 LOGF(debug,
"missing_hits %u", missing_hits);
1046 SysPoint point{(ms->Tai.Sec - tai_utc_dif) * 1s + ms->Tai.NSec * 1ns};
1047 uint32_t n_slices = ms->Hdr.Len - 1 - (
sizeof(MSC16VE_EHeader) -
sizeof(MStreamHeader)) /
kNBYTESINWORD;
1050 vector<uint8_t>& vals = dig->
GetValues();
1051 vector<SysPoint>& times = dig->
GetTimes();
1053 int32_t istart = index;
1054 while (index < len) {
1055 uint8_t cnt =
d[index] & (BIT(ms->NCntrBits) - 1);
1056 uint8_t ext_cond = (
d[index] >> ms->NCntrBits) & (BIT(ms->ExtCondCnt) - 1);
1057 UInt_t sliceNum =
d[index] >> (ms->NCntrBits + ms->ExtCondCnt);
1058 auto sc_time_shift = ms->SliceInt * sliceNum * 1ns;
1059 SysPoint point_slice{point + sc_time_shift};
1060 int32_t iVal = index - istart;
1063 times[iVal] = point_slice;
1064 conds[iVal] = ext_cond;
1066 LOGF(debug,
"MSC ext_cond %2u cnt %2u sliceNum %7u time %s", ext_cond, cnt, sliceNum,
1079 LOGF(warning,
"MSC16 ver $u not implemented", ms->GetVersion());
1088BmnStatus BmnConverterThread::FillVirtualDevice(UInt_t*
d, DeviceHeader* dh)
1090 LOGF(info,
"Found virtual device 0x%08X block", dh->Serial);
1093 LOGF(info,
"Not T0 device");
1097 if (fExportExternalSpillStat) {
1098 std::ofstream outfile(Form(
"virt_device_run_%u_%08X_%02X_t_%lld_%lld.txt", fCurEvent.
fRunId, dh->Serial,
1101 ios::out | ios::binary);
1103 outfile << std::hex <<
d[
i];
1104 outfile.write(
reinterpret_cast<const char*
>(
d) + bin_block_len, dh->Len - bin_block_len);
1108 const Int_t date_len = 19;
1110 TPRegexp re_str_cfg_t0(
"(\\d{2})\\.(\\d{2})\\.(\\d{4})\\s(\\d{2}:\\d{2}:\\d{2})");
1111 int32_t re_subst_ret = re_str_cfg_t0.Substitute(str,
"$3-$2-$1 $4");
1112 LOGF(info,
"ts line return %d", re_subst_ret);
1114 LOGF(debug,
"cntr[%3d]: %8u",
i,
d[
i]);
1120 TTimeStamp ts_unix_sec(t_unix_sec, 0);
1121 TTimeStamp ts_2020_sec(t_2020_sec + TTimeStamp(2020, 1, 1, 0, 0, 0), 0);
1122 LOGF(info,
"unix ts: %s", ts_unix_sec.AsString());
1123 LOGF(info,
"2020 ts: %s", ts_2020_sec.AsString());
1125 lastT0->SetTriggerMask(trig_bit_conf);
1126 bitset<32> trig_bit_conf_bs(trig_bit_conf);
1127 LOGF(debug,
"trig bitset %u", trig_bit_conf);
1128 LOGF(debug,
"trig bitset %s", trig_bit_conf_bs.to_string());
1130 string tcfg(
reinterpret_cast<const char*
>(
d) + pos, dh->Len - pos);
1136 TTimeStamp(ts_unix_sec.GetSec() - 3 * 3600,
1137 ts_unix_sec.GetNanoSec());
1139 lastT0->SetTS(ts_unix_sec);
1141 if (t_2020_sec > 0) {
1142 lastT0->SetTS(ts_2020_sec);
1143 }
else if (re_subst_ret > 0) {
1145 TTimeStamp ts_from_string(
static_cast<UInt_t
>(dt.GetDate()),
static_cast<UInt_t
>(dt.GetTime()), 0u);
1146 LOGF(info,
"ts line: %s", ts_from_string.AsString());
1147 ts_from_string = TTimeStamp(
1148 ts_from_string.GetSec() - 3 * 3600,
1149 ts_from_string.GetNanoSec());
1157 lastT0->SetTS(ts_from_string);
1159 LOGF(warning,
"Unable to find raw T0 block timestamp!");
1166 lastT0->SetTimeSinceLastEvNs(duration_cast<nanoseconds>(tsle).count());
1172BmnStatus BmnConverterThread::FillUT24VE_TRC(UInt_t*
d, UInt_t& serial, UInt_t& len)
1175 MStreamHeader* ms =
reinterpret_cast<MStreamHeader*
>(
d);
1179 MStreamTAI* ms0 =
reinterpret_cast<MStreamTAI*
>(
d + index);
1187 LOGF(error,
"UT24VE-TRC Error! MSHeader payload length larger than from device header!");
1195 while (++index < len) {
1196 uint32_t sig_states =
d[index];
1197 vec.push_back(sig_states);
1198 bitset<32> sig_states_bs(sig_states);
1199 LOGF(debug2,
"TRC states d[%3u] %s", index, sig_states_bs.to_string());
1204BmnSyncDigit* BmnConverterThread::FillWR(UInt_t serial, ULong64_t iEvent, Long64_t t_sec, Long64_t t_ns)
1208 if (tai_utc_dif == 0) {
1209 tai_utc_dif = GetUTCShift(TTimeStamp(time_t(t_sec), t_ns));
1210 if (tai_utc_dif == 0)
1211 LOGF(warn,
"Possibly wrong state of %08X", serial);
1213 return new ((*sync)[
sync->GetEntriesFast()])
BmnSyncDigit(serial, iEvent, t_sec - tai_utc_dif, t_ns);
1216BmnStatus BmnConverterThread::FillFVME2TMWR(UInt_t*
d, UInt_t serial, UInt_t& idx, UInt_t& len)
1219 UInt_t word =
d[idx];
1220 UInt_t
id = word >> 28;
1223 UInt_t d0 =
d[idx + 0];
1224 UInt_t d1 =
d[idx + 1];
1225 UInt_t d2 =
d[idx + 2];
1226 UInt_t d3 =
d[idx + 3];
1227 if ((d0 >> 28) != 2 || (d1 >> 28) != 2 || (d2 >> 28) != 2 || (d3 >> 28) != 2)
1229 Long64_t ts_t0_s = -1;
1230 Long64_t ts_t0_ns = -1;
1231 Long64_t GlobalEvent = -1;
1232 ts_t0_ns = (d0 & 0x0FFFFFFF) | ((d1 & 0x3) << 28);
1233 ts_t0_s = ((d1 >> 4) & 0xFFFFFF) | ((d2 & 0xFFFF) << 24);
1234 GlobalEvent = ((d3 & 0x0FFFFFFF) << 12) | ((d2 >> 16) & 0xFFF);
1235 BmnSyncDigit* sd = FillWR(serial, GlobalEvent, ts_t0_s, ts_t0_ns);
1236 if (fPeriodId < 8) {
1241 LOGF(debug3,
"ts :\t %10lli %9lli TMWR 0x%08X", ts_t0_s, ts_t0_ns, serial);
1244 UInt_t d0 =
d[idx + 0];
1245 UInt_t d1 =
d[idx + 1];
1246 if (((d0 >> 28) != 4) || ((d1 >> 28) != 5))
1272 printf(
"unrecognized TMWR id %u\n",
id);
1280BmnStatus BmnConverterThread::FillMSC(UInt_t*
d, UInt_t serial, UInt_t slot, UInt_t& idx)
1282 UInt_t
type =
d[idx] >> 28;
1286 std::array<UInt_t, MSC_N_COUNTERS>& cntrArrCur = dig->
GetValue();
1295 }
else if (type == 5) {
1296 UInt_t cnt =
d[idx] & (BIT(28) - 1);
1299 cntrArrCur[iCnt++] = cnt;
1302 type = (
d[++idx] >> 28) & (BIT(5) - 1);
1308BmnStatus BmnConverterThread::InitUTCShift()
1310 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1972, 1, 1, 0, 0, 9), 10));
1311 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1972, 7, 1, 0, 0, 10), 11));
1312 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1973, 1, 1, 0, 0, 11), 12));
1313 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1974, 1, 1, 0, 0, 12), 13));
1314 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1975, 1, 1, 0, 0, 13), 14));
1315 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1976, 1, 1, 0, 0, 14), 15));
1316 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1977, 1, 1, 0, 0, 15), 16));
1317 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1978, 1, 1, 0, 0, 16), 17));
1318 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1979, 1, 1, 0, 0, 17), 18));
1319 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1980, 1, 1, 0, 0, 18), 19));
1320 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1981, 7, 1, 0, 0, 19), 20));
1321 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1982, 7, 1, 0, 0, 20), 21));
1322 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1983, 7, 1, 0, 0, 21), 22));
1323 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1985, 7, 1, 0, 0, 22), 23));
1324 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1988, 1, 1, 0, 0, 23), 24));
1325 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1990, 1, 1, 0, 0, 24), 25));
1326 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1991, 1, 1, 0, 0, 25), 26));
1327 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1992, 7, 1, 0, 0, 26), 27));
1328 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1993, 7, 1, 0, 0, 27), 28));
1329 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1994, 7, 1, 0, 0, 28), 29));
1330 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1996, 1, 1, 0, 0, 29), 30));
1331 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1997, 7, 1, 0, 0, 30), 31));
1332 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1999, 1, 1, 0, 0, 31), 32));
1333 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2006, 1, 1, 0, 0, 32), 33));
1334 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2009, 1, 1, 0, 0, 33), 34));
1335 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2012, 7, 1, 0, 0, 34), 35));
1336 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2015, 7, 1, 0, 0, 35), 36));
1337 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2017, 1, 1, 0, 0, 36), 37));
1338 utc_valid = TTimeStamp(2026, 12, 30, 0, 0, 1);
1342Int_t BmnConverterThread::GetUTCShift(TTimeStamp t)
1344 if (t < leaps.begin()->first) {
1345 LOGF(warning,
"Wrong time! %s", t.AsString());
1349 LOGF(warning,
"Warning! Leap seconds table expired!");
1351 auto it = leaps.lower_bound(t);
1352 if ((it == leaps.end()))
1354 else if (it->first > t)
const Float_t d
Z-ccordinate of the first GEM-station.
void memset(T *dest, T i, size_t num)
uses binary expansion of copied volume for speed up
std::chrono::time_point< SysClock > SysPoint
#define ADC_SAMPLING_LIMIT
const uint32_t kMSTREAM_TYPE_TRIG
const uint32_t kADC64VE_XGE
const uint32_t kEVENTTYPESLOT
const uint32_t kVSP_SERIALS
const uint32_t kMODTRAILER
const uint32_t kT0_BIN_BLOCK_2020_SEC
const uint32_t TDC_TRAILING
const uint32_t kMSTREAM_TYPE_TDC
const uint32_t TMWR_REL_TS
const uint32_t kVIRTUAL_DEVICE
const uint32_t kTQDC16VS_E
const uint32_t kEVTRAILER
const uint32_t TMWR_REL_TS_TB
const uint32_t TMWR_EOS_CNT
const uint32_t kUT24VE_TRC
const uint32_t kMSTREAM_TYPE_STAT
const uint32_t kTDC64VHLE
const uint32_t TDC_EV_HEADER
const uint32_t TDC_EV_TRAILER
const uint32_t TDC_LEADING
const uint32_t MSC_N_COUNTERS
const uint32_t kMSTREAM_TYPE_ADC
const uint32_t kNBYTESINWORD
const uint32_t kGENERIC_DEVICE
const uint32_t kT0_BIN_BLOCK_UNIX_SEC
const uint32_t kHGND_SERIALS
const uint32_t SERIAL_TO_CFG
const uint32_t TMWR_PULSE
const uint32_t kTDC64VHLE_E
const uint32_t kT0_BIN_BLOCK_WORDS
const uint8_t MSC_TIME_SLICE_INFO
const uint32_t kMSC16VE_E
const uint32_t kMODHEADER
const uint32_t TMWR_EOS_CNT_MATCHED
void ClearRawSpillArrays()
void SetTrees(TTree *tree, TTree *treeSpills)
std::map< uint8_t, uint32_t * > time_slice_map
std::shared_ptr< TBufferMergerFile > mergerFile
BmnEventHeader * eventHeaderDAQ
void SetData(Int_t taskId, Int_t len=0, UInt_t *data=nullptr, BmnEventType fCurEvType=kBMNEMPTY, UInt_t fRunId=7444, UInt_t fEventId=-1)
void RegisterSpillBranches()
static std::string TimePoint2String(SysPoint p)
static SysPoint TimeStamp2TP(TTimeStamp p)
std::array< IntType, MSC_N_COUNTERS > & GetValue()
std::vector< IntType > & GetValues()
std::vector< uint8_t > & GetExtCond()
std::vector< SysPoint > & GetTimes()
Long64_t GetTime_sec() const
Long64_t GetTime_ns() const
void SetTrigBefo(UInt_t _v)
void SetTrigAccepted(UInt_t _v)
void SetTrigAfter(UInt_t _v)
void SetTrigAll(UInt_t _v)
void SetTrigRjct(UInt_t _v)
void SetTrigCand(UInt_t _v)
void SetTrigAvail(UInt_t _v)
void AppendHit(uint64_t HitTime, uint16_t ElinkIdx, uint16_t Chan, uint16_t Adc)
void SetTHitMissedEvts(uint16_t val)
void SetTTrigTime(uint64_t val)
The StorableTimeslice class contains the data of a single timeslice.
bool is_word_event_header(uint16_t word)
uint16_t get_block_size(EventPacketVersion packet_version=ERR)
EventPacketVersion get_event_packet_version(uint16_t word)
Microslice descriptor struct.
uint64_t idx
Microslice index / start time.
uint32_t size
Content size (bytes)
uint16_t eq_id
Equipment identifier.