Belle II Software  release-05-02-19
TOPModuleT0LLAlgorithm.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2019 - Belle II Collaboration *
4  * *
5  * *
6  * Author: The Belle II Collaboration *
7  * Contributors: Marko Staric *
8  * *
9  * This software is provided "as is" without any warranty. *
10  **************************************************************************/
11 
12 #include <top/calibration/TOPModuleT0LLAlgorithm.h>
13 #include <top/dbobjects/TOPCalModuleT0.h>
14 #include <top/utilities/Chi2MinimumFinder1D.h>
15 
16 #include <math.h>
17 #include <TFile.h>
18 #include <TH1F.h>
19 #include <TH1D.h>
20 #include <TH2F.h>
21 
22 #include <string>
23 #include <vector>
24 
25 using namespace std;
26 
27 namespace Belle2 {
32  namespace TOP {
33 
34  TOPModuleT0LLAlgorithm::TOPModuleT0LLAlgorithm():
35  CalibrationAlgorithm("TOPModuleT0LLCollector")
36  {
37  setDescription("Calibration algorithm for method LL");
38  }
39 
41  {
42  // get basic histogram
43 
44  auto h1 = getObjectPtr<TH2F>("tracks_per_slot");
45  if (not h1) {
46  B2ERROR("TOPModuleT0LLAlgorithm: histogram 'tracks_per_slot' not found");
47  return c_Failure;
48  }
49  unsigned numModules = h1->GetNbinsX();
50  unsigned numSets = h1->GetNbinsY();
51 
52  // construct file name, open output root file
53 
54  const auto& expRun = getRunList();
55  string expNo = to_string(expRun[0].first);
56  while (expNo.length() < 4) expNo.insert(0, "0");
57  string runNo = to_string(expRun[0].second);
58  while (runNo.length() < 5) runNo.insert(0, "0");
59  string outputFileName = "moduleT0_final-e" + expNo + "-r" + runNo + ".root";
60  auto* file = TFile::Open(outputFileName.c_str(), "recreate");
61 
62  // write-out input histograms
63 
64  h1->Write();
65  auto h2 = getObjectPtr<TH1F>("numHits");
66  if (h2) h2->Write();
67  auto h3 = getObjectPtr<TH2F>("timeHits");
68  if (h3) h3->Write();
69  auto h4 = getObjectPtr<TH1F>("offset");
70  if (h4) h4->Write();
71 
72  // create histogram of pulls which is needed for error rescaling
73 
74  auto h_pulls = new TH1F("pulls", "Pulls of statistically independent results",
75  200, -15.0, 15.0);
76  h_pulls->SetXTitle("pulls");
77 
78  // create vectors for keeping the results
79 
80  std::vector<double> T0(numModules, 0);
81  std::vector<double> errT0(numModules, 0);
82 
83  // find minimum for each slot
84 
85  bool ok = true;
86  for (unsigned slot = 1; slot <= numModules; slot++) {
87 
88  Chi2MinimumFinder1D slotFinder;
89  std::vector<double> pos, err;
90 
91  // loop over statistically independent subsamples, add them
92  for (unsigned set = 0; set < numSets; set++) {
93 
94  if (h1->GetBinContent(slot, set + 1) == 0) continue;
95 
96  string name = "chi2_set" + to_string(set) + "_slot" + to_string(slot);
97  auto h = getObjectPtr<TH1D>(name);
98  if (not h) {
99  B2ERROR("TOPModuleT0LLAlgorithm: histogram '" << name << "' not found");
100  continue;
101  }
102  Chi2MinimumFinder1D setFinder(h);
103  if (slotFinder.getNbins() == 0) {
104  slotFinder = setFinder;
105  } else {
106  slotFinder.add(setFinder);
107  }
108  const auto& minimum = setFinder.getMinimum();
109  if (not minimum.valid) continue;
110  pos.push_back(minimum.position);
111  err.push_back(minimum.error);
112  }
113 
114  // fill pulls
115  for (unsigned i = 0; i < pos.size(); i++) {
116  for (unsigned j = i + 1; j < pos.size(); j++) {
117  double pull = (pos[i] - pos[j]) / sqrt(err[i] * err[i] + err[j] * err[j]);
118  h_pulls->Fill(pull);
119  }
120  }
121 
122  // determine minimum and store it
123  const auto& minimum = slotFinder.getMinimum();
124  if (minimum.valid) {
125  T0[slot - 1] = minimum.position;
126  errT0[slot - 1] = minimum.error;
127  } else {
128  B2ERROR("TOPModuleT0Algorithm: no minimum found for slot " << slot);
129  ok = false;
130  }
131 
132  // write-out histogram of a chi2 scan
133  string name = "chi2_slot_" + to_string(slot);
134  string title = "chi2 scan, slot " + to_string(slot) + "; t0 [ns]; -2 logL";
135  auto h = slotFinder.getHistogram(name, title);
136  h.Write();
137  }
138 
139  // rescale the errors
140 
141  if (h_pulls->GetEntries() > 1) {
142  double scaleError = h_pulls->GetRMS();
143  for (auto& err : errT0) err *= scaleError;
144  }
145 
146  // store the results in a histogram
147 
148  auto* h_moduleT0 = new TH1F("moduleT0", "Module T0", 16, 0.5, 16.5);
149  h_moduleT0->SetXTitle("slot number");
150  h_moduleT0->SetYTitle("module T0 [ns]");
151  for (unsigned i = 0; i < T0.size(); i++) {
152  h_moduleT0->SetBinContent(i + 1, T0[i]);
153  h_moduleT0->SetBinError(i + 1, errT0[i]);
154  }
155 
156  // write the results and close the file
157 
158  file->Write();
159  file->Close();
160 
161  // check the results and return if not good enough
162 
163  if (not ok) return c_Failure;
164  for (auto err : errT0) {
165  if (err > m_minError) return c_NotEnoughData;
166  }
167 
168  // otherwise create and import payload to DB
169 
170  auto* moduleT0 = new TOPCalModuleT0();
171  for (unsigned i = 0; i < T0.size(); i++) {
172  moduleT0->setT0(i + 1, T0[i], errT0[i]);
173  }
174  moduleT0->suppressAverage();
175  saveCalibration(moduleT0);
176 
177  return c_OK;
178  }
179 
180  } // end namespace TOP
182 } // end namespace Belle2
Belle2::TOP::Chi2MinimumFinder1D::getHistogram
TH1F getHistogram(std::string name, std::string title) const
Returns chi^2 packed into 1D histogram.
Definition: Chi2MinimumFinder1D.cc:135
Belle2::CalibrationAlgorithm::saveCalibration
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
Definition: CalibrationAlgorithm.cc:290
Belle2::TOP::Chi2MinimumFinder1D
Minimum finder using tabulated chi^2 values in one dimension.
Definition: Chi2MinimumFinder1D.h:37
Belle2::CalibrationAlgorithm::c_OK
@ c_OK
Finished successfuly =0 in Python.
Definition: CalibrationAlgorithm.h:51
Belle2::CalibrationAlgorithm::setDescription
void setDescription(const std::string &description)
Set algorithm description (in constructor)
Definition: CalibrationAlgorithm.h:331
Belle2::TOP::TOPModuleT0LLAlgorithm::m_minError
double m_minError
minimal moduleT0 uncertainty [ns] to declare c_OK
Definition: TOPModuleT0LLAlgorithm.h:58
Belle2::TOP::Chi2MinimumFinder1D::getMinimum
const Minimum & getMinimum()
Returns parabolic minimum.
Definition: Chi2MinimumFinder1D.h:147
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::CalibrationAlgorithm::c_Failure
@ c_Failure
Failed =3 in Python.
Definition: CalibrationAlgorithm.h:54
Belle2::CalibrationAlgorithm::EResult
EResult
The result of calibration.
Definition: CalibrationAlgorithm.h:50
Belle2::CalibrationAlgorithm::getRunList
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
Definition: CalibrationAlgorithm.h:276
Belle2::TOP::Chi2MinimumFinder1D::add
void add(unsigned i, double chi2)
Add chi^2 value to bin i.
Definition: Chi2MinimumFinder1D.cc:72
Belle2::CalibrationAlgorithm::c_NotEnoughData
@ c_NotEnoughData
Needs more data =2 in Python.
Definition: CalibrationAlgorithm.h:53
Belle2::CalibrationAlgorithm
Base class for calibration algorithms.
Definition: CalibrationAlgorithm.h:47
Belle2::TOP::Chi2MinimumFinder1D::getNbins
int getNbins() const
Returns number of bins.
Definition: Chi2MinimumFinder1D.h:118
Belle2::TOPCalModuleT0
Module T0 calibration constants for all 16 modules.
Definition: TOPCalModuleT0.h:33
Belle2::TOP::TOPModuleT0LLAlgorithm::calibrate
virtual EResult calibrate() final
algorithm implementation
Definition: TOPModuleT0LLAlgorithm.cc:40