10 #include "CbmTofUnpackPar.h"
12 #include "CbmTbDaqBuffer.h"
13 #include "CbmTofDigiExp.h"
15 #include "StorableTimeslice.hpp"
17 #include "FairMQLogger.h"
18 #include "FairMQProgOptions.h"
23 #include <boost/archive/binary_iarchive.hpp>
30 using std::runtime_error::runtime_error;
40 , fuMsAcceptsPercent(100)
45 , fuNrOfFebsPerGdpb(0)
47 , fuNrOfChannelsPerGet4(0)
48 , fuNrOfChannelsPerFeet(0)
50 , fuNrOfGet4PerGdpb(0)
51 , fuNrOfChannelsPerGdpb(0)
62 , fulCurrentEpochTime(0.)
66 , fbEpochSuppModeOn(kFALSE)
69 , fbMergedEpochsOn(kFALSE)
74 , fdFirstDigiTimeDif(0.)
76 , fhRawTDigEvT0(nullptr)
77 , fhRawTDigRef0(nullptr)
78 , fhRawTDigRef(nullptr)
79 , fhRawTRefDig0(nullptr)
80 , fhRawTRefDig1(nullptr)
81 , fhRawDigiLastDigi(nullptr)
86 , fhDetChanCoinc(nullptr)
88 , fBuffer(CbmTbDaqBuffer::Instance())
93 , fulGdpbTsFullLast(0.)
94 , fulStarTsFullLast(0.)
97 , fuStarTrigCmdLast(0) {}
108 int noChannel = fChannels.size();
109 LOG(info) <<
"Number of defined input channels: " << noChannel;
110 for (
auto const& entry : fChannels) {
111 LOG(info) <<
"Channel name: " << entry.first;
118 LOG(error) << e.what();
125 std::size_t pos1 = channelName.find(entry);
126 if (pos1 != std::string::npos) {
127 const vector<std::string>::const_iterator
pos =
130 LOG(info) <<
"Found " << entry <<
" in " << channelName;
131 LOG(info) <<
"Channel name " << channelName
132 <<
" found in list of allowed channel names at position "
137 LOG(info) <<
"Channel name " << channelName
138 <<
" not found in list of allowed channel names.";
139 LOG(error) <<
"Stop device.";
144 LOG(info) <<
"Init parameter containers for CbmDeviceUnpackTofStar2018.";
148 std::string message {
"CbmTofUnpackPar,111"};
150 <<
"Requesting parameter container CbmTofUnpackPar, sending message: "
153 FairMQMessagePtr req(NewSimpleMessage(
"CbmTofUnpackPar,111"));
154 FairMQMessagePtr rep(NewMessage());
156 if (Send(req,
"parameters") > 0) {
157 if (Receive(rep,
"parameters") >= 0) {
158 if (rep->GetSize() != 0) {
161 static_cast<CbmTofUnpackPar*
>(tmsg.ReadObject(tmsg.GetClass()));
162 LOG(info) <<
"Received parameter from the server:";
165 LOG(error) <<
"Received empty reply. Parameter not available";
189 LOG(info) <<
"ReInit parameter containers for CbmDeviceUnpackTofStar2018.";
219 LOG(info) <<
"GDPB Id of TOF " <<
i <<
" : " << std::hex
222 UInt_t uNrOfChannels =
fUnpackPar->GetNumberOfChannels();
223 LOG(info) <<
"Nr. of mapped Tof channels: " << uNrOfChannels;
224 for (UInt_t
i = 0;
i < uNrOfChannels; ++
i) {
225 if (
i % 8 == 0) LOG(info);
226 LOG(info) << Form(
" 0x%08x",
fUnpackPar->GetChannelToDetUIdMap(
i));
230 LOG(info) <<
"Plot Channel Rate => "
231 << (
fUnpackPar->IsChannelRateEnabled() ?
"ON" :
"OFF");
239 LOG(info) <<
"create Histos for " <<
fuNrOfGdpbs <<
" gDPBs ";
242 new TH1F(Form(
"Raw_TDig-EvT0"),
243 Form(
"Raw digi time difference to 1st digi ; time [ns]; cts"),
250 new TH1F(Form(
"Raw_TDig-Ref0"),
251 Form(
"Raw digi time difference to Ref ; time [ns]; cts"),
258 new TH1F(Form(
"Raw_TDig-Ref"),
259 Form(
"Raw digi time difference to Ref ; time [ns]; cts"),
266 new TH1F(Form(
"Raw_TRef-Dig0"),
267 Form(
"Raw Ref time difference to last digi ; time [ns]; cts"),
274 new TH1F(Form(
"Raw_TRef-Dig1"),
275 Form(
"Raw Ref time difference to last digi ; time [ns]; cts"),
282 new TH1F(Form(
"Raw_Digi-LastDigi"),
283 Form(
"Raw Digi time difference to last digi ; time [ns]; cts"),
293 for (UInt_t uGdpb = 0; uGdpb <
fuNrOfGdpbs; uGdpb++) {
295 new TH2F(Form(
"Raw_Tot_gDPB_%02u", uGdpb),
296 Form(
"Raw TOT gDPB %02u; channel; TOT [bin]", uGdpb),
306 new TH1I(Form(
"ChCount_gDPB_%02u", uGdpb),
307 Form(
"Channel counts gDPB %02u; channel; Hits", uGdpb),
324 new TH2F(Form(
"fhChanCoinc_%02u", uGdpb),
325 Form(
"Channels Coincidence %02u; Left; Right", uGdpb),
334 "Det Channels Coincidence; Left; Right",
351 LOG(info) <<
"Received message number " <<
fNumMessages <<
" with size "
354 std::string msgStr(
static_cast<char*
>(msg->GetData()), msg->GetSize());
355 std::istringstream iss(msgStr);
356 boost::archive::binary_iarchive inputArchive(iss);
358 fles::StorableTimeslice component {0};
359 inputArchive >> component;
369 LOG(debug) <<
"Timeslice contains " << ts.num_microslices(component)
370 <<
" microslices of component " << component;
373 Int_t iMessageType = -111;
374 size_t numCompMsInTs = ts.num_microslices(component);
375 for (
size_t m = 0;
m < numCompMsInTs; ++
m) {
383 constexpr uint32_t kuBytesPerMessage = 8;
385 auto msDescriptor = ts.descriptor(component,
m);
387 fdMsIndex =
static_cast<double>(msDescriptor.idx);
388 const uint8_t* msContent =
389 reinterpret_cast<const uint8_t*
>(ts.content(component,
m));
391 uint32_t size = msDescriptor.size;
393 LOG(debug) <<
"Microslice " <<
m <<
": " <<
fdMsIndex
394 <<
" has size: " << size;
397 if (0 != (size % kuBytesPerMessage))
398 LOG(error) <<
"The input microslice buffer does NOT "
399 <<
"contain only complete nDPB messages!";
402 if (0 != (size % kuBytesPerMessage))
403 LOG(error) <<
"The input microslice buffer does NOT "
404 <<
"contain only complete nDPB messages!";
407 uint32_t uNbMessages =
408 (size - (size % kuBytesPerMessage)) / kuBytesPerMessage;
411 const uint64_t* pInBuff =
reinterpret_cast<const uint64_t*
>(msContent);
412 for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
414 uint64_t ulData =
static_cast<uint64_t
>(pInBuff[uIdx]);
415 ngdpb::Message mess(ulData);
425 iMessageType = mess.getMessageType();
437 LOG(warn) <<
"Message with Get4 ID too high: " <<
fuGet4Id <<
" VS "
442 switch (mess.getMessageType()) {
445 case ngdpb::MSG_GET4: {
452 case ngdpb::MSG_EPOCH2: {
459 ngdpb::Message tmpMess(mess);
460 tmpMess.setGdpbGenChipId(uGet4Index);
471 case ngdpb::MSG_GET4_32B: {
474 LOG(debug) <<
"Add 32B message from Gdpb " <<
fuGdpbNr
475 <<
" to EpSupprBuffer of Get4 " <<
fuGet4Nr <<
" size "
482 case ngdpb::MSG_GET4_SLC: {
486 case ngdpb::MSG_GET4_SYS: {
490 case ngdpb::MSG_STAR_TRI: {
496 LOG(error) <<
"Message (" <<
iMess <<
") type " << std::hex
498 <<
static_cast<uint16_t
>(mess.getMessageType())
499 <<
" not included in Get4 unpacker.";
500 if (100 ==
iMess) LOG(error) <<
"Stop reporting MSG errors... ";
514 UInt_t uGet4Id = mess.getGdpbGenChipId();
515 UInt_t uChannel = mess.getGdpbHitChanId();
516 UInt_t uTot = mess.getGdpbHit32Tot();
523 if (0 < ulCurEpochGdpbGet4)
524 ulCurEpochGdpbGet4--;
532 dHitTime = mess.getMsgG4v2FullTimeD(ulCurEpochGdpbGet4);
542 dHitTime = mess.getMsgFullTimeD(ulCurEpochGdpbGet4);
545 Double_t dHitTot = uTot;
553 if (
fUnpackPar->GetNumberOfChannels() < uChanInSyst) {
554 LOG(error) <<
"Invalid mapping index " << uChanInSyst <<
" VS "
556 <<
", " << uGet4Id <<
", " << uChannel;
562 UInt_t uChanUId =
fUnpackPar->GetChannelToDetUIdMap(uChanInSyst);
563 if (0 == uChanUId)
return;
580 LOG(debug) << Form(
"Insert 0x%08x digi with time ", uChanUId) << dHitTime
581 << Form(
", Tot %4.0f", dHitTot) <<
" into buffer with "
582 <<
fBuffer->GetSize() <<
" data from "
583 << Form(
"%11.1f to %11.1f ",
586 <<
" at epoch " << ulCurEpochGdpbGet4;
588 fDigi =
new CbmTofDigiExp(uChanUId, dHitTime, dHitTot);
600 ULong64_t ulEpochNr = mess.getGdpbEpEpochNb();
616 mess.setEpoch2Number(ulEpochNr - 1);
621 if (0 < iBufferSize) {
622 LOG(debug) <<
"Now processing " << iBufferSize
623 <<
" stored messages for get4 " <<
fuGet4Nr
626 for (Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++) {
675 Int_t mType = mess.getMessageType();
676 Int_t rocId = mess.getRocNumber();
677 Int_t get4Id = mess.getGdpbGenChipId();
678 Int_t channel = mess.getGdpbHitChanId();
679 uint64_t uData = mess.getData();
681 LOG(info) <<
"Get4 MSG type " << mType <<
" from rocId " << rocId
682 <<
", getId " << get4Id <<
", (hit channel) " << channel
683 << Form(
" hex data %0lx ", uData);
687 LOG(info) <<
"GET4 System message, epoch "
690 <<
" for board ID " << std::hex << std::setw(4) <<
fuGdpbId
693 switch (mess.getGdpbSysSubType()) {
694 case ngdpb::SYSMSG_GET4_EVENT: {
695 LOG(info) <<
" +++++++ > Chip = " << std::setw(2)
696 << mess.getGdpbGenChipId() <<
", Chan = " << std::setw(1)
697 << mess.getGdpbSysErrChanId() <<
", Edge = " << std::setw(1)
698 << mess.getGdpbSysErrEdge() <<
", Empt = " << std::setw(1)
699 << mess.getGdpbSysErrUnused() <<
", Data = " << std::hex
700 << std::setw(2) << mess.getGdpbSysErrData() << std::dec
701 <<
" -- GET4 V1 Error Event";
704 case ngdpb::SYSMSG_CLOSYSYNC_ERROR:
705 LOG(info) <<
"Closy synchronization error";
707 case ngdpb::SYSMSG_TS156_SYNC:
708 LOG(info) <<
"156.25MHz timestamp reset";
710 case ngdpb::SYSMSG_GDPB_UNKWN:
711 LOG(info) <<
"Unknown GET4 message, data: " << std::hex << std::setw(8)
712 << mess.getGdpbSysUnkwData() << std::dec;
718 Int_t iMsgIndex = mess.getStarTrigMsgIndex();
731 ULong64_t ulNewStarTsFull =
733 UInt_t uNewToken = mess.getStarTokenStarD();
734 UInt_t uNewDaqCmd = mess.getStarDaqCmdStarD();
735 UInt_t uNewTrigCmd = mess.getStarTrigCmdStarD();
741 LOG(debug) <<
"Possible error: identical STAR tokens found twice in a "
742 "row => ignore 2nd! "
771 LOG(info) <<
"Reference fake digi time shift initialized to "
778 LOG(debug) <<
"Insert fake digi with time " << dTime <<
", Tot " << dTot;
782 fDigi =
new CbmTofDigiExp(
783 0x00005006, dTime, dTot);
787 default: LOG(error) <<
"Unknown Star Trigger messageindex: " << iMsgIndex;
795 const fles::MicrosliceDescriptor& mdsc) {
796 LOG(info) <<
"Header ID: Ox" << std::hex << static_cast<int>(mdsc.hdr_id)
798 LOG(info) <<
"Header version: Ox" << std::hex
799 <<
static_cast<int>(mdsc.hdr_ver) << std::dec;
800 LOG(info) <<
"Equipement ID: " << mdsc.eq_id;
801 LOG(info) <<
"Flags: " << mdsc.flags;
802 LOG(info) <<
"Sys ID: Ox" << std::hex << static_cast<int>(mdsc.sys_id)
804 LOG(info) <<
"Sys version: Ox" << std::hex << static_cast<int>(mdsc.sys_ver)
806 LOG(info) <<
"Microslice Idx: " << mdsc.idx;
807 LOG(info) <<
"Checksum: " << mdsc.crc;
808 LOG(info) <<
"Size: " << mdsc.size;
809 LOG(info) <<
"Offset: " << mdsc.offset;
813 if (0 == ts.num_components()) {
814 LOG(error) <<
"No Component in TS " << ts.index();
817 LOG(info) <<
"Found " << ts.num_components()
818 <<
" different components in timeslice";
820 for (
size_t c = 0; c < ts.num_components(); ++c) {
821 LOG(info) <<
"Found " << ts.num_microslices(c)
822 <<
" microslices in component " << c;
823 LOG(info) <<
"Component " << c <<
" has a size of " << ts.size_component(c)
825 LOG(info) <<
"Sys ID: Ox" << std::hex
826 <<
static_cast<int>(ts.descriptor(0, 0).sys_id) << std::dec;