DABC (Data Acquisition Backbone Core)  2.9.9
TdcCalibrationModule.cxx
Go to the documentation of this file.
1 // $Id: TdcCalibrationModule.cxx 4708 2021-02-26 13:36:33Z linev $
2 
3 /************************************************************
4  * The Data Acquisition Backbone Core (DABC) *
5  ************************************************************
6  * Copyright (C) 2009 - *
7  * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
8  * Planckstr. 1, 64291 Darmstadt, Germany *
9  * Contact: http://dabc.gsi.de *
10  ************************************************************
11  * This software can be used under the GPL license *
12  * agreements as stated in LICENSE.txt file *
13  * which is part of the distribution. *
14  ************************************************************/
15 
17 
18 #include "hadaq/HadaqTypeDefs.h"
19 #include "hadaq/Iterator.h"
20 
21 #include "dabc/timing.h"
22 
23 #include <cmath>
24 #include <cstdlib>
25 
26 #include "hadaq/TdcProcessor.h"
27 
28 
30  dabc::ModuleAsync(name, cmd),
31  fProcMgr(0),
32  fOwnProcMgr(false),
33  fTrbProc(0),
34  fDummy(false),
35  fReplace(true),
36  fAutoCalibr(1000),
37  fDummyCounter(0),
38  fLastCalibr(),
39  fTRB(0),
40  fProgress(0),
41  fState(),
42  fQuality(0)
43 {
45 
46  fDummy = Cfg("Dummy", cmd).AsBool(false);
47  fDebug = Cfg("Debug", cmd).AsInt(0);
48  fReplace = Cfg("Replace", cmd).AsBool(true);
49 
50  fFineMin = Cfg("FineMin", cmd).AsInt();
51  fFineMax = Cfg("FineMax", cmd).AsInt();
52  if ((fFineMin > 0) && (fFineMax > fFineMin))
53  hadaq::TdcMessage::SetFineLimits(fFineMin, fFineMax);
54 
55  fNumCh = Cfg("NumChannels", cmd).AsInt(65);
56  fEdges = Cfg("EdgeMask", cmd).AsUInt(1);
57  fTdcMin = Cfg("TdcMin", cmd).AsUIntVect();
58  fTdcMax = Cfg("TdcMax", cmd).AsUIntVect();
59  fTotStatLimit = Cfg("TotStat", cmd).AsInt(0);
60  fTotRMSLimit = Cfg("TotRMS", cmd).AsDouble(0.);
61 
62  // window for hits
63  double dlow = Cfg("TrigDWindowLow", cmd).AsDouble();
64  double dhigh = Cfg("TrigDWindowHigh", cmd).AsDouble();
65  if (dlow < dhigh-1) hadaq::TdcProcessor::SetTriggerDWindow(dlow, dhigh);
66 
67 
68  std::vector<uint64_t> caltr = Cfg("CalibrTrigger", cmd).AsUIntVect();
69 
70  // default channel numbers and edges mask
71  hadaq::TrbProcessor::SetDefaults(fNumCh, fEdges);
72 
73  fWorkerHierarchy.Create("Worker");
74 
76  fState = "Init";
77 
78  fTRB = Cfg("TRB", cmd).AsUInt(0x0);
79  int portid = cmd.GetInt("portid", 0); // this is portid parameter from hadaq::Factory
80  if (fTRB==0) fTRB = 0x8000 | portid;
81 
82  item.SetField("trb", fTRB);
83 
84  fProcMgr = (stream::DabcProcMgr*) cmd.GetPtr("ProcMgr");
85  hadaq::HldProcessor* hld = (hadaq::HldProcessor*) cmd.GetPtr("HLDProc");
86 
87  int hfill = Cfg("HistFilling", cmd).AsInt(1);
88 
89  if (!fProcMgr) {
90  fOwnProcMgr = true;
92  fProcMgr->SetHistFilling(hfill); // set default for newly created processes
94  }
95 
96  fTrbProc = new hadaq::TrbProcessor(fTRB, hld, hfill);
97  std::vector<uint64_t> hubid = Cfg("HUB", cmd).AsUIntVect();
98  for (unsigned n=0;n<hubid.size();n++)
99  fTrbProc->AddHadaqHUBId(hubid[n]);
100  unsigned hubmin = Cfg("HUBmin", cmd).AsUInt();
101  unsigned hubmax = Cfg("HUBmax", cmd).AsUInt();
102  for (unsigned n=hubmin;n<hubmax;n++)
103  fTrbProc->AddHadaqHUBId(hubid[n]);
104 
105  fAutoTdcMode = Cfg("Mode", cmd).AsInt(-1);
106 
107  if ((fAutoTdcMode < 0) || fDummy) {
108  DOUT0("TRB 0x%04x creates TDCs %s", (unsigned) fTRB, Cfg("TDC", cmd).AsStr().c_str());
109  fTDCs = Cfg("TDC", cmd).AsUIntVect();
110  for(unsigned n=0;n<fTDCs.size();n++) {
111  fTrbProc->CreateTDC(fTDCs[n]);
112 
113  hadaq::TdcProcessor *tdc = fTrbProc->GetTDC(fTDCs[n], true);
114  if (fAutoTdcMode == 1) tdc->SetUseLinear(); // force linear
115  if (fAutoToTRange > 0) tdc->SetToTRange(20., 30., 60.);
116  tdc->UseExplicitCalibration();
117  if (fTotStatLimit > 0) tdc->SetTotStatLimit(fTotStatLimit);
118  if (fTotRMSLimit > 0) tdc->SetTotRMSLimit(fTotRMSLimit);
119  }
120  item.SetField("tdc", fTDCs);
121  } else {
122  if (fAutoTdcMode >= 10) {
124  fAutoTdcMode = fAutoTdcMode % 10;
125  }
126 
127  DOUT0("TRB 0x%04x configured in auto mode %d ToT range %d NumCh %d Edges %d", (unsigned) fTRB, fAutoTdcMode, fAutoToTRange, fNumCh, fEdges);
128 
129  for (unsigned n=0;n<fTdcMin.size();++n)
130  DOUT0(" TDC range 0x%04x - 0x%04x", (unsigned) fTdcMin[n], (unsigned) fTdcMax[n]);
131  }
132 
133  fCalibrMask = 0xffff;
134  if ((caltr.size() > 0) && (caltr[0] != 0xffff)) {
135  fCalibrMask = 0;
136  for (unsigned n=0;n<caltr.size();n++)
137  fCalibrMask |= (1 << caltr[n]);
138  }
139 
140  fTrbProc->SetCalibrTriggerMask(fCalibrMask);
141 
142  fDisabledCh = Cfg("DisableCalibrationFor", cmd).AsIntVect();
143  for (unsigned n=0;n<fDisabledCh.size();n++)
144  fTrbProc->DisableCalibrationFor(fDisabledCh[n]);
145 
146  fAutoCalibr = Cfg("Auto", cmd).AsInt(0);
147  if (fDummy && (fAutoCalibr>0)) fAutoCalibr = 1000;
148  fTrbProc->SetAutoCalibrations(fAutoCalibr);
149 
150  fCountLinear = Cfg("CountLinear", cmd).AsInt(10000);
151  fCountNormal = Cfg("CountNormal", cmd).AsInt(100000);
152 
153  fLinearNumPoints = Cfg("LinearNumPoints", cmd).AsInt(2);
154 
155  fCalibrFile = Cfg("CalibrFile", cmd).AsStr();
156  if (!fCalibrFile.empty()) {
157  if ((fAutoTdcMode < 0) && (fAutoCalibr > 0))
158  fTrbProc->SetWriteCalibrations(fCalibrFile.c_str(), true);
159  fTrbProc->LoadCalibrations(fCalibrFile.c_str());
160  }
161 
162  item.SetField("value", fState);
163 
164  dabc::Hierarchy logitem = fWorkerHierarchy.CreateHChild("CalibrLog");
165  logitem.SetField(dabc::prop_kind, "log");
166  logitem.EnableHistory(5000);
167 
168  if (!RecordTRBStatus(false, logitem))
169  fEnableProgressUpdate = true; // if not read from file, enable life update
170 
171  // set ids and create more histograms
172  if (fOwnProcMgr) {
173  fProcMgr->UserPreLoop();
174  DOUT2("%s USER PRELLOP NUMCHILDS %u HASHISTOS %s", GetName(), fWorkerHierarchy.NumChilds(), DBOOL(fTrbProc->HasPerTDCHistos()));
175  Publish(fWorkerHierarchy, dabc::format("$CONTEXT$/%s", GetName()));
176  // remove pointer, let other modules to create and use it
177  base::ProcMgr::ClearInstancePointer(fProcMgr);
178  }
179 
180  // in AutoTDCMode==0 no data is changed, but also no new buffer are required
181  if ((fAutoTdcMode==0) && !fReplace) fReplace = true;
182 
183  // one need additional buffers
185 
186  if (fDebug) CreatePar("DataRate").SetRatemeter(false, 3.).SetUnits("MB");
187 
188  if (fAutoTdcMode > 0)
189  CreateTimer("RecheckTimer", 5.);
190 
191  DOUT0("TdcCalibrationModule dummy %s autotdc %d histfill %d replace %s", DBOOL(fDummy), fAutoCalibr, hfill, DBOOL(fReplace));
192 }
193 
195 {
196 // if (fOwnProcMgr && fProcMgr) {
197 // fProcMgr->UserPostLoop();
198 // }
199 
200  fTrbProc = nullptr;
201  if (fOwnProcMgr) delete fProcMgr;
202  fOwnProcMgr = false;
203  fProcMgr = nullptr;
204 }
205 
207 {
208  fRecheckTdcs = (fAutoTdcMode > 0);
209  if (fWarningCnt >= 0) fWarningCnt--;
210 }
211 
212 void stream::TdcCalibrationModule::SetTRBStatus(dabc::Hierarchy& item, dabc::Hierarchy &logitem, hadaq::TrbProcessor* trb,
213  bool change_progress,
214  int *res_progress, double *res_quality,
215  std::string *res_state, std::vector<std::string> *res_msgs,
216  bool acknowledge_quality)
217 {
218  if (item.null() || (trb==0)) return;
219 
220  item.SetField("trb", trb->GetID());
221 
222  std::vector<int64_t> tdcs;
223  std::vector<int64_t> tdc_progr;
224  std::vector<double> tdc_quality;
225  std::vector<std::string> status;
226 
227  double p0(0), p1(1), worse_quality(1), worse_progress(1e10);
228  bool ready(true), explicitmode(true), is_any_progress(false);
229  std::string worse_status = "Ready"; // overall status from all TDCs
230 
231  for (unsigned n=0;n<trb->NumberOfTDC();n++) {
232  hadaq::TdcProcessor* tdc = trb->GetTDCWithIndex(n);
233 
234  if (tdc) {
235 
236  // ensure that all calibrations has quality level 0.9 disregard of any errors
237  if (acknowledge_quality)
238  tdc->AcknowledgeCalibrQuality(0.9);
239 
240  double progr = tdc->GetCalibrProgress();
241  std::string sname = tdc->GetCalibrStatus();
242  double quality = tdc->GetCalibrQuality();
243  int mode = tdc->GetExplicitCalibrationMode();
244 
245  if (!logitem.null()) {
246  auto errlog = tdc->TakeCalibrLog();
247  for (auto &item : errlog) {
248  logitem.SetField("value", item);
249  logitem.MarkChangedItems();
250  if (res_msgs) res_msgs->push_back(item);
251  }
252  }
253 
254  // DOUT0("TDC 0x%04x mode %d Progress %5.4f Quality %5.4f state %s", tdc->GetID(), mode, progr, quality, sname.c_str());
255 
256  if (quality < worse_quality) {
257  worse_quality = quality;
258  worse_status = sname;
259  }
260 
261  if (mode < 0) {
262  explicitmode = false;
263  // auto calibration
264  if (sname.find("Ready")==0) {
265  if (p1 > progr) p1 = progr;
266  } else {
267  if (p0 < progr) p0 = progr;
268  ready = false;
269  }
270  } else {
271  if ((progr > 0) && (progr < worse_progress)) {
272  worse_progress = progr;
273  is_any_progress = true;
274  }
275  }
276 
277  tdcs.push_back(tdc->GetID());
278  tdc_progr.push_back((int) (progr*100.));
279  status.push_back(sname);
280  tdc_quality.push_back(quality);
281  } else {
282  tdcs.push_back(0);
283  tdc_progr.push_back(0);
284  status.push_back("Init");
285  tdc_quality.push_back(0);
286  }
287  }
288 
289  if (!explicitmode) {
290  worse_progress = ready ? p1 : -p0;
291  is_any_progress = true;
292  // at the end check if auto-calibration can be done
293  if (worse_progress > 0) {
294  worse_status = "Ready";
295  } else {
296  worse_status = "Init";
297  }
298  }
299 
300  if (!logitem.null() && acknowledge_quality) {
301  std::string item = "Acknowledge quality";
302  logitem.SetField("value", item);
303  logitem.MarkChangedItems();
304  if (res_msgs) res_msgs->push_back(item);
305  }
306 
307  if (!is_any_progress) worse_progress = 0;
308  if (worse_progress > 1.) worse_progress = 1.;
309 
310  if (!change_progress) {
311  if (res_progress) worse_progress = *res_progress / 100.;
312  if (res_quality) worse_quality = *res_quality;
313  if (res_state) worse_status = *res_state;
314  }
315 
316  item.SetField("value", worse_status);
317  item.SetField("progress", (int)(fabs(worse_progress)*100));
318  item.SetField("quality", worse_quality);
319  item.SetField("tdc", tdcs);
320  item.SetField("tdc_progr", tdc_progr);
321  item.SetField("tdc_status", status);
322  item.SetField("tdc_quality", tdc_quality);
323 
324 // DOUT0("Calibr Quality %5.4f Progress %5.4f", progress, worse_quality);
325 
326  if (change_progress) {
327  if (res_progress) *res_progress = (int) (fabs(worse_progress)*100);
328  if (res_quality) *res_quality = worse_quality;
329  if (res_state) *res_state = worse_status;
330  }
331 }
332 
333 
334 void stream::TdcCalibrationModule::ConfigureNewTDC(hadaq::TdcProcessor *tdc)
335 {
336  tdc->SetCalibrTriggerMask(fCalibrMask);
337 
338  for (unsigned n=0;n<fDisabledCh.size();n++)
339  tdc->DisableCalibrationFor(fDisabledCh[n]);
340 
341  tdc->SetAutoCalibration(fAutoCalibr);
342 
343  tdc->SetLinearNumPoints(fLinearNumPoints);
344 
345  if (!fCalibrFile.empty()) {
346  if (fAutoCalibr > 0)
347  tdc->SetWriteCalibration(fCalibrFile.c_str(), true);
348  tdc->LoadCalibration(fCalibrFile.c_str());
349  }
350 
351  if (fAutoTdcMode==1) tdc->SetUseLinear(); // force linear
352  if (fAutoToTRange==1) tdc->SetToTRange(20., 30., 60.); // special mode for DiRICH
353 
354  if (fTotStatLimit > 0) tdc->SetTotStatLimit(fTotStatLimit);
355  if (fTotRMSLimit > 0) tdc->SetTotRMSLimit(fTotRMSLimit);
356 
357  tdc->UseExplicitCalibration();
358 
359  fTDCs.emplace_back(tdc->GetID());
360  DOUT0("TRB 0x%04x created TDC 0x%04x", (unsigned) fTRB, tdc->GetID());
361 }
362 
364 {
365  if (dataid == 0x5555) return false;
366  for (unsigned n=0;n<fTdcMin.size();++n)
367  if ((dataid>=fTdcMin[n]) && (dataid<fTdcMax[n])) return true;
368  return false;
369 }
370 
372 {
373  // method reads one buffer, calibrate it and send further
374 
375  // dabc::ProfilerGuard grd(fProfiler, "checks", 0);
376 
377  // nothing to do
378  if (CanSend() && CanRecv()) {
379 
380  if (!fReplace && !CanTakeBuffer()) return false;
381 
382  dabc::Buffer buf = Recv();
383 
384  if (fDebug) Par("DataRate").SetValue(buf.GetTotalSize()/1024./1024.);
385 
386  if (fDummy && false) {
387 
388  dabc::Hierarchy item = fWorkerHierarchy.GetHChild("Status");
389 
390  fDummyCounter++;
391 
392  fProgress = 0;
393  if (fAutoCalibr>0) fProgress = (int) (100*fDummyCounter/fAutoCalibr); else
394  if (fDoingTdcCalibr) fProgress = (int) (100*fDummyCounter/1000);
395  item.SetField("progress", fProgress);
396 
397  fQuality = 0;
398  if (fProgress > 0) fQuality = 0.7 + fProgress*1e-3;
399 
400  if (fProgress >= 100) {
401  fQuality = 1;
402  if (fAutoCalibr>0) fDummyCounter = 0;
403  fState = "Ready";
404  item.SetField("value", fState);
405  item.SetField("time", dabc::DateTime().GetNow().OnlyTimeAsString());
406  }
407 
408  std::vector<int64_t> progr;
409  progr.assign(fTDCs.size(), fProgress);
410  item.SetField("tdc_progr", progr);
411 
412  std::vector<std::string> status;
413  status.assign(fTDCs.size(), item.GetField("value").AsStr());
414  item.SetField("tdc_status", status);
415 
416  std::vector<double> tdc_quality;
417  tdc_quality.assign(fTDCs.size(), fQuality);
418  item.SetField("tdc_quality", tdc_quality);
419 
420  hadaq::ReadIterator iter(buf);
421  while (iter.NextSubeventsBlock()) {
422  while (iter.NextSubEvent()) {
423  iter.subevnt()->SetId(fTRB);
424  }
425  }
426 
427  item.SetField("quality", fQuality);
428 
429  } else if (fTrbProc) {
430 
431  if ((buf.GetTypeId() == hadaq::mbt_HadaqEvents) || // this is debug mode when processing events from the file
432  (buf.GetTypeId() == hadaq::mbt_HadaqTransportUnit) || // this is normal operation mode
433  (buf.GetTypeId() == hadaq::mbt_HadaqSubevents) || fDummy) { // this could be data after sorting
434 
435  // grd.Next("auto");
436 
437  // this is special case when TDC should be created
438 
439  fDummyCounter++;
440 
441  bool auto_create = (fAutoTdcMode > 0) && (fTDCs.size() == 0) && (fTdcMin.size() > 0) && !fDummy;
442 
443  if (auto_create) {
444 
445  // configure calibration mask before creation of TDC
446  fTrbProc->SetCalibrTriggerMask(fCalibrMask);
447 
448  // special loop over data to create missing TDCs
449 
450  std::vector<unsigned> ids;
451 
452  hadaq::ReadIterator iter0(buf);
453  // take only first event - all other ignored
454  if (iter0.NextSubeventsBlock()) {
455  while (iter0.NextSubEvent()) {
456  if (iter0.subevnt()->GetPaddedSize() > iter0.rawdata_maxsize()) {
457  EOUT("Creating TDCs HUB %u Wrong subevent header len %u maximial %u", fTrbProc->GetID(), iter0.subevnt()->GetPaddedSize(), iter0.rawdata_maxsize());
458  break;
459  }
460 
461  fTrbProc->CollectMissingTDCs((hadaqs::RawSubevent *)iter0.subevnt(), ids);
462 
463  // fTrbProc->CreateMissingTDC((hadaqs::RawSubevent*)iter0.subevnt(), fTdcMin, fTdcMax, fNumCh, fEdges);
464  }
465  }
466 
467  unsigned numtdc = 0;
468  for (unsigned indx = 0; indx < ids.size(); ++indx) {
469  if (MatchTdcId(ids[indx])) {
470  hadaq::TdcProcessor *tdc = new hadaq::TdcProcessor(fTrbProc, ids[indx], fNumCh, fEdges);
471  numtdc++;
472  ConfigureNewTDC(tdc);
473  }
474  }
475 
476  if (numtdc > 0)
477  fTrbProc->CreatePerTDCHistos();
478 
479  // set field with TDCs
480  fWorkerHierarchy.GetHChild("Status").SetField("tdc", fTDCs);
481 
482  if ((numtdc==0) && (fWarningCnt <= 0)) {
483  DOUT0("No any TDC found in %s - please disable Mode in XML file", GetName());
484  fWarningCnt = 10;
485  }
486 
487  if (fDebug == 2) {
488  // just start explicit calculations
489  dabc::Command cmd("TdcCalibrations");
490  cmd.SetStr("mode", "start");
491  ExecuteCommand(cmd);
492  }
493 
494  fRecheckTdcs = false;
495  }
496 
497  // grd.Next("buf");
498 
499  // from here starts transformation of the data
500 
501  unsigned char* tgt = nullptr;
502  unsigned tgtlen(0), reslen(0);
503  dabc::Buffer resbuf;
504  if (!fReplace) {
505  resbuf = TakeBuffer();
506  tgt = (unsigned char*) resbuf.SegmentPtr();
507  tgtlen = resbuf.SegmentSize();
508  }
509 
510  std::vector<unsigned> newids;
511 
512  // grd.Next("main");
513 
514  hadaq::ReadIterator iter(buf);
515  while (iter.NextSubeventsBlock()) {
516  while (iter.NextSubEvent()) {
517 
518  if (iter.subevnt()->GetPaddedSize() > iter.rawdata_maxsize()) {
519  EOUT("TransferData HUB %u Wrong subevent header len %u maximial %u", fTrbProc->GetID(), iter.subevnt()->GetPaddedSize(), iter.rawdata_maxsize());
520  break;
521  }
522 
523  if (tgt && (tgtlen - reslen < iter.subevnt()->GetPaddedSize())) {
524  EOUT("Not enough space for subevent sz %u in output buffer sz %u seg0 %u filled %u remains in src %u", iter.subevnt()->GetPaddedSize(), resbuf.GetTotalSize(), tgtlen, reslen, iter.remained_size());
525  exit(4);
526  return false;
527  }
528 
529  unsigned sublen = 0;
530 
531  // sublen = iter.subevnt()->GetPaddedSize();
532 
533  if (fDummy) {
534  iter.subevnt()->SetId(fTRB);
535  sublen = fTrbProc->EmulateTransform((hadaqs::RawSubevent*)iter.subevnt(), fDummyCounter);
536  } else {
537  hadaqs::RawSubevent *sub = (hadaqs::RawSubevent *) iter.subevnt();
538 
539  if ((sub->Alignment()!=4) || !sub->IsSwapped()) {
540  EOUT("UNEXPECTED TRB DATA FORMAT align %u swap %s - ABORT!!!\n", sub->Alignment(), DBOOL(sub->IsSwapped()));
541  exit(7);
542  }
543 
544  sublen = fTrbProc->TransformSubEvent(sub, tgt, tgtlen - reslen, (fAutoTdcMode==0), fRecheckTdcs ? &newids : nullptr);
545  }
546 
547  if (tgt) {
548  tgt += sublen;
549  reslen += sublen;
550  }
551  }
552 
553  if (fRecheckTdcs) {
554  fRecheckTdcs = false;
555  unsigned numtdc = 0;
556  for (unsigned indx = 0; indx < newids.size(); ++indx) {
557  if (MatchTdcId(newids[indx])) {
558  hadaq::TdcProcessor *tdc = new hadaq::TdcProcessor(fTrbProc, newids[indx], fNumCh, fEdges);
559  numtdc++;
560  ConfigureNewTDC(tdc);
561  }
562  }
563  if (numtdc > 0) {
564  fWorkerHierarchy.GetHChild("Status").SetField("tdc", fTDCs);
565  fTrbProc->ClearFastTDCVector();
566  // FIXME: not yet works
567  // fTrbProc->CreatePerTDCHistos();
568  }
569  }
570 
571  }
572 
573  // grd.Next("finish");
574 
575  if (!fReplace) {
576  resbuf.SetTotalSize(reslen);
578  buf = resbuf;
579  }
580 
581  if (fLastCalibr.Expired(1.)) {
582  fLastCalibr.GetNow();
583 
584  dabc::Hierarchy item = fWorkerHierarchy.GetHChild("Status");
585 
586  dabc::Hierarchy logitem = fWorkerHierarchy.GetHChild("CalibrLog");
587 
588  SetTRBStatus(item, logitem, fTrbProc, fEnableProgressUpdate, &fProgress, &fQuality, &fState, &fLogMessages);
589 
590  // DOUT0("%s PROGR %d QUALITY %5.3f STATE %s", GetName(), fProgress, fQuality, fState.c_str());
591 
592  // if (fProgress>0) fState = "Ready";
593  }
594  } else {
595  if (buf.GetTypeId() != dabc::mbt_EOF)
596  EOUT("Error buffer type!!! %d", buf.GetTypeId());
597  }
598  }
599 
600  Send(buf);
601 
602  return true;
603  }
604 
605  return false;
606 }
607 
608 
610 {
611  if (fOwnProcMgr && fProcMgr && fProcMgr->ExecuteHCommand(cmd)) return dabc::cmd_true;
612 
613  if (cmd.IsName("ResetTransportStat")) {
614  if (fTrbProc)
615  fTrbProc->ClearDAQHistos();
616  // redirect command to real transport
617  if (SubmitCommandToTransport(InputName(), cmd))
618  return dabc::cmd_postponed;
619  return dabc::cmd_false;
620  }
621 
622  if (cmd.IsName("HCMD_AcknowledgeQuality")) {
623  dabc::Hierarchy item = fWorkerHierarchy.GetHChild("Status");
624 
625  dabc::Hierarchy logitem = fWorkerHierarchy.GetHChild("CalibrLog");
626 
627  fEnableProgressUpdate = true;
628 
629  SetTRBStatus(item, logitem, fTrbProc, fEnableProgressUpdate, &fProgress, &fQuality, &fState, &fLogMessages, true);
630 
631  RecordTRBStatus(true, logitem);
632 
633  return dabc::cmd_true;
634  }
635 
636  if (cmd.IsName("GetCalibrState")) {
637  cmd.SetUInt("trb", fTRB);
638  cmd.SetField("tdcs", fTDCs);
639  cmd.SetInt("progress", fProgress);
640  cmd.SetDouble("quality", fQuality);
641  cmd.SetStr("state", fState);
642  return dabc::cmd_true;
643  }
644 
645  if (cmd.IsName("GetHadaqTransportInfo")) {
646  // redirect command to real transport
647  cmd.SetStr("CalibrModule", ItemName());
648  if (SubmitCommandToTransport(InputName(), cmd)) return dabc::cmd_postponed;
649  return dabc::cmd_true;
650  }
651 
652  if (cmd.IsName("TdcCalibrations")) {
653  fDummyCounter = 0; // only for debugging
654 
655  fDoingTdcCalibr = (cmd.GetStr("mode") == "start");
656 
657  if (fDoingTdcCalibr) fLogMessages.clear(); // reset previous log messages
658 
659  fEnableProgressUpdate = true;
660 
661  std::string subdir = cmd.GetStr("rundir");
662 
663  DOUT0("%s ENTER CALIBRATION Mode %s subdir %s\n", GetName(), cmd.GetStr("mode").c_str(), subdir.c_str());
664  if (!subdir.empty()) subdir.append(fCalibrFile);
665 
666  unsigned numtdc = fTrbProc->NumberOfTDC();
667 
668  if (cmd.GetStr("mode") == "start")
669  DOUT0("%s START CALIBRATIONS autotdc %d NumTDC %u", GetName(), fAutoTdcMode, numtdc);
670  else
671  DOUT0("%s STORE CALIBRATIONS IN %s %s NumTDC %u", GetName(), fCalibrFile.c_str(), subdir.c_str(), numtdc);
672 
673  for (unsigned indx = 0; indx < numtdc; ++indx) {
674  hadaq::TdcProcessor *tdc = fTrbProc->GetTDCWithIndex(indx);
675 
676  if (cmd.GetStr("mode") == "start") {
677  tdc->BeginCalibration(fAutoTdcMode==1 ? fCountLinear : fCountNormal);
678  } else {
679 
680  std::string s1 = dabc::format("BEFORE mode %d Progress %5.4f Quality %5.4f state %s", tdc->GetExplicitCalibrationMode(), tdc->GetCalibrProgress(), tdc->GetCalibrQuality(), tdc->GetCalibrStatus().c_str());
681 
682  tdc->CompleteCalibration(fDummy, fCalibrFile, subdir);
683 
684  std::string s2 = dabc::format("AFTER mode %d Progress %5.4f Quality %5.4f state %s", tdc->GetExplicitCalibrationMode(), tdc->GetCalibrProgress(), tdc->GetCalibrQuality(), tdc->GetCalibrStatus().c_str());
685 
686  DOUT0("TDC %04x edges %u %s %s", tdc->GetID(), tdc->GetEdgeMask(), s1.c_str(), s2.c_str());
687  }
688  }
689 
690  fLastCalibr.GetNow();
691  dabc::Hierarchy item = fWorkerHierarchy.GetHChild("Status");
692  dabc::Hierarchy logitem = fWorkerHierarchy.GetHChild("CalibrLog");
693 
694 
695  std::string msg = fDoingTdcCalibr ? "Performing calibration: " : "Complete calibration: ";
696  msg += dabc::DateTime().GetNow().AsJSString();
697  logitem.SetField("value", msg);
698  logitem.MarkChangedItems();
699  if (fDoingTdcCalibr) {
700  msg += " quality = ";
701  msg += std::to_string(fQuality);
702  }
703  fLogMessages.push_back(msg);
704 
705  SetTRBStatus(item, logitem, fTrbProc, fEnableProgressUpdate, &fProgress, &fQuality, &fState, &fLogMessages);
706 
707  RecordTRBStatus(true, logitem);
708 
709  cmd.SetDouble("quality", fQuality);
710 
711  DOUT0("RESULT!!! %s PROGR %d QUALITY %5.3f STATE %s", GetName(), fProgress, fQuality, fState.c_str());
712 
713  return dabc::cmd_true;
714  }
715 
716  if (cmd.IsName("CalibrRefresh")) {
717  cmd.SetDouble("quality", fQuality);
718  return dabc::cmd_true;
719  }
720 
722 }
723 
725 {
726  std::string fname = GetName();
727  fname.append(".txt");
728 
729  FILE *f = fopen(fname.c_str(), do_write ? "w" : "r");
730  if (!f) {
731  EOUT("FAIL to open file %s for %s", fname.c_str(), do_write ? "writing" : "reading");
732  return false;
733  }
734 
735  dabc::DateTime tm;
736 
737  if (do_write) {
738  tm.GetNow();
739  fprintf(f,"%lu\n", (long unsigned) tm.AsJSDate());
740  fprintf(f,"%s\n", fState.c_str());
741  fprintf(f,"%f\n", fQuality);
742  fprintf(f,"%d\n", fProgress);
743  if (fLogMessages.size() > 1000)
744  fLogMessages.erase(fLogMessages.begin(), fLogMessages.end() - 1000);
745  for (auto &item: fLogMessages)
746  fprintf(f,"%s\n", item.c_str());
747  } else {
748  char sbuf[1000];
749 
750  long unsigned tm_js = 0;
751  fgets(sbuf, sizeof(sbuf), f);
752  if (sscanf(sbuf,"%lu", &tm_js) != 1) EOUT("Fail to get time from %s file", fname.c_str());
753  tm.SetJSDate(tm_js);
754 
755  fgets(sbuf, sizeof(sbuf), f);
756  fState = sbuf;
757 
758  fgets(sbuf, sizeof(sbuf), f);
759  if (sscanf(sbuf,"%lf", &fQuality) != 1) EOUT("Fail to get quality from %s file", fname.c_str());
760 
761  fgets(sbuf, sizeof(sbuf), f);
762  if (sscanf(sbuf,"%d", &fProgress) != 1) EOUT("Fail to get progress from %s file", fname.c_str());
763 
764  int cnt = 1000;
765  while (fgets(sbuf, sizeof(sbuf), f) && (cnt-- > 0)) {
766  fLogMessages.push_back(sbuf);
767  logitem.SetField("value", sbuf);
768  logitem.MarkChangedItems();
769  }
770  }
771 
772  fclose(f);
773 
774  return true;
775 }
776 
777 
778 
780 {
781  dabc::Hierarchy logitem = fWorkerHierarchy.GetHChild("CalibrLog");
782 
783  logitem.SetField("value", std::string("Starting calibration module ") + GetName() + " at " + dabc::DateTime().GetNow().AsJSString());
784  logitem.MarkChangedItems();
785 
786  // fProfiler.Reserve(50);
787  // fProfiler.MakeStatistic();
788 }
789 
790 
792 {
793  //fProfiler.MakeStatistic();
794  //DOUT0("PROFILER %s", fProfiler.Format().c_str());
795 
796  if (fDebug == 2) {
797  // just start explicit calculations
798  dabc::Command cmd("TdcCalibrations");
799  cmd.SetStr("mode", "stop");
800  ExecuteCommand(cmd);
801  }
802 
803 }
Reference on memory from memory pool.
Definition: Buffer.h:135
unsigned SegmentSize(unsigned n=0) const
Returns size on the segment, no any boundary checks.
Definition: Buffer.h:174
void SetTotalSize(BufferSize_t len)
Set total length of the buffer to specified value Size cannot be bigger than original size of the buf...
Definition: Buffer.cxx:99
unsigned GetTypeId() const
Definition: Buffer.h:152
BufferSize_t GetTotalSize() const
Return total size of all buffer segments.
Definition: Buffer.cxx:91
void SetTypeId(unsigned tid)
Definition: Buffer.h:151
void * SegmentPtr(unsigned n=0) const
Returns pointer on the segment, no any boundary checks.
Definition: Buffer.h:171
Represents command with its arguments.
Definition: Command.h:99
bool SetStr(const std::string &name, const char *value)
Definition: Command.h:134
bool SetInt(const std::string &name, int v)
Definition: Command.h:138
std::string GetStr(const std::string &name, const std::string &dflt="") const
Definition: Command.h:136
bool SetUInt(const std::string &name, unsigned v)
Definition: Command.h:147
bool SetDouble(const std::string &name, double v)
Definition: Command.h:144
int GetInt(const std::string &name, int dflt=0) const
Definition: Command.h:139
void * GetPtr(const std::string &name, void *deflt=0) const
Get pointer argument from the command.
Definition: Command.cxx:158
Class for holding GMT time with precision of nanoseconds.
Definition: timing.h:190
std::string OnlyTimeAsString(const char *separ=nullptr, bool localtime=false) const
Fills only time as string.
Definition: timing.cxx:273
std::string AsJSString(int ndecimal=3) const
convert string into sec.frac format, can be interpret directly in JavaScript ISO 8601 standard is use...
Definition: timing.cxx:212
void SetJSDate(uint64_t jsdate)
Set value in form of JS date - milliseconds since 1.1.1970.
Definition: timing.h:224
uint64_t AsJSDate() const
Return date and time in JS format - number of millisecond since 1.1.1970.
Definition: timing.cxx:158
DateTime & GetNow()
Definition: timing.cxx:147
Represents objects hierarchy of remote (or local) DABC process.
Definition: Hierarchy.h:285
void MarkChangedItems(uint64_t tm=0)
If any field was modified, item will be marked with new version.
Definition: Hierarchy.h:330
Hierarchy CreateHChild(const std::string &name, bool allowslahes=false, bool sortorder=false)
Create child item in hierarchy with specified name If allowslahes enabled, instead of subfolders item...
Definition: Hierarchy.h:392
Hierarchy GetHChild(const std::string &name, bool allowslahes=false, bool force=false, bool sortorder=false)
Return child, if necessary creates with full subfolder If force specified, missing childs and folders...
Definition: Hierarchy.cxx:944
void Create(const std::string &name, bool withmutex=false)
Create top-level object with specified name.
Definition: Hierarchy.cxx:934
void EnableHistory(unsigned length=100, bool withchilds=false)
Activate history production for selected element and its childs.
Definition: Hierarchy.cxx:837
virtual Parameter CreatePar(const std::string &name, const std::string &kind="")
Definition: Module.cxx:129
unsigned CreatePoolHandle(const std::string &poolname, unsigned queue=10)
Creates handle for memory pool, which preserves reference on memory pool and provides fast access to ...
Definition: Module.cxx:607
virtual int ExecuteCommand(Command cmd)
Main method where commands are executed.
Definition: Module.h:232
unsigned CreateTimer(const std::string &name, double period_sec=-1., bool synchron=false)
Definition: Module.cxx:109
const char * GetName() const
Returns name of the object, thread safe
Definition: Object.h:295
Parameter & SetUnits(const std::string &unit)
Set units field of parameter.
Definition: Parameter.h:256
Parameter & SetRatemeter(bool synchron=false, double interval=1.0)
Converts parameter in ratemeter - all values will be summed up and divided on specified interval.
Definition: Parameter.cxx:365
std::vector< uint64_t > AsUIntVect() const
Definition: Record.cxx:631
uint64_t AsUInt(uint64_t dflt=0) const
Definition: Record.cxx:525
std::vector< int64_t > AsIntVect() const
Definition: Record.cxx:573
bool AsBool(bool dflt=false) const
Definition: Record.cxx:477
std::string AsStr(const std::string &dflt="") const
Definition: Record.cxx:749
int64_t AsInt(int64_t dflt=0) const
Definition: Record.cxx:501
double AsDouble(double dflt=0.) const
Definition: Record.cxx:549
RecordField GetField(const std::string &name) const
Definition: Record.h:510
bool SetField(const std::string &name, const RecordField &v)
Definition: Record.h:516
bool IsName(const char *name) const
Returns true if object name is the same as specified one.
Definition: Reference.cxx:177
unsigned NumChilds() const
Return number of childs in referenced object.
Definition: Reference.cxx:194
bool null() const
Returns true if reference contains nullptr.
Definition: Reference.h:151
Hierarchy fWorkerHierarchy
place for publishing of worker parameters
Definition: Worker.h:168
RecordField Cfg(const std::string &name, Command cmd=nullptr) const
Returns configuration field of specified name Configuration value of specified name searched in follo...
Definition: Worker.cxx:521
virtual bool Publish(const Hierarchy &h, const std::string &path)
Definition: Worker.cxx:1075
Read iterator for HADAQ events/subevents.
Definition: Iterator.h:39
hadaq::RawSubevent * subevnt() const
Definition: Iterator.h:90
unsigned rawdata_maxsize() const
Try to define maximal length for the raw data.
Definition: Iterator.cxx:252
unsigned remained_size() const
Returns size used by current event plus rest.
Definition: Iterator.h:85
bool NextSubEvent()
Used for sub-events iteration inside current block.
Definition: Iterator.cxx:199
bool NextSubeventsBlock()
Depending from buffer type calls NextHadTu() or NextEvent()
Definition: Iterator.cxx:166
void SetTop(dabc::Hierarchy &top, bool withcmds=false)
Definition: DabcProcMgr.cxx:43
std::vector< uint64_t > fTDCs
remember TDCs in the beginning
bool fEnableProgressUpdate
set true to enable trb progress update
int fCountLinear
number of count for liner calibrations when starting explicitly
unsigned fCalibrMask
mask to used for triggers
int fTotStatLimit
limit for ToT statistic
int fLinearNumPoints
number of points used in linear calibration
bool fOwnProcMgr
if created in the module
int fFineMin
configure min value
static void SetTRBStatus(dabc::Hierarchy &item, dabc::Hierarchy &logitem, hadaq::TrbProcessor *trb, bool change_progress=true, int *res_progress=nullptr, double *res_quality=nullptr, std::string *res_state=nullptr, std::vector< std::string > *res_msgs=nullptr, bool acknowledge_quality=false)
int ExecuteCommand(dabc::Command cmd) override
Main method where commands are executed.
std::string fState
current state
bool RecordTRBStatus(bool do_store, dabc::Hierarchy &logitem)
int fNumCh
configured number of channel
int fAutoTdcMode
automatic mode of TDC creation 0 - off, 1 - with linear calibr, 2 - with normal calibr
dabc::TimeStamp fLastCalibr
use not to check for calibration very often
DabcProcMgr * fProcMgr
stream process manager
unsigned fTRB
remember TRB id, used in module name
int fAutoToTRange
ToT range, 0 - normal, 1 - DiRICH.
void ProcessTimerEvent(unsigned) override
Method called by framework when timer event is produced.
std::vector< uint64_t > fTdcMax
configured max TDC id
std::string fCalibrFile
names to load/store calibrations
double fTotRMSLimit
limit for ToT RMS calibration
hadaq::TrbProcessor * fTrbProc
TRB processor.
int fAutoCalibr
amount of statistic for the auto calibration in channels
std::vector< int64_t > fDisabledCh
disabled for calibrations channels
int fFineMax
configure max value
int fCountNormal
number of counts for normal calibrations when starting explicitly
bool fReplace
replace hit messages (true) or add calibration messages (false)
void ConfigureNewTDC(hadaq::TdcProcessor *tdc)
bool fDummy
module creates all TDCs but do not perform any transformation
int fDebug
when specified, provides more debug output and special mode
std::vector< uint64_t > fTdcMin
configured min TDC id
TdcCalibrationModule(const std::string &name, dabc::Command cmd=nullptr)
std::vector< unsigned > tdcs
Definition: hldprint.cxx:996
#define DOUT2(args ...)
Definition: logging.h:170
#define DOUT0(args ...)
Definition: logging.h:156
#define EOUT(args ...)
Definition: logging.h:150
#define DBOOL(arg)
Definition: logging.h:191
Event manipulation API.
Definition: api.h:23
const char * xmlWorkPool
Definition: Object.cxx:46
std::string format(const char *fmt,...)
Definition: string.cxx:49
const char * prop_kind
Definition: Hierarchy.cxx:29
@ mbt_EOF
Definition: Buffer.h:45
@ cmd_postponed
Definition: Command.h:42
@ cmd_false
Definition: Command.h:37
@ cmd_true
Definition: Command.h:38
@ mbt_HadaqSubevents
Definition: HadaqTypeDefs.h:26
@ mbt_HadaqTransportUnit
Definition: HadaqTypeDefs.h:25
@ mbt_HadaqEvents
Definition: HadaqTypeDefs.h:24
void GetNow()
Method to acquire current time stamp.
Definition: timing.h:137
void SetId(uint32_t id)
Definition: defines.h:209
uint32_t GetPaddedSize() const
Definition: defines.h:184