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