Belle II Software  release-06-02-00
TOPDatabaseImporter.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 // Own include
10 #include <top/calibration/TOPDatabaseImporter.h>
11 #include <top/geometry/TOPGeometryPar.h>
12 
13 // framework - Database
14 #include <framework/database/IntervalOfValidity.h>
15 #include <framework/database/DBImportArray.h>
16 #include <framework/database/DBImportObjPtr.h>
17 #include <framework/database/DBArray.h>
18 #include <framework/database/DBObjPtr.h>
19 
20 // framework aux
21 #include <framework/logging/Logger.h>
22 
23 // DB objects
24 #include <top/dbobjects/TOPCalTimebase.h>
25 #include <top/dbobjects/TOPCalChannelT0.h>
26 #include <top/dbobjects/TOPCalModuleT0.h>
27 #include <top/dbobjects/TOPCalChannelMask.h>
28 #include <top/dbobjects/TOPCalChannelPulseHeight.h>
29 #include <top/dbobjects/TOPCalChannelThresholdEff.h>
30 #include <top/dbobjects/TOPCalChannelNoise.h>
31 #include <top/dbobjects/TOPCalChannelRQE.h>
32 #include <top/dbobjects/TOPCalChannelThreshold.h>
33 #include <top/dbobjects/TOPCalCommonT0.h>
34 #include <top/dbobjects/TOPCalIntegratedCharge.h>
35 #include <top/dbobjects/TOPCalModuleAlignment.h>
36 #include <top/dbobjects/TOPCalAsicShift.h>
37 #include <top/dbobjects/TOPCalTimeWalk.h>
38 
39 #include <top/dbobjects/TOPPmtGainPar.h>
40 #include <top/dbobjects/TOPPmtQE.h>
41 #include <top/dbobjects/TOPPmtInstallation.h>
42 #include <top/dbobjects/TOPPmtObsoleteData.h>
43 #include <top/dbobjects/TOPPmtTTSPar.h>
44 #include <top/dbobjects/TOPPmtTTSHisto.h>
45 
46 #include <top/dbobjects/TOPFrontEndSetting.h>
47 
48 #include <iostream>
49 #include <fstream>
50 #include <sstream>
51 #include <set>
52 #include <map>
53 
54 #include "TFile.h"
55 #include "TTree.h"
56 
57 extern "C" {
58  float phind_lambda_(float*); // phase refractive index of quartz (top_geo.F)
59 }
60 
61 using namespace std;
62 
63 namespace Belle2 {
69  using namespace TOP;
70 
71  void TOPDatabaseImporter::importSampleTimeCalibration(string fNames,
72  int firstExp, int firstRun,
73  int lastExp, int lastRun)
74  {
75 
76  // make vector out of files separated with space
77 
78  vector<string> fileNames;
79  stringstream ss(fNames);
80  string fName;
81  while (ss >> fName) {
82  fileNames.push_back(fName);
83  }
84 
85  // prepare what is needed
86 
87  const auto* geo = TOPGeometryPar::Instance()->getGeometry();
88  auto syncTimeBase = geo->getNominalTDC().getSyncTimeBase();
89 
91  timeBase.construct(syncTimeBase);
92 
93  set<int> scrodIDs;
94 
95  // read constants from files and put them to DB object
96 
97  for (const auto& fileName : fileNames) {
98  TFile* file = TFile::Open(fileName.c_str(), "r");
99  if (!file) {
100  B2ERROR("openFile: " << fileName << " *** failed to open");
101  continue;
102  }
103  B2INFO(fileName << ": open for reading");
104 
105  TH1F* hsuccess = (TH1F*) file->Get("success");
106  if (!hsuccess) {
107  B2ERROR("Fit status histogram '" << hsuccess << "' not found");
108  file->Close();
109  continue;
110  }
111 
112  int goodChannels = 0;
113  int numChannels = hsuccess->GetNbinsX();
114  for (int channel = 0; channel < numChannels; channel++) {
115  if (hsuccess->GetBinContent(channel + 1) == 0) continue;
116 
117  string hname = "sampleTimes_ch" + to_string(channel);
118 
119  TH1F* hsampleTimes = (TH1F*) file->Get(hname.c_str());
120  if (!hsampleTimes) {
121  B2ERROR("Histogram '" << hname << "' with calibration constants not found");
122  continue;
123  }
124  // parse scrodID from histogram title
125  string title = hsampleTimes->GetTitle();
126  auto iscrod = title.find("scrod");
127  auto ichannel = title.find("channel");
128  if (iscrod == string::npos or ichannel == string::npos) {
129  B2ERROR("Unsuccessful parsing of scrodID from '" << title << "'");
130  continue;
131  }
132  iscrod += 5;
133  int len = ichannel - iscrod;
134  if (len < 1) {
135  B2ERROR("Unsuccessful parsing of scrodID from '" << title << "'");
136  continue;
137  }
138  int scrodID = stoi(title.substr(iscrod, len));
139  scrodIDs.insert(scrodID);
140 
141  double rescale = 1;
142  if (hsampleTimes->GetBinContent(257) > 0)
143  rescale = 2 * syncTimeBase / hsampleTimes->GetBinContent(257);
144 
145  vector<double> sampleTimes;
146  for (int isamp = 0; isamp < 256; isamp++) {
147  sampleTimes.push_back(hsampleTimes->GetBinContent(isamp + 1) * rescale);
148  }
149  goodChannels++;
150 
151  timeBase->append(scrodID, channel, sampleTimes);
152  }
153 
154  file->Close();
155  B2INFO("--> number of calibrated channels: " << goodChannels);
156  B2INFO("file closed");
157  }
158 
159  // set calibration for missing ones, using previous calibrated channel within asic
160 
161  B2INFO("set constants for uncalibrated channels using nearest calibrated channel within an ASIC");
162  for (auto scrodID : scrodIDs) {
163  int nasic = 128 / 8;
164  for (int as = 0; as < nasic; as++) {
165  const TOPSampleTimes* sampleTimes = 0;
166  for (int ch = 0; ch < 15; ch++) {
167  int channel = as * 8 + (ch % 8);
168  if (timeBase->isAvailable(scrodID, channel)) {
169  sampleTimes = timeBase->getSampleTimes(scrodID, channel);
170  } else if (sampleTimes) {
171  timeBase->append(scrodID, channel, sampleTimes->getTimeAxis());
172  }
173  }
174  if (!sampleTimes) {
175  B2INFO("No calibration available for ASIC " << as << " of scrodID " << scrodID);
176  }
177  }
178  }
179 
180  // import constants
181  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
182  timeBase.import(iov);
183 
184  // final message
185 
186  int nall = timeBase->getSampleTimes().size();
187  int ncal = 0;
188  for (const auto& sampleTimes : timeBase->getSampleTimes()) {
189  if (sampleTimes.isCalibrated()) ncal++;
190  }
191 
192  B2RESULT("Sample time calibration constants imported to database, calibrated channels: "
193  << ncal << "/" << nall);
194  }
195 
196 
197  void TOPDatabaseImporter::importLocalT0Calibration(string fNames,
198  int firstExp, int firstRun,
199  int lastExp, int lastRun)
200  {
201  vector<string> fileNames;
202  stringstream ss(fNames);
203  string fName;
204  while (ss >> fName) {
205  fileNames.push_back(fName);
206  }
207 
208  const auto* geo = TOPGeometryPar::Instance()->getGeometry();
209 
211  channelT0.construct();
212 
213  int nCal[16] = {0}; // number of calibrated channels per slot
214 
215  for (const auto& fileName : fileNames) {
216  TFile* file = TFile::Open(fileName.c_str(), "r");
217  B2INFO("--> Opening constants file " << fileName);
218 
219  if (!file) {
220  B2ERROR("openFile: " << fileName << " *** failed to open");
221  continue;
222  }
223  B2INFO("--> " << fileName << ": open for reading");
224 
225  TTree* treeCal = (TTree*)file->Get("chT0");
226 
227  if (!treeCal) {
228  B2ERROR("openFile: no tree named chT0 found in " << fileName);
229  file->Close();
230  continue;
231  }
232 
233  double t0Cal = 0.;
234  double t0CalErr = 0.;
235  int channelID = 0; // 0-511
236  int slotID = 0; // 1-16
237  int fitStatus = 0; // fit status, 0 = OK
238 
239  treeCal->SetBranchAddress("channel", &channelID);
240  treeCal->SetBranchAddress("slot", &slotID);
241  treeCal->SetBranchAddress("channelT0", &t0Cal);
242  treeCal->SetBranchAddress("channelT0Err", &t0CalErr);
243  treeCal->SetBranchAddress("fitStatus", &fitStatus);
244 
245  B2INFO("--> importing constats");
246 
247  for (int iCal = 0; iCal < treeCal->GetEntries(); iCal++) {
248  treeCal->GetEntry(iCal);
249  if (!geo->isModuleIDValid(slotID)) {
250  B2ERROR("Slot ID is not valid (fileName = " << fileName
251  << ", SlotID = " << slotID << ", ChannelID = " << channelID <<
252  "). Skipping the entry.");
253  continue;
254  }
255  if (channelID < 0 or channelID > 511) {
256  B2ERROR("Channel ID is not valid (fileName = " << fileName
257  << ", SlotID = " << slotID << ", ChannelID = " << channelID <<
258  "). Skipping the entry.");
259  continue;
260  }
261  channelT0->setT0(slotID, channelID, t0Cal, t0CalErr);
262  if (fitStatus == 0) {
263  nCal[slotID - 1]++;
264  } else {
265  channelT0->setUnusable(slotID, channelID);
266  }
267  }
268 
269  file->Close();
270  B2INFO("--> Input file closed");
271  }
272  channelT0->suppressAverage();
273 
274  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
275  channelT0.import(iov);
276 
277  short nCalTot = 0;
278  B2INFO("Summary: ");
279  for (int iSlot = 1; iSlot < 17; iSlot++) {
280  B2INFO("--> Number of calibrated channels on Slot " << iSlot << " : " << nCal[iSlot - 1] << "/512");
281  B2INFO("--> Cal on ch 1, 256 and 511: " << channelT0->getT0(iSlot, 0) << ", " << channelT0->getT0(iSlot,
282  257) << ", " << channelT0->getT0(iSlot, 511));
283  nCalTot += nCal[iSlot - 1];
284  }
285 
286 
287  B2RESULT("Channel T0 calibration constants imported to database, calibrated channels: "
288  << nCalTot << "/ 8192");
289  }
290 
291 
292  void TOPDatabaseImporter::importChannelT0(std::string fileName,
293  int expNo, int firstRun, int lastRun)
294  {
295  // declare db object to be imported -- and construct it
297  channelT0.construct();
298 
299  // open the root file
300  TFile* file = TFile::Open(fileName.c_str(), "r");
301  if (!file) {
302  B2ERROR("openFile: " << fileName << " *** failed to open");
303  return;
304  }
305  B2INFO(fileName << ": open for reading");
306 
307  // loop over slots and set channel T0
308  int nModules = TOPGeometryPar::Instance()->getGeometry()->getNumModules();
309  int count = 0; // counter of calibrated constants
310  for (int moduleID = 1; moduleID <= nModules; moduleID++) {
311  std::string name = "channelT0_slot";
312  if (moduleID < 10) name += "0";
313  name += std::to_string(moduleID);
314  auto* h = (TH1F*) file->Get(name.c_str());
315  if (!h) {
316  B2ERROR("Histogram with name '" + name + "' not found");
317  continue;
318  }
319  for (int channel = 0; channel < h->GetNbinsX(); channel++) {
320  double value = h->GetBinContent(channel + 1);
321  double error = h->GetBinError(channel + 1);
322  channelT0->setT0(moduleID, channel, value, error);
323  if (error > 0) {
324  count++;
325  } else {
326  channelT0->setUnusable(moduleID, channel);
327  }
328  }
329  }
330  file->Close();
331 
332  channelT0->suppressAverage();
333 
334  // import to database
335  IntervalOfValidity iov(expNo, firstRun, expNo, lastRun);
336  channelT0.import(iov);
337 
338  B2INFO("Channel T0 for exp " << expNo << " run " << firstRun << " to " << lastRun
339  << " imported. Calibrated channels: " << count << "/" << nModules * 512);
340 
341  }
342 
343 
344  void TOPDatabaseImporter::importAsicShifts_BS13d(double s0, double s1, double s2, double s3,
345  int expNo, int firstRun, int lastRun)
346  {
347 
348  std::vector<double> shifts;
349  shifts.push_back(s0);
350  shifts.push_back(s1);
351  shifts.push_back(s2);
352  shifts.push_back(s3);
353 
355  asicShift.construct();
356 
357  int moduleID = 13;
358  unsigned bs = 3;
359  for (unsigned carrier = 0; carrier < 4; carrier++) {
360  for (unsigned a = 0; a < 4; a++) {
361  unsigned asic = a + carrier * 4 + bs * 16;
362  asicShift->setT0(moduleID, asic, shifts[carrier]);
363  }
364  }
365 
366  IntervalOfValidity iov(expNo, firstRun, expNo, lastRun);
367  asicShift.import(iov);
368 
369  B2INFO("ASIC shifts of BS13d imported for exp " << expNo << " run " << firstRun <<
370  " to " << lastRun);
371  }
372 
373 
374  void TOPDatabaseImporter::importOfflineCommonT0Calibration(string fileName,
375  int firstExp, int firstRun,
376  int lastExp, int lastRun)
377  {
378  TFile* file = TFile::Open(fileName.c_str(), "r");
379  B2INFO("--> Opening constants file " << fileName);
380 
381  if (!file) {
382  B2ERROR("openFile: " << fileName << " *** failed to open");
383  return;
384  }
385  B2INFO("--> " << fileName << ": open for reading");
386 
387  TTree* treeCal = (TTree*)file->Get("tree");
388 
389  if (!treeCal) {
390  B2ERROR("openFile: no tree named tree found in " << fileName);
391  file->Close();
392  return;
393  }
394 
395  float t0 = 0.;
396  float t0Err = 0;
397  float chi2 = 0;
398  float integral = 0;
399  float sigma = 0;
400  int runNum = 0;
401  int fitStatus = 0;
402 
403  treeCal->SetBranchAddress("offset", &t0);
404  treeCal->SetBranchAddress("runNum", &runNum);
405  treeCal->SetBranchAddress("sigma", &sigma);
406  treeCal->SetBranchAddress("offsetErr", &t0Err);
407  treeCal->SetBranchAddress("chi2", &chi2);
408  treeCal->SetBranchAddress("integral", &integral);
409  treeCal->SetBranchAddress("fitStatus", &fitStatus);
410 
411  treeCal->GetEntry(0);
412 
413  if (lastRun == -1 and firstRun == -1) {
414  lastRun = runNum;
415  firstRun = runNum;
416  B2INFO("Using the run number from the tree ");
417  } else {
418  B2INFO("Using the run numbers passed to the importer");
419  }
420  B2INFO("IOV = (" << firstExp << ", " << firstRun << ", "
421  << lastExp << ", " << lastRun << ")");
422 
424  commonT0.construct(t0, t0Err);
425 
426  if (fitStatus == 0 and integral > 10 and sigma > 0.05 and sigma < 0.33) {
427  B2INFO("Good calibration found ");
428  B2INFO("t0 = " << t0 << " +- " << t0Err);
429  B2INFO("sigma = " << sigma);
430  B2INFO("chi2 = " << chi2);
431  } else {
432  B2INFO("BAD calibration found - set calibration to 'unusable'");
433  B2INFO("t0 = " << t0 << " +- " << t0Err);
434  B2INFO("sigma = " << sigma);
435  B2INFO("chi2 = " << chi2);
436  B2INFO("fit status = " << fitStatus);
437  commonT0->setUnusable();
438  }
439 
440  file->Close();
441 
442  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
443  commonT0.import(iov);
444  B2INFO("--> constants imported");
445  B2INFO(" ");
446  }
447 
448  void TOPDatabaseImporter::importCommonT0(double value, double error,
449  int expNo, int firstRun, int lastRun,
450  bool roughlyCalibrated)
451  {
453  commonT0.construct(value, error);
454  if (roughlyCalibrated) commonT0->setRoughlyCalibrated();
455 
456  IntervalOfValidity iov(expNo, firstRun, expNo, lastRun);
457  commonT0.import(iov);
458 
459  B2INFO("--> constants for exp = " << expNo
460  << " run = " << firstRun << " to " << lastRun << " imported");
461  }
462 
463  void TOPDatabaseImporter::importModuleT0Calibration(string fileName,
464  int firstExp, int firstRun,
465  int lastExp, int lastRun)
466  {
467 
468 
470  moduleT0.construct();
471 
472 
473  ifstream inFile(fileName);
474  B2INFO("--> Opening constants file " << fileName);
475 
476  if (!inFile) {
477  B2ERROR("openFile: " << fileName << " *** failed to open");
478  return;
479  }
480  B2INFO("--> " << fileName << ": open for reading");
481 
482 
483  B2INFO("--> importing constants");
484 
485  while (!inFile.eof()) {
486  int slot = 0;
487  int dummy = 0;
488  double T0 = 0;
489  double T0_err = 0;
490 
491  inFile >> slot >> dummy >> T0 >> T0_err;
492  if (slot < 1 or slot > 16) {
493  B2ERROR("Module ID is not valid. Skipping the entry.");
494  continue;
495  }
496  moduleT0->setT0(slot, T0, T0_err);
497 
498  }
499  inFile.close();
500  B2INFO("--> Input file closed");
501 
502  moduleT0->suppressAverage();
503 
504  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
505  moduleT0.import(iov);
506 
507  B2INFO("Summary: ");
508  for (int iSlot = 1; iSlot < 17; iSlot++) {
509  B2INFO("--> Time offset of Slot " << iSlot << " = " << moduleT0->getT0(iSlot));
510  }
511 
512 
513  }
514 
515 
516  void TOPDatabaseImporter::importModuleT0(std::string fileName,
517  int expNo, int firstRun, int lastRun)
518  {
519 
520  // construct DB import object
522  moduleT0.construct();
523 
524  // open the root file
525  TFile* file = TFile::Open(fileName.c_str(), "r");
526  if (!file) {
527  B2ERROR("openFile: " << fileName << " *** failed to open");
528  return;
529  }
530  B2INFO(fileName << ": open for reading");
531 
532  // get histogram and set the DB import object
533  auto* h = (TH1F*) file->Get("moduleT0");
534  if (not h) {
535  B2ERROR("no histogram 'moduleT0' found in the file, nothing imported");
536  return;
537  }
538  int count = 0; // counter of calibrated
539  for (int slot = 1; slot <= h->GetNbinsX(); slot++) {
540  double value = h->GetBinContent(slot);
541  double error = h->GetBinError(slot);
542  moduleT0->setT0(slot, value, error);
543  if (error > 0) {
544  count++;
545  } else {
546  moduleT0->setUnusable(slot);
547  }
548  }
549  file->Close();
550 
551  moduleT0->suppressAverage();
552 
553  // import the object
554  IntervalOfValidity iov(expNo, firstRun, expNo, lastRun);
555  moduleT0.import(iov);
556 
557  B2INFO("Module T0 for exp " << expNo << " run " << firstRun << " to " << lastRun
558  << " imported. Calibrated modules: " << count << "/" << 16);
559 
560  }
561 
562 
563  void TOPDatabaseImporter::getSampleTimeCalibrationInfo()
564  {
565  DBObjPtr<TOPCalTimebase> timeBase;
566  if (!timeBase.isValid()) {
567  B2ERROR("No time base calibration available");
568  return;
569  }
570 
571  const auto* geo = TOPGeometryPar::Instance()->getGeometry();
572  int numModules = geo->getNumModules();
573  auto& feMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
574 
575  cout << "Time base calibration: number of calibrated channels in database" << endl << endl;
576  for (int moduleID = 1; moduleID <= numModules; moduleID++) {
577  int ncal[4] = {0, 0, 0, 0};
578  int scrodID[4] = {0, 0, 0, 0};
579  for (int bs = 0; bs < 4; bs++) {
580  auto* femap = feMapper.getMap(moduleID, bs);
581  if (!femap) {
582  B2ERROR("No FrontEnd map available for boardstack " << bs << " of module " << moduleID);
583  continue;
584  }
585  scrodID[bs] = femap->getScrodID();
586  for (int channel = 0; channel < 128; channel++) {
587  if (timeBase->isAvailable(scrodID[bs], channel)) ncal[bs]++;
588  }
589  }
590  if (ncal[0] + ncal[1] + ncal[2] + ncal[3] == 0) continue;
591 
592  cout << "Slot " << moduleID << endl;
593  for (int bs = 0; bs < 4; bs++) {
594  cout << " scrodID " << scrodID[bs] << ": " << ncal[bs] << "/128" << endl;
595  }
596  }
597 
598  cout << endl;
599  }
600 
601 
602  void TOPDatabaseImporter::printSampleTimeCalibration()
603  {
604 
605  DBObjPtr<TOPCalTimebase> timeBase;
606  if (!timeBase.isValid()) {
607  B2ERROR("No time base calibration available");
608  return;
609  }
610 
611  for (const auto& sampleTimes : timeBase->getSampleTimes()) {
612  cout << sampleTimes.getScrodID() << " " << sampleTimes.getChannel() << endl;
613  for (const auto& time : sampleTimes.getTimeAxis()) {
614  cout << time << " ";
615  }
616  cout << endl;
617  }
618 
619  }
620 
621 
622  void TOPDatabaseImporter::importChannelMask(std::string fileName,
623  int expNo, int firstRun, int lastRun)
624  {
625  // declare db object to be imported -- and construct it
627  channelMask.construct();
628 
629  // open the root file
630  TFile* file = TFile::Open(fileName.c_str(), "r");
631  if (!file) {
632  B2ERROR("openFile: " << fileName << " *** failed to open");
633  return;
634  }
635  B2INFO(fileName << ": open for reading");
636 
637  // loop over slots and set channel mask
638  int nModules = TOPGeometryPar::Instance()->getGeometry()->getNumModules();
639  int active = 0, dead = 0, noisy = 0;
640  for (int moduleID = 1; moduleID <= nModules; moduleID++) {
641  std::string name = "slot_" + std::to_string(moduleID);
642  auto* h = (TH1F*) file->Get(name.c_str());
643  if (!h) {
644  B2ERROR("Histogram with name '" + name + "' not found");
645  continue;
646  }
647  for (int channel = 0; channel < h->GetNbinsX(); channel++) {
648  int value = h->GetBinContent(channel + 1);
649  if (value == 0) {
650  channelMask->setActive(moduleID, channel);
651  active++;
652  } else if (value == 1) {
653  channelMask->setDead(moduleID, channel);
654  dead++;
655  } else {
656  channelMask->setNoisy(moduleID, channel);
657  noisy++;
658  }
659  }
660  }
661  file->Close();
662 
663  // import to database
664  IntervalOfValidity iov(expNo, firstRun, expNo, lastRun);
665  channelMask.import(iov);
666 
667  B2INFO("Channel mask for exp " << expNo << " run " << firstRun << " to " << lastRun
668  << " imported. Active channels: " << active << ", dead: " << dead
669  << ", noisy: " << noisy);
670 
671  }
672 
673 
674  void TOPDatabaseImporter::generateFakeChannelMask(double fractionDead,
675  double fractionHot,
676  int firstExp, int firstRun,
677  int lastExp, int lastRun)
678  {
679  // declare db object to be imported -- and construct it
681  channelMask.construct();
682 
683  // set up for loop channel mapper
684  auto& chMapper = TOPGeometryPar::Instance()->getChannelMapper();
685  const size_t nModules = TOPGeometryPar::Instance()->getGeometry()->getNumModules();
686  unsigned ncall = 0;
687  unsigned nall = 0;
688 
689  // loop over module (1-based)
690  for (size_t moduleID = 1; moduleID <= nModules; moduleID++) {
691 
692  // loop over boardStack*carrierBoard*assic*channel to get channel (0 to 512)
693  // TODO: get these loop limits from some sensible enum somewhere
694  for (int boardStack = 0; boardStack < 4; boardStack++) {
695  for (int carrierBoard = 0; carrierBoard < 4; carrierBoard++) {
696  for (int asic = 0; asic < 4; asic++) {
697  for (int chan = 0; chan < 8; chan++) {
698  auto channel = chMapper.getChannel(boardStack, carrierBoard, asic, chan);
699  nall++;
700  if (gRandom->Rndm() < fractionDead) {
701  channelMask->setDead(moduleID, channel);
702  ncall++;
703  }
704  if (gRandom->Rndm() < fractionHot) {
705  channelMask->setNoisy(moduleID, channel);
706  ncall++;
707  }
708  }
709  }
710  }
711  }
712  } // module
713 
714  // declare interval of validity
715  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
716  channelMask.import(iov);
717 
718  B2RESULT("Generated and imported a fake channel mask to database for testing: "
719  << ncall << "/" << nall);
720  return;
721  }
722 
723 
724  void TOPDatabaseImporter::importPmtQEData(string fileName, string treeName,
725  int firstExp, int firstRun,
726  int lastExp, int lastRun)
727  {
728 
729  // declare db objects to be imported
731 
732  static const int nChann = 16;
733  std::string* serialNum = 0;
734  std::vector<float>* QE_data[nChann];
735  float lambdaFirst, lambdaStep, collEff0, collEff;
736 
737  TBranch* bQE_data[nChann];
738 
739  // open root file and get tree
740  TFile* file = TFile::Open(fileName.c_str(), "r");
741  if (!file) {
742  B2ERROR("Cannot open the file " << fileName);
743  return;
744  }
745  TTree* tQeData = (TTree*)file->Get(treeName.c_str());
746  if (!tQeData) {
747  B2ERROR("No TTree with name " << treeName << " in file " << fileName);
748  file->Close();
749  return;
750  }
751 
752  tQeData->SetBranchAddress("serialNum", &serialNum);
753  tQeData->SetBranchAddress("lambdaFirst", &lambdaFirst);
754  tQeData->SetBranchAddress("lambdaStep", &lambdaStep);
755  tQeData->SetBranchAddress("collEff0", &collEff0);
756  tQeData->SetBranchAddress("collEff", &collEff);
757 
758  for (int ic = 0; ic < nChann; ic++) {
759  // must initialize vectors and branches
760  QE_data[ic] = new std::vector<float>;
761  bQE_data[ic] = new TBranch();
762 
763  TString cString = "QE_ch";
764  cString += ic + 1;
765  tQeData->SetBranchAddress(cString, &QE_data[ic], &bQE_data[ic]);
766  }
767 
768  // loop on input tree entries and construct the pmtQE objects
769  int countPMTs = 0;
770 
771  for (int ient = 0; ient < tQeData->GetEntries(); ient++) {
772 
773  tQeData->GetEntry(ient);
774 
775  auto* pmtQE = pmtQEs.appendNew(*serialNum, lambdaFirst, lambdaStep, collEff0, collEff);
776 
777  for (int ic = 0; ic < nChann; ic++) {
778  int tEntry = tQeData->LoadTree(ient);
779  bQE_data[ic]->GetEntry(tEntry);
780 
781  pmtQE->setQE(ic + 1, *QE_data[ic]);
782  } // end loop on channels
783 
784  countPMTs++;
785  }
786  file->Close();
787 
788  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
789  pmtQEs.import(iov);
790 
791  B2RESULT("PMT QE data imported to database for " << countPMTs << " PMT's.");
792 
793  return;
794  }
795 
796 
797  void TOPDatabaseImporter::importPmtGainData(string fileName, string treeName,
798  int firstExp, int firstRun,
799  int lastExp, int lastRun)
800  {
801 
802  // declare db objects to be imported
804 
805  static const int nChann = 16;
806  std::string* serialNum = 0;
807  float gain_const[nChann], gain_slope[nChann], gain_ratio[nChann];
808  float hv_op0, hv_op;
809 
810  // open root file and get tree
811  TFile* file = TFile::Open(fileName.c_str(), "r");
812  if (!file) {
813  B2ERROR("Cannot open the file " << fileName);
814  return;
815  }
816  TTree* tGainData = (TTree*)file->Get(treeName.c_str());
817  if (!tGainData) {
818  B2ERROR("No TTree with name " << treeName << " in file " << fileName);
819  file->Close();
820  return;
821  }
822 
823  tGainData->SetBranchAddress("serialNum", &serialNum);
824  tGainData->SetBranchAddress("gain_const", &gain_const);
825  tGainData->SetBranchAddress("gain_slope", &gain_slope);
826  tGainData->SetBranchAddress("gain_ratio", &gain_ratio);
827  tGainData->SetBranchAddress("hv_op0", &hv_op0);
828  tGainData->SetBranchAddress("hv_op", &hv_op);
829 
830 
831  // loop on input tree entries and construct the pmtGain objects
832  int countPMTs = 0;
833 
834  for (int ient = 0; ient < tGainData->GetEntries(); ient++) {
835  tGainData->GetEntry(ient);
836  auto* pmtGain = pmtGains.appendNew(*serialNum);
837 
838  for (int ic = 0; ic < nChann; ic++) {
839  pmtGain->setPmtPixelData(ic + 1, gain_const[ic], gain_slope[ic], gain_ratio[ic]);
840  pmtGain->setNominalHV0(-fabs(hv_op0));
841  pmtGain->setNominalHV(-fabs(hv_op));
842  }
843  countPMTs++;
844  }
845  file->Close();
846 
847  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
848  pmtGains.import(iov);
849 
850  B2RESULT("PMT gain data imported to database for " << countPMTs << " PMT's.");
851 
852  return;
853  }
854 
855 
856  void TOPDatabaseImporter::importPmtInstallationData(string fileName, string treeName ,
857  int firstExp, int firstRun,
858  int lastExp, int lastRun)
859  {
860 
861  // declare db objects to be imported
863 
864  std::string* serialNum = 0;
865  int moduleCNum, slotNum, arrayNum, PMTposition;
867 
868  // open root file and get tree
869  TFile* file = TFile::Open(fileName.c_str(), "r");
870  if (!file) {
871  B2ERROR("Cannot open the file " << fileName);
872  return;
873  }
874  TTree* tInstData = (TTree*)file->Get(treeName.c_str());
875  if (!tInstData) {
876  B2ERROR("No TTree with name " << treeName << " in file " << fileName);
877  file->Close();
878  return;
879  }
880 
881  tInstData->SetBranchAddress("serialNum", &serialNum);
882  tInstData->SetBranchAddress("moduleCNum", &moduleCNum);
883  tInstData->SetBranchAddress("slotNum", &slotNum);
884  tInstData->SetBranchAddress("arrayNum", &arrayNum);
885  tInstData->SetBranchAddress("PMTposition", &PMTposition);
886  tInstData->SetBranchAddress("type", &type);
887 
888  // loop on input tree entries and construct the pmtInstallation objects
889  int countPMTs = 0;
890 
891  for (int ient = 0; ient < tInstData->GetEntries(); ient++) {
892  tInstData->GetEntry(ient);
893  pmtInst.appendNew(*serialNum, moduleCNum, slotNum, arrayNum, PMTposition, type);
894  countPMTs++;
895  }
896  file->Close();
897 
898  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
899  pmtInst.import(iov);
900 
901  B2RESULT("PMT installation data imported to database for " << countPMTs << " PMT's.");
902 
903  }
904 
905 
906  void TOPDatabaseImporter::importPmtObsoleteData(string fileName, string treeName,
907  int firstExp, int firstRun,
908  int lastExp, int lastRun)
909  {
910 
911  // declare db objects to be imported
913 
914  std::string* serialNum = 0;
915  std::string* cathode = 0;
916  float hv_spec, dark_spec, qe380_spec;
918 
919  // open root file and get tree
920  TFile* file = TFile::Open(fileName.c_str(), "r");
921  if (!file) {
922  B2ERROR("Cannot open the file " << fileName);
923  return;
924  }
925  TTree* tObsData = (TTree*)file->Get(treeName.c_str());
926  if (!tObsData) {
927  B2ERROR("No TTree with name " << treeName << " in file " << fileName);
928  file->Close();
929  return;
930  }
931 
932  tObsData->SetBranchAddress("serialNum", &serialNum);
933  tObsData->SetBranchAddress("cathode", &cathode);
934  tObsData->SetBranchAddress("hv_spec", &hv_spec);
935  tObsData->SetBranchAddress("dark_spec", &dark_spec);
936  tObsData->SetBranchAddress("qe380_spec", &qe380_spec);
937  tObsData->SetBranchAddress("type", &type);
938 
939  // loop on input tree entries and construct the pmt obsolete data objects
940  int countPMTs = 0;
941 
942  for (int ient = 0; ient < tObsData->GetEntries(); ient++) {
943  tObsData->GetEntry(ient);
944 
945  // make sure the HV from specifications is negative
946  hv_spec = -fabs(hv_spec);
947 
948  pmtObsData.appendNew(*serialNum, type, *cathode, hv_spec, dark_spec, qe380_spec);
949  countPMTs++;
950  }
951 
952  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
953  pmtObsData.import(iov);
954 
955  B2RESULT("PMT obsolete data imported to database for " << countPMTs << " PMT's.");
956 
957  file->Close();
958 
959  delete serialNum;
960  delete cathode;
961 
962  return;
963  }
964 
965 
966  void TOPDatabaseImporter::importPmtTTSPar(string fileName, string treeName,
967  int firstExp, int firstRun,
968  int lastExp, int lastRun)
969  {
970 
971  // declare db objects to be imported
972  DBImportArray<TOPPmtTTSPar> pmtTtsPars;
973 
974  static const int nChann = 16;
975  std::string* serialNum = 0;
976  std::vector<float>* gausFrac[nChann];
977  std::vector<float>* gausMean[nChann];
978  std::vector<float>* gausSigma[nChann];
979 
980  TBranch* bGFrac[nChann];
981  TBranch* bGMean[nChann];
982  TBranch* bGSigma[nChann];
983 
984 
985  // open root file and get tree
986  TFile* file = TFile::Open(fileName.c_str(), "r");
987  if (!file) {
988  B2ERROR("Cannot open the file " << fileName);
989  return;
990  }
991  TTree* tTtsPar = (TTree*)file->Get(treeName.c_str());
992  if (!tTtsPar) {
993  B2ERROR("No TTree with name " << treeName << " in file " << fileName);
994  file->Close();
995  return;
996  }
997 
998  tTtsPar->SetBranchAddress("serialNum", &serialNum);
999  for (int ic = 0; ic < nChann; ic++) {
1000  // must initialize vectors and branches
1001  gausFrac[ic] = new std::vector<float>;
1002  gausMean[ic] = new std::vector<float>;
1003  gausSigma[ic] = new std::vector<float>;
1004 
1005  bGFrac[ic] = new TBranch();
1006  bGMean[ic] = new TBranch();
1007  bGSigma[ic] = new TBranch();
1008 
1009 
1010  TString cStringF = "gausFrac_ch";
1011  TString cStringM = "gausMean_ch";
1012  TString cStringS = "gausSigma_ch";
1013 
1014  cStringF += ic + 1;
1015  cStringM += ic + 1;
1016  cStringS += ic + 1;
1017 
1018  tTtsPar->SetBranchAddress(cStringF, &gausFrac[ic], &bGFrac[ic]);
1019  tTtsPar->SetBranchAddress(cStringM, &gausMean[ic], &bGMean[ic]);
1020  tTtsPar->SetBranchAddress(cStringS, &gausSigma[ic], &bGSigma[ic]);
1021  }
1022 
1023  // loop on input tree entries and construct the pmt tts par objects
1024  int countPMTs = 0;
1025 
1026  for (int ient = 0; ient < tTtsPar->GetEntries(); ient++) {
1027 
1028  tTtsPar->GetEntry(ient);
1029 
1030  auto* pmtTtsPar = pmtTtsPars.appendNew(*serialNum);
1031 
1032  for (int ic = 0; ic < nChann; ic++) {
1033 
1034  int tEntry = tTtsPar->LoadTree(ient);
1035  bGFrac[ic]->GetEntry(tEntry);
1036  bGMean[ic]->GetEntry(tEntry);
1037  bGSigma[ic]->GetEntry(tEntry);
1038 
1039  // check that the vectors have the same size. Otherwise skip the channel
1040  if ((gausFrac[ic]->size() != gausMean[ic]->size()) ||
1041  (gausFrac[ic]->size() != gausSigma[ic]->size())) {
1042 
1043  B2ERROR("The TTSPar vectors for PMT " << serialNum << ", channel " << ic + 1 << " have different sizes! Skipping channel...");
1044  continue;
1045  }
1046 
1047  for (uint iv = 0; iv < gausFrac[ic]->size(); iv++) {
1048  pmtTtsPar->appendGaussian(ic + 1,
1049  gausFrac[ic]->at(iv),
1050  gausMean[ic]->at(iv),
1051  gausSigma[ic]->at(iv));
1052  }
1053  }
1054  countPMTs++;
1055  }
1056  file->Close();
1057 
1058  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1059  pmtTtsPars.import(iov);
1060 
1061  B2RESULT("PMT TTS parameters imported to database for " << countPMTs << " PMT's.");
1062 
1063  return;
1064  }
1065 
1066 
1067  void TOPDatabaseImporter::importPmtTTSHisto(string fileName,
1068  string treeName,
1069  int firstExp, int firstRun,
1070  int lastExp, int lastRun)
1071  {
1072 
1073  // declare db objects to be imported
1074  DBImportArray<TOPPmtTTSHisto> pmtTtsHistos;
1075 
1076  static const int nChann = 16;
1077  std::string* serialNum = 0;
1078  float hv = 0;
1079  TH1F* histo[nChann] = {0};
1080 
1081  // open root file and get tree
1082  TFile* file = TFile::Open(fileName.c_str(), "r");
1083  if (!file) {
1084  B2ERROR("Cannot open the file " << fileName);
1085  return;
1086  }
1087  TTree* tTtsHisto = (TTree*)file->Get(treeName.c_str());
1088  if (!tTtsHisto) {
1089  B2ERROR("No TTree with name " << treeName << " in file " << fileName);
1090  file->Close();
1091  return;
1092  }
1093 
1094  tTtsHisto->SetBranchAddress("serialNum", &serialNum);
1095  tTtsHisto->SetBranchAddress("hv", &hv);
1096  for (int ic = 0; ic < nChann; ic++) {
1097  TString hString = "hist_ch";
1098  hString += ic + 1;
1099  tTtsHisto->SetBranchAddress(hString, &histo[ic]);
1100  }
1101 
1102  // loop on input tree entries and construct the pmt tts histo objects
1103  int countHists = 0;
1104 
1105  for (int ient = 0; ient < tTtsHisto->GetEntries(); ient++) {
1106 
1107  tTtsHisto->GetEntry(ient);
1108 
1109  // make sure the HV used in the test is negative
1110  hv = -fabs(hv);
1111 
1112  B2INFO("Saving TTS histograms for PMT " << *serialNum << ", HV = " << hv);
1113 
1114  auto* pmtTtsHisto = pmtTtsHistos.appendNew(*serialNum, hv);
1115  for (int ic = 0; ic < nChann; ic++) {
1116  pmtTtsHisto->setHistogram(ic + 1, histo[ic]);
1117  }
1118  countHists++;
1119  }
1120  file->Close();
1121 
1122  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1123  pmtTtsHistos.import(iov);
1124 
1125  B2RESULT("Imported " << countHists << " sets of TTS histograms from " << fileName << " file.");
1126 
1127  return;
1128  }
1129 
1130  void TOPDatabaseImporter::importPmtPulseHeightFitResult(std::string fileName,
1131  int firstExp, int firstRun,
1132  int lastExp, int lastRun)
1133  {
1134  // declare db objects to be imported
1135  DBImportObjPtr<TOPCalChannelPulseHeight> calChannelPulseHeight;
1136  DBImportObjPtr<TOPCalChannelThresholdEff> calChannelThresholdEff;
1137  calChannelPulseHeight.construct();
1138  calChannelThresholdEff.construct();
1139 
1140  TFile* file = TFile::Open(fileName.c_str());
1141  if (!file) {
1142  B2ERROR("openFile: " << fileName << " *** failed to open");
1143  return;
1144  }
1145  TTree* tr = (TTree*)file->Get("tree"); // defined in TOPGainEfficiencyCalculatorModule
1146  if (!tr) {
1147  B2ERROR("No TTree with name tree found in " << fileName);
1148  file->Close();
1149  return;
1150  }
1151 
1152  short slotId = 0;
1153  short pixelId = 0;
1154  float p1 = -1;
1155  float p2 = -1;
1156  float x0 = -1;
1157  float threshold = -1;
1158  float efficiency = -1;
1159  float chisquare = -1;
1160  int ndf = 0;
1161  tr->SetBranchAddress("slotId", &slotId);
1162  tr->SetBranchAddress("pixelId", &pixelId);
1163  tr->SetBranchAddress("p1UseIntegral", &p1);
1164  tr->SetBranchAddress("p2UseIntegral", &p2);
1165  tr->SetBranchAddress("x0UseIntegral", &x0);
1166  tr->SetBranchAddress("thresholdForIntegral", &threshold);
1167  tr->SetBranchAddress("efficiencyUseIntegral", &efficiency);
1168  tr->SetBranchAddress("chisquareUseIntegral", &chisquare);
1169  tr->SetBranchAddress("ndfUseIntegral", &ndf);
1170 
1171  const auto& channelMapper = TOPGeometryPar::Instance()->getChannelMapper();
1172  if (!channelMapper.isValid()) {
1173  B2ERROR("No valid channel mapper found");
1174  file->Close();
1175  return;
1176  }
1177 
1178  long nEntries = tr->GetEntries();
1179  std::map<short, float> reducedChisqMap;
1180  for (long iEntry = 0 ; iEntry < nEntries ; iEntry++) {
1181  tr->GetEntry(iEntry);
1182 
1183  if (efficiency < 0) continue;
1184 
1185  if (!channelMapper.isPixelIDValid(pixelId)) {
1186  B2ERROR("invalid pixelID" << pixelId);
1187  continue;
1188  }
1189  auto channel = channelMapper.getChannel(pixelId);
1190  short globalChannelNumber = slotId * 1000 + channel;
1191  float redChisq = chisquare / ndf;
1192 
1193  //in case entries for the same channel appears multiple time, use data with smaller reduced chisquare
1194  //(This can happen when distribution is fit manually and results are appended for channels with fit failure)
1195  if (reducedChisqMap.count(globalChannelNumber) == 0
1196  or reducedChisqMap[globalChannelNumber] > redChisq) {
1197  reducedChisqMap[globalChannelNumber] = redChisq;
1198  calChannelPulseHeight->setParameters(slotId, channel, x0, p1, p2);
1199  calChannelThresholdEff->setThrEff(slotId, channel, efficiency, (short)threshold);
1200 
1201  if (redChisq > 10.) {
1202  calChannelPulseHeight->setUnusable(slotId, channel);
1203  calChannelThresholdEff->setUnusable(slotId, channel);
1204  }
1205  }
1206  }
1207  file->Close();
1208 
1209  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1210  calChannelPulseHeight.import(iov);
1211  calChannelThresholdEff.import(iov);
1212 
1213  B2RESULT("Imported channel-by-channel gain and efficiency data from fitting of pulse height distribution for "
1214  << reducedChisqMap.size() << " channels from " << fileName << " file.");
1215 
1216  return;
1217  }
1218 
1219 
1220  void TOPDatabaseImporter::exportPmtTTSHisto(string outFileName)
1221  {
1222 
1223  // this is just an example on how to retrieve TTS histograms
1224  DBArray<TOPPmtTTSHisto> elements("TOPPmtTTSHistos");
1225 
1226  TFile file(outFileName.c_str(), "recreate");
1227 
1228  // prints serialNum of PMTs and hv setting used, and saves TTS histograms to root file
1229  for (const auto& element : elements) {
1230 
1231  B2INFO("serialNum = " << element.getSerialNumber() << ", HV = " << element.getHV());
1232  for (int ic = 0; ic < element.getNumOfPixels(); ic++) {
1233  const auto* ttsHisto = element.getHistogram(ic + 1);
1234  if (ttsHisto) ttsHisto->Write();
1235  }
1236  }
1237 
1238  file.Close();
1239 
1240  return;
1241  }
1242 
1243  void TOPDatabaseImporter::importFrontEndSettings(int lookback, int readoutWin,
1244  int extraWin, int offset,
1245  int expNo, int firstRun, int lastRun)
1246  {
1248  feSetting.construct();
1249 
1250  // write-window depths (write-window is 128 samples)
1251  std::vector<int> writeDepths;
1252  for (int i = 0; i < 3; i++) {
1253  writeDepths.push_back(214);
1254  writeDepths.push_back(212);
1255  writeDepths.push_back(214);
1256  }
1257  feSetting->setWriteDepths(writeDepths);
1258  feSetting->setLookbackWindows(lookback);
1259  feSetting->setReadoutWindows(readoutWin);
1260  feSetting->setExtraWindows(extraWin);
1261  feSetting->setOffset(offset);
1262 
1263  // window shifts
1264  std::vector<int> shifts = {0, 0, 1, 1, 1, 2};
1265  feSetting->setWindowShifts(shifts);
1266 
1267  IntervalOfValidity iov(expNo, firstRun, expNo, lastRun);
1268  feSetting.import(iov);
1269 
1270  B2INFO("Front-end settings imported for exp " << expNo << " run " << firstRun <<
1271  " to " << lastRun);
1272  }
1273 
1274 
1275  void TOPDatabaseImporter::importDummyCalModuleAlignment(int firstExp, int firstRun,
1276  int lastExp, int lastRun)
1277  {
1278  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1279  DBImportObjPtr<TOPCalModuleAlignment> moduleAlignment;
1280  moduleAlignment.construct();
1281  moduleAlignment.import(iov);
1282  B2INFO("Dummy TOPCalModuleAlignment imported");
1283  return;
1284  }
1285 
1286  void TOPDatabaseImporter::importDummyCalModuleT0(int firstExp, int firstRun,
1287  int lastExp, int lastRun)
1288  {
1289  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1291  moduleT0.construct();
1292  moduleT0.import(iov);
1293  B2INFO("Dummy TOPCalModuleT0 imported");
1294  return;
1295  }
1296 
1297  void TOPDatabaseImporter::importDummyCalChannelT0(int firstExp, int firstRun,
1298  int lastExp, int lastRun)
1299  {
1300  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1302  channelT0.construct();
1303  channelT0.import(iov);
1304  B2INFO("Dummy TOPCalChannelT0 imported");
1305  return;
1306  }
1307 
1308  void TOPDatabaseImporter::importDummyCalTimebase(int firstExp, int firstRun,
1309  int lastExp, int lastRun)
1310  {
1311  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1313  timebase.construct();
1314  timebase.import(iov);
1315  B2INFO("Dummy TOPCalTimebase imported");
1316  return;
1317  }
1318 
1319  void TOPDatabaseImporter::importDummyCalChannelNoise(int firstExp, int firstRun,
1320  int lastExp, int lastRun)
1321  {
1322  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1324  channelNoise.construct();
1325  channelNoise.import(iov);
1326  B2INFO("Dummy TOPCalChannelNoise imported");
1327  return;
1328  }
1329 
1330  void TOPDatabaseImporter::importDummyCalChannelPulseHeight(int firstExp, int firstRun,
1331  int lastExp, int lastRun)
1332  {
1333  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1335  pulseHeight.construct();
1336  pulseHeight.import(iov);
1337  B2INFO("Dummy TOPCalChannelPulseHeight imported");
1338  return;
1339  }
1340 
1341  void TOPDatabaseImporter::importDummyCalChannelRQE(int firstExp, int firstRun,
1342  int lastExp, int lastRun)
1343  {
1344  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1346  channelRQE.construct();
1347  channelRQE.import(iov);
1348  B2INFO("Dummy TOPCalChannelRQE imported");
1349  return;
1350  }
1351 
1352  void TOPDatabaseImporter::importDummyCalChannelThresholdEff(int firstExp, int firstRun,
1353  int lastExp, int lastRun)
1354  {
1355  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1356  DBImportObjPtr<TOPCalChannelThresholdEff> channelThresholdEff;
1357  channelThresholdEff.construct();
1358  channelThresholdEff.import(iov);
1359  B2INFO("Dummy TOPCalChannelThresholdEff imported");
1360  return;
1361  }
1362 
1363  void TOPDatabaseImporter::importDummyCalChannelThreshold(int firstExp, int firstRun,
1364  int lastExp, int lastRun)
1365  {
1366  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1367  DBImportObjPtr<TOPCalChannelThreshold> channelThreshold;
1368  channelThreshold.construct();
1369  channelThreshold.import(iov);
1370  B2INFO("Dummy TOPCalChannelThreshold imported");
1371  return;
1372  }
1373 
1374  void TOPDatabaseImporter::importDummyCalCommonT0(int firstExp, int firstRun,
1375  int lastExp, int lastRun)
1376  {
1377  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1379  commonT0.construct();
1380  commonT0.import(iov);
1381  B2INFO("Dummy TOPCalCommonT0 imported");
1382  return;
1383  }
1384 
1385  void TOPDatabaseImporter::importDummyCalIntegratedCharge(int firstExp, int firstRun,
1386  int lastExp, int lastRun)
1387  {
1388  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1389  DBImportObjPtr<TOPCalIntegratedCharge> integratedCharge;
1390  integratedCharge.construct();
1391  integratedCharge.import(iov);
1392  B2INFO("Dummy TOPCalIntegratedCharge imported");
1393  return;
1394  }
1395 
1396  void TOPDatabaseImporter::importDummyCalAsicShift(int firstExp, int firstRun,
1397  int lastExp, int lastRun)
1398  {
1399  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1401  asicShift.construct();
1402  asicShift.import(iov);
1403  B2INFO("Dummy TOPCalAsicShift imported");
1404  }
1405 
1406  void TOPDatabaseImporter::correctTOPPmtQE()
1407  {
1408  B2ERROR("Function disabled since the corrected payload TOPPmtQEs already imported");
1409  return;
1410 
1411  DBArray<TOPPmtQE> pmtQEData;
1412  DBImportArray<TOPPmtQE> pmtQECorrected;
1413 
1414  for (const auto& pmt : pmtQEData) {
1415  auto* pmtCorr = pmtQECorrected.appendNew(pmt.getSerialNumber(),
1416  pmt.getLambdaFirst(),
1417  pmt.getLambdaStep(),
1418  pmt.getCE(false),
1419  pmt.getCE(true));
1420  for (unsigned pmtPixel = 1; pmtPixel <= TOPPmtQE::c_NumPmtPixels; pmtPixel++) {
1421  auto qeData = pmt.getQE(pmtPixel);
1422  float lambda = pmt.getLambdaFirst();
1423  float step = pmt.getLambdaStep();
1424  for (auto& qe : qeData) {
1425  double n = phind_lambda_(&lambda); // phase refractive index of quartz
1426  double reflectance = pow((n - 1) / (n + 1), 2);
1427  qe /= (1 - reflectance);
1428  lambda += step;
1429  }
1430  pmtCorr->setQE(pmtPixel, qeData);
1431  }
1432  }
1433 
1434  IntervalOfValidity iov(0, 0, -1, -1);
1435  pmtQECorrected.import(iov);
1436 
1437  B2RESULT("Corrected PMT QE data imported to database for "
1438  << pmtQECorrected.getEntries() << " PMT's.");
1439 
1440  }
1441 
1442 
1443  void TOPDatabaseImporter::importTimeWalk(PyObject* list, double a, double b,
1444  int firstExp, int firstRun,
1445  int lastExp, int lastRun)
1446  {
1447 
1448  std::vector<double> params;
1449  if (PyList_Check(list)) {
1450  for (Py_ssize_t i = 0; i < PyList_Size(list); i++) {
1451  PyObject* value = PyList_GetItem(list, i);
1452  params.push_back(PyFloat_AsDouble(value));
1453  B2INFO(i << " " << params.back());
1454  }
1455  } else {
1456  B2ERROR("Input Python object is not a list");
1457  return;
1458  }
1459 
1461  timeWalk.construct();
1462  timeWalk->set(params, a, b);
1463 
1464  IntervalOfValidity iov(firstExp, firstRun, lastExp, lastRun);
1465  timeWalk.import(iov);
1466 
1467  B2RESULT("Time-walk constants imported");
1468  }
1469 
1470 
1471 
1472 //---- for testing only -- will be removed --------------------------------
1473 
1474  void TOPDatabaseImporter::importTest(int runNumber, double syncTimeBase)
1475  {
1476 
1478  vector<double> timeAxis;
1479  for (int i = 0; i < 256; i++) {
1480  timeAxis.push_back(syncTimeBase / 128.0 * i);
1481  }
1482 
1483 
1484  timeBase.construct(syncTimeBase);
1485  for (unsigned scrodID = 0; scrodID < 64; scrodID++) {
1486  for (unsigned channel = 0; channel < 128; channel++) {
1487  timeBase->append(scrodID, channel, timeAxis);
1488  }
1489  }
1490 
1491  if (runNumber == 3) {
1492  timeBase.addEventDependency(10);
1493  timeBase.construct(syncTimeBase + 100);
1494  for (unsigned scrodID = 0; scrodID < 64; scrodID++) {
1495  for (unsigned channel = 0; channel < 128; channel++) {
1496  timeBase->append(scrodID, channel, timeAxis);
1497  }
1498  }
1499  }
1500 
1501  IntervalOfValidity iov(1, runNumber, 1, runNumber);
1502  timeBase.import(iov);
1503 
1504  }
1505 
1506 
1507  void TOPDatabaseImporter::importTest()
1508  {
1509 
1511 
1512  auto* pmtGain = pmtGains.appendNew("JT00123");
1513  pmtGain->setNominalHV(3520);
1514  for (unsigned channel = 1; channel <= 16; channel++) {
1515  pmtGain->setPmtPixelData(channel, -13.77, 0.0042, 0.4);
1516  }
1517 
1518  pmtGain = pmtGains.appendNew("JT02135");
1519  pmtGain->setNominalHV(3450);
1520  for (unsigned channel = 1; channel <= 16; channel++) {
1521  pmtGain->setPmtPixelData(channel, -12.77, 0.0045, 0.4);
1522  }
1523 
1524  for (const auto& gain : pmtGains) gain.print();
1525 
1526  // IntervalOfValidity iov(0, 0, -1, -1); // all experiments and runs
1527  // pmtGains.import(iov);
1528 
1529 
1530  }
1531 
1532 
1534 } // end Belle2 namespace
1535 
bool isValid() const
Check whether a valid object was obtained from the database.
Class for accessing arrays of objects in the database.
Definition: DBArray.h:26
Class for importing array of objects to the database.
Definition: DBImportArray.h:25
T * appendNew()
Construct a new T object at the end of the array.
Definition: DBImportArray.h:67
int getEntries() const
Returns number of objects in the array.
Definition: DBImportArray.h:54
bool import(const IntervalOfValidity &iov)
Import the object to database.
Definition: DBImportBase.cc:36
virtual void addEventDependency(unsigned int eventNumber)
add event dependency
Definition: DBImportBase.h:47
Class for importing a single object to the database.
void construct(Args &&... params)
Construct an object of type T in this DBImportObjPtr using the provided constructor arguments.
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
A class that describes the interval of experiments/runs for which an object in the database is valid.
Calibration constants of a singe ASIC channel: time axis (sample times)
std::vector< double > getTimeAxis() const
Returns time axis (sample times)
Abstract base class for different kinds of events.