32#include <ElogRecord.h>
35#define DECO_SOCK_WAIT_PERIOD 20
36#define DECO_SOCK_WAIT_LIMIT 15e3
38using namespace chrono;
43 , fRecoTree4Show(nullptr)
45 , fHistOutTemp(nullptr)
47 , fDigiArrays(nullptr)
51 , fTrigMapper(nullptr)
53 , fNItersSinceUpdate(0)
54 , fNItersToUpdate(1000)
55 , fTimeToProcessRequests(milliseconds(20))
57 , fTimeToUpdate(seconds(3))
61 TString name =
"infoCanvas";
63 infoCanvas->Divide(3, 1);
66 refTable =
new TList();
67 refTable->SetName(
"refTable");
69 runPub->SetName(
"CurRun");
71 runPub->Add((TObject*)CurRun);
86 for (
auto h : bhVec4show)
93 zmq_ctx_destroy(_ctx);
108 _ctx = zmq_ctx_new();
109 _decoSocket = zmq_socket(_ctx, ZMQ_SUB);
110 if (_decoSocket ==
nullptr) {
114 if (zmq_setsockopt(_decoSocket, ZMQ_SUBSCRIBE,
nullptr, 0) == -1) {
119 if (zmq_setsockopt(_decoSocket, ZMQ_RCVBUF, &rcvBuf,
sizeof(rcvBuf)) == -1)
120 DBGERR(
"zmq_setsockopt of ZMQ_RCVBUF")
121 if (zmq_setsockopt(_decoSocket, ZMQ_SNDBUF, &rcvBuf,
sizeof(rcvBuf)) == -1)
122 DBGERR(
"zmq_setsockopt of ZMQ_SNDBUF")
124 gSystem->ExpandPathName(dirname);
125 printf(
"dir %s\n", dirname.Data());
126 _curDir = dirname +
"/";
130 gSystem->ExpandPathName(refDir);
131 _refDir = refDir +
"/";
133 printf(
"Ref dir set to %s\n", _refDir.Data());
134 TString PeriodSetupExt = Form(
"%d%s.txt", fPeriodID, ((fSetup ==
kBMNSETUP) ?
"" :
"_SRC"));
135 TString MapFileName = TString(
"Trig_map_Run") + PeriodSetupExt;
136 TString PlaceMapFileName = TString(
"Trig_PlaceMap_Run") + PeriodSetupExt;
137 TTree* temp_tree =
new TTree(
"Temp",
"Temp");
138 fTrigMapper =
new BmnTrigRaw2Digit(PlaceMapFileName, MapFileName, temp_tree);
142 for (
auto h : bhVec4show)
144 fRawDecoAddr = decoAddr;
145 TString conStr = Form(
"tcp://%s", fRawDecoAddr.Data());
147 if (zmq_connect(_decoSocket, conStr.Data()) != 0) {
151 printf(
"Monitor listens to %s\n", conStr.Data());
153 TBufferFile t(TBuffer::kRead);
155 Int_t frame_size = 0;
158 while (keepWorking) {
159 if (fIsSlowMode || (fState ==
kBMNWAIT))
160 fServer->ProcessRequests();
163 frame_size = zmq_msg_recv(&msg, _decoSocket, ZMQ_DONTWAIT);
165 if (frame_size == -1) {
166 if (errno == EAGAIN) {
174 DBG(
"state changed to kBMNWAIT")
177 printf(
"Receive error № %d #%s\n", errno, zmq_strerror(errno));
183 t.SetBuffer(zmq_msg_data(&msg), zmq_msg_size(&msg));
184 fDigiArrays = (
DigiArrays*)(t.ReadObject(DigiArrays::Class()));
188 uint32_t runID = head->GetRunId();
194 DBG(
"state changed to kBMNWORK")
200 if (fRunID != runID) {
201 printf(
"change run %5u to %5u\n", fRunID, runID);
214 fDigiArrays->
Clear();
220 zmq_close(_decoSocket);
221 zmq_ctx_destroy(_ctx);
225void BmnMonitor::InitServer()
227 TString mode =
"http";
228 TString cgiStr = Form(
"%s:%d;noglobal;cors", mode.Data(), _webPort);
229 if (gSystem->AccessPathName(_curDir +
"auth.htdigest") != 0) {
230 printf(
"Authorization file not found\nStarting server without authorization\n");
231 fServer =
new THttpServer(cgiStr.Data());
233 fServer =
new THttpServer(TString(cgiStr +
"?auth_file=auth.htdigest&auth_domain=root").Data());
234 fServer->SetTimer(50, kTRUE);
237void BmnMonitor::InitHistVectors(vector<BmnHist*>& vec, TString refName)
239 if (fDetectorSetup & BIT(
kGEM))
240 vec.push_back(
new BmnHistGem(refName +
"GEM", _curDir, fPeriodID, fSetup));
241 if (fDetectorSetup & BIT(
kVSP))
242 vec.push_back(
new BmnHistVsp(refName +
"VSP", _curDir, fPeriodID, fSetup));
244 vec.push_back(
new BmnHistSilicon(refName +
"Silicon", _curDir, fPeriodID, fSetup));
247 if (fDetectorSetup & BIT(
kTOF1))
248 vec.push_back(
new BmnHistToF(refName +
"ToF400", _curDir));
249 if (fDetectorSetup & BIT(
kTOF701))
250 vec.push_back(
new BmnHistToF700(refName +
"ToF700", _curDir));
251 if (fDetectorSetup & BIT(
kBC)) {
252 vec.push_back(
new BmnHistTrigger(refName +
"Triggers", _curDir, fPeriodID, fSetup, fTrigMapper));
253 vec.push_back(
new BmnHistStat(refName +
"Statistics", _curDir));
255 if (fDetectorSetup & BIT(
kSCWALL))
256 vec.push_back(
new BmnHistScWall(refName +
"ScWall", _curDir, fPeriodID, fSetup));
257 if (fDetectorSetup & BIT(
kCSC))
258 vec.push_back(
new BmnHistCsc(refName +
"CSC", _curDir, fPeriodID, fSetup));
259 if (fDetectorSetup & BIT(
kFHCAL))
260 vec.push_back(
new BmnHistFHCal(refName +
"FHCal", _curDir, fPeriodID, fSetup));
261 if (fDetectorSetup & BIT(
kHODO))
262 vec.push_back(
new BmnHistHodo(refName +
"Hodo", _curDir));
263 if (fDetectorSetup & BIT(
kNDET))
264 vec.push_back(
new BmnHistNdet(refName +
"Ndet", _curDir, fPeriodID, fSetup));
265 if (fDetectorSetup & BIT(
kSiBT))
266 vec.push_back(
new BmnHistSiBT(refName +
"SiBT", _curDir, fPeriodID));
267 if (fDetectorSetup & BIT(
kMSC)) {
274BmnStatus BmnMonitor::CreateFile(uint32_t runID)
279 TString outHistName = Form(
"%s/bmn_run%04u%s_hist.root", _curDir.Data(), runID, fHistFileNameAdd.Data());
280 fHistOut =
new TFile(outHistName,
"recreate");
282 printf(
"file %s created\n", outHistName.Data());
284 printf(
"file tempo.root created\n");
286 TString refName = Form(
"ref%06u_", fRunID);
287 InitHistVectors(bhVec, refName);
289 for (
auto h : bhVec) {
290 h->SetDir(fHistOut, fRecoTree);
291 h->SetPeriodID(fPeriodID);
293 for (
auto h : bhVec4show) {
297 h->SetPeriodID(fPeriodID);
304void BmnMonitor::ProcessDigi(Int_t iEv)
308 fNItersSinceUpdate++;
310 LOGF(debug,
"Event type %u", (uint8_t)head->
GetEventType());
320 h->FillFromDigi(fDigiArrays);
328 for (
auto h : bhVec4show)
334 h->FillFromDigi(fDigiArrays);
338 rtime = timer.RealTime();
339 ctime = timer.CpuTime();
340 LOGF(debug,
"Real time %f s, CPU time %f s %s ClassName %s Class_Name %s ", rtime, ctime, h->GetName(),
341 h->ClassName(), h->Class_Name());
346 auto now = system_clock::now();
347 seconds time = duration_cast<seconds>(now - fTicksLastUpdate);
348 if (((fNItersSinceUpdate > fNItersToUpdate)
350 || ((time > fTimeToUpdate)))
352 LOGF(debug,
"Draw! iters %d", fNItersSinceUpdate);
355 TVirtualPad* pad = infoCanvas->cd(1);
371 Tl.SetTextSize(0.16);
372 TString shownID = head->GetRunId() ==
UNKNOWN_RUNID ?
" o_O" : TString::UItoa(head->GetRunId(), 10);
373 Tl.DrawLatex(0.3, 0.9, Form(
"Run: %s", shownID.Data()));
374 Tl.DrawLatex(0.3, 0.6, Form(
"Event: %d", head->
GetEventId()));
375 Tl.DrawLatex(0.3, 0.3, Form(
"Run Type: %s", runType.Data()));
379 pad = infoCanvas->cd(2);
383 Tl.SetTextSize(0.16);
384 Tl.DrawLatex(0.3, 0.9, Form(
"Energy: %1.2f", CurRun->
GetEnergy()));
385 Tl.DrawLatex(0.3, 0.7, Form(
"Beam: %s", CurRun->
GetBeamParticle().Data()));
387 Tl.DrawLatex(0.3, 0.3, Form(
"Field Voltage: %1.2f", CurRun->
GetFieldVoltage()));
391 for (
auto h : bhVec4show)
393 if (fEvents % 1000 == 0)
394 if (refTable->GetEntries() == 0)
396 fNItersSinceUpdate = 0;
397 fTicksLastUpdate = now;
402void BmnMonitor::ProcessRequests()
404 auto now = system_clock::now();
405 milliseconds time_since_last_process = duration_cast<milliseconds>(now - fTicksLastProcess);
407 if (time_since_last_process > fTimeToProcessRequests) {
409 fServer->ProcessRequests();
410 fTicksLastProcess = now;
414void BmnMonitor::RegisterAll()
416 InitHistVectors(bhVec4show);
417 fServer->Register(
"/", infoCanvas);
419 fServer->Register(
"/", refTable);
420 fServer->Register(
"/", runPub);
421 for (
auto h : bhVec4show) {
422 h->SetDir(
nullptr,
nullptr);
423 h->Register(fServer);
424 h->SetRefPath(_refDir);
425 h->SetPeriodID(fPeriodID);
426 bhVecIsStat.push_back(strcmp(h->ClassName(),
"BmnHistMSC") == 0);
430void BmnMonitor::UpdateRuns()
432 if (refTable->GetEntries())
437 if (refRuns ==
nullptr) {
438 fprintf(stderr,
"Ref list is empty!\n");
442 runPub->Add((TObject*)CurRun);
445 runPub->Add((TObject*)CurRun);
446 for (Int_t iRun = 0; iRun < refRuns->GetEntriesFast(); iRun++) {
449 refTable->Add((TObject*)runInfo);
450 LOGF(debug,
"run %04d Energy %f Voltage %f Beam %s Target %s Date %d",
run->GetRunNumber(),
451 run->GetEnergy() ? *
run->GetEnergy() : -1,
run->GetFieldVoltage() ? *
run->GetFieldVoltage() : -1,
452 run->GetBeamParticle().Data(),
run->GetTargetParticle().Data(),
run->GetStartDatetime().GetDate());
458void BmnMonitor::FinishRun()
462 printf(
"fHistOut Write result = %d\n", fHistOut->Write());
476 TPRegexp reElementName(
".*(\\w+).*");
477 TString beamParticle =
"";
478 TString targetParticle =
"";
479 Double_t beamEnergy = 0;
482 if (recs ==
nullptr) {
483 fprintf(stderr,
"Run not found in ELOG!\n");
486 for (Int_t iRec = 0; iRec < recs->GetEntriesFast(); iRec++) {
488 TObjArray* strings = reElementName.MatchS(rec->
GetBeam().Data());
489 if (strings->GetEntriesFast() > 1)
490 beamParticle = ((TObjString*)strings->At(1))->GetString();
492 strings = reElementName.MatchS(rec->
GetTarget().Data());
493 if (strings->GetEntriesFast() > 1)
494 targetParticle = ((TObjString*)strings->At(1))->GetString();
499 if (beamParticle ==
"" || targetParticle ==
"" || beamEnergy == 0 || I_SP41 == 0) {
500 fprintf(stderr,
"Not enough run data in ELOG!\n");
503 printf(
"search Energy %f I %f beam %s target %s\n\n", beamEnergy, I_SP41, beamParticle.Data(),
504 targetParticle.Data());
505 TObjArray arrayConditions;
508 arrayConditions.Add((TObject*)searchCondition);
511 arrayConditions.Add((TObject*)searchCondition);
514 arrayConditions.Add((TObject*)searchCondition);
519 arrayConditions.SetOwner(kTRUE);
520 arrayConditions.Delete();
521 for (Int_t iRun = 0; iRun < refRuns->GetEntriesFast(); iRun++) {
523 printf(
"run %04d Energy %f Voltage %f Date %d\n",
run->GetRunNumber(), *
run->GetEnergy(),
524 *
run->GetFieldVoltage(),
run->GetStartDatetime().GetDate());
535 printf(
"getalike \n");
537 printf(
"getalike request returned\n");
538 if (Run.get() ==
nullptr) {
542 if (!(Run->GetFieldVoltage() && Run->GetEnergy())) {
543 fprintf(stderr,
"Not enough info on current run!\n");
549 TObjArray arrayConditions;
550 TString beamParticle = Run->GetBeamParticle();
551 printf(
"Beam particle %s\n", Run->GetBeamParticle().Data());
554 arrayConditions.Add((TObject*)searchCondition);
555 TString targetParticle = Run->GetTargetParticle();
556 printf(
"Target particle %s\n", targetParticle.Data());
559 arrayConditions.Add((TObject*)searchCondition);
560 if (Run->GetEnergy()) {
561 printf(
"Beam Energy %f\n", *Run->GetEnergy());
562 Double_t beamEnergy = *Run->GetEnergy();
565 arrayConditions.Add((TObject*)searchCondition);
567 if (Run->GetFieldVoltage()) {
568 printf(
"Field voltage %f\n", *Run->GetFieldVoltage());
569 Double_t V_SP41 = *Run->GetFieldVoltage();
572 arrayConditions.Add((TObject*)searchCondition);
575 arrayConditions.Add((TObject*)searchCondition);
580 printf(
"search request returned\n");
581 arrayConditions.SetOwner(kTRUE);
582 arrayConditions.Delete();
#define DECO_SOCK_WAIT_PERIOD
#define DECO_SOCK_WAIT_LIMIT
void SetHistFileNameAdd(TString add)
void MonitorStreamZ(TString dir, TString refDir="", TString decoAddr="localhost", Int_t webPort=9000)
TObjArray * GetAlikeRunsByElog(uint32_t periodID, uint32_t rinID)
TObjArray * GetAlikeRunsByUniDB(uint32_t periodID, uint32_t rinID)
TString GetBeamParticle()
get beam particle of the current run
Double_t GetFieldVoltage()
get field voltage of the current run
Double_t GetEnergy()
get energy of the current run
void SetRunNumber(Int_t run_number)
set run number of the current run
TString GetTargetParticle()
get target particle of the current run
int * GetSp41()
get sp 41 of the current record
double * GetEnergy()
get energy of the current record
static TObjArray * GetRecords(int period_number, int run_number, bool findPreviousRun=false)
get array of ElogRecord-s for a given or a previous run from the database
TString GetBeam()
get beam of the current record
TString GetTarget()
get target of the current record
static UniRun * GetRun(int period_number, int run_number)
get run from the database
static TObjArray * Search(UniSearchCondition &search_condition)
get runs corresponding to the specified single condition and set owner for search_condition to kTRUE
@ conditionGreaterOrEqual