Belle II Software  release-06-01-15
eclMergingCrystalEAlgorithm.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 #include <ecl/calibration/eclMergingCrystalEAlgorithm.h>
9 #include <ecl/dbobjects/ECLCrystalCalib.h>
10 #include "TH1F.h"
11 #include "TString.h"
12 #include "TFile.h"
13 #include "TDirectory.h"
14 
15 using namespace std;
16 using namespace Belle2;
17 using namespace ECL;
18 using namespace Calibration;
19 
21 eclMergingCrystalEAlgorithm::eclMergingCrystalEAlgorithm(): CalibrationAlgorithm("DummyCollector"),
22  m_existingGammaGamma("ECLCrystalEnergyGammaGamma"), m_existingMuMu("ECLCrystalEnergyMuMu"),
23  m_existing5x5("ECLCrystalEnergyee5x5"), m_existing(m_payloadName)
24 {
26  "Perform energy calibration of ecl crystals by combining previous values from the DB for different calibrations."
27  );
28 }
29 
31 {
32  //------------------------------------------------------------------------
33  // Get the input run list (should be only 1) for us to use to update the DBObjectPtrs
34  auto runs = getRunList();
35  // Take the first run
36  ExpRun chosenRun = runs.front();
37  B2INFO("merging using the ExpRun (" << chosenRun.second << "," << chosenRun.first << ")");
38  // After here your DBObjPtrs are correct
39  updateDBObjPtrs(1, chosenRun.second, chosenRun.first);
40 
41  //------------------------------------------------------------------------
42  // Test the DBObjects we want to exist and fail if not all of them do.
43  bool allObjectsFound = true;
44  // Test that the DBObjects are valid
45  if (!m_existingGammaGamma) {
46  allObjectsFound = false;
47  B2ERROR("No valid DBObject found for 'ECLCrystalEnergyGammaGamma'");
48  }
49  if (!m_existingMuMu) {
50  allObjectsFound = false;
51  B2ERROR("No valid DBObject found for 'ECLCrystalEnergyMuMu'");
52  }
53  if (!m_existing5x5) {
54  allObjectsFound = false;
55  B2ERROR("No valid DBObject found for 'ECLCrystalEnergyee5x5'");
56  }
57  if (!m_existing) {
58  allObjectsFound = false;
59  B2ERROR("No valid DBObject found for 'ECLCrystalEnergy'");
60  }
61 
62  if (allObjectsFound) {
63  B2INFO("Valid objects found for both 'ECLCrystalEnergy' and 'ECLCrystalEnergyGammaGamma'");
64  } else {
65  B2INFO("Exiting with failure");
66  return c_Failure;
67  }
68 
69  //------------------------------------------------------------------------
71  vector<float> gammaGammaCalib = m_existingGammaGamma->getCalibVector();
72  vector<float> gammaGammaCalibUnc = m_existingGammaGamma->getCalibUncVector();
73 
74  vector<float> existingCalib = m_existing->getCalibVector();
75  vector<float> existingCalibUnc = m_existing->getCalibUncVector();
76 
77  //------------------------------------------------------------------------
79  //..For now, use Gamma Gamma if available; otherwise, use existing value
80  vector<float> newCalib(m_numCrystals);
81  vector<float> newCalibUnc(m_numCrystals);
82 
83  for (int ic = 0; ic < m_numCrystals; ic++) {
84  if (gammaGammaCalib[ic] > 0.) {
85  newCalib[ic] = gammaGammaCalib[ic];
86  newCalibUnc[ic] = gammaGammaCalibUnc[ic];
87  } else {
88  newCalib[ic] = existingCalib[ic];
89  newCalibUnc[ic] = existingCalibUnc[ic];
90  }
91  }
92 
93  //------------------------------------------------------------------------
95  for (int ic = 0; ic < 9000; ic += 1000) {
96  B2INFO(ic + 1 << " " << existingCalib[ic] << " " << existingCalibUnc[ic] << " "
97  << gammaGammaCalib[ic] << " " << gammaGammaCalibUnc[ic] << " "
98  << newCalib[ic] << " " << newCalibUnc[ic]);
99  }
100 
101  //------------------------------------------------------------------------
102  //..Histograms of existing calibration, new calibration, and ratio new/old
103 
104  // Just in case, we remember the current TDirectory so we can return to it
105  TDirectory* executeDir = gDirectory;
106 
107  TString fname = m_payloadName;
108  fname += ".root";
109  TFile hfile(fname, "recreate");
110 
111  TString htitle = m_payloadName;
112  htitle += " existing values;cellID";
113  TH1F* existingPayload = new TH1F("existingPayload", htitle, m_numCrystals, 1, 8737);
114 
115  htitle = m_payloadName;
116  htitle += " new values;cellID";
117  TH1F* newPayload = new TH1F("newPayload", htitle, m_numCrystals, 1, 8737);
118 
119  htitle = m_payloadName;
120  htitle += " ratio new/old;cellID";
121  TH1F* payloadRatioVsCellID = new TH1F("payloadRatioVsCellID", htitle, m_numCrystals, 1, 8737);
122 
123  htitle = m_payloadName;
124  htitle += " ratio new/old";
125  TH1F* payloadRatio = new TH1F("payloadRatio", htitle, 200, 0.95, 1.05);
126 
127  for (int cellID = 1; cellID <= m_numCrystals; cellID++) {
128  existingPayload->SetBinContent(cellID, existingCalib[cellID - 1]);
129  existingPayload->SetBinError(cellID, existingCalibUnc[cellID - 1]);
130 
131  newPayload->SetBinContent(cellID, newCalib[cellID - 1]);
132  newPayload->SetBinError(cellID, newCalibUnc[cellID - 1]);
133 
134  float ratio = 1.;
135  float ratioUnc = 0.;
136  if (abs(existingCalib[cellID - 1]) > 1.0e-12) {
137  ratio = newCalib[cellID - 1] / existingCalib[cellID - 1];
138  float rUnc0 = existingCalibUnc[cellID - 1] / existingCalib[cellID - 1];
139  float rUnc1 = 0.;
140  if (abs(newCalib[cellID - 1]) > 1.0e-12) {rUnc1 = newCalibUnc[cellID - 1] / newCalib[cellID - 1];}
141  ratioUnc = ratio * sqrt(rUnc0 * rUnc0 + rUnc1 * rUnc1);
142  }
143 
144  payloadRatioVsCellID->SetBinContent(cellID, ratio);
145  payloadRatioVsCellID->SetBinError(cellID, ratioUnc);
146 
147  payloadRatio->Fill(ratio);
148  }
149  hfile.cd();
150  hfile.Write();
151  hfile.Close();
152  B2INFO("Debugging histograms written to " << fname);
153  // Go back to original TDirectory
154  executeDir->cd();
155 
156  ECLCrystalCalib* newCrystalEnergy = new ECLCrystalCalib();
157  newCrystalEnergy->setCalibVector(newCalib, newCalibUnc);
158  saveCalibration(newCrystalEnergy, m_payloadName);
159  return c_OK;
160 }
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
@ c_Failure
Failed =3 in Python.
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
General DB object to store one calibration number per ECL crystal.
void setCalibVector(const std::vector< float > &CalibConst, const std::vector< float > &CalibConstUnc)
Set vector of constants with uncertainties.
DBObjPtr< ECLCrystalCalib > m_existing5x5
ECLCrystalEnergyee5x5 payloads that we want to read from the DB.
DBObjPtr< ECLCrystalCalib > m_existing
ECLCrystalEnergy payloads that we want to read from the DB.
const std::string m_payloadName
The output payload name.
DBObjPtr< ECLCrystalCalib > m_existingGammaGamma
ECLCrystalEnergyGammaGamma payloads that we want to read from the DB.
const int m_numCrystals
Number of Crystals expected.
virtual EResult calibrate() override
..Run algorithm
DBObjPtr< ECLCrystalCalib > m_existingMuMu
ECLCrystalEnergyMuMu payloads that we want to read from the DB.
Abstract base class for different kinds of events.
Struct containing exp number and run number.
Definition: Splitter.h:51