10 #include <top/calibration/TOPDatabaseImporter.h>
11 #include <top/geometry/TOPGeometryPar.h>
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>
21 #include <framework/logging/Logger.h>
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>
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>
46 #include <top/dbobjects/TOPFrontEndSetting.h>
58 float phind_lambda_(
float*);
71 void TOPDatabaseImporter::importSampleTimeCalibration(
string fNames,
72 int firstExp,
int firstRun,
73 int lastExp,
int lastRun)
78 vector<string> fileNames;
79 stringstream ss(fNames);
82 fileNames.push_back(fName);
87 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
88 auto syncTimeBase = geo->getNominalTDC().getSyncTimeBase();
97 for (
const auto& fileName : fileNames) {
98 TFile* file = TFile::Open(fileName.c_str(),
"r");
100 B2ERROR(
"openFile: " << fileName <<
" *** failed to open");
103 B2INFO(fileName <<
": open for reading");
105 TH1F* hsuccess = (TH1F*) file->Get(
"success");
107 B2ERROR(
"Fit status histogram '" << hsuccess <<
"' not found");
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;
117 string hname =
"sampleTimes_ch" + to_string(channel);
119 TH1F* hsampleTimes = (TH1F*) file->Get(hname.c_str());
121 B2ERROR(
"Histogram '" << hname <<
"' with calibration constants not found");
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 <<
"'");
133 int len = ichannel - iscrod;
135 B2ERROR(
"Unsuccessful parsing of scrodID from '" << title <<
"'");
138 int scrodID = stoi(title.substr(iscrod, len));
139 scrodIDs.insert(scrodID);
142 if (hsampleTimes->GetBinContent(257) > 0)
143 rescale = 2 * syncTimeBase / hsampleTimes->GetBinContent(257);
145 vector<double> sampleTimes;
146 for (
int isamp = 0; isamp < 256; isamp++) {
147 sampleTimes.push_back(hsampleTimes->GetBinContent(isamp + 1) * rescale);
151 timeBase->append(scrodID, channel, sampleTimes);
155 B2INFO(
"--> number of calibrated channels: " << goodChannels);
156 B2INFO(
"file closed");
161 B2INFO(
"set constants for uncalibrated channels using nearest calibrated channel within an ASIC");
162 for (
auto scrodID : scrodIDs) {
164 for (
int as = 0; as < nasic; as++) {
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());
175 B2INFO(
"No calibration available for ASIC " << as <<
" of scrodID " << scrodID);
186 int nall = timeBase->getSampleTimes().size();
188 for (
const auto& sampleTimes : timeBase->getSampleTimes()) {
189 if (sampleTimes.isCalibrated()) ncal++;
192 B2RESULT(
"Sample time calibration constants imported to database, calibrated channels: "
193 << ncal <<
"/" << nall);
197 void TOPDatabaseImporter::importLocalT0Calibration(
string fNames,
198 int firstExp,
int firstRun,
199 int lastExp,
int lastRun)
201 vector<string> fileNames;
202 stringstream ss(fNames);
204 while (ss >> fName) {
205 fileNames.push_back(fName);
208 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
215 for (
const auto& fileName : fileNames) {
216 TFile* file = TFile::Open(fileName.c_str(),
"r");
217 B2INFO(
"--> Opening constants file " << fileName);
220 B2ERROR(
"openFile: " << fileName <<
" *** failed to open");
223 B2INFO(
"--> " << fileName <<
": open for reading");
225 TTree* treeCal = (TTree*)file->Get(
"chT0");
228 B2ERROR(
"openFile: no tree named chT0 found in " << fileName);
234 double t0CalErr = 0.;
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);
245 B2INFO(
"--> importing constats");
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.");
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.");
261 channelT0->setT0(slotID, channelID, t0Cal, t0CalErr);
262 if (fitStatus == 0) {
265 channelT0->setUnusable(slotID, channelID);
270 B2INFO(
"--> Input file closed");
272 channelT0->suppressAverage();
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];
287 B2RESULT(
"Channel T0 calibration constants imported to database, calibrated channels: "
288 << nCalTot <<
"/ 8192");
292 void TOPDatabaseImporter::importChannelT0(std::string fileName,
293 int expNo,
int firstRun,
int lastRun)
300 TFile* file = TFile::Open(fileName.c_str(),
"r");
302 B2ERROR(
"openFile: " << fileName <<
" *** failed to open");
305 B2INFO(fileName <<
": open for reading");
308 int nModules = TOPGeometryPar::Instance()->getGeometry()->getNumModules();
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());
316 B2ERROR(
"Histogram with name '" + name +
"' not found");
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);
326 channelT0->setUnusable(moduleID, channel);
332 channelT0->suppressAverage();
338 B2INFO(
"Channel T0 for exp " << expNo <<
" run " << firstRun <<
" to " << lastRun
339 <<
" imported. Calibrated channels: " << count <<
"/" << nModules * 512);
344 void TOPDatabaseImporter::importAsicShifts_BS13d(
double s0,
double s1,
double s2,
double s3,
345 int expNo,
int firstRun,
int lastRun)
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);
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]);
369 B2INFO(
"ASIC shifts of BS13d imported for exp " << expNo <<
" run " << firstRun <<
374 void TOPDatabaseImporter::importOfflineCommonT0Calibration(
string fileName,
375 int firstExp,
int firstRun,
376 int lastExp,
int lastRun)
378 TFile* file = TFile::Open(fileName.c_str(),
"r");
379 B2INFO(
"--> Opening constants file " << fileName);
382 B2ERROR(
"openFile: " << fileName <<
" *** failed to open");
385 B2INFO(
"--> " << fileName <<
": open for reading");
387 TTree* treeCal = (TTree*)file->Get(
"tree");
390 B2ERROR(
"openFile: no tree named tree found in " << fileName);
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);
411 treeCal->GetEntry(0);
413 if (lastRun == -1 and firstRun == -1) {
416 B2INFO(
"Using the run number from the tree ");
418 B2INFO(
"Using the run numbers passed to the importer");
420 B2INFO(
"IOV = (" << firstExp <<
", " << firstRun <<
", "
421 << lastExp <<
", " << lastRun <<
")");
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);
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();
444 B2INFO(
"--> constants imported");
448 void TOPDatabaseImporter::importCommonT0(
double value,
double error,
449 int expNo,
int firstRun,
int lastRun,
450 bool roughlyCalibrated)
454 if (roughlyCalibrated) commonT0->setRoughlyCalibrated();
459 B2INFO(
"--> constants for exp = " << expNo
460 <<
" run = " << firstRun <<
" to " << lastRun <<
" imported");
463 void TOPDatabaseImporter::importModuleT0Calibration(
string fileName,
464 int firstExp,
int firstRun,
465 int lastExp,
int lastRun)
473 ifstream inFile(fileName);
474 B2INFO(
"--> Opening constants file " << fileName);
477 B2ERROR(
"openFile: " << fileName <<
" *** failed to open");
480 B2INFO(
"--> " << fileName <<
": open for reading");
483 B2INFO(
"--> importing constants");
485 while (!inFile.eof()) {
491 inFile >> slot >> dummy >> T0 >> T0_err;
492 if (slot < 1 or slot > 16) {
493 B2ERROR(
"Module ID is not valid. Skipping the entry.");
496 moduleT0->setT0(slot, T0, T0_err);
500 B2INFO(
"--> Input file closed");
502 moduleT0->suppressAverage();
508 for (
int iSlot = 1; iSlot < 17; iSlot++) {
509 B2INFO(
"--> Time offset of Slot " << iSlot <<
" = " << moduleT0->getT0(iSlot));
516 void TOPDatabaseImporter::importModuleT0(std::string fileName,
517 int expNo,
int firstRun,
int lastRun)
525 TFile* file = TFile::Open(fileName.c_str(),
"r");
527 B2ERROR(
"openFile: " << fileName <<
" *** failed to open");
530 B2INFO(fileName <<
": open for reading");
533 auto* h = (TH1F*) file->Get(
"moduleT0");
535 B2ERROR(
"no histogram 'moduleT0' found in the file, nothing imported");
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);
546 moduleT0->setUnusable(slot);
551 moduleT0->suppressAverage();
557 B2INFO(
"Module T0 for exp " << expNo <<
" run " << firstRun <<
" to " << lastRun
558 <<
" imported. Calibrated modules: " << count <<
"/" << 16);
563 void TOPDatabaseImporter::getSampleTimeCalibrationInfo()
567 B2ERROR(
"No time base calibration available");
571 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
572 int numModules = geo->getNumModules();
573 auto& feMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
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);
582 B2ERROR(
"No FrontEnd map available for boardstack " << bs <<
" of module " << moduleID);
585 scrodID[bs] = femap->getScrodID();
586 for (
int channel = 0; channel < 128; channel++) {
587 if (timeBase->isAvailable(scrodID[bs], channel)) ncal[bs]++;
590 if (ncal[0] + ncal[1] + ncal[2] + ncal[3] == 0)
continue;
592 cout <<
"Slot " << moduleID << endl;
593 for (
int bs = 0; bs < 4; bs++) {
594 cout <<
" scrodID " << scrodID[bs] <<
": " << ncal[bs] <<
"/128" << endl;
602 void TOPDatabaseImporter::printSampleTimeCalibration()
607 B2ERROR(
"No time base calibration available");
611 for (
const auto& sampleTimes : timeBase->getSampleTimes()) {
612 cout << sampleTimes.getScrodID() <<
" " << sampleTimes.getChannel() << endl;
613 for (
const auto& time : sampleTimes.getTimeAxis()) {
622 void TOPDatabaseImporter::importChannelMask(std::string fileName,
623 int expNo,
int firstRun,
int lastRun)
630 TFile* file = TFile::Open(fileName.c_str(),
"r");
632 B2ERROR(
"openFile: " << fileName <<
" *** failed to open");
635 B2INFO(fileName <<
": open for reading");
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());
644 B2ERROR(
"Histogram with name '" + name +
"' not found");
647 for (
int channel = 0; channel < h->GetNbinsX(); channel++) {
648 int value = h->GetBinContent(channel + 1);
650 channelMask->setActive(moduleID, channel);
652 }
else if (value == 1) {
653 channelMask->setDead(moduleID, channel);
656 channelMask->setNoisy(moduleID, channel);
667 B2INFO(
"Channel mask for exp " << expNo <<
" run " << firstRun <<
" to " << lastRun
668 <<
" imported. Active channels: " << active <<
", dead: " << dead
669 <<
", noisy: " << noisy);
674 void TOPDatabaseImporter::generateFakeChannelMask(
double fractionDead,
676 int firstExp,
int firstRun,
677 int lastExp,
int lastRun)
684 auto& chMapper = TOPGeometryPar::Instance()->getChannelMapper();
685 const size_t nModules = TOPGeometryPar::Instance()->getGeometry()->getNumModules();
690 for (
size_t moduleID = 1; moduleID <= nModules; moduleID++) {
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);
700 if (gRandom->Rndm() < fractionDead) {
701 channelMask->setDead(moduleID, channel);
704 if (gRandom->Rndm() < fractionHot) {
705 channelMask->setNoisy(moduleID, channel);
718 B2RESULT(
"Generated and imported a fake channel mask to database for testing: "
719 << ncall <<
"/" << nall);
724 void TOPDatabaseImporter::importPmtQEData(
string fileName,
string treeName,
725 int firstExp,
int firstRun,
726 int lastExp,
int lastRun)
732 static const int nChann = 16;
733 std::string* serialNum = 0;
734 std::vector<float>* QE_data[nChann];
735 float lambdaFirst, lambdaStep, collEff0, collEff;
737 TBranch* bQE_data[nChann];
740 TFile* file = TFile::Open(fileName.c_str(),
"r");
742 B2ERROR(
"Cannot open the file " << fileName);
745 TTree* tQeData = (TTree*)file->Get(treeName.c_str());
747 B2ERROR(
"No TTree with name " << treeName <<
" in file " << fileName);
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);
758 for (
int ic = 0; ic < nChann; ic++) {
760 QE_data[ic] =
new std::vector<float>;
761 bQE_data[ic] =
new TBranch();
763 TString cString =
"QE_ch";
765 tQeData->SetBranchAddress(cString, &QE_data[ic], &bQE_data[ic]);
771 for (
int ient = 0; ient < tQeData->GetEntries(); ient++) {
773 tQeData->GetEntry(ient);
775 auto* pmtQE = pmtQEs.
appendNew(*serialNum, lambdaFirst, lambdaStep, collEff0, collEff);
777 for (
int ic = 0; ic < nChann; ic++) {
778 int tEntry = tQeData->LoadTree(ient);
779 bQE_data[ic]->GetEntry(tEntry);
781 pmtQE->setQE(ic + 1, *QE_data[ic]);
791 B2RESULT(
"PMT QE data imported to database for " << countPMTs <<
" PMT's.");
797 void TOPDatabaseImporter::importPmtGainData(
string fileName,
string treeName,
798 int firstExp,
int firstRun,
799 int lastExp,
int lastRun)
805 static const int nChann = 16;
806 std::string* serialNum = 0;
807 float gain_const[nChann], gain_slope[nChann], gain_ratio[nChann];
811 TFile* file = TFile::Open(fileName.c_str(),
"r");
813 B2ERROR(
"Cannot open the file " << fileName);
816 TTree* tGainData = (TTree*)file->Get(treeName.c_str());
818 B2ERROR(
"No TTree with name " << treeName <<
" in file " << fileName);
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);
834 for (
int ient = 0; ient < tGainData->GetEntries(); ient++) {
835 tGainData->GetEntry(ient);
836 auto* pmtGain = pmtGains.
appendNew(*serialNum);
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));
850 B2RESULT(
"PMT gain data imported to database for " << countPMTs <<
" PMT's.");
856 void TOPDatabaseImporter::importPmtInstallationData(
string fileName,
string treeName ,
857 int firstExp,
int firstRun,
858 int lastExp,
int lastRun)
864 std::string* serialNum = 0;
865 int moduleCNum, slotNum, arrayNum, PMTposition;
869 TFile* file = TFile::Open(fileName.c_str(),
"r");
871 B2ERROR(
"Cannot open the file " << fileName);
874 TTree* tInstData = (TTree*)file->Get(treeName.c_str());
876 B2ERROR(
"No TTree with name " << treeName <<
" in file " << fileName);
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);
891 for (
int ient = 0; ient < tInstData->GetEntries(); ient++) {
892 tInstData->GetEntry(ient);
893 pmtInst.
appendNew(*serialNum, moduleCNum, slotNum, arrayNum, PMTposition, type);
901 B2RESULT(
"PMT installation data imported to database for " << countPMTs <<
" PMT's.");
906 void TOPDatabaseImporter::importPmtObsoleteData(
string fileName,
string treeName,
907 int firstExp,
int firstRun,
908 int lastExp,
int lastRun)
914 std::string* serialNum = 0;
915 std::string* cathode = 0;
916 float hv_spec, dark_spec, qe380_spec;
920 TFile* file = TFile::Open(fileName.c_str(),
"r");
922 B2ERROR(
"Cannot open the file " << fileName);
925 TTree* tObsData = (TTree*)file->Get(treeName.c_str());
927 B2ERROR(
"No TTree with name " << treeName <<
" in file " << fileName);
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);
942 for (
int ient = 0; ient < tObsData->GetEntries(); ient++) {
943 tObsData->GetEntry(ient);
946 hv_spec = -fabs(hv_spec);
948 pmtObsData.
appendNew(*serialNum, type, *cathode, hv_spec, dark_spec, qe380_spec);
955 B2RESULT(
"PMT obsolete data imported to database for " << countPMTs <<
" PMT's.");
966 void TOPDatabaseImporter::importPmtTTSPar(
string fileName,
string treeName,
967 int firstExp,
int firstRun,
968 int lastExp,
int lastRun)
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];
980 TBranch* bGFrac[nChann];
981 TBranch* bGMean[nChann];
982 TBranch* bGSigma[nChann];
986 TFile* file = TFile::Open(fileName.c_str(),
"r");
988 B2ERROR(
"Cannot open the file " << fileName);
991 TTree* tTtsPar = (TTree*)file->Get(treeName.c_str());
993 B2ERROR(
"No TTree with name " << treeName <<
" in file " << fileName);
998 tTtsPar->SetBranchAddress(
"serialNum", &serialNum);
999 for (
int ic = 0; ic < nChann; ic++) {
1001 gausFrac[ic] =
new std::vector<float>;
1002 gausMean[ic] =
new std::vector<float>;
1003 gausSigma[ic] =
new std::vector<float>;
1005 bGFrac[ic] =
new TBranch();
1006 bGMean[ic] =
new TBranch();
1007 bGSigma[ic] =
new TBranch();
1010 TString cStringF =
"gausFrac_ch";
1011 TString cStringM =
"gausMean_ch";
1012 TString cStringS =
"gausSigma_ch";
1018 tTtsPar->SetBranchAddress(cStringF, &gausFrac[ic], &bGFrac[ic]);
1019 tTtsPar->SetBranchAddress(cStringM, &gausMean[ic], &bGMean[ic]);
1020 tTtsPar->SetBranchAddress(cStringS, &gausSigma[ic], &bGSigma[ic]);
1026 for (
int ient = 0; ient < tTtsPar->GetEntries(); ient++) {
1028 tTtsPar->GetEntry(ient);
1030 auto* pmtTtsPar = pmtTtsPars.
appendNew(*serialNum);
1032 for (
int ic = 0; ic < nChann; ic++) {
1034 int tEntry = tTtsPar->LoadTree(ient);
1035 bGFrac[ic]->GetEntry(tEntry);
1036 bGMean[ic]->GetEntry(tEntry);
1037 bGSigma[ic]->GetEntry(tEntry);
1040 if ((gausFrac[ic]->size() != gausMean[ic]->size()) ||
1041 (gausFrac[ic]->size() != gausSigma[ic]->size())) {
1043 B2ERROR(
"The TTSPar vectors for PMT " << serialNum <<
", channel " << ic + 1 <<
" have different sizes! Skipping channel...");
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));
1061 B2RESULT(
"PMT TTS parameters imported to database for " << countPMTs <<
" PMT's.");
1067 void TOPDatabaseImporter::importPmtTTSHisto(
string fileName,
1069 int firstExp,
int firstRun,
1070 int lastExp,
int lastRun)
1076 static const int nChann = 16;
1077 std::string* serialNum = 0;
1079 TH1F* histo[nChann] = {0};
1082 TFile* file = TFile::Open(fileName.c_str(),
"r");
1084 B2ERROR(
"Cannot open the file " << fileName);
1087 TTree* tTtsHisto = (TTree*)file->Get(treeName.c_str());
1089 B2ERROR(
"No TTree with name " << treeName <<
" in file " << fileName);
1094 tTtsHisto->SetBranchAddress(
"serialNum", &serialNum);
1095 tTtsHisto->SetBranchAddress(
"hv", &hv);
1096 for (
int ic = 0; ic < nChann; ic++) {
1097 TString hString =
"hist_ch";
1099 tTtsHisto->SetBranchAddress(hString, &histo[ic]);
1105 for (
int ient = 0; ient < tTtsHisto->GetEntries(); ient++) {
1107 tTtsHisto->GetEntry(ient);
1112 B2INFO(
"Saving TTS histograms for PMT " << *serialNum <<
", HV = " << hv);
1114 auto* pmtTtsHisto = pmtTtsHistos.
appendNew(*serialNum, hv);
1115 for (
int ic = 0; ic < nChann; ic++) {
1116 pmtTtsHisto->setHistogram(ic + 1, histo[ic]);
1123 pmtTtsHistos.
import(iov);
1125 B2RESULT(
"Imported " << countHists <<
" sets of TTS histograms from " << fileName <<
" file.");
1130 void TOPDatabaseImporter::importPmtPulseHeightFitResult(std::string fileName,
1131 int firstExp,
int firstRun,
1132 int lastExp,
int lastRun)
1140 TFile* file = TFile::Open(fileName.c_str());
1142 B2ERROR(
"openFile: " << fileName <<
" *** failed to open");
1145 TTree* tr = (TTree*)file->Get(
"tree");
1147 B2ERROR(
"No TTree with name tree found in " << fileName);
1157 float threshold = -1;
1158 float efficiency = -1;
1159 float chisquare = -1;
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);
1171 const auto& channelMapper = TOPGeometryPar::Instance()->getChannelMapper();
1172 if (!channelMapper.isValid()) {
1173 B2ERROR(
"No valid channel mapper found");
1178 long nEntries = tr->GetEntries();
1179 std::map<short, float> reducedChisqMap;
1180 for (
long iEntry = 0 ; iEntry < nEntries ; iEntry++) {
1181 tr->GetEntry(iEntry);
1183 if (efficiency < 0)
continue;
1185 if (!channelMapper.isPixelIDValid(pixelId)) {
1186 B2ERROR(
"invalid pixelID" << pixelId);
1189 auto channel = channelMapper.getChannel(pixelId);
1190 short globalChannelNumber = slotId * 1000 + channel;
1191 float redChisq = chisquare / ndf;
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);
1201 if (redChisq > 10.) {
1202 calChannelPulseHeight->setUnusable(slotId, channel);
1203 calChannelThresholdEff->setUnusable(slotId, channel);
1210 calChannelPulseHeight.
import(iov);
1211 calChannelThresholdEff.
import(iov);
1213 B2RESULT(
"Imported channel-by-channel gain and efficiency data from fitting of pulse height distribution for "
1214 << reducedChisqMap.size() <<
" channels from " << fileName <<
" file.");
1220 void TOPDatabaseImporter::exportPmtTTSHisto(
string outFileName)
1226 TFile file(outFileName.c_str(),
"recreate");
1229 for (
const auto& element : elements) {
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();
1243 void TOPDatabaseImporter::importFrontEndSettings(
int lookback,
int readoutWin,
1244 int extraWin,
int offset,
1245 int expNo,
int firstRun,
int lastRun)
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);
1257 feSetting->setWriteDepths(writeDepths);
1258 feSetting->setLookbackWindows(lookback);
1259 feSetting->setReadoutWindows(readoutWin);
1260 feSetting->setExtraWindows(extraWin);
1261 feSetting->setOffset(offset);
1264 std::vector<int> shifts = {0, 0, 1, 1, 1, 2};
1265 feSetting->setWindowShifts(shifts);
1270 B2INFO(
"Front-end settings imported for exp " << expNo <<
" run " << firstRun <<
1275 void TOPDatabaseImporter::importDummyCalModuleAlignment(
int firstExp,
int firstRun,
1276 int lastExp,
int lastRun)
1281 moduleAlignment.
import(iov);
1282 B2INFO(
"Dummy TOPCalModuleAlignment imported");
1286 void TOPDatabaseImporter::importDummyCalModuleT0(
int firstExp,
int firstRun,
1287 int lastExp,
int lastRun)
1293 B2INFO(
"Dummy TOPCalModuleT0 imported");
1297 void TOPDatabaseImporter::importDummyCalChannelT0(
int firstExp,
int firstRun,
1298 int lastExp,
int lastRun)
1304 B2INFO(
"Dummy TOPCalChannelT0 imported");
1308 void TOPDatabaseImporter::importDummyCalTimebase(
int firstExp,
int firstRun,
1309 int lastExp,
int lastRun)
1315 B2INFO(
"Dummy TOPCalTimebase imported");
1319 void TOPDatabaseImporter::importDummyCalChannelNoise(
int firstExp,
int firstRun,
1320 int lastExp,
int lastRun)
1325 channelNoise.
import(iov);
1326 B2INFO(
"Dummy TOPCalChannelNoise imported");
1330 void TOPDatabaseImporter::importDummyCalChannelPulseHeight(
int firstExp,
int firstRun,
1331 int lastExp,
int lastRun)
1337 B2INFO(
"Dummy TOPCalChannelPulseHeight imported");
1341 void TOPDatabaseImporter::importDummyCalChannelRQE(
int firstExp,
int firstRun,
1342 int lastExp,
int lastRun)
1348 B2INFO(
"Dummy TOPCalChannelRQE imported");
1352 void TOPDatabaseImporter::importDummyCalChannelThresholdEff(
int firstExp,
int firstRun,
1353 int lastExp,
int lastRun)
1358 channelThresholdEff.
import(iov);
1359 B2INFO(
"Dummy TOPCalChannelThresholdEff imported");
1363 void TOPDatabaseImporter::importDummyCalChannelThreshold(
int firstExp,
int firstRun,
1364 int lastExp,
int lastRun)
1369 channelThreshold.
import(iov);
1370 B2INFO(
"Dummy TOPCalChannelThreshold imported");
1374 void TOPDatabaseImporter::importDummyCalCommonT0(
int firstExp,
int firstRun,
1375 int lastExp,
int lastRun)
1381 B2INFO(
"Dummy TOPCalCommonT0 imported");
1385 void TOPDatabaseImporter::importDummyCalIntegratedCharge(
int firstExp,
int firstRun,
1386 int lastExp,
int lastRun)
1391 integratedCharge.
import(iov);
1392 B2INFO(
"Dummy TOPCalIntegratedCharge imported");
1396 void TOPDatabaseImporter::importDummyCalAsicShift(
int firstExp,
int firstRun,
1397 int lastExp,
int lastRun)
1403 B2INFO(
"Dummy TOPCalAsicShift imported");
1406 void TOPDatabaseImporter::correctTOPPmtQE()
1408 B2ERROR(
"Function disabled since the corrected payload TOPPmtQEs already imported");
1414 for (
const auto& pmt : pmtQEData) {
1415 auto* pmtCorr = pmtQECorrected.
appendNew(pmt.getSerialNumber(),
1416 pmt.getLambdaFirst(),
1417 pmt.getLambdaStep(),
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);
1426 double reflectance = pow((n - 1) / (n + 1), 2);
1427 qe /= (1 - reflectance);
1430 pmtCorr->setQE(pmtPixel, qeData);
1435 pmtQECorrected.
import(iov);
1437 B2RESULT(
"Corrected PMT QE data imported to database for "
1438 << pmtQECorrected.
getEntries() <<
" PMT's.");
1443 void TOPDatabaseImporter::importTimeWalk(PyObject* list,
double a,
double b,
1444 int firstExp,
int firstRun,
1445 int lastExp,
int lastRun)
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());
1456 B2ERROR(
"Input Python object is not a list");
1462 timeWalk->set(params, a, b);
1467 B2RESULT(
"Time-walk constants imported");
1474 void TOPDatabaseImporter::importTest(
int runNumber,
double syncTimeBase)
1478 vector<double> timeAxis;
1479 for (
int i = 0; i < 256; i++) {
1480 timeAxis.push_back(syncTimeBase / 128.0 * i);
1485 for (
unsigned scrodID = 0; scrodID < 64; scrodID++) {
1486 for (
unsigned channel = 0; channel < 128; channel++) {
1487 timeBase->append(scrodID, channel, timeAxis);
1491 if (runNumber == 3) {
1494 for (
unsigned scrodID = 0; scrodID < 64; scrodID++) {
1495 for (
unsigned channel = 0; channel < 128; channel++) {
1496 timeBase->append(scrodID, channel, timeAxis);
1507 void TOPDatabaseImporter::importTest()
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);
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);
1524 for (
const auto& gain : pmtGains) gain.print();
bool isValid() const
Check whether a valid object was obtained from the database.
Class for accessing arrays of objects in the database.
Class for importing array of objects to the database.
T * appendNew()
Construct a new T object at the end of the array.
int getEntries() const
Returns number of objects in the array.
bool import(const IntervalOfValidity &iov)
Import the object to database.
virtual void addEventDependency(unsigned int eventNumber)
add event dependency
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.
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.