16 #include "FairLogger.h"
17 #include "FairRootManager.h"
19 #include "FairRunOnline.h"
20 #include "FairRuntimeDb.h"
24 #include "TClonesArray.h"
29 #include "THttpServer.h"
31 #include "TPaveStats.h"
33 #include "TProfile2D.h"
54 , fvMsComponentsList()
57 , fbIgnoreOverlapMs(kFALSE)
58 , fsHistoFileFullname(
"data/TofPulserHistos.root")
59 , fuMsAcceptsPercent(100)
64 , fdTsCoreSizeInNs(0.0)
71 , fuNrOfChannelsPerGet4(0)
72 , fuNrOfChannelsPerFee(0)
74 , fuNrOfGet4PerGdpb(0)
75 , fuNrOfChannelsPerGdpb(0)
76 , fuRawDataPrintMsgNb(100000)
77 , fuRawDataPrintMsgIdx(fuRawDataPrintMsgNb)
78 , fbPrintAllHitsEnable(kFALSE)
79 , fbPrintAllEpochsEnable(kFALSE)
81 , fuDiamondDpbIdx(10000)
92 , fviMsgCounter(11, 0)
98 , fvulGdpbTsFullLast()
99 , fvulStarTsFullLast()
101 , fvuStarDaqCmdLast()
102 , fvuStarTrigCmdLast()
104 , fvbFirstEpochSeen()
105 , fvulCurrentEpochCycle()
106 , fvulCurrentEpochFull()
107 , fulCurrentEpochTime(0)
110 , fvuFeeNbHitsLastMs()
111 , fdTsLastPulserHit()
112 , fvuCoincNbHitsLastMs()
113 , fvdCoincTsLastHit()
119 , fuNbFeePlotsPerGdpb(0)
121 , fdStartTimeLong(-1.)
122 , fdStartTimeMsSz(-1.)
123 , fuHistoryHistoSize(1800)
124 , fuHistoryHistoSizeLong(600)
125 , fdLastRmsUpdateTime(0.0)
126 , fdFitZoomWidthPs(0.0)
128 , fvhMsSzPerLink(12, NULL)
129 , fvhMsSzTimePerLink(12, NULL)
130 , fvhTimeDiffPulser()
131 , fhTimeMeanPulser(NULL)
132 , fhTimeRmsPulser(NULL)
133 , fhTimeRmsZoomFitPuls(NULL)
134 , fhTimeResFitPuls(NULL)
135 , fvhPulserCountEvoPerFeeGdpb()
136 , fvhPulserTimeDiffEvoGbtxGbtx()
137 , fvvhPulserTimeDiffEvoGdpbGdpb()
138 , fvvhPulserTimeDiffEvoFeeFee()
143 , fTimeLastHistoSaving() {}
148 LOG(info) <<
"Initializing Get4 monitor";
150 FairRootManager* ioman = FairRootManager::Instance();
152 LOG(fatal) <<
"No FairRootManager instance";
159 LOG(info) <<
"Setting parameter containers for " << GetName();
162 "CbmMcbm2018TofPar"));
166 LOG(info) <<
"Init parameter containers for " << GetName();
187 LOG(info) <<
"ReInit parameter containers for " << GetName();
217 LOG(info) <<
"GDPB Id of TOF " <<
i <<
" : " << std::hex
231 for (UInt_t uGbtx = 0; uGbtx <
fuNrOfGbtx; ++uGbtx) {
238 LOG(info) <<
"Nr. of RPCs per GBTx: ";
239 std::stringstream ss;
240 for (UInt_t uGbtx = 0; uGbtx <
fuNrOfGbtx; ++uGbtx)
242 LOG(info) << ss.str();
244 LOG(info) <<
"RPC type per GBTx: ";
246 for (UInt_t uGbtx = 0; uGbtx <
fuNrOfGbtx; ++uGbtx)
248 LOG(info) << ss.str();
250 LOG(info) <<
"RPC side per GBTx: ";
252 for (UInt_t uGbtx = 0; uGbtx <
fuNrOfGbtx; ++uGbtx)
254 LOG(info) << ss.str();
256 LOG(info) <<
"Module ID per GBTx: ";
258 for (UInt_t uGbtx = 0; uGbtx <
fuNrOfGbtx; ++uGbtx)
260 LOG(info) << ss.str();
267 LOG(info) <<
"Timeslice parameters: " <<
fuTotalMsNb
281 for (UInt_t uGdpb = 0; uGdpb <
fuNrOfGdpbs; ++uGdpb) {
314 UInt_t uGet4topadi[32] = {4, 3, 2, 1,
315 8, 7, 6, 5, 12, 11, 10, 9, 16, 15,
316 14, 13, 20, 19, 18, 17, 24, 23, 22, 21,
317 28, 27, 26, 25, 32, 31, 30, 29};
319 UInt_t uPaditoget4[32] = {4, 3, 2, 1,
320 12, 11, 10, 9, 20, 19, 18, 17, 28, 27,
321 26, 25, 32, 31, 30, 29, 8, 7, 6, 5,
322 16, 15, 14, 13, 24, 23, 22, 21};
334 27, 2, 7, 3, 31, 26, 30, 1, 33, 37, 32, 13, 9, 14,
335 10, 15, 17, 21, 16, 35, 34, 38, 25, 24, 0, 6, 20, 23,
336 18, 22, 28, 4, 29, 5, 19, 36, 39, 8, 12, 11};
338 24, 7, 1, 3, 31, 33, 25, 2, 37, 12, 14, 39, 38, 11,
339 13, 15, 18, 16, 28, 34, 26, 17, 29, 27, 23, 22, 5, 0,
340 30, 32, 6, 4, 10, 8, 20, 19, 35, 9, 21, 36};
363 TString sMsSzName = Form(
"MsSz_link_%02lu", component);
365 Form(
"Size of MS from link %02lu; Ms Size [bytes]", component);
367 new TH1F(sMsSzName.Data(), sMsSzTitle.Data(), 160000, 0., 20000.);
369 sMsSzName = Form(
"MsSzTime_link_%02lu", component);
371 "Size of MS vs time for gDPB of link %02lu; Time[s] ; Ms Size [bytes]",
378 THttpServer* server = FairRunOnline::Instance()->GetHttpServer();
388 LOG(info) <<
"Added MS size histo for component (link): " << component;
392 size_t uOverlapMsNb) {
400 LOG(info) <<
"create Histos for " <<
fuNrOfGdpbs <<
" gDPBs ";
402 THttpServer* server = FairRunOnline::Instance()->GetHttpServer();
414 Double_t dBinSzG4v2 = (6250. / 112.);
431 new TH1I(Form(
"hTimeDiffPulser_g%02u_f%1u_g%02u_f%1u",
436 Form(
"Time difference for pulser on gDPB %02u FEE %1u and "
437 "gDPB %02u FEE %1u; DeltaT [ps]; Counts",
451 name =
"hTimeMeanPulser";
454 "Time difference Mean for each FEE pairs; FEE A; FEE B ; Mean [ps]",
462 name =
"hTimeRmsPulser";
464 new TH2D(name.Data(),
465 "Time difference RMS for each FEE pairs; FEE A; FEE B ; RMS [ps]",
473 name =
"hTimeRmsZoomFitPuls";
475 "Time difference RMS after zoom for each FEE "
476 "pairs; FEE A; FEE B ; RMS [ps]",
484 name =
"hTimeResFitPuls";
486 "Time difference Res from fit for each FEE "
487 "pairs; FEE A; FEE B ; Sigma [ps]",
497 for (UInt_t uGdpb = 0; uGdpb <
fuNrOfGdpbs; ++uGdpb) {
499 name = Form(
"hPulserCountEvoPerFeeGdpb%02u", uGdpb);
502 Form(
"Pulser count per FEE in gDPB %02u; time in run [s]; dt [ps]",
512 name = Form(
"hPulserTimeDiffEvoGdpb%02uGbtx00Gbtx%02u", uGdpb, uGbtx + 1);
514 new TProfile(name.Data(),
515 Form(
"Time difference of the 1st FEE in the 1st GBTx of "
516 "gDPB %02u vs GBTx %02u; time in run [s]; dt [ps]",
525 for (UInt_t uGdpbB = uGdpb + 1; uGdpbB <
fuNrOfGdpbs; ++uGdpbB) {
526 name = Form(
"hPulserTimeDiffEvoGdpb%02uGdpb%02u", uGdpb, uGdpbB);
528 new TProfile(name.Data(),
529 Form(
"Time difference of the 1st FEE in the 1st GBTx of "
530 "gDPB %02u vs %02u; time in run [s]; dt [ps]",
540 for (UInt_t uFeeRef = 0; uFeeRef <
kuNbRefFeeEvo; ++uFeeRef) {
550 new TProfile(Form(
"hTimeDiffEvoFeeFee_g%02u_f%02u_g%02u_f%02u",
555 Form(
"Time difference for pulser on gDPB %02u FEE %1u and "
556 "gDPB %02u FEE %02u; time in run [s]; DeltaT [ps]",
578 for (UInt_t uGdpb = 0; uGdpb <
fuNrOfGdpbs; ++uGdpb) {
588 for (UInt_t uGdpbB = uGdpb + 1; uGdpbB <
fuNrOfGdpbs; ++uGdpbB)
590 server->Register(
"/TofDtEvo",
594 server->RegisterCommand(
"/Reset_All_eTOF",
595 "bMcbmMoniTofPulserResetHistos=kTRUE");
596 server->RegisterCommand(
"/Save_All_eTof",
597 "bMcbmMoniTofPulserSaveHistos=kTRUE");
598 server->RegisterCommand(
"/Update_PulsFit",
599 "bMcbmMoniTofPulserUpdateZoomedFit=kTRUE");
600 server->RegisterCommand(
"/Print_Raw_Data",
601 "bMcbmMoniTofPulserRawDataPrint=kTRUE");
602 server->RegisterCommand(
"/Print_AllHits",
603 "bMcbmMoniTofPulserPrintAllHitsEna=kTRUE");
604 server->RegisterCommand(
"/Print_AllEps",
605 "bMcbmMoniTofPulserPrintAllEpochsEna=kTRUE");
607 server->Restrict(
"/Reset_All_eTof",
"allow=admin");
608 server->Restrict(
"/Save_All_eTof",
"allow=admin");
609 server->Restrict(
"/Update_PulsFit",
"allow=admin");
610 server->Restrict(
"/Print_Raw_Data",
"allow=admin");
611 server->Restrict(
"/Print_AllHits",
"allow=admin");
612 server->Restrict(
"/Print_AllEps",
"allow=admin");
620 TCanvas* cPulser =
new TCanvas(
622 "Time difference RMS for pulser channels when FEE pulser mode is ON",
625 cPulser->Divide(2, 2);
649 TCanvas* cPulserEvo =
new TCanvas(
651 "Time difference evolution between 1st FEE of 1st GBTx of gDPB pairs",
655 for (UInt_t uGdpb = 0; uGdpb <
fuNrOfGdpbs - 1; uGdpb++) {
656 cPulserEvo->cd(1 + uGdpb);
665 for (UInt_t uGdpb = 0; uGdpb <
fuNrOfGdpbs; uGdpb++) {
666 TCanvas* cPulserEvoGbtx =
new TCanvas(
667 Form(
"cPulserEvoGbtx%02u", uGdpb),
669 "Time difference evolution between 1st FEE of GBTx pairs in gDPB %02u",
676 cPulserEvoGbtx->cd(1 + uGbtx);
692 fcMsSizeAll =
dynamic_cast<TCanvas*
>(gROOT->FindObject(
"cMsSizeAll"));
695 new TCanvas(
"cMsSizeAll",
"Evolution of MS size in last 300 s", w,
h);
697 LOG(info) <<
"Created MS size canvas in TOF monitor";
700 LOG(info) <<
"Recovered MS size canvas in TOF monitor";
702 LOG(info) <<
"Leaving CreateHistograms";
708 LOG(info) <<
"Reset eTOF STAR histos ";
713 LOG(info) <<
"Start saving eTOF STAR histos ";
735 std::chrono::time_point<std::chrono::system_clock> timeCurrent =
736 std::chrono::system_clock::now();
737 std::chrono::duration<double> elapsed_seconds =
744 else if (300 < elapsed_seconds.count()) {
745 std::time_t cTimeCurrent =
746 std::chrono::system_clock::to_time_t(timeCurrent);
748 std::strftime(tempBuff, 80,
"%F %T", localtime(&cTimeCurrent));
761 LOG(debug1) <<
"Timeslice contains " << ts.num_microslices(component)
768 Int_t messageType = -111;
769 Double_t dTsStartTime = -1;
772 for (UInt_t uMsIdx = 0; uMsIdx < uNbMsLoop; uMsIdx++) {
781 auto msDescriptor = ts.descriptor(uMsComp, uMsIdx);
798 constexpr uint32_t kuBytesPerMessage = 8;
801 auto msDescriptor = ts.descriptor(uMsComp, uMsIdx);
803 fdMsIndex =
static_cast<double>(msDescriptor.idx);
805 const uint8_t* msContent =
806 reinterpret_cast<const uint8_t*
>(ts.content(uMsComp, uMsIdx));
808 uint32_t size = msDescriptor.size;
811 LOG(debug) <<
"Microslice: " << msDescriptor.idx
812 <<
" has size: " << size;
820 if (0 == uMsIdx && 0 == uMsCompIdx) dTsStartTime = (1e-9) *
fdMsIndex;
833 if (0 != (size % kuBytesPerMessage))
834 LOG(error) <<
"The input microslice buffer does NOT "
835 <<
"contain only complete nDPB messages!";
838 uint32_t uNbMessages =
839 (size - (size % kuBytesPerMessage)) / kuBytesPerMessage;
848 <<
"---------------------------------------------------------------";
859 LOG(warning) <<
"Could not find the gDPB index for AFCK id 0x"
860 << std::hex <<
fuGdpbId << std::dec <<
" in timeslice "
862 <<
" component " << uMsCompIdx <<
"\n"
863 <<
"If valid this index has to be added in the TOF "
864 "parameter file in the RocIdArray field";
871 const uint64_t* pInBuff =
reinterpret_cast<const uint64_t*
>(msContent);
872 for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
874 uint64_t ulData =
static_cast<uint64_t
>(pInBuff[uIdx]);
885 || gLogger->IsLogNeeded(fair::Severity::debug2)) {
904 LOG(warning) <<
"Message with Get4 ID too high: " <<
fuGet4Id
907 switch (messageType) {
930 LOG(info) <<
"Epoch: " << Form(
"0x%08x ",
fuGdpbId) <<
", Merg"
932 <<
", epoch " << std::setw(8)
935 <<
", Data loss " << std::setw(1)
938 <<
", Epoch miss " << std::setw(1)
946 LOG(info) <<
"Epoch: " << Form(
"0x%08x ",
fuGdpbId) <<
", "
947 << std::setw(4) <<
fuGet4Nr <<
", Link "
949 <<
", epoch " << std::setw(8)
952 <<
", Data loss " << std::setw(1)
955 <<
", Epoch miss " << std::setw(1)
1009 LOG(error) <<
"Message type " << std::hex << std::setw(2)
1010 <<
static_cast<uint16_t
>(messageType)
1011 <<
" not included in Get4 unpacker.";
1029 for (UInt_t uFeeRef = 0; uFeeRef <
kuNbRefFeeEvo; ++uFeeRef)
1039 for (UInt_t uFeeRef = 0; uFeeRef <
kuNbRefFeeEvo; ++uFeeRef)
1042 Double_t dTimeDiff =
1062 if (uGdpbNr == uGdpbNrB) {
1073 if (0 == uGbtxNr && 0 == uGbtxNrB)
1117 || gLogger->IsLogNeeded(fair::Severity::debug2)) {
1119 <<
"CbmMcbm2018MonitorTofPulser::ProcessEpochCyle => "
1152 if (0 < ulCurEpochGdpbGet4)
1153 ulCurEpochGdpbGet4--;
1158 UInt_t uChannelNrInFee =
1199 if (92 < uTot && uTot < 95) {
1208 && 0 == uChannelNrInFee) {
1236 LOG(info) <<
"Hit: " << Form(
"0x%08x ",
fuGdpbId) <<
", " << std::setw(2)
1237 <<
fuGet4Nr <<
", " << std::setw(3) << uChannel <<
", "
1238 << std::setw(3) << uTot <<
", epoch " << std::setw(3)
1239 << ulCurEpochGdpbGet4 <<
", FullTime Clk "
1240 << Form(
"%12lu ", ulHitTime) <<
", FullTime s "
1241 << Form(
"%12.9f ", dHitTime / 1e9) <<
", FineTime " << uFts;
1265 if (0 < iBufferSize) {
1266 LOG(debug) <<
"Now processing stored messages for for get4 " <<
fuGet4Nr
1274 for (Int_t iMsgIdx = 0; iMsgIdx < iBufferSize; iMsgIdx++) {
1303 uint64_t uData = mess.
getData();
1305 LOG(debug) <<
"Get4 MSG type " << mType <<
" from gdpbId " <<
fuGdpbId
1306 <<
", getId " <<
fuGet4Id <<
", (hit channel) " << channel
1307 <<
" data " << std::hex << uData;
1312 LOG(debug) <<
"GET4 System message, epoch "
1314 << std::setprecision(9) << std::fixed
1316 <<
" for board ID " << std::hex << std::setw(4) <<
fuGdpbId
1328 LOG(debug) <<
" +++++++ > gDPB: " << std::hex << std::setw(4)
1329 <<
fuGdpbId << std::dec <<
", Chip = " << std::setw(2)
1334 << std::setw(2) << uData << std::dec
1335 <<
" -- GET4 V1 Error Event";
1337 LOG(debug) <<
" +++++++ >gDPB: " << std::hex << std::setw(4) <<
fuGdpbId
1338 << std::dec <<
", Chip = " << std::setw(2)
1343 << std::setw(2) << uData << std::dec
1344 <<
" -- GET4 V1 Error Event ";
1348 LOG(debug) <<
"Unknown GET4 message, data: " << std::hex << std::setw(8)
1350 <<
" Full message: " << std::hex << std::setw(16)
1351 << mess.
getData() << std::dec;
1356 LOG(info) << Form(
"GET4 Resynchronization: Get4:0x%04x ",
1358 << std::hex << std::setw(4) <<
fuGdpbId << std::dec;
1360 LOG(info) <<
"GET4 synchronization pulse missing in gDPB " << std::hex
1361 << std::setw(4) <<
fuGdpbId << std::dec;
1365 LOG(debug) <<
"ASIC pattern for missmatch, disable or resync";
1369 LOG(debug) <<
"Crazy system message, subtype "
1440 switch (iMsgIndex) {
1449 ULong64_t ulNewGdpbTsFull =
1466 LOG(warning) <<
"Possible error: identical STAR tokens found twice in "
1467 "a row => ignore 2nd! "
1474 << Form(
"TRG Wrd = %5x ", uTrigWord);
1491 LOG(debug) <<
"Probable reset of the STAR TS: old = "
1493 <<
" new = " << Form(
"%16llu", ulNewStarTsFull)
1536 default: LOG(error) <<
"Unknown Star Trigger messageindex: " << iMsgIndex;
1544 TString message_type;
1547 case 0: message_type =
"NOP";
break;
1548 case 1: message_type =
"HIT";
break;
1549 case 2: message_type =
"EPOCH";
break;
1550 case 3: message_type =
"SYNC";
break;
1551 case 4: message_type =
"AUX";
break;
1552 case 5: message_type =
"EPOCH2";
break;
1553 case 6: message_type =
"GET4";
break;
1554 case 7: message_type =
"SYS";
break;
1555 case 8: message_type =
"GET4_SLC";
break;
1556 case 9: message_type =
"GET4_32B";
break;
1557 case 10: message_type =
"GET4_SYS";
break;
1558 default: message_type =
"UNKNOWN";
break;
1563 LOG(info) <<
"-------------------------------------";
1566 LOG(info) <<
"Last epoch for gDPB: " << std::hex << std::setw(4) <<
i
1567 << std::dec <<
" , GET4 " << std::setw(4) << j <<
" => "
1571 LOG(info) <<
"-------------------------------------";
1596 TDirectory* oldDir = NULL;
1597 TFile* histoFile = NULL;
1598 if (
"" != sFileName) {
1600 oldDir = gDirectory;
1602 histoFile =
new TFile(sFileName,
"RECREATE");
1606 gDirectory->mkdir(
"Tof_Raw_gDPB");
1607 gDirectory->cd(
"Tof_Raw_gDPB");
1613 gDirectory->cd(
"..");
1617 gDirectory->mkdir(
"TofDt");
1618 gDirectory->cd(
"TofDt");
1623 gDirectory->cd(
"..");
1626 gDirectory->mkdir(
"TofDtEvo");
1627 gDirectory->cd(
"TofDtEvo");
1628 for (UInt_t uGdpb = 0; uGdpb <
fuNrOfGdpbs; ++uGdpb) {
1634 for (UInt_t uGdpbB = uGdpb + 1; uGdpbB <
fuNrOfGdpbs; ++uGdpbB)
1638 for (UInt_t uFeeRef = 0; uFeeRef <
kuNbRefFeeEvo; ++uFeeRef) {
1644 gDirectory->cd(
"..");
1646 gDirectory->mkdir(
"Flib_Raw");
1647 gDirectory->cd(
"Flib_Raw");
1648 for (UInt_t uLinks = 0; uLinks <
fvhMsSzPerLink.size(); uLinks++) {
1655 TH1* pMissedTsH1 =
dynamic_cast<TH1*
>(gROOT->FindObjectAny(
"Missed_TS"));
1656 if (NULL != pMissedTsH1) pMissedTsH1->Write();
1658 TProfile* pMissedTsEvoP =
1659 dynamic_cast<TProfile*
>(gROOT->FindObjectAny(
"Missed_TS_Evo"));
1660 if (NULL != pMissedTsEvoP) pMissedTsEvoP->Write();
1662 gDirectory->cd(
"..");
1665 if (
"" != sFileName) {
1670 if (
"" != sFileName) {
1678 LOG(info) <<
"Reseting all TOF histograms.";
1692 for (UInt_t uGdpb = 0; uGdpb <
fuNrOfGdpbs; ++uGdpb) {
1698 for (UInt_t uGdpbB = uGdpb + 1; uGdpbB <
fuNrOfGdpbs; ++uGdpbB)
1702 for (UInt_t uFeeRef = 0; uFeeRef <
kuNbRefFeeEvo; ++uFeeRef) {
1708 for (UInt_t uLinks = 0; uLinks <
fvhMsSzPerLink.size(); uLinks++) {
1747 <<
"CbmMcbm2018MonitorTofPulser::UpdateZoomedFit => Empty input "
1748 <<
"for FEE pair " << uFeeA <<
" and " << uFeeB <<
" !!! ";
1765 if ((dZoomCounts / dNbCounts) < 0.99) {
1768 LOG(warning) <<
"CbmMcbm2018MonitorTofPulser::UpdateZoomedFit => "
1770 <<
"more than 1% loss for FEE pair " << uFeeA
1771 <<
" and " << uFeeB <<
" !!! ";
1782 fitFuncPairs[uFeeA][uFeeB] =
1783 new TF1(Form(
"fPair_%02d_%02d", uFeeA, uFeeB),
1788 fitFuncPairs[uFeeA][uFeeB]->SetParameter(0, dZoomCounts);
1789 fitFuncPairs[uFeeA][uFeeB]->SetParameter(1, dPeakPos);
1790 fitFuncPairs[uFeeA][uFeeB]->SetParameter(
1794 Form(
"fPair_%02d_%02d", uFeeA, uFeeB),
"QRM0");
1796 dRes = fitFuncPairs[uFeeA][uFeeB]->GetParameter(2);
1798 delete fitFuncPairs[uFeeA][uFeeB];
1803 LOG(info) <<
"CbmMcbm2018MonitorTofPulser::UpdateZoomedFit => "
1804 <<
"For FEE pair " << uFeeA <<
" and " << uFeeB
1805 <<
" we have zoomed RMS = "
1807 <<
" and a resolution of " << dRes / TMath::Sqrt2();
1814 LOG(error) <<
"CbmMcbm2018MonitorTofPulser::UpdateZoomedFit => Zoom width "
1816 <<
"please use SetFitZoomWidthPs, e.g. in macro, before trying "