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