Belle II Software  release-06-00-14
eclElectronicsPayloads.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 #include <framework/database/DBImportObjPtr.h>
10 #include <framework/database/DBObjPtr.h>
11 #include <framework/database/DBStore.h>
12 #include <framework/datastore/StoreObjPtr.h>
13 #include <framework/datastore/DataStore.h>
14 #include <framework/dataobjects/EventMetaData.h>
15 #include <framework/database/Configuration.h>
16 #include <framework/logging/LogSystem.h>
17 #include <ecl/dbobjects/ECLCrystalCalib.h>
18 #include <iostream>
19 #include <TFile.h>
20 #include <TH1F.h>
21 
22 using namespace Belle2;
23 
24 //------------------------------------------------------------------------
25 //..Set experiment, run, and event numbers before reading a payload from the DB
26 namespace {
27  void setupDatabase(int exp, int run, int eventNr = 1)
28  {
30  // simulate the initialize() phase where we can register objects in the DataStore
32  evtPtr.registerInDataStore();
34  std::cout << "about to construct EventMetaData, exp = " << exp << " run = " << run << " eventNr = " << eventNr << std::endl;
35  evtPtr.construct(eventNr, run, exp);
36  DBStore& dbstore = DBStore::Instance();
37  dbstore.update();
38  dbstore.updateEvent();
39  }
40 }
41 
42 //------------------------------------------------------------------------
43 int main(int argc, char** argv)
44 {
45  if (argc < 4 || argc > 5) {
46  std::cout << "insufficient arguments for eclElectronicsPayloads" << std::endl;
47  return -1;
48  }
49  std::string payloadName = argv[1];
50  if (payloadName != "ECLCrystalElectronics" and payloadName != "ECLCrystalElectronicsTime" and payloadName != "ECLRefAmplNom"
51  and payloadName != "ECLRefTimeNom") {
52  std::cout << "First argument must be ECLCrystalElectronics, ECLCrystalElectronicsTime, ECLRefAmplNom, or ECLRefTimeNom" <<
53  std::endl;
54  return -1;
55  }
56  int experiment = std::stoi(argv[2]);
57  int run = std::stoi(argv[3]);
58  bool writeOutput = true;
59  if (argc == 5) writeOutput = std::stoi(argv[4]);
60  std::cout << "eclElectronicsPayloads called with arguments " << payloadName << " " << experiment << " " << run << " " << writeOutput
61  << std::endl;
62 
63  //------------------------------------------------------------------------
64  //..Specify database
66  auto states = conf.getUsableTagStates();
67  states.insert("OPEN");
68  conf.setUsableTagStates(states);
69  conf.prependGlobalTag("ECL_localrun_data");
70  conf.prependTestingPayloadLocation("localdb/database.txt");
71 
72  //..set debug level
74  logging->setLogLevel(LogConfig::c_Debug);
75  logging->setDebugLevel(10);
76 
77  //..Populate database contents
78  std::cout << "calling setupDatabase " << std::endl;
79  setupDatabase(experiment, run);
80 
81  //------------------------------------------------------------------------
82  //..Read input and existing output payloads from database
83  DBObjPtr<Belle2::ECLCrystalCalib> existingObject(payloadName);
84  DBObjPtr<Belle2::ECLCrystalCalib> InputAmpl("ECLRefAmpl");
85  DBObjPtr<Belle2::ECLCrystalCalib> InputAmplNom("ECLRefAmplNom");
86  DBObjPtr<Belle2::ECLCrystalCalib> InputTime("ECLRefTime");
87  DBObjPtr<Belle2::ECLCrystalCalib> InputTimeNom("ECLRefTimeNom");
88  DBObjPtr<Belle2::ECLCrystalCalib> CurrentElec("ECLCrystalElectronics");
89  DBObjPtr<Belle2::ECLCrystalCalib> CurrentTime("ECLCrystalElectronicsTime");
90 
91  //..Print out some information about the existing payload
92  std::cout << "Reading ECLRefAmpl, ECLRefAmplNom, ECLRefTime, ECLRefTimeNom, ECLCrystalElectronics, and ECLCrystalElectronicsTime" <<
93  std::endl;
94  std::cout << "Dumping " << payloadName << std::endl;
95  existingObject->Dump();
96 
97  //..Get vectors of values from the payloads
98  std::vector<float> currentValues = existingObject->getCalibVector();
99  std::vector<float> currentUnc = existingObject->getCalibUncVector();
100 
101  std::vector<float> refAmpl = InputAmpl->getCalibVector();
102  std::vector<float> refAmplUnc = InputAmpl->getCalibUncVector();
103 
104  std::vector<float> refAmplNom = InputAmplNom->getCalibVector();
105 
106  std::vector<float> refTime = InputTime->getCalibVector();
107  std::vector<float> refTimeUnc = InputTime->getCalibUncVector();
108 
109  std::vector<float> refTimeNom = InputTimeNom->getCalibVector();
110 
111  std::vector<float> crysElec = CurrentElec->getCalibVector();
112 
113  std::vector<float> crysTime = CurrentTime->getCalibVector();
114 
115 
116  //..Print out a few values for quality control
117  std::cout << std::endl << "Reference amplitudes and times read from database " << std::endl;
118  for (int ic = 0; ic < 9000; ic += 1000) {
119  std::cout << "cellID " << ic + 1 << " ref amplitude = " << refAmpl[ic] << " +/- " << refAmplUnc[ic] << " nom = " << refAmplNom[ic]
120  << " ref time = " << refTime[ic]
121  << " +/- " << refTimeUnc[ic] << " nom = " << refTimeNom[ic] << std::endl;
122  }
123 
124  //------------------------------------------------------------------------
125  //..Calculate the new values for requested payload
126  std::vector<float> newValues;
127  std::vector<float> newUnc;
128  for (int ic = 0; ic < 8736; ic++) {
129  if (payloadName == "ECLCrystalElectronics") {
130  newValues.push_back(refAmplNom[ic] / refAmpl[ic]);
131  newUnc.push_back(newValues[ic]*refAmplUnc[ic] / refAmpl[ic]);
132  } else if (payloadName == "ECLCrystalElectronicsTime") {
133  newValues.push_back(refTime[ic] - refTimeNom[ic]);
134  newUnc.push_back(refTimeUnc[ic]);
135  } else if (payloadName == "ECLRefAmplNom") {
136  newValues.push_back(crysElec[ic]*refAmpl[ic]);
137  newUnc.push_back(0.);
138  } else if (payloadName == "ECLRefTimeNom") {
139  newValues.push_back(refTime[ic] - crysTime[ic]);
140  newUnc.push_back(0.);
141  }
142 
143  }
144 
145  //------------------------------------------------------------------------
146  //..Compare current values to new ones
147  std::cout << std::endl << "Comparison of existing and new values for " << payloadName << std::endl;
148  for (int ic = 0; ic < 9000; ic += 1000) {
149  std::cout << "cellID " << ic + 1 << " existing = " << currentValues[ic] << " +/- " << currentUnc[ic] << " new = " << newValues[ic]
150  << " +/- " << newUnc[ic] << std::endl;
151  }
152  std::cout << std::endl;
153 
154  TString payloadTitle = payloadName;
155  payloadTitle += "_";
156  payloadTitle += experiment;
157  payloadTitle += "_";
158  payloadTitle += run;
159  TString fname = payloadTitle;
160  fname += ".root";
161  TFile hfile(fname, "recreate");
162  TString htitle = payloadTitle;
163  htitle += " existing calibration values;cellID";
164  TH1F* existingCalib = new TH1F("existingCalib", htitle, 8736, 1, 8737);
165 
166  htitle = payloadTitle;
167  htitle += " new calibration values;cellID";
168  TH1F* newCalib = new TH1F("newCalib", htitle, 8736, 1, 8737);
169 
170  htitle = payloadTitle;
171  htitle += " ratio";
172  TH1F* calibRatio = new TH1F("calibRatio", htitle, 200, 0.9, 1.1);
173 
174  htitle = payloadTitle;
175  htitle += " difference";
176  TH1F* calibDiff = new TH1F("calibDiff", htitle, 200, -100, 100);
177 
178  htitle = payloadTitle;
179  htitle += " reference";
180  TH1F* refValues = new TH1F("refValues", htitle, 8736, 1, 8737);
181 
182  htitle = payloadTitle;
183  htitle += " ratio vs cellID;cellID;new/old";
184  TH1F* ratioVsCellID = new TH1F("ratioVsCellID", htitle, 8736, 1, 8737);
185 
186  htitle = payloadTitle;
187  htitle += " diff vs cellID;cellID;new - old";
188  TH1F* diffVsCellID = new TH1F("diffVsCellID", htitle, 8736, 1, 8737);
189 
190  for (int cellID = 1; cellID <= 8736; cellID++) {
191  float oldValue = currentValues[cellID - 1];
192  float newValue = newValues[cellID - 1];
193  float ratio = 9999.;
194  if (oldValue != 0.) {
195  ratio = newValue / oldValue;
196  } else if (newValue != 0.) {
197  ratio = ratio * newValue / fabs(newValue);
198  }
199 
200  existingCalib->SetBinContent(cellID, oldValue);
201  existingCalib->SetBinError(cellID, currentUnc[cellID - 1]);
202  newCalib->SetBinContent(cellID, newValue);
203  newCalib->SetBinError(cellID, newUnc[cellID - 1]);
204  calibRatio->Fill(ratio);
205  ratioVsCellID->SetBinContent(cellID, ratio);
206  ratioVsCellID->SetBinError(cellID, 0);
207  calibDiff->Fill(newValue - oldValue);
208  diffVsCellID->SetBinContent(cellID, newValue - oldValue);
209  diffVsCellID->SetBinError(cellID, 0);
210  if (payloadName == "ECLCrystalElectronics" or payloadName == "ECLRefAmplNom") {
211  refValues->SetBinContent(cellID, refAmpl[cellID - 1]);
212  refValues->SetBinError(cellID, refAmplUnc[cellID - 1]);
213  } else {
214  refValues->SetBinContent(cellID, refTime[cellID - 1]);
215  refValues->SetBinError(cellID, refTimeUnc[cellID - 1]);
216  }
217 
218  //..Note any large changes
219  if ((payloadName == "ECLCrystalElectronics" or payloadName == "ECLRefAmplNom") and (ratio<0.99 or ratio>1.01)) {
220  std::cout << "Ratio = " << ratio << " for cellID = " << cellID << " refAmpl = " << refAmpl[cellID - 1] << " refAmplNom = " <<
221  refAmplNom[cellID - 1] << std::endl;
222  } else if (abs(newValue - oldValue) > 20.) {
223  std::cout << "Difference = " << newValue - oldValue << " for cellID = " << cellID << " refTime = " << refTime[cellID - 1] <<
224  " refTimeNom = " << refTimeNom[cellID - 1] << std::endl;
225  }
226  }
227 
228  hfile.cd();
229  hfile.Write();
230  hfile.Close();
231  std::cout << std::endl << "Comparison of existing and new calibration values written to " << fname << std::endl;
232 
233  //------------------------------------------------------------------------
234  //..Write out to localdb if requested
235  if (writeOutput) {
236  std::cout << "Creating importer" << std::endl;
238  importer.construct();
239  importer->setCalibVector(newValues, newUnc);
240  importer.import(Belle2::IntervalOfValidity(experiment, run, -1, -1));
241  std::cout << "Successfully wrote payload " << payloadName << " with iov " << experiment << "," << run << ",-1,-1" << std::endl;
242  }
243 }
static Configuration & getInstance()
Get a reference to the instance which will be used when the Database is initialized.
Class for importing a single object to the database.
Singleton class to cache database objects.
Definition: DBStore.h:32
static DataStore & Instance()
Instance of singleton Store.
Definition: DataStore.cc:52
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition: DataStore.cc:92
A class that describes the interval of experiments/runs for which an object in the database is valid.
The LogConfig class.
Definition: LogConfig.h:22
@ c_Debug
Debug: for code development.
Definition: LogConfig.h:26
LogConfig * getLogConfig()
Returns global log system configuration.
Definition: LogSystem.h:78
static LogSystem & Instance()
Static method to get a reference to the LogSystem instance.
Definition: LogSystem.cc:31
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
bool construct(Args &&... params)
Construct an object of type T in this StoreObjPtr, using the provided constructor arguments.
Definition: StoreObjPtr.h:118
static DBStore & Instance()
Instance of a singleton DBStore.
Definition: DBStore.cc:26
void updateEvent()
Updates all intra-run dependent objects.
Definition: DBStore.cc:140
void update()
Updates all objects that are outside their interval of validity.
Definition: DBStore.cc:77
Abstract base class for different kinds of events.
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:75