14#include "CbmTofUnpackPar.h"
17#include "CbmTofDigiExp.h"
19#include "StorableTimeslice.hpp"
21#include "FairMQLogger.h"
22#include "FairMQProgOptions.h"
27#include <boost/archive/binary_iarchive.hpp>
33 using std::runtime_error::runtime_error;
43 , fuMsAcceptsPercent(100)
48 , fuNrOfFebsPerGdpb(0)
50 , fuNrOfChannelsPerGet4(0)
51 , fuNrOfChannelsPerFeet(0)
53 , fuNrOfGet4PerGdpb(0)
54 , fuNrOfChannelsPerGdpb(0)
65 , fulCurrentEpochTime(0.)
69 , fbEpochSuppModeOn(kFALSE)
72 , fbMergedEpochsOn(kFALSE)
77 , fdFirstDigiTimeDif(0.)
79 , fhRawTDigEvBmon(nullptr)
80 , fhRawTDigRef0(nullptr)
81 , fhRawTDigRef(nullptr)
82 , fhRawTRefDig0(nullptr)
83 , fhRawTRefDig1(nullptr)
84 , fhRawDigiLastDigi(nullptr)
89 , fhDetChanCoinc(nullptr)
96 , fulGdpbTsFullLast(0.)
97 , fulStarTsFullLast(0.)
100 , fuStarTrigCmdLast(0)
114 int noChannel = fChannels.size();
115 LOG(info) <<
"Number of defined input channels: " << noChannel;
116 for (
auto const& entry : fChannels) {
117 LOG(info) <<
"Channel name: " << entry.first;
124 LOG(error) << e.what();
125 ChangeState(ERROR_FOUND);
132 std::size_t pos1 = channelName.find(entry);
133 if (pos1 != std::string::npos) {
134 const vector<std::string>::const_iterator
pos =
137 LOG(info) <<
"Found " << entry <<
" in " << channelName;
138 LOG(info) <<
"Channel name " << channelName <<
" found in list of allowed channel names at position " << idx;
142 LOG(info) <<
"Channel name " << channelName <<
" not found in list of allowed channel names.";
143 LOG(error) <<
"Stop device.";
149 LOG(info) <<
"Init parameter containers for CbmDeviceUnpackTofStar2018.";
153 std::string message {
"CbmTofUnpackPar,111"};
154 LOG(info) <<
"Requesting parameter container CbmTofUnpackPar, sending message: " << message;
156 FairMQMessagePtr req(NewSimpleMessage(
"CbmTofUnpackPar,111"));
157 FairMQMessagePtr rep(NewMessage());
159 if (Send(req,
"parameters") > 0) {
160 if (Receive(rep,
"parameters") >= 0) {
161 if (rep->GetSize() != 0) {
163 fUnpackPar =
static_cast<CbmTofUnpackPar*
>(tmsg.ReadObject(tmsg.GetClass()));
164 LOG(info) <<
"Received parameter from the server:";
168 LOG(error) <<
"Received empty reply. Parameter not available";
193 LOG(info) <<
"ReInit parameter containers for CbmDeviceUnpackTofStar2018.";
223 LOG(info) <<
"GDPB Id of TOF " << i <<
" : " << std::hex <<
fUnpackPar->GetRocId(i) << std::dec;
225 UInt_t uNrOfChannels =
fUnpackPar->GetNumberOfChannels();
226 LOG(info) <<
"Nr. of mapped Tof channels: " << uNrOfChannels;
227 for (UInt_t i = 0; i < uNrOfChannels; ++i) {
228 if (i % 8 == 0) LOG(info);
229 LOG(info) << Form(
" 0x%08x",
fUnpackPar->GetChannelToDetUIdMap(i));
233 LOG(info) <<
"Plot Channel Rate => " << (
fUnpackPar->IsChannelRateEnabled() ?
"ON" :
"OFF");
242 LOG(info) <<
"create Histos for " <<
fuNrOfGdpbs <<
" gDPBs ";
245 new TH1F(Form(
"Raw_TDig-EvBmon"), Form(
"Raw digi time difference to 1st digi ; time [ns]; cts"), 500, 0, 100.);
249 new TH1F(Form(
"Raw_TDig-Ref0"), Form(
"Raw digi time difference to Ref ; time [ns]; cts"), 6000, -10000, 50000);
253 new TH1F(Form(
"Raw_TDig-Ref"), Form(
"Raw digi time difference to Ref ; time [ns]; cts"), 6000, -1000, 5000);
256 fhRawTRefDig0 =
new TH1F(Form(
"Raw_TRef-Dig0"), Form(
"Raw Ref time difference to last digi ; time [ns]; cts"), 9999,
261 new TH1F(Form(
"Raw_TRef-Dig1"), Form(
"Raw Ref time difference to last digi ; time [ns]; cts"), 9999, -5000, 5000);
265 Form(
"Raw Digi time difference to last digi ; time [ns]; cts"), 9999, -5000, 5000);
272 for (UInt_t uGdpb = 0; uGdpb <
fuNrOfGdpbs; uGdpb++) {
273 fhRawTotCh[uGdpb] =
new TH2F(Form(
"Raw_Tot_gDPB_%02u", uGdpb), Form(
"Raw TOT gDPB %02u; channel; TOT [bin]", uGdpb),
278 new TH1I(Form(
"ChCount_gDPB_%02u", uGdpb), Form(
"Channel counts gDPB %02u; channel; Hits", uGdpb),
293 new TH2F(Form(
"fhChanCoinc_%02u", uGdpb), Form(
"Channels Coincidence %02u; Left; Right", uGdpb),
296 fhDetChanCoinc =
new TH2F(
"fhDetChanCoinc",
"Det Channels Coincidence; Left; Right", 32, 0., 32, 32, 0., 32);
307 LOG(info) <<
"Received message number " <<
fNumMessages <<
" with size " << msg->GetSize();
309 std::string msgStr(
static_cast<char*
>(msg->GetData()), msg->GetSize());
310 std::istringstream iss(msgStr);
311 boost::archive::binary_iarchive inputArchive(iss);
313 fles::StorableTimeslice component {0};
314 inputArchive >> component;
324 LOG(debug) <<
"Timeslice contains " << ts.num_microslices(component) <<
" microslices of component " << component;
327 Int_t iMessageType = -111;
328 size_t numCompMsInTs = ts.num_microslices(component);
329 for (
size_t m = 0; m < numCompMsInTs; ++m) {
337 constexpr uint32_t kuBytesPerMessage = 8;
339 auto msDescriptor = ts.descriptor(component, m);
341 fdMsIndex =
static_cast<double>(msDescriptor.idx);
342 const uint8_t* msContent =
reinterpret_cast<const uint8_t*
>(ts.content(component, m));
344 uint32_t
size = msDescriptor.size;
345 if (0 <
size) LOG(debug) <<
"Microslice " << m <<
": " <<
fdMsIndex <<
" has size: " <<
size;
348 if (0 != (
size % kuBytesPerMessage))
349 LOG(error) <<
"The input microslice buffer does NOT "
350 <<
"contain only complete nDPB messages!";
353 if (0 != (
size % kuBytesPerMessage))
354 LOG(error) <<
"The input microslice buffer does NOT "
355 <<
"contain only complete nDPB messages!";
358 uint32_t uNbMessages = (
size - (
size % kuBytesPerMessage)) / kuBytesPerMessage;
361 const uint64_t* pInBuff =
reinterpret_cast<const uint64_t*
>(msContent);
362 for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
364 uint64_t ulData =
static_cast<uint64_t
>(pInBuff[uIdx]);
365 ngdpb::Message mess(ulData);
375 iMessageType = mess.getMessageType();
387 <<
" set in parameters, message ignored";
391 switch (mess.getMessageType()) {
393 case ngdpb::MSG_EPOCH:
394 case ngdpb::MSG_GET4: {
400 case ngdpb::MSG_EPOCH2: {
405 ngdpb::Message tmpMess(mess);
406 tmpMess.setGdpbGenChipId(uGet4Index);
417 case ngdpb::MSG_GET4_32B: {
420 LOG(debug) <<
"Add 32B message from Gdpb " <<
fuGdpbNr <<
" to EpSupprBuffer of Get4 " <<
fuGet4Nr
428 case ngdpb::MSG_GET4_SLC: {
432 case ngdpb::MSG_GET4_SYS: {
436 case ngdpb::MSG_STAR_TRI: {
442 LOG(error) <<
"Message (" <<
iMess <<
") type " << std::hex << std::setw(2)
443 <<
static_cast<uint16_t
>(mess.getMessageType()) <<
" not included in Get4 unpacker.";
444 if (100 ==
iMess) LOG(error) <<
"Stop reporting MSG errors... ";
459 UInt_t uGet4Id = mess.getGdpbGenChipId();
460 UInt_t uChannel = mess.getGdpbHitChanId();
461 UInt_t uTot = mess.getGdpbHit32Tot();
468 if (0 < ulCurEpochGdpbGet4) ulCurEpochGdpbGet4--;
470 ulCurEpochGdpbGet4 = get4v1x::kuEpochCounterSz;
476 dHitTime = mess.getMsgG4v2FullTimeD(ulCurEpochGdpbGet4);
486 dHitTime = mess.getMsgFullTimeD(ulCurEpochGdpbGet4);
489 Double_t dHitTot = uTot;
497 if (
fUnpackPar->GetNumberOfChannels() < uChanInSyst) {
498 LOG(error) <<
"Invalid mapping index " << uChanInSyst <<
" VS " <<
fUnpackPar->GetNumberOfChannels() <<
", from "
499 <<
fuGdpbNr <<
", " << uGet4Id <<
", " << uChannel;
505 UInt_t uChanUId =
fUnpackPar->GetChannelToDetUIdMap(uChanInSyst);
506 if (0 == uChanUId)
return;
523 LOG(debug) << Form(
"Insert 0x%08x digi with time ", uChanUId) << dHitTime << Form(
", Tot %4.0f", dHitTot)
526 << ulCurEpochGdpbGet4;
528 fDigi =
new CbmTofDigiExp(uChanUId, dHitTime, dHitTot);
541 ULong64_t ulEpochNr = mess.getGdpbEpEpochNb();
555 if (0 < ulEpochNr) mess.setEpoch2Number(ulEpochNr - 1);
557 mess.setEpoch2Number(get4v1x::kuEpochCounterSz);
560 if (0 < iBufferSize) {
561 LOG(debug) <<
"Now processing " << iBufferSize <<
" stored messages for get4 " <<
fuGet4Nr <<
" with epoch number "
564 for (Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++) {
615 Int_t mType = mess.getMessageType();
616 Int_t rocId = mess.getRocNumber();
617 Int_t get4Id = mess.getGdpbGenChipId();
618 Int_t channel = mess.getGdpbHitChanId();
619 uint64_t uData = mess.getData();
621 LOG(info) <<
"Get4 MSG type " << mType <<
" from rocId " << rocId <<
", getId " << get4Id <<
", (hit channel) "
622 << channel << Form(
" hex data %0lx ", uData);
629 <<
" for board ID " << std::hex << std::setw(4) <<
fuGdpbId << std::dec;
631 switch (mess.getGdpbSysSubType()) {
632 case ngdpb::SYSMSG_GET4_EVENT: {
633 LOG(info) <<
" +++++++ > Chip = " << std::setw(2) << mess.getGdpbGenChipId() <<
", Chan = " << std::setw(1)
634 << mess.getGdpbSysErrChanId() <<
", Edge = " << std::setw(1) << mess.getGdpbSysErrEdge()
635 <<
", Empt = " << std::setw(1) << mess.getGdpbSysErrUnused() <<
", Data = " << std::hex << std::setw(2)
636 << mess.getGdpbSysErrData() << std::dec <<
" -- GET4 V1 Error Event";
639 case ngdpb::SYSMSG_CLOSYSYNC_ERROR: LOG(info) <<
"Closy synchronization error";
break;
640 case ngdpb::SYSMSG_TS156_SYNC: LOG(info) <<
"156.25MHz timestamp reset";
break;
641 case ngdpb::SYSMSG_GDPB_UNKWN:
642 LOG(info) <<
"Unknown GET4 message, data: " << std::hex << std::setw(8) << mess.getGdpbSysUnkwData() << std::dec;
649 Int_t iMsgIndex = mess.getStarTrigMsgIndex();
663 UInt_t uNewToken = mess.getStarTokenStarD();
664 UInt_t uNewDaqCmd = mess.getStarDaqCmdStarD();
665 UInt_t uNewTrigCmd = mess.getStarTrigCmdStarD();
669 LOG(debug) <<
"Possible error: identical STAR tokens found twice in a "
670 "row => ignore 2nd! "
704 LOG(debug) <<
"Insert fake digi with time " << dTime <<
", Tot " << dTot;
708 fDigi =
new CbmTofDigiExp(0x00005006, dTime, dTot);
712 default: LOG(error) <<
"Unknown Star Trigger messageindex: " << iMsgIndex;
721 LOG(info) <<
"Header ID: Ox" << std::hex << static_cast<int>(mdsc.hdr_id) << std::dec;
722 LOG(info) <<
"Header version: Ox" << std::hex << static_cast<int>(mdsc.hdr_ver) << std::dec;
723 LOG(info) <<
"Equipement ID: " << mdsc.eq_id;
724 LOG(info) <<
"Flags: " << mdsc.flags;
725 LOG(info) <<
"Sys ID: Ox" << std::hex << static_cast<int>(mdsc.sys_id) << std::dec;
726 LOG(info) <<
"Sys version: Ox" << std::hex << static_cast<int>(mdsc.sys_ver) << std::dec;
727 LOG(info) <<
"Microslice Idx: " << mdsc.idx;
728 LOG(info) <<
"Checksum: " << mdsc.crc;
729 LOG(info) <<
"Size: " << mdsc.size;
730 LOG(info) <<
"Offset: " << mdsc.offset;
735 if (0 == ts.num_components()) {
736 LOG(error) <<
"No Component in TS " << ts.index();
739 LOG(info) <<
"Found " << ts.num_components() <<
" different components in timeslice";
741 for (
size_t c = 0; c < ts.num_components(); ++c) {
742 LOG(info) <<
"Found " << ts.num_microslices(c) <<
" microslices in component " << c;
743 LOG(info) <<
"Component " << c <<
" has a size of " << ts.size_component(c) <<
" bytes";
744 LOG(info) <<
"Sys ID: Ox" << std::hex << static_cast<int>(ts.descriptor(0, 0).sys_id) << std::dec;
static constexpr size_t size()
std::vector< std::vector< ngdpb::Message > > fvmEpSupprBuffer
void PrintMicroSliceDescriptor(const fles::MicrosliceDescriptor &mdsc)
std::vector< ULong64_t > fvulCurrentEpoch
void FillHitInfo(ngdpb::Message)
void FillStarTrigInfo(ngdpb::Message)
std::vector< Bool_t > fvbFirstEpochSeen
ULong64_t fulGdpbTsFullLast
Bool_t ReInitContainers()
Double_t fdFirstDigiTimeDif
Bool_t DoUnpack(const fles::Timeslice &ts, size_t component)
std::vector< TH2 * > fhChanCoinc
ULong64_t fulStarTsFullLast
void FillEpochInfo(ngdpb::Message)
bool HandleData(FairMQMessagePtr &, int)
ULong64_t fulCurrentEpochTime
void PrintSysInfo(ngdpb::Message)
bool IsChannelNameAllowed(std::string channelName)
std::vector< TH2 * > fhRawTotCh
void PrintGenInfo(ngdpb::Message)
std::vector< Bool_t > fvbChanThere
UInt_t fuNrOfChannelsPerGet4
UInt_t fuNrOfChannelsPerFeet
CbmTofUnpackPar * fUnpackPar
virtual ~CbmDeviceUnpackTofStar2018()
UInt_t fuNrOfChannelsPerGdpb
void PrintSlcInfo(ngdpb::Message)
bool CheckTimeslice(const fles::Timeslice &ts)
std::vector< std::string > fAllowedChannels
std::map< UInt_t, UInt_t > fGdpbIdIndexMap
CbmDeviceUnpackTofStar2018()
std::vector< int > fMsgCounter
Int_t GetArrayIndex(Int_t gdpbId, Int_t get4Id)
std::vector< TH1 * > fhChCount
Singleton buffer class for CBM raw data.
Double_t GetTimeLast() const
Double_t GetTimeFirst() const
void InsertData(Digi *digi)