Belle II Software development
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
30using namespace Belle2;
31
32//------------------------------------------------------------------------
33//..Set experiment, run, and event numbers before reading a payload from the DB
34namespace {
35 void setupDatabase(int exp, int run, int eventNr = 1)
36 {
38 // simulate the initialize() phase where we can register objects in the DataStore
40 evtPtr.registerInDataStore();
42 std::cout << "about to construct EventMetaData, exp = " << exp << " run = " << run << " eventNr = " << eventNr << std::endl;
43 evtPtr.construct(eventNr, run, exp);
44 DBStore& dbstore = DBStore::Instance();
45 dbstore.update();
46 dbstore.updateEvent();
47 }
48}
49
50//------------------------------------------------------------------------
51int main(int argc, char** argv)
52{
53 if (argc < 4 || argc > 5) {
54 std::cout << "insufficient arguments for eclElectronicsPayloads" << std::endl;
55 return -1;
56 }
57 std::string payloadName = argv[1];
58 if (payloadName != "ECLCrystalElectronics" and payloadName != "ECLCrystalElectronicsTime" and payloadName != "ECLRefAmplNom"
59 and payloadName != "ECLRefTimeNom") {
60 std::cout << "First argument must be ECLCrystalElectronics, ECLCrystalElectronicsTime, ECLRefAmplNom, or ECLRefTimeNom" <<
61 std::endl;
62 return -1;
63 }
64 int experiment = std::stoi(argv[2]);
65 int run = std::stoi(argv[3]);
66 bool writeOutput = true;
67 if (argc == 5) writeOutput = std::stoi(argv[4]);
68 std::cout << "eclElectronicsPayloads called with arguments " << payloadName << " " << experiment << " " << run << " " << writeOutput
69 << std::endl;
70
71 //------------------------------------------------------------------------
72 //..Specify database
74 auto states = conf.getUsableTagStates();
75 states.insert("OPEN");
76 conf.setUsableTagStates(states);
77 conf.prependGlobalTag("ECL_localrun_data");
78 conf.prependTestingPayloadLocation("localdb/database.txt");
79
80 //..set debug level
83 logging->setDebugLevel(10);
84
85 //..Populate database contents
86 std::cout << "calling setupDatabase " << std::endl;
87 setupDatabase(experiment, run);
88
89 //------------------------------------------------------------------------
90 //..Read input and existing output payloads from database
91 DBObjPtr<Belle2::ECLCrystalCalib> existingObject(payloadName);
92 DBObjPtr<Belle2::ECLCrystalCalib> InputAmpl("ECLRefAmpl");
93 DBObjPtr<Belle2::ECLCrystalCalib> InputAmplNom("ECLRefAmplNom");
94 DBObjPtr<Belle2::ECLCrystalCalib> InputTime("ECLRefTime");
95 DBObjPtr<Belle2::ECLCrystalCalib> InputTimeNom("ECLRefTimeNom");
96 DBObjPtr<Belle2::ECLCrystalCalib> CurrentElec("ECLCrystalElectronics");
97 DBObjPtr<Belle2::ECLCrystalCalib> CurrentTime("ECLCrystalElectronicsTime");
98
99 //..Print out some information about the existing payload
100 std::cout << "Reading ECLRefAmpl, ECLRefAmplNom, ECLRefTime, ECLRefTimeNom, ECLCrystalElectronics, and ECLCrystalElectronicsTime" <<
101 std::endl;
102 std::cout << "Dumping " << payloadName << std::endl;
103 existingObject->Dump();
104
105 //..Get vectors of values from the payloads
106 std::vector<float> currentValues = existingObject->getCalibVector();
107 std::vector<float> currentUnc = existingObject->getCalibUncVector();
108
109 std::vector<float> refAmpl = InputAmpl->getCalibVector();
110 std::vector<float> refAmplUnc = InputAmpl->getCalibUncVector();
111
112 std::vector<float> refAmplNom = InputAmplNom->getCalibVector();
113
114 std::vector<float> refTime = InputTime->getCalibVector();
115 std::vector<float> refTimeUnc = InputTime->getCalibUncVector();
116
117 std::vector<float> refTimeNom = InputTimeNom->getCalibVector();
118
119 std::vector<float> crysElec = CurrentElec->getCalibVector();
120
121 std::vector<float> crysTime = CurrentTime->getCalibVector();
122
123
124 //..Print out a few values for quality control
125 std::cout << std::endl << "Reference amplitudes and times read from database " << std::endl;
126 for (int ic = 0; ic < 9000; ic += 1000) {
127 std::cout << "cellID " << ic + 1 << " ref amplitude = " << refAmpl[ic] << " +/- " << refAmplUnc[ic] << " nom = " << refAmplNom[ic]
128 << " ref time = " << refTime[ic]
129 << " +/- " << refTimeUnc[ic] << " nom = " << refTimeNom[ic] << std::endl;
130 }
131
132 //------------------------------------------------------------------------
133 //..Calculate the new values for requested payload
134 std::vector<float> newValues;
135 std::vector<float> newUnc;
136 for (int ic = 0; ic < ECLElementNumbers::c_NCrystals; ic++) {
137 if (payloadName == "ECLCrystalElectronics") {
138 newValues.push_back(refAmplNom[ic] / refAmpl[ic]);
139 newUnc.push_back(newValues[ic]*refAmplUnc[ic] / refAmpl[ic]);
140 } else if (payloadName == "ECLCrystalElectronicsTime") {
141 newValues.push_back(refTime[ic] - refTimeNom[ic]);
142 newUnc.push_back(refTimeUnc[ic]);
143 } else if (payloadName == "ECLRefAmplNom") {
144 newValues.push_back(crysElec[ic]*refAmpl[ic]);
145 newUnc.push_back(0.);
146 } else if (payloadName == "ECLRefTimeNom") {
147 newValues.push_back(refTime[ic] - crysTime[ic]);
148 newUnc.push_back(0.);
149 }
150
151 }
152
153 //------------------------------------------------------------------------
154 //..Compare current values to new ones
155 std::cout << std::endl << "Comparison of existing and new values for " << payloadName << std::endl;
156 for (int ic = 0; ic < 9000; ic += 1000) {
157 std::cout << "cellID " << ic + 1 << " existing = " << currentValues[ic] << " +/- " << currentUnc[ic] << " new = " << newValues[ic]
158 << " +/- " << newUnc[ic] << std::endl;
159 }
160 std::cout << std::endl;
161
162 TString payloadTitle = payloadName;
163 payloadTitle += "_";
164 payloadTitle += experiment;
165 payloadTitle += "_";
166 payloadTitle += run;
167 TString fname = payloadTitle;
168 fname += ".root";
169 TFile hfile(fname, "recreate");
170 TString htitle = payloadTitle;
171 htitle += " existing calibration values;cellID";
172 TH1F* existingCalib = new TH1F("existingCalib", htitle, ECLElementNumbers::c_NCrystals, 1, 8737);
173
174 htitle = payloadTitle;
175 htitle += " new calibration values;cellID";
176 TH1F* newCalib = new TH1F("newCalib", htitle, ECLElementNumbers::c_NCrystals, 1, 8737);
177
178 htitle = payloadTitle;
179 htitle += " ratio";
180 TH1F* calibRatio = new TH1F("calibRatio", htitle, 200, 0.9, 1.1);
181
182 htitle = payloadTitle;
183 htitle += " difference";
184 TH1F* calibDiff = new TH1F("calibDiff", htitle, 200, -100, 100);
185
186 htitle = payloadTitle;
187 htitle += " reference";
188 TH1F* refValues = new TH1F("refValues", htitle, ECLElementNumbers::c_NCrystals, 1, 8737);
189
190 htitle = payloadTitle;
191 htitle += " ratio vs cellID;cellID;new/old";
192 TH1F* ratioVsCellID = new TH1F("ratioVsCellID", htitle, ECLElementNumbers::c_NCrystals, 1, 8737);
193
194 htitle = payloadTitle;
195 htitle += " diff vs cellID;cellID;new - old";
196 TH1F* diffVsCellID = new TH1F("diffVsCellID", htitle, ECLElementNumbers::c_NCrystals, 1, 8737);
197
198 for (int cellID = 1; cellID <= ECLElementNumbers::c_NCrystals; cellID++) {
199 float oldValue = currentValues[cellID - 1];
200 float newValue = newValues[cellID - 1];
201 float ratio = 9999.;
202 if (oldValue != 0.) {
203 ratio = newValue / oldValue;
204 } else if (newValue != 0.) {
205 ratio = ratio * newValue / fabs(newValue);
206 }
207
208 existingCalib->SetBinContent(cellID, oldValue);
209 existingCalib->SetBinError(cellID, currentUnc[cellID - 1]);
210 newCalib->SetBinContent(cellID, newValue);
211 newCalib->SetBinError(cellID, newUnc[cellID - 1]);
212 calibRatio->Fill(ratio);
213 ratioVsCellID->SetBinContent(cellID, ratio);
214 ratioVsCellID->SetBinError(cellID, 0);
215 calibDiff->Fill(newValue - oldValue);
216 diffVsCellID->SetBinContent(cellID, newValue - oldValue);
217 diffVsCellID->SetBinError(cellID, 0);
218 if (payloadName == "ECLCrystalElectronics" or payloadName == "ECLRefAmplNom") {
219 refValues->SetBinContent(cellID, refAmpl[cellID - 1]);
220 refValues->SetBinError(cellID, refAmplUnc[cellID - 1]);
221 } else {
222 refValues->SetBinContent(cellID, refTime[cellID - 1]);
223 refValues->SetBinError(cellID, refTimeUnc[cellID - 1]);
224 }
225
226 //..Note any large changes
227 if ((payloadName == "ECLCrystalElectronics" or payloadName == "ECLRefAmplNom") and (ratio<0.99 or ratio>1.01)) {
228 std::cout << "Ratio = " << ratio << " for cellID = " << cellID << " refAmpl = " << refAmpl[cellID - 1] << " refAmplNom = " <<
229 refAmplNom[cellID - 1] << std::endl;
230 } else if (abs(newValue - oldValue) > 20.) {
231 std::cout << "Difference = " << newValue - oldValue << " for cellID = " << cellID << " refTime = " << refTime[cellID - 1] <<
232 " refTimeNom = " << refTimeNom[cellID - 1] << std::endl;
233 }
234 }
235
236 hfile.cd();
237 hfile.Write();
238 hfile.Close();
239 std::cout << std::endl << "Comparison of existing and new calibration values written to " << fname << std::endl;
240
241 //------------------------------------------------------------------------
242 //..Write out to localdb if requested
243 if (writeOutput) {
244 std::cout << "Creating importer" << std::endl;
246 importer.construct();
247 importer->setCalibVector(newValues, newUnc);
248 importer.import(Belle2::IntervalOfValidity(experiment, run, -1, -1));
249 std::cout << "Successfully wrote payload " << payloadName << " with iov " << experiment << "," << run << ",-1,-1" << std::endl;
250 }
251}
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.
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
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.