From 92e200bdd54270ff8dddca342f58a96b159c7e8a Mon Sep 17 00:00:00 2001 From: "P.-A. Loizeau" <p.-a.loizeau@gsi.de> Date: Fri, 26 Mar 2021 15:56:00 +0100 Subject: [PATCH] [mCBM] Improve spill detection in T0 monitor to make it compatible with MQ operation - Add threshold for non pulser digis in both algo, Task and device - Make interval for spill threshold checks configurable in both algo, Task and device - Spill detection only when both threshold passed - Add Monitor macro for mCBM 2021 using this functionality --- MQ/monitor/CbmDeviceMonitorT0.cxx | 12 +- MQ/monitor/CbmDeviceMonitorT0.h | 2 + MQ/monitor/runMonitorT0.cxx | 8 +- .../monitor/CbmMcbm2018MonitorAlgoT0.cxx | 33 +++-- .../monitor/CbmMcbm2018MonitorAlgoT0.h | 24 +++- .../monitor/CbmMcbm2018MonitorTaskT0.cxx | 4 + .../monitor/CbmMcbm2018MonitorTaskT0.h | 8 ++ macro/beamtime/mcbm2021/MonitorT0.C | 121 ++++++++++++++++++ 8 files changed, 190 insertions(+), 22 deletions(-) create mode 100644 macro/beamtime/mcbm2021/MonitorT0.C diff --git a/MQ/monitor/CbmDeviceMonitorT0.cxx b/MQ/monitor/CbmDeviceMonitorT0.cxx index 4b951f6452..fc83b46eaa 100644 --- a/MQ/monitor/CbmDeviceMonitorT0.cxx +++ b/MQ/monitor/CbmDeviceMonitorT0.cxx @@ -6,7 +6,6 @@ */ #include "CbmDeviceMonitorT0.h" -#include "CbmMQDefs.h" #include "CbmFlesCanvasTools.h" #include "CbmMcbm2018MonitorAlgoT0.h" @@ -49,7 +48,9 @@ CbmDeviceMonitorT0::CbmDeviceMonitorT0() , fuHistoryHistoSize {3600} , fuMinTotPulser {185} , fuMaxTotPulser {195} - , fuOffSpillCountLimit {1000} + , fuOffSpillCountLimit {25} + , fuOffSpillCountLimitNonPulser {10} + , fdSpillCheckInterval {0.0128} , fvuChanMap {0, 1, 2, 3, 4, 5, 6, 7} , fuPublishFreqTs {100} , fdMinPublishTime {0.5} @@ -74,6 +75,8 @@ void CbmDeviceMonitorT0::InitTask() try { fuMinTotPulser = fConfig->GetValue<uint32_t>("PulsTotMin"); fuMaxTotPulser = fConfig->GetValue<uint32_t>("PulsTotMax"); fuOffSpillCountLimit = fConfig->GetValue<uint32_t>("SpillThr"); + fuOffSpillCountLimitNonPulser = fConfig->GetValue<uint32_t>("SpillThrNonPuls"); + fdSpillCheckInterval = fConfig->GetValue<double>("SpillCheckInt"); std::string sChanMap = fConfig->GetValue<std::string>("ChanMap"); fuPublishFreqTs = fConfig->GetValue<uint32_t>("PubFreqTs"); fdMinPublishTime = fConfig->GetValue<double_t>("PubTimeMin"); @@ -130,8 +133,7 @@ void CbmDeviceMonitorT0::InitTask() try { InitContainers(); } catch (InitTaskError& e) { LOG(error) << e.what(); - // Wrapper defined in CbmMQDefs.h to support different FairMQ versions - cbm::mq::ChangeState(this, cbm::mq::Transition::ErrorFound); + ChangeState(fair::mq::Transition::ErrorFound); } bool CbmDeviceMonitorT0::IsChannelNameAllowed(std::string channelName) { @@ -200,6 +202,8 @@ Bool_t CbmDeviceMonitorT0::InitContainers() { fMonitorAlgo->SetHistoryHistoSize(fuHistoryHistoSize); fMonitorAlgo->SetPulserTotLimits(fuMinTotPulser, fuMaxTotPulser); fMonitorAlgo->SetSpillThreshold(fuOffSpillCountLimit); + fMonitorAlgo->SetSpillThresholdNonPulser(fuOffSpillCountLimitNonPulser); + fMonitorAlgo->SetSpillCheckInterval(fdSpillCheckInterval); fMonitorAlgo->SetChannelMap(fvuChanMap[0], fvuChanMap[1], fvuChanMap[2], fvuChanMap[3], fvuChanMap[4], fvuChanMap[5], fvuChanMap[6], fvuChanMap[7]); diff --git a/MQ/monitor/CbmDeviceMonitorT0.h b/MQ/monitor/CbmDeviceMonitorT0.h index 2c24b424d0..886fc067df 100644 --- a/MQ/monitor/CbmDeviceMonitorT0.h +++ b/MQ/monitor/CbmDeviceMonitorT0.h @@ -50,6 +50,8 @@ private: uint32_t fuMinTotPulser; uint32_t fuMaxTotPulser; uint32_t fuOffSpillCountLimit; + uint32_t fuOffSpillCountLimitNonPulser; + double fdSpillCheckInterval; std::vector<uint32_t> fvuChanMap; uint32_t fuPublishFreqTs; double_t fdMinPublishTime; diff --git a/MQ/monitor/runMonitorT0.cxx b/MQ/monitor/runMonitorT0.cxx index e53c761b07..5f82ce8c93 100644 --- a/MQ/monitor/runMonitorT0.cxx +++ b/MQ/monitor/runMonitorT0.cxx @@ -21,8 +21,14 @@ void addCustomOptions(bpo::options_description& options) { bpo::value<uint32_t>()->default_value(195), "Maximal TOT for pulser cut"); options.add_options()("SpillThr", - bpo::value<uint32_t>()->default_value(1000), + bpo::value<uint32_t>()->default_value(25), "Hits Nb Thr for spill detection"); + options.add_options()("SpillThrNonPuls", + bpo::value<uint32_t>()->default_value(10), + "Non pulser Hits Nb Thr for spill detection"); + options.add_options()("SpillCheckInt", + bpo::value<double>()->default_value(0.128), + "Interval in seconds between count checks for spill detection"); options.add_options()("ChanMap", bpo::value<std::string>()->default_value("0,1,2,3,4,5,6,7"), "Set T0 channel map e.g. 0,1,2,3,4,5,6,7"); options.add_options()("PubFreqTs", diff --git a/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoT0.cxx b/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoT0.cxx index b4cd936ffa..8d6fc39cad 100644 --- a/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoT0.cxx +++ b/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoT0.cxx @@ -306,22 +306,30 @@ Bool_t CbmMcbm2018MonitorAlgoT0::ProcessMs(const fles::Timeslice& ts, /// Spill Detection if (0 == fuCurrDpbIdx) { /// Check only every second - if (1.0 < fdMsTime - fdLastSecondTime) { + if (fdSpillCheckInterval < fdMsTime - fdLastInterTime) { /// Spill Off detection - if (fbSpillOn && fuCountsLastSecond < fuOffSpillCountLimit) { + if (fbSpillOn && fuCountsLastInter < fuOffSpillCountLimit + && fuNonPulserCountsLastInter < fuOffSpillCountLimitNonPulser) { fbSpillOn = kFALSE; fuCurrentSpillIdx++; fuCurrentSpillPlot = (fuCurrentSpillPlot + 1) % kuNbSpillPlots; fdStartTimeSpill = fdMsTime; fvhDpbMapSpill[fuCurrentSpillPlot]->Reset(); fvhChannelMapSpill[fuCurrentSpillPlot]->Reset(); - } // if( fbSpillOn && fuCountsLastSecond < fuOffSpillCountLimit ) - else if (fuOffSpillCountLimit < fuCountsLastSecond) + } // if( fbSpillOn && fuCountsLastInter < fuOffSpillCountLimit && same for non pulser) + else if (fuOffSpillCountLimit < fuCountsLastInter) fbSpillOn = kTRUE; - fuCountsLastSecond = 0; - fdLastSecondTime = fdMsTime; - } // if( 1 < fdMsTime - fdLastSecondTime ) + LOG(debug) << Form( "%6llu %6.4f %9u %9u %2d", + fulCurrentTsIdx, fdMsTime - fdLastInterTime, + fuCountsLastInter, + fuNonPulserCountsLastInter, + fuCurrentSpillIdx); + + fuCountsLastInter = 0; + fuNonPulserCountsLastInter = 0; + fdLastInterTime = fdMsTime; + } // if( fdSpillCheckInterval < fdMsTime - fdLastInterTime ) } // if( 0 == fuCurrDpbIdx ) /// Save start time of first valid MS ) @@ -379,7 +387,7 @@ Bool_t CbmMcbm2018MonitorAlgoT0::ProcessMs(const fles::Timeslice& ts, } // if( getGdpbHitIs24b() ) else { /// Spill detection - fuCountsLastSecond++; + fuCountsLastInter++; fhErrorFractEvo->Fill(fdMsTime - fdStartTime, 0.0); fhLostEvtFractEvo->Fill(fdMsTime - fdStartTime, 0.0); @@ -396,6 +404,8 @@ Bool_t CbmMcbm2018MonitorAlgoT0::ProcessMs(const fles::Timeslice& ts, /// Do not fill the pulser hits to keep counts low for channel 0 UInt_t uTot = mess.getGdpbHit32Tot(); if (uTot < fuMinTotPulser || fuMaxTotPulser < uTot) { + fuNonPulserCountsLastInter++; + fhDpbMap->Fill(fuCurrDpbIdx); fhChannelMap->Fill(uChannelT0); fhChanHitMap->Fill(fuDiamChanMap[uChannelT0]); @@ -1248,7 +1258,7 @@ Bool_t CbmMcbm2018MonitorAlgoT0::CreateHistograms() { fcSpillCounts->cd(1 + uSpill); gPad->SetGridx(); gPad->SetGridy(); - // gPad->SetLogy(); + gPad->SetLogy(); // fvhChannelMapSpill[ uSpill ]->SetStats( kTRUE ); fvhChannelMapSpill[uSpill]->Draw(); gPad->Update(); @@ -1393,8 +1403,6 @@ Bool_t CbmMcbm2018MonitorAlgoT0::ResetHistograms(Bool_t bResetTime) { fvhEvtLostFractPerMsEvoChan[uChan]->Reset(); } // for( UInt_t uChan = 0; uChan < kuNbChanDiamond; ++uChan ) - fuCurrentSpillIdx = 0; - fuCurrentSpillPlot = 0; fhDpbMap->Reset(); fhChannelMap->Reset(); fhHitMapEvo->Reset(); @@ -1424,6 +1432,9 @@ Bool_t CbmMcbm2018MonitorAlgoT0::ResetHistograms(Bool_t bResetTime) { if (kTRUE == bResetTime) { /// Also reset the Start time for the evolution plots! fdStartTime = -1.0; + + fuCurrentSpillIdx = 0; + fuCurrentSpillPlot = 0; } // if( kTRUE == bResetTime ) return kTRUE; diff --git a/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoT0.h b/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoT0.h index 1a5bb4aa94..a450a80c6f 100644 --- a/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoT0.h +++ b/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoT0.h @@ -72,6 +72,12 @@ public: inline void SetSpillThreshold(UInt_t uCntLimit) { fuOffSpillCountLimit = uCntLimit; } + inline void SetSpillThresholdNonPulser(UInt_t uCntLimit) { + fuOffSpillCountLimitNonPulser = uCntLimit; + } + inline void SetSpillCheckInterval(Double_t dIntervalSec) { + fdSpillCheckInterval = dIntervalSec; + } inline void SetChannelMap(UInt_t uChan0, UInt_t uChan1, UInt_t uChan2, @@ -115,6 +121,8 @@ private: UInt_t fuMinTotPulser = 90; UInt_t fuMaxTotPulser = 100; UInt_t fuOffSpillCountLimit = 200; + UInt_t fuOffSpillCountLimitNonPulser = 80; + Double_t fdSpillCheckInterval = 1.0; /// Constants static const Int_t kiMaxNbFlibLinks = 32; @@ -169,6 +177,16 @@ private: std::vector<gdpbv100::FullMessage> fvmHitsInMs = {}; //! All hits (time in bins, TOT in bins, asic, channel) in last MS, sorted with "<" operator + /// Spill detection + Bool_t fbSpillOn = kTRUE; + UInt_t fuCurrentSpillIdx = 0; + UInt_t fuCurrentSpillPlot = 0; + Double_t fdStartTimeSpill = -1.0; + Double_t fdLastInterTime = -1.0; + UInt_t fuCountsLastInter = 0; + UInt_t fuNonPulserCountsLastInter = 0; + + /// Histograms related variables UInt_t fuHistoryHistoSize = 3600; /** Size in seconds of the evolution histograms **/ @@ -205,12 +223,6 @@ private: std::vector<TH2*> fvhEvtLostFractPerMsEvoChan = std::vector<TH2*>(kuNbChanDiamond, nullptr); /// Channels map - Bool_t fbSpillOn = kTRUE; - UInt_t fuCurrentSpillIdx = 0; - UInt_t fuCurrentSpillPlot = 0; - Double_t fdStartTimeSpill = -1.0; - Double_t fdLastSecondTime = -1.0; - UInt_t fuCountsLastSecond = 0; static const UInt_t kuNbSpillPlots = 5; // UInt_t kuDiamChanMap[ kuNbChanDiamond ] = { 2, 3, 4, 5, 0, 1, 6, 7 }; //! Map from electronics channel to Diamond strip UInt_t fuDiamChanMap[kuNbChanDiamond] = diff --git a/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskT0.cxx b/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskT0.cxx index 8f08a21cf8..0674c524b2 100644 --- a/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskT0.cxx +++ b/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskT0.cxx @@ -41,6 +41,8 @@ CbmMcbm2018MonitorTaskT0::CbmMcbm2018MonitorTaskT0() , fuMinTotPulser(90) , fuMaxTotPulser(100) , fuOffSpillCountLimit(200) + , fuOffSpillCountLimitNonPulser(80) + , fdSpillCheckInterval(1.0) , fulTsCounter(0) , fMonitorAlgo(nullptr) { fMonitorAlgo = new CbmMcbm2018MonitorAlgoT0(); @@ -105,6 +107,8 @@ Bool_t CbmMcbm2018MonitorTaskT0::InitContainers() { fMonitorAlgo->SetHistoryHistoSize(fuHistoryHistoSize); fMonitorAlgo->SetPulserTotLimits(fuMinTotPulser, fuMaxTotPulser); fMonitorAlgo->SetSpillThreshold(fuOffSpillCountLimit); + fMonitorAlgo->SetSpillThresholdNonPulser(fuOffSpillCountLimitNonPulser); + fMonitorAlgo->SetSpillCheckInterval(fdSpillCheckInterval); /// Histos creation, obtain pointer on them and add them to the HTTP server /// Trigger histo creation on all associated algos diff --git a/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskT0.h b/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskT0.h index 962d86e53f..7452056384 100644 --- a/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskT0.h +++ b/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskT0.h @@ -55,6 +55,12 @@ public: inline void SetSpillThreshold(UInt_t uCntLimit) { fuOffSpillCountLimit = uCntLimit; } + inline void SetSpillThresholdNonPulser(UInt_t uCntLimit) { + fuOffSpillCountLimitNonPulser = uCntLimit; + } + inline void SetSpillCheckInterval(Double_t dIntervalSec) { + fdSpillCheckInterval = dIntervalSec; + } void SetChannelMap(UInt_t uChan0, UInt_t uChan1, UInt_t uChan2, @@ -77,6 +83,8 @@ private: UInt_t fuMinTotPulser; UInt_t fuMaxTotPulser; UInt_t fuOffSpillCountLimit; + UInt_t fuOffSpillCountLimitNonPulser; + Double_t fdSpillCheckInterval; /// Statistics & first TS rejection uint64_t fulTsCounter; diff --git a/macro/beamtime/mcbm2021/MonitorT0.C b/macro/beamtime/mcbm2021/MonitorT0.C new file mode 100644 index 0000000000..88a19cafaf --- /dev/null +++ b/macro/beamtime/mcbm2021/MonitorT0.C @@ -0,0 +1,121 @@ +/** @file MCBM DATA unpacking + ** @author Florian Uhlig <f.uhlig@gsi.de> + ** @date 20.06.2016 + ** Modified by P.-A. Loizeau + ** @date 30.01.2019 + ** ROOT macro to read tsa files which have been produced with the new data transport + ** Convert data into cbmroot format. + ** Uses CbmMcbm2018Source as source task. + */ +// In order to call later Finish, we make this global +FairRunOnline* run = NULL; + +void MonitorT0(TString inFile = "", + TString sHostname = "cbmflesnode8:5558;cbmflesnode9:5559", + Int_t iServerHttpPort = 8080, + Int_t iServerRefreshRate = 100, + UInt_t uRunId = 0, + UInt_t nrEvents = 0) { + TString srcDir = gSystem->Getenv("VMCWORKDIR"); + + // --- Specify number of events to be produced. + // --- -1 means run until the end of the input file. + Int_t nEvents = -1; + // --- Specify output file name (this is just an example) + TString runId = TString::Format("%u", uRunId); + TString parFile = "data/moni_t0_params_" + runId + ".root"; + + // --- Set log output levels + FairLogger::GetLogger(); + gLogger->SetLogScreenLevel("INFO"); + //gLogger->SetLogScreenLevel("DEBUG"); + gLogger->SetLogVerbosityLevel("MEDIUM"); + + // --- Define parameter files + TList* parFileList = new TList(); + TString paramDir = srcDir + "/macro/beamtime/mcbm2021/"; + + TString paramFileTof = paramDir + "mT0Par.par"; + TObjString* parTofFileName = new TObjString(paramFileTof); + parFileList->Add(parTofFileName); + + // --- Set debug level + gDebug = 0; + + std::cout << std::endl; + + // ======================================================================== + // ======================================================================== + std::cout << std::endl; + std::cout << ">>> MonitorT0: Initialising..." << std::endl; + CbmMcbm2018MonitorTaskT0* monitor_t0 = new CbmMcbm2018MonitorTaskT0(); + + monitor_t0->SetIgnoreOverlapMs(); + monitor_t0->SetHistoryHistoSize(1800); + if (0 < uRunId) + monitor_t0->SetHistoFilename( + Form("data/HistosMonitorT0_%03u.root", uRunId)); + monitor_t0->SetPulserTotLimits(180, 210); // for runs > 86 + + // --- Source task + CbmMcbm2018Source* source = new CbmMcbm2018Source(); + + if ("" != inFile) { + source->SetFileName(inFile); + } // if( "" != inFile ) + else { + source->SetHostName(sHostname); + } // else of if( "" != inFile ) + + // Use kHodo since there is no entry for T0 in the enum yet + source->AddUnpacker(monitor_t0, 0x90, ECbmModuleId::kHodo); //gDPB T0 + + source->SetSubscriberHwm(1000); + + // --- Run + run = new FairRunOnline(source); + run->ActivateHttpServer(iServerRefreshRate, + iServerHttpPort); // refresh each 100 events + /// To avoid the server sucking all Histos from gROOT when no output file is used + /// ===> Need to explicitely add the canvases to the server in the task! + run->GetHttpServer()->GetSniffer()->SetScanGlobalDir(kFALSE); + run->SetAutoFinish(kFALSE); + + + // ----- Runtime database --------------------------------------------- + FairRuntimeDb* rtdb = run->GetRuntimeDb(); + FairParAsciiFileIo* parIn = new FairParAsciiFileIo(); + parIn->open(parFileList, "in"); + rtdb->setFirstInput(parIn); + + run->Init(); + + // --- Start run + TStopwatch timer; + timer.Start(); + std::cout << ">>> MonitorT0: Starting run..." << std::endl; + if (0 == nrEvents) { + run->Run(nEvents, 0); // run until end of input file + } else { + run->Run(0, nrEvents); // process 2000 Events + } + run->Finish(); + + timer.Stop(); + + std::cout << "Processed " << std::dec << source->GetTsCount() << " timeslices" + << std::endl; + + // --- End-of-run info + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + std::cout << std::endl << std::endl; + std::cout << ">>> MonitorT0: Macro finished successfully." << std::endl; + std::cout << ">>> MonitorT0: Real time " << rtime << " s, CPU time " << ctime + << " s" << std::endl; + std::cout << std::endl; + + /// --- Screen output for automatic tests + std::cout << " Test passed" << std::endl; + std::cout << " All ok " << std::endl; +} -- GitLab