Belle II Software  release-06-00-14
eclDQMExtended.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 //THIS MODULE
10 #include <ecl/modules/eclDQMExtended/eclDQMExtended.h>
11 
12 //FRAMEWORK
13 #include <framework/core/HistoModule.h>
14 #include <framework/datastore/StoreArray.h>
15 #include <framework/logging/Logger.h>
16 
17 //ECL
18 #include <ecl/utility/ECLDspUtilities.h>
19 #include <ecl/utility/ECLDspEmulator.h>
20 
21 //STL
22 #include <regex>
23 #include <map>
24 #include <vector>
25 #include <string>
26 #include <iostream>
27 
28 //ROOT
29 #include <TH1F.h>
30 #include <TH2F.h>
31 #include <TDirectory.h>
32 
33 //BOOST
34 #include <boost/filesystem.hpp>
35 #include <boost/format.hpp>
36 
37 
38 //NAMESPACE(S)
39 using namespace Belle2;
40 using namespace ECL;
41 
42 //-----------------------------------------------------------------
43 // Register the Module
44 //-----------------------------------------------------------------
45 REG_MODULE(ECLDQMEXTENDED)
46 
47 
48 //-----------------------------------------------------------------
49 // Implementation
50 //-----------------------------------------------------------------
51 
53  : HistoModule(),
54  m_ECLDspDataArray0("ECLDSPPars0"),
55  m_ECLDspDataArray1("ECLDSPPars1"),
56  m_ECLDspDataArray2("ECLDSPPars2"),
57  m_calibrationThrA0("ECL_FPGA_LowAmp"),
58  m_calibrationThrAhard("ECL_FPGA_HitThresh"),
59  m_calibrationThrAskip("ECL_FPGA_StoreDigit")
60 
61 {
62 
63  //Set module properties
64  setDescription("ECL Data Quality Monitor. Logic Test");
65  setPropertyFlags(c_ParallelProcessingCertified); // specify this flag if you need parallel processing
66  addParam("histogramDirectoryName", m_histogramDirectoryName,
67  "histogram directory in ROOT file", std::string("ECL"));
68  addParam("InitKey", m_InitKey,
69  "How to initialize DSP coeffs: ''DB'' or ''File'' are acceptable ", std::string("DB"));
70  addParam("DSPDirectoryName", m_DSPDirectoryName,
71  "directory for DSP coeffs", std::string("/hsm/belle2/bdata/users/dmitry/dsp/"));
72  addParam("RunName", m_RunName,
73  "Name of run with DSP files", std::string("run0000/"));
74  addParam("SaveDetailedFitData", m_SaveDetailedFitData, "Save detailed data "
75  "(ampdiff_{cellid,shaper}, timediff_{cellid,shaper} histograms) for "
76  "failed fits.", false);
77  addParam("AdjustedTiming", m_adjusted_timing, "Use improved procedure for "
78  "time determination in ShaperDSP emulator", true);
79 
80  std::vector<int> default_skip = {
81  // By default, skip delayed bhabha and random trigger events
82  TRGSummary::ETimingType::TTYP_DPHY,
83  TRGSummary::ETimingType::TTYP_RAND,
84  TRGSummary::ETimingType::TTYP_POIS,
85  };
86  addParam("skipEvents", m_skipEvents, "Skip events that have listed timing "
87  "source (from TRGSummary)", default_skip);
88 }
89 
91 {
92 }
93 
94 //------------------------------------------------------------------
95 // Function to define histograms
96 //-----------------------------------------------------------------
97 
99 {
100  TDirectory* oldDir = gDirectory;
101 
102  // Create a separate histogram directory and cd into it.
103 
104  TDirectory* dirDAQ = dynamic_cast<TDirectory*>(oldDir->Get(m_histogramDirectoryName.c_str()));
105  if (!dirDAQ) dirDAQ = oldDir->mkdir(m_histogramDirectoryName.c_str());
106  dirDAQ->cd();
107 
108  //1D histograms creation.
109 
110  std::vector<TH1F*> h_amp_qualityfail_raw, h_time_qualityfail_raw;
111 
112  for (int i = 0; i < 4; i++) {
113  std::string h_name_a, h_title_a, h_name_t, h_title_t;
114  h_name_a = str(boost::format("amp_timefail_q%1%") % i);
115  h_title_a = str(boost::format("Amp for time mismatches w/ FPGA fit qual=%1%") % i);
116  h_name_t = str(boost::format("time_ampfail_q%1%") % i);
117  h_title_t = str(boost::format("Time for amp mismatches w/ FPGA fit qual=%1%") % i);
118  TH1F* h_a = new TH1F(h_name_a.c_str(), h_title_a.c_str(), 1200, 0, 262144);
119  TH1F* h_t = new TH1F(h_name_t.c_str(), h_title_t.c_str(), 240, -2050, 2050);
120  h_a->SetOption("LIVE");
121  h_t->SetOption("LIVE");
122  h_amp_timefail.push_back(h_a);
123  h_time_ampfail.push_back(h_t);
124  }
125 
126  for (int i = 0; i < 4; i++) {
127  for (int j = 0; j < 4; j++) {
128  if (j != i) {
129  std::string h_name_a, h_title_a, h_name_t, h_title_t;
130  h_name_a = str(boost::format("amp_qf%1%_qd%2%") % i % j);
131  h_title_a = str(boost::format("Amp for C++ fit qual=%1% and FPGA fit qual=%2%") % i % j);
132  h_name_t = str(boost::format("time_qf%1%_qd%2%") % i % j);
133  h_title_t = str(boost::format("Time for C++ fit qual=%1% and FPGA fit qual=%2%") % i % j);
134  TH1F* h_a = new TH1F(h_name_a.c_str(), h_title_a.c_str(), 1200, 0, 262144);
135  TH1F* h_t = new TH1F(h_name_t.c_str(), h_title_t.c_str(), 240, -2050, 2050);
136  h_a->SetOption("LIVE");
137  h_t->SetOption("LIVE");
138  h_amp_qualityfail_raw.push_back(h_a);
139  h_time_qualityfail_raw.push_back(h_t);
140  }
141  }
142  h_amp_qualityfail.push_back(h_amp_qualityfail_raw);
143  h_time_qualityfail.push_back(h_time_qualityfail_raw);
144  h_amp_qualityfail_raw.clear();
145  h_time_qualityfail_raw.clear();
146  }
147 
148  h_ampfail_quality = new TH1F("ampfail_quality", "Number of FPGA <-> C++ fitter #bf{amp} inconsistencies vs fit qual", 5, -1, 4);
149  h_ampfail_quality->SetFillColor(kPink - 4);
150  h_ampfail_quality->GetXaxis()->SetTitle("FPGA fit qual. -1-all evts,0-good,1-int overflow,2-low amp,3-bad chi2");
151  h_ampfail_quality->SetDrawOption("hist");
152  h_ampfail_quality->SetOption("LIVE");
153 
154  h_timefail_quality = new TH1F("timefail_quality", "Number of FPGA <-> C++ fitter #bf{time} inconsistencies vs fit qual", 5, -1, 4);
155  h_timefail_quality->SetFillColor(kPink - 4);
156  h_timefail_quality->GetXaxis()->SetTitle("FPGA fit qual. -1-all evts,0-good,1-int overflow,2-low amp,3-bad chi2");
157 
158  h_ampfail_cellid = new TH1F("ampfail_cellid", "Cell IDs w/ amp inconsistencies", 8736, 1, 8737);
159  h_ampfail_cellid->GetXaxis()->SetTitle("Cell ID");
160  h_ampfail_cellid->SetOption("LIVE");
161 
162  h_timefail_cellid = new TH1F("timefail_cellid", "Cell IDs w/ time inconsistencies", 8736, 1, 8737);
163  h_timefail_cellid->GetXaxis()->SetTitle("Cell ID");
164  h_timefail_cellid->SetOption("LIVE");
165 
166  h_amptimefail_cellid = new TH1F("amptimefail_cellid", "Cell IDs w/ time and amp inconsistencies", 8736, 1, 8737);
167  h_amptimefail_cellid->GetXaxis()->SetTitle("Cell ID");
168  h_amptimefail_cellid->SetOption("LIVE");
169 
170  h_ampfail_shaperid = new TH1F("ampfail_shaperid", "Shaper IDs w/ amp inconsistencies", 624, 1, 625);
171  h_ampfail_shaperid->GetXaxis()->SetTitle("Shaper ID");
172  h_ampfail_shaperid->SetOption("LIVE");
173 
174  h_timefail_shaperid = new TH1F("timefail_shaperid", "Shaper IDs w/ time inconsistencies", 624, 1, 625);
175  h_timefail_shaperid->GetXaxis()->SetTitle("Shaper ID");
176  h_timefail_shaperid->SetOption("LIVE");
177 
178  h_amptimefail_shaperid = new TH1F("amptimefail_shaperid", "Shaper IDs w/ time and amp inconsistencies", 624, 1, 625);
179  h_amptimefail_shaperid->GetXaxis()->SetTitle("Shaper ID");
180  h_amptimefail_shaperid->SetOption("LIVE");
181 
182  h_ampfail_crateid = new TH1F("ampfail_crateid", "Crate IDs w/ amp inconsistencies", 52, 1, 53);
183  h_ampfail_crateid->GetXaxis()->SetTitle("Crate ID (same as ECLCollector ID)");
184  h_ampfail_crateid->SetOption("LIVE");
185 
186  h_timefail_crateid = new TH1F("timefail_crateid", "Crate IDs w/ time inconsistencies", 52, 1, 53);
187  h_timefail_crateid->GetXaxis()->SetTitle("Crate ID (same as ECLCollector ID)");
188  h_timefail_crateid->SetOption("LIVE");
189 
190  h_amptimefail_crateid = new TH1F("amptimefail_crateid", "Crate IDs w/ time and amp inconsistencies", 52, 1, 53);
191  h_amptimefail_crateid->GetXaxis()->SetTitle("Crate ID (same as ECLCollector ID)");
192  h_amptimefail_crateid->SetOption("LIVE");
193 
194  h_qualityfail_cellid = new TH1F("qualityfail_cellid", "Cell IDs w/ fit qual inconsistencies", 8736, 1, 8737);
195  h_qualityfail_cellid->GetXaxis()->SetTitle("Cell ID");
196  h_qualityfail_cellid->SetOption("LIVE");
197 
198  h_qualityfail_shaperid = new TH1F("qualityfail_shaperid", "Shaper IDs w/ fit qual inconsistencies", 624, 1, 625);
199  h_qualityfail_shaperid->GetXaxis()->SetTitle("Shaper ID");
200  h_qualityfail_shaperid->SetOption("LIVE");
201 
202  h_qualityfail_crateid = new TH1F("qualityfail_crateid", "Crate IDs w/ fit qual inconsistencies", 52, 1, 53);
203  h_qualityfail_crateid->GetXaxis()->SetTitle("Crate ID (same as ECLCollector ID)");
204  h_qualityfail_crateid->SetOption("LIVE");
205 
206  h_fail_shaperid = new TH1F("fail_shaperid", "Shaper IDs w/ inconsistencies", 624, 1, 625);
207  h_fail_shaperid->GetXaxis()->SetTitle("Shaper ID");
208  h_fail_shaperid->SetOption("LIVE");
209 
210  h_fail_crateid = new TH1F("fail_crateid", "Crate IDs w/ inconsistencies", 52, 1, 53);
211  h_fail_crateid->GetXaxis()->SetTitle("Crate ID (same as ECLCollector ID)");
212  h_fail_crateid->SetOption("LIVE");
213 
214 
215  //2D histograms creation.
216 
217  if (m_SaveDetailedFitData) {
218  h_ampdiff_cellid = new TH2F("ampdiff_cellid", "Amp. diff. (Emulator-Data) for amp inconsistencies",
219  8736, 1, 8737, 239, -262143, 262143);
220  h_ampdiff_cellid->GetXaxis()->SetTitle("Cell ID");
221  h_ampdiff_cellid->GetYaxis()->SetTitle("Amplitude difference");
222  h_ampdiff_cellid->SetOption("LIVE");
223 
224  h_timediff_cellid = new TH2F("timediff_cellid", "Time diff. (Emulator-Data) for time inconsistencies",
225  8736, 1, 8737, 239, -4095, 4095);
226  h_timediff_cellid->GetXaxis()->SetTitle("Cell ID");
227  h_timediff_cellid->GetYaxis()->SetTitle("Time difference");
228  h_timediff_cellid->SetOption("LIVE");
229 
230  h_ampdiff_shaperid = new TH2F("ampdiff_shaper", "Amp. diff. (Emulator-Data) "
231  "for amp inconsistencies vs Shaper Id",
232  624, 1, 625, 239, -262143, 262143);
233  h_ampdiff_shaperid->GetXaxis()->SetTitle("Shaper Id");
234  h_ampdiff_shaperid->GetYaxis()->SetTitle("Amplitude difference");
235  h_ampdiff_shaperid->SetOption("LIVE");
236 
237  h_timediff_shaperid = new TH2F("timediff_shaper", "Time diff. (Emulator-Data) "
238  "for time inconsistencies vs Shaper Id",
239  624, 1, 625, 239, -4095, 4095);
240  h_timediff_shaperid->GetXaxis()->SetTitle("Shaper Id");
241  h_timediff_shaperid->GetYaxis()->SetTitle("Time difference");
242  h_timediff_shaperid->SetOption("LIVE");
243  }
244 
245  h_ampdiff_quality = new TH2F("ampdiff_quality", "Amp. diff. (Emulator-Data) for amp. inconsistencies", 4, 0, 4, 239,
246  -262143, 262143);
247  h_ampdiff_quality->GetXaxis()->SetTitle("FPGA fit quality. 0-good, 1-int overflow, 2-low amp, 3-bad chi2");
248  h_ampdiff_quality->GetYaxis()->SetTitle("Amplitude difference");
249  h_ampdiff_quality->SetOption("LIVE");
250 
251  h_timediff_quality = new TH2F("timediff_quality", "Time diff. (Emulator-Data) for time inconsistencies", 4, 0, 4, 239,
252  -4095, 4095);
253  h_timediff_quality->GetXaxis()->SetTitle("FPGA fit quality. 0-good, 1-int overflow, 2-low amp, 3-bad chi2");
254  h_timediff_quality->GetYaxis()->SetTitle("Time difference");
255  h_timediff_quality->SetOption("LIVE");
256 
257  h_quality_fit_data = new TH2F("quality_fit_data", "C++ fitter vs FPGA, fit quality inconsistencies", 4, 0, 4, 4, 0, 4);
258  h_quality_fit_data->GetXaxis()->SetTitle("C++ fit qual. 0-good,1-int overflow,2-low amp,3-bad chi2");
259  h_quality_fit_data->GetYaxis()->SetTitle("FPGA fit qual. 0-good,1-int overflow,2-low amp,3-bad chi2");
260  h_quality_fit_data->SetOption("LIVE");
261 
262  h_ampflag_qualityfail = new TH2F("ampflag_qualityfail", "Amp flag (0/1) for fit qual inconsistencies", 4, 0, 4, 4, -1,
263  3);
264  h_ampflag_qualityfail->GetXaxis()->SetTitle("FPGA fit quality. 0-good,1-int overflow,2-low amp,3-bad chi2");
265  h_ampflag_qualityfail->GetYaxis()->SetTitle("Amp flag (0-amp consistent)");
266  h_ampflag_qualityfail->SetOption("LIVE");
267 
268  h_timeflag_qualityfail = new TH2F("timeflag_qualityfail", "Time flag (0/1) for fit qual inconsistencies", 4, 0, 4, 4,
269  -1, 3);
270  h_timeflag_qualityfail->GetXaxis()->SetTitle("FPGA fit quality. 0-good,1-int overflow,2-low amp,3-bad chi2");
271  h_timeflag_qualityfail->GetYaxis()->SetTitle("Time flag (0-time consistent)");
272  h_timeflag_qualityfail->SetOption("LIVE");
273 
274  oldDir->cd();
275 }
276 
277 
279 {
280  REG_HISTOGRAM; // required to register histograms to HistoManager
281 
282  m_ECLDigits.isRequired();
283  m_ECLTrigs.isOptional();
284  m_ECLDsps.isOptional();
285 
286  if (!mapper.initFromDB()) B2FATAL("ECL DQM logic test FATAL:: Can't initialize eclChannelMapper");
287 
288  if (m_InitKey == "DB") initDspfromDB();
289  else if (m_InitKey == "File") initDspfromFile();
290  else B2FATAL("ECL DQM logic test FATAL: No way to initialize DSP coeffs!!! Please choose InitKey = DB or InitKey = File");
291 }
292 
293 void ECLDQMEXTENDEDModule::callbackCalibration(DBObjPtr<ECLCrystalCalib>& cal, std::vector<short int>& constants)
294 {
295  const std::vector<float> intermediate = cal->getCalibVector();
296  constants.resize(intermediate.size());
297  for (size_t i = 0; i < constants.size(); i++) constants[i] = (short int)intermediate[i];
298 }
299 
300 
302  std::map<std::string, std::vector<short int>>& map1,
303  std::map<std::string, short int>& map2)
304 {
305 
306  dspdata->getF(map1["F"]);
307  dspdata->getF1(map1["F1"]);
308  dspdata->getF31(map1["F31"]);
309  dspdata->getF32(map1["F32"]);
310  dspdata->getF33(map1["F33"]);
311  dspdata->getF41(map1["F41"]);
312  dspdata->getF43(map1["F43"]);
313 
314  map2["k_a"] = (short int)dspdata->getka();
315  map2["k_b"] = (short int)dspdata->getkb();
316  map2["k_c"] = (short int)dspdata->getkc();
317  map2["k_16"] = (short int)dspdata->gety0Startr();
318  map2["k_1"] = (short int)dspdata->getk1();
319  map2["k_2"] = (short int)dspdata->getk2();
320  map2["chi_thres"] = dspdata->getchiThresh();
321 }
322 
323 
325 {
326  int iCrate = mapper.getCrateID(cellID);
327  int iShaperPosition = mapper.getShaperPosition(cellID);
328  return (iCrate - 1) * 12 + iShaperPosition;
329 
330 }
331 const short int* ECLDQMEXTENDEDModule::vectorsplit(const std::vector<short int>& vectorFrom, int iChannel)
332 {
333  size_t size = vectorFrom.size();
334  if (size % 16) B2ERROR("ECL DQM logic test error: Split is impossible!" << LogVar("Vector size", size));
335  return (vectorFrom.data() + (size / 16) * (iChannel - 1));
336 }
337 
338 
340 {
341  size_t iShaper = 0;
342 
343  callbackCalibration(m_calibrationThrA0, v_totalthrA0);
344  callbackCalibration(m_calibrationThrAhard, v_totalthrAhard);
345  callbackCalibration(m_calibrationThrAskip, v_totalthrAskip);
346 
347  for (const auto& dspdata : m_ECLDspDataArray0) { //iCrate = 1, ..., 18
348  iShaper++;
349  callbackCalibration(&dspdata, map_container_vec[iShaper],
350  map_container_coef[iShaper]);
351  }
352 
353  for (const auto& dspdata : m_ECLDspDataArray1) { //iCrate = 19, ..., 36
354  iShaper++;
355  callbackCalibration(&dspdata, map_container_vec[iShaper],
356  map_container_coef[iShaper]);
357  }
358 
359  for (const auto& dspdata : m_ECLDspDataArray2) { //iCrate = 37, ..., 52
360  iShaper++;
361  if (iShaper < 529) {
362  if (iShaper - (iShaper - 1) / 12 * 12 > 10) continue;
363  } else {
364  if (iShaper - (iShaper - 1) / 12 * 12 > 8) continue;
365  }
366  callbackCalibration(&dspdata, map_container_vec[iShaper],
367  map_container_coef[iShaper]);
368  }
369 }
370 
372 {
373  const boost::filesystem::path MainDir(m_DSPDirectoryName);
374  const boost::filesystem::path RunSubDir(m_RunName);
375  const std::regex Filter(".*(crate)([0-9]{2})/.*(dsp)([0-9]{2})(.dat)");
376  if (!exists(MainDir / RunSubDir)) B2FATAL("ECL DQM logic test FATAL: Directory w/ DSP files don't exist" << LogVar("Directory",
377  MainDir / RunSubDir));
378  for (boost::filesystem::directory_entry& x : boost::filesystem::recursive_directory_iterator(MainDir / RunSubDir)) {
379  if (!std::regex_match(x.path().string(), Filter) || !boost::filesystem::is_regular_file(x.path())) continue;
380  int iCrate = atoi(std::regex_replace(x.path().string(), Filter, "$2").c_str());
381  int iShaperPosition = atoi(std::regex_replace(x.path().string(), Filter, "$4").c_str());
382  int iShaper = (iCrate - 1) * 12 + iShaperPosition;
383  if (iCrate > 36 && iCrate < 45) {
384  if (iShaperPosition > 10) continue;
385  } else if (iCrate > 44) {
386  if (iShaperPosition > 8) continue;
387  }
388  ECLDspData* dspdata = ECLDspUtilities::readEclDsp(x.path().string().c_str(), iShaperPosition - 1);
389  callbackCalibration(dspdata, map_container_vec[iShaper],
390  map_container_coef[iShaper]);
391  callbackCalibration(m_calibrationThrA0, v_totalthrA0);
392  callbackCalibration(m_calibrationThrAhard, v_totalthrAhard);
393  callbackCalibration(m_calibrationThrAskip, v_totalthrAskip);
394  }
395 }
396 
397 void ECLDQMEXTENDEDModule::emulator(int cellID, int trigger_time, std::vector<int> adc_data)
398 {
399  int iShaper = conversion(cellID);
400  int iChannelPosition = mapper.getShaperChannel(cellID);
401 
402  const auto& map_vec = map_container_vec[iShaper];
403  const short int* f = vectorsplit(map_vec.at("F"), iChannelPosition);
404  const short int* f1 = vectorsplit(map_vec.at("F1"), iChannelPosition);
405  const short int* fg31 = vectorsplit(map_vec.at("F31"), iChannelPosition);
406  const short int* fg32 = vectorsplit(map_vec.at("F32"), iChannelPosition);
407  const short int* fg33 = vectorsplit(map_vec.at("F33"), iChannelPosition);
408  const short int* fg41 = vectorsplit(map_vec.at("F41"), iChannelPosition);
409  const short int* fg43 = vectorsplit(map_vec.at("F43"), iChannelPosition);
410 
411  const auto& map_coef = map_container_coef[iShaper];
412  int k_a = map_coef.at("k_a");
413  int k_b = map_coef.at("k_b");
414  int k_c = map_coef.at("k_c");
415  int k_1 = map_coef.at("k_1");
416  int k_2 = map_coef.at("k_2");
417  int k_16 = map_coef.at("k_16");
418  int chi_thres = map_coef.at("chi_thres");
419 
420  int A0 = (int)v_totalthrA0[cellID - 1];
421  int Ahard = (int)v_totalthrAhard[cellID - 1];
422  int Askip = (int)v_totalthrAskip[cellID - 1];
423 
424  int* y = adc_data.data();
425  int ttrig2 = trigger_time - 2 * (trigger_time / 8);
426 
427  auto result = lftda_(f, f1, fg41, fg43, fg31, fg32, fg33, y, ttrig2, A0,
428  Ahard, Askip, k_a, k_b, k_c, k_16, k_1, k_2, chi_thres,
429  m_adjusted_timing);
430  m_AmpFit = result.amp;
431  m_TimeFit = result.time;
432  m_QualityFit = result.quality;
433 
434  if (result.skip_thr || result.hit_thr) m_QualityFit += 4;
435 }
436 
438 {
439  for (int i = 0; i < 4; i++) {
440  h_amp_timefail[i]->Reset();
441  h_time_ampfail[i]->Reset();
442  }
443  for (int i = 0; i < 4; i++) {
444  for (int j = 0; j < 3; j++) {
445  h_amp_qualityfail[i][j]->Reset();
446  h_time_qualityfail[i][j]->Reset();
447  }
448  }
449  h_ampfail_quality->Reset();
450  h_timefail_quality->Reset();
451  h_ampfail_cellid->Reset();
452  h_timefail_cellid->Reset();
453  h_amptimefail_cellid->Reset();
454  h_ampfail_shaperid->Reset();
455  h_timefail_shaperid->Reset();
456  h_amptimefail_shaperid->Reset();
457  h_ampfail_crateid->Reset();
458  h_timefail_crateid->Reset();
459  h_amptimefail_crateid->Reset();
460  h_qualityfail_cellid->Reset();
461  h_qualityfail_shaperid->Reset();
462  h_qualityfail_crateid->Reset();
463  if (m_SaveDetailedFitData) {
464  h_ampdiff_cellid->Reset();
465  h_timediff_cellid->Reset();
466  h_ampdiff_shaperid->Reset();
467  h_timediff_shaperid->Reset();
468  }
469  h_ampdiff_quality->Reset();
470  h_timediff_quality->Reset();
471  h_quality_fit_data->Reset();
472  h_ampflag_qualityfail->Reset();
473  h_timeflag_qualityfail->Reset();
474 }
475 
477 {
478  if (m_TRGSummary.isValid()) {
479  // Skip events for several types of timing sources
480  // to reduce CPU time usage on HLT (random trigger, delayed bhahba).
481  int timing_type = m_TRGSummary->getTimType();
482  for (auto& skipped_timing_type : m_skipEvents) {
483  if (timing_type == skipped_timing_type) return;
484  }
485  }
486 
487  int iAmpflag_qualityfail = 0;
488  int iTimeflag_qualityfail = 0;
489 
490  for (auto& aECLDsp : m_ECLDsps) {
491  m_CellId = aECLDsp.getCellId();
492  std::vector<int> DspArray = aECLDsp.getDspA();
493  if (!m_ECLTrigs.isValid()) B2FATAL("ECL DQM logic test FATAL: Trigger time information is not available");
494  for (auto& aECLTrig : m_ECLTrigs) {
495  if (aECLTrig.getTrigId() == mapper.getCrateID(m_CellId)) {
496  m_TrigTime = aECLTrig.getTimeTrig();
497  break;
498  }
499  }
500 
501  emulator(m_CellId, m_TrigTime, DspArray);
502  ECLDigit* aECLDigit = aECLDsp.getRelated<ECLDigit>();
503 
504  if ((m_AmpFit >= (int)v_totalthrAskip[m_CellId - 1]) && m_QualityFit < 4 && !aECLDigit)
505  B2ERROR("ECL DQM logic test error: ECL Digit does not exist for A_emulator > Thr_skip"
506  << LogVar("Thr_skip", (int)v_totalthrAskip[m_CellId - 1])
507  << LogVar("A_emulator", m_AmpFit)
508  << LogVar("Quality_emulator", m_QualityFit));
509 
510  if ((m_AmpFit >= (int)v_totalthrAskip[m_CellId - 1]) && aECLDigit) {
511 
512  m_AmpData = aECLDigit->getAmp();
513  m_TimeData = aECLDigit->getTimeFit();
514  m_QualityData = aECLDigit->getQuality();
515 
516  if (m_AmpFit != m_AmpData) {
517  for (int i = 0; i < 4; i++) if (m_QualityData == i && m_TimeFit == m_TimeData) h_time_ampfail[i]->Fill(m_TimeData);
518  h_ampfail_quality->Fill(m_QualityData);
519  h_ampfail_cellid->Fill(m_CellId);
520  h_ampfail_shaperid->Fill(conversion(m_CellId));
521  h_ampfail_crateid->Fill(mapper.getCrateID(m_CellId));
522  if (m_SaveDetailedFitData) {
523  h_ampdiff_cellid->Fill(m_CellId, m_AmpFit - m_AmpData);
524  h_ampdiff_shaperid->Fill(conversion(m_CellId), m_AmpFit - m_AmpData);
525  }
526  h_ampdiff_quality->Fill(m_QualityData, m_AmpFit - m_AmpData);
527  }
528  if (m_TimeFit != m_TimeData) {
529  for (int i = 0; i < 4; i++) if (m_QualityData == i && m_AmpFit == m_AmpData) h_amp_timefail[i]->Fill(m_AmpData);
530  h_timefail_quality->Fill(m_QualityData);
531  h_timefail_cellid->Fill(m_CellId);
532  h_timefail_shaperid->Fill(conversion(m_CellId));
533  h_timefail_crateid->Fill(mapper.getCrateID(m_CellId));
534  if (m_SaveDetailedFitData) {
535  h_timediff_cellid->Fill(m_CellId, m_TimeFit - m_TimeData);
536  h_timediff_shaperid->Fill(conversion(m_CellId), m_TimeFit - m_TimeData);
537  }
538  h_timediff_quality->Fill(m_QualityData, m_TimeFit - m_TimeData);
539  }
540  if (m_AmpFit != m_AmpData && m_TimeFit != m_TimeData) {
541  h_amptimefail_cellid->Fill(m_CellId);
542  h_amptimefail_shaperid->Fill(conversion(m_CellId));
543  h_amptimefail_crateid->Fill(mapper.getCrateID(m_CellId));
544  }
545  if (m_QualityFit != m_QualityData) {
546  for (int i = 0; i < 4; i++) {
547  for (int j = 0; j < 3; j++) {
548  int k = 0;
549  if (i == 0) k = j + 1;
550  if (i == 1) { if (j == 0) k = j; else k = j + 1; }
551  if (i == 2) { if (j == 2) k = j + 1; else k = j; }
552  if (i == 3) k = j;
553  if (m_QualityFit == i && m_QualityData == k) { h_amp_qualityfail[i][j]->Fill(m_AmpData); h_time_qualityfail[i][j]->Fill(m_TimeData); }
554  }
555  }
556  if (m_AmpFit != m_AmpData) iAmpflag_qualityfail = 1;
557  if (m_TimeFit != m_TimeData) iTimeflag_qualityfail = 1;
558  h_qualityfail_cellid->Fill(m_CellId);
559  h_qualityfail_shaperid->Fill(conversion(m_CellId));
560  h_qualityfail_crateid->Fill(mapper.getCrateID(m_CellId));
561  h_ampflag_qualityfail->Fill(m_QualityData, iAmpflag_qualityfail);
562  h_timeflag_qualityfail->Fill(m_QualityData, iTimeflag_qualityfail);
563  h_quality_fit_data->Fill(m_QualityFit, m_QualityData);
564  }
565  if (m_AmpFit != m_AmpData || m_TimeFit != m_TimeData || m_QualityFit != m_QualityData) {
566  h_fail_shaperid->Fill(conversion(m_CellId));
567  h_fail_crateid->Fill(mapper.getCrateID(m_CellId));
568  }
569  h_ampfail_quality->Fill(-1);
570  h_timefail_quality->Fill(-1);
571  } //aECLDigit
572  } //aECLDsp
573 } //event
574 
575 
577 {
578 }
579 
580 
581 
583 {
584 }
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
This module is created to monitor ECL electronics logic in frame of DQM system.
virtual ~ECLDQMEXTENDEDModule() override
Destructor.
void initDspfromDB()
Get DSP coeffs and auxiliary constants from DB.
virtual void initialize() override
Initialize the module.
virtual void event() override
Event processor.
void emulator(int, int, std::vector< int >)
Call for DSP emulator.
virtual void endRun() override
Call when a run ends.
virtual void terminate() override
Terminate.
void callbackCalibration(DBObjPtr< ECLCrystalCalib > &, std::vector< short int > &)
Read calibration values for thresholds from DBObject.
const short int * vectorsplit(const std::vector< short int > &, int)
Select from vector of DSP coeffs a subvector corresponding to accurate channel number.
int conversion(int)
Convert a CellID number to the global Shaper number.
virtual void beginRun() override
Call when a run begins.
void initDspfromFile()
Get DSP coeffs and auxiliary constants from Files.
virtual void defineHisto() override
Function to define histograms.
Class to store ECL digitized hits (output of ECLDigi) relation to ECLHit filled in ecl/modules/eclDig...
Definition: ECLDigit.h:23
int getAmp() const
Get Fitting Amplitude.
Definition: ECLDigit.h:69
int getQuality() const
Get Fitting Quality.
Definition: ECLDigit.h:79
int getTimeFit() const
Get Fitting Time.
Definition: ECLDigit.h:74
This object contains ECL DSP coefs – electromagnetic calorimeter digital signal processing coefficien...
Definition: ECLDspData.h:34
unsigned char getkb() const
Number of bits for FG32.
Definition: ECLDspData.h:200
short int getchiThresh() const
chi2 threshold for fit quality flag
Definition: ECLDspData.h:192
void getF43(std::vector< short int > &dst) const
Alternative for FG33 for signals with small amplitude.
Definition: ECLDspData.h:170
unsigned char gety0Startr() const
start point for pedestal calculation
Definition: ECLDspData.h:204
void getF(std::vector< short int > &dst) const
Array with tabulated signal waveform.
Definition: ECLDspData.h:140
void getF31(std::vector< short int > &dst) const
Array FG31, used to estimate signal amplitude.
Definition: ECLDspData.h:149
unsigned char getk2() const
multipliers power of 2 for chi2 calculation
Definition: ECLDspData.h:196
void getF33(std::vector< short int > &dst) const
Array FG33, used to estimate pedestal height in signal.
Definition: ECLDspData.h:162
unsigned char getka() const
Number of bits for FG31, FG41.
Definition: ECLDspData.h:198
unsigned char getk1() const
multipliers power of 2 for f, f1
Definition: ECLDspData.h:194
void getF32(std::vector< short int > &dst) const
Array FG32, used to estimate A * delta_t.
Definition: ECLDspData.h:156
void getF41(std::vector< short int > &dst) const
Alternative for FG31 for signals with small amplitude.
Definition: ECLDspData.h:166
void getF1(std::vector< short int > &dst) const
Array with tabulated derivative of signal waveform.
Definition: ECLDspData.h:144
unsigned char getkc() const
Number of bits for FG33, FG43.
Definition: ECLDspData.h:202
static ECLDspData * readEclDsp(const char *raw_file, int boardNumber)
Convert ECLDspData from *.dat file to Root object.
This class is used to select pairs, triplets...
Definition: Filter.h:34
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Definition: HistoModule.h:29
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
Class to store variables with their name which were sent to the logging service.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.