Belle II Software  release-08-02-06
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 /* ECL headers. */
10 #include <ecl/dataobjects/ECLElementNumbers.h>
11 #include <ecl/dbobjects/ECLCrystalCalib.h>
12 
13 /* Basf2 headers. */
14 #include <framework/database/Configuration.h>
15 #include <framework/database/DBImportObjPtr.h>
16 #include <framework/database/DBObjPtr.h>
17 #include <framework/database/DBStore.h>
18 #include <framework/dataobjects/EventMetaData.h>
19 #include <framework/datastore/DataStore.h>
20 #include <framework/datastore/StoreObjPtr.h>
21 #include <framework/logging/LogSystem.h>
22 
23 /* ROOT headers. */
24 #include <TFile.h>
25 #include <TH1F.h>
26 
27 /* C++ headers. */
28 #include <iostream>
29 
30 using namespace Belle2;
31 
32 
33 //------------------------------------------------------------------------
34 // eclElectronicsPayloads.cc produces payloads ECLCrystalElectronics or
35 // ECLCrystalElectronicsTime using payloads ECLRefAmpl, ECLRefTime,
36 // ECLRefAmplNom, and ECLRefTimeNom, which must be present in the specified
37 // global tag. The payloads are written to subdirectory localdb.
38 
39 // Usage to produce payload ECLCrystalElectronics or ECLCrystalElectronicsTime:
40 // eclElectronicsPayloads ECLCrystalElectronics[Time] experiment run
41 // global_tag [iWrite]
42 // Set optional argument iWrite = 0 to disable the writing of the payload.
43 
44 // Diagnostic histograms are written to a root file.
45 
46 // Code can also find payloads ECLRefAmplNom or ECLRefTimeNom. This option
47 // is rarely used.
48 
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 < 5 || argc > 6) {
72  std::cout << "incorrected number of 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  std::string globalTag = argv[4];
85  bool writeOutput = true;
86  if (argc == 6) writeOutput = std::stoi(argv[5]);
87  std::cout << "eclElectronicsPayloads called with arguments " << payloadName << " " << experiment << " " << run << " " << globalTag
88  << " " << writeOutput << std::endl;
89 
90  //------------------------------------------------------------------------
91  //..Specify database
93  auto states = conf.getUsableTagStates();
94  states.insert("OPEN");
95  conf.setUsableTagStates(states);
96  conf.prependGlobalTag(globalTag);
97  conf.prependTestingPayloadLocation("localdb/database.txt");
98 
99  //..set debug level
102  logging->setDebugLevel(10);
103 
104  //..Populate database contents
105  std::cout << "calling setupDatabase " << std::endl;
106  setupDatabase(experiment, run);
107 
108  //------------------------------------------------------------------------
109  //..Read input and existing output payloads from database
110  DBObjPtr<Belle2::ECLCrystalCalib> existingObject(payloadName);
111  DBObjPtr<Belle2::ECLCrystalCalib> InputAmpl("ECLRefAmpl");
112  DBObjPtr<Belle2::ECLCrystalCalib> InputAmplNom("ECLRefAmplNom");
113  DBObjPtr<Belle2::ECLCrystalCalib> InputTime("ECLRefTime");
114  DBObjPtr<Belle2::ECLCrystalCalib> InputTimeNom("ECLRefTimeNom");
115  DBObjPtr<Belle2::ECLCrystalCalib> CurrentElec("ECLCrystalElectronics");
116  DBObjPtr<Belle2::ECLCrystalCalib> CurrentTime("ECLCrystalElectronicsTime");
117 
118  //..Print out some information about the existing payload
119  std::cout << "Reading ECLRefAmpl, ECLRefAmplNom, ECLRefTime, ECLRefTimeNom, ECLCrystalElectronics, and ECLCrystalElectronicsTime" <<
120  std::endl;
121  std::cout << "Dumping " << payloadName << std::endl;
122  existingObject->Dump();
123 
124  //..Get vectors of values from the payloads
125  std::vector<float> currentValues = existingObject->getCalibVector();
126  std::vector<float> currentUnc = existingObject->getCalibUncVector();
127 
128  std::vector<float> refAmpl = InputAmpl->getCalibVector();
129  std::vector<float> refAmplUnc = InputAmpl->getCalibUncVector();
130 
131  std::vector<float> refAmplNom = InputAmplNom->getCalibVector();
132 
133  std::vector<float> refTime = InputTime->getCalibVector();
134  std::vector<float> refTimeUnc = InputTime->getCalibUncVector();
135 
136  std::vector<float> refTimeNom = InputTimeNom->getCalibVector();
137 
138  std::vector<float> crysElec = CurrentElec->getCalibVector();
139 
140  std::vector<float> crysTime = CurrentTime->getCalibVector();
141 
142 
143  //..Print out a few values for quality control
144  std::cout << std::endl << "Reference amplitudes and times read from database " << std::endl;
145  for (int ic = 0; ic < 9000; ic += 1000) {
146  std::cout << "cellID " << ic + 1 << " ref amplitude = " << refAmpl[ic] << " +/- " << refAmplUnc[ic] << " nom = " << refAmplNom[ic]
147  << " ref time = " << refTime[ic]
148  << " +/- " << refTimeUnc[ic] << " nom = " << refTimeNom[ic] << std::endl;
149  }
150 
151  //------------------------------------------------------------------------
152  //..Calculate the new values for requested payload
153  std::vector<float> newValues;
154  std::vector<float> newUnc;
155  for (int ic = 0; ic < ECLElementNumbers::c_NCrystals; ic++) {
156  if (payloadName == "ECLCrystalElectronics") {
157  newValues.push_back(refAmplNom[ic] / refAmpl[ic]);
158  newUnc.push_back(newValues[ic]*refAmplUnc[ic] / refAmpl[ic]);
159  } else if (payloadName == "ECLCrystalElectronicsTime") {
160  newValues.push_back(refTime[ic] - refTimeNom[ic]);
161  newUnc.push_back(refTimeUnc[ic]);
162  } else if (payloadName == "ECLRefAmplNom") {
163  newValues.push_back(crysElec[ic]*refAmpl[ic]);
164  newUnc.push_back(0.);
165  } else if (payloadName == "ECLRefTimeNom") {
166  newValues.push_back(refTime[ic] - crysTime[ic]);
167  newUnc.push_back(0.);
168  }
169 
170  }
171 
172  //------------------------------------------------------------------------
173  //..Compare current values to new ones
174  std::cout << std::endl << "Comparison of existing and new values for " << payloadName << std::endl;
175  for (int ic = 0; ic < 9000; ic += 1000) {
176  std::cout << "cellID " << ic + 1 << " existing = " << currentValues[ic] << " +/- " << currentUnc[ic] << " new = " << newValues[ic]
177  << " +/- " << newUnc[ic] << std::endl;
178  }
179  std::cout << std::endl;
180 
181  TString payloadTitle = payloadName;
182  payloadTitle += "_";
183  payloadTitle += experiment;
184  payloadTitle += "_";
185  payloadTitle += run;
186  TString fname = payloadTitle;
187  fname += ".root";
188  TFile hfile(fname, "recreate");
189  TString htitle = payloadTitle;
190  htitle += " existing calibration values;cellID";
191  TH1F* existingCalib = new TH1F("existingCalib", htitle, ECLElementNumbers::c_NCrystals, 1, 8737);
192 
193  htitle = payloadTitle;
194  htitle += " new calibration values;cellID";
195  TH1F* newCalib = new TH1F("newCalib", htitle, ECLElementNumbers::c_NCrystals, 1, 8737);
196 
197  htitle = payloadTitle;
198  htitle += " ratio";
199  TH1F* calibRatio = new TH1F("calibRatio", htitle, 200, 0.9, 1.1);
200 
201  htitle = payloadTitle;
202  htitle += " difference";
203  TH1F* calibDiff = new TH1F("calibDiff", htitle, 200, -100, 100);
204 
205  htitle = payloadTitle;
206  htitle += " reference";
207  TH1F* refValues = new TH1F("refValues", htitle, ECLElementNumbers::c_NCrystals, 1, 8737);
208 
209  htitle = payloadTitle;
210  htitle += " ratio vs cellID;cellID;new/old";
211  TH1F* ratioVsCellID = new TH1F("ratioVsCellID", htitle, ECLElementNumbers::c_NCrystals, 1, 8737);
212 
213  htitle = payloadTitle;
214  htitle += " diff vs cellID;cellID;new - old";
215  TH1F* diffVsCellID = new TH1F("diffVsCellID", htitle, ECLElementNumbers::c_NCrystals, 1, 8737);
216 
217  for (int cellID = 1; cellID <= ECLElementNumbers::c_NCrystals; cellID++) {
218  float oldValue = currentValues[cellID - 1];
219  float newValue = newValues[cellID - 1];
220  float ratio = 9999.;
221  if (oldValue != 0.) {
222  ratio = newValue / oldValue;
223  } else if (newValue != 0.) {
224  ratio = ratio * newValue / fabs(newValue);
225  }
226 
227  existingCalib->SetBinContent(cellID, oldValue);
228  existingCalib->SetBinError(cellID, currentUnc[cellID - 1]);
229  newCalib->SetBinContent(cellID, newValue);
230  newCalib->SetBinError(cellID, newUnc[cellID - 1]);
231  calibRatio->Fill(ratio);
232  ratioVsCellID->SetBinContent(cellID, ratio);
233  ratioVsCellID->SetBinError(cellID, 0);
234  calibDiff->Fill(newValue - oldValue);
235  diffVsCellID->SetBinContent(cellID, newValue - oldValue);
236  diffVsCellID->SetBinError(cellID, 0);
237  if (payloadName == "ECLCrystalElectronics" or payloadName == "ECLRefAmplNom") {
238  refValues->SetBinContent(cellID, refAmpl[cellID - 1]);
239  refValues->SetBinError(cellID, refAmplUnc[cellID - 1]);
240  } else {
241  refValues->SetBinContent(cellID, refTime[cellID - 1]);
242  refValues->SetBinError(cellID, refTimeUnc[cellID - 1]);
243  }
244 
245  //..Note any large changes
246  if ((payloadName == "ECLCrystalElectronics" or payloadName == "ECLRefAmplNom") and (ratio<0.99 or ratio>1.01)) {
247  std::cout << "Ratio = " << ratio << " for cellID = " << cellID << " refAmpl = " << refAmpl[cellID - 1] << " refAmplNom = " <<
248  refAmplNom[cellID - 1] << std::endl;
249  } else if (abs(newValue - oldValue) > 20.) {
250  std::cout << "Difference = " << newValue - oldValue << " for cellID = " << cellID << " refTime = " << refTime[cellID - 1] <<
251  " refTimeNom = " << refTimeNom[cellID - 1] << std::endl;
252  }
253  }
254 
255  hfile.cd();
256  hfile.Write();
257  hfile.Close();
258  std::cout << std::endl << "Comparison of existing and new calibration values written to " << fname << std::endl;
259 
260  //------------------------------------------------------------------------
261  //..Write out to localdb if requested
262  if (writeOutput) {
263  std::cout << "Creating importer" << std::endl;
265  importer.construct();
266  importer->setCalibVector(newValues, newUnc);
267  importer.import(Belle2::IntervalOfValidity(experiment, run, -1, -1));
268  std::cout << "Successfully wrote payload " << payloadName << " with iov " << experiment << "," << run << ",-1,-1" << std::endl;
269  }
270 }
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:31
static DataStore & Instance()
Instance of singleton Store.
Definition: DataStore.cc:54
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition: DataStore.cc:94
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
void setDebugLevel(int debugLevel)
Configure the debug messaging level.
Definition: LogConfig.h:98
@ c_Debug
Debug: for code development.
Definition: LogConfig.h:26
void setLogLevel(ELogLevel logLevel)
Configure the log level.
Definition: LogConfig.cc:25
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:96
bool construct(Args &&... params)
Construct an object of type T in this StoreObjPtr, using the provided constructor arguments.
Definition: StoreObjPtr.h:119
static DBStore & Instance()
Instance of a singleton DBStore.
Definition: DBStore.cc:28
void updateEvent()
Updates all intra-run dependent objects.
Definition: DBStore.cc:142
void update()
Updates all objects that are outside their interval of validity.
Definition: DBStore.cc:79
const int c_NCrystals
Number of crystals.
Abstract base class for different kinds of events.
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:91