Belle II Software development
TOPCommonT0LLAlgorithm.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#include <top/calibration/TOPCommonT0LLAlgorithm.h>
10#include <top/dbobjects/TOPCalCommonT0.h>
11#include <top/utilities/Chi2MinimumFinder1D.h>
12
13#include <math.h>
14#include <TFile.h>
15#include <TTree.h>
16#include <TH1F.h>
17#include <TH1D.h>
18#include <TH2F.h>
19
20#include <string>
21#include <vector>
22
23using namespace std;
24
25namespace Belle2 {
30 namespace TOP {
31
33 CalibrationAlgorithm("TOPCommonT0LLCollector")
34 {
35 setDescription("Calibration algorithm for common T0 calibration "
36 "with neg. log likelihood minimization (method LL)");
37 }
38
40 {
41
42 // get histograms
43
44 auto h1 = getObjectPtr<TH1F>("tracks_per_set");
45 if (not h1) {
46 B2ERROR("TOPCommonT0LLAlgorithm: histogram 'tracks_per_set' not found");
47 return c_NotEnoughData;
48 }
49 unsigned numSets = h1->GetNbinsX();
50
51 vector<Chi2MinimumFinder1D> finders;
52 for (unsigned set = 0; set < numSets; set++) {
53 string name = "chi2_set" + to_string(set);
54 auto h = getObjectPtr<TH1D>(name);
55 if (not h) continue;
56 finders.push_back(Chi2MinimumFinder1D(h));
57 }
58 if (finders.size() != numSets) {
59 B2ERROR("TOPCommonT0LLAlgorithm: got number of chi2 scans not as expected"
60 << LogVar("expected", numSets)
61 << LogVar("found", finders.size()));
62 return c_NotEnoughData;
63 }
64
65 // bunch separation in time
66
67 auto h4 = getObjectPtr<TH1F>("offset");
68 if (not h4) {
69 B2ERROR("TOPCommonT0LLAlgorithm: histogram 'offset' not found");
70 return c_NotEnoughData;
71 }
72 double bunchTimeSep = h4->GetXaxis()->GetXmax() - h4->GetXaxis()->GetXmin();
73
74 // construct file name, open output root file and book output tree
75
76 const auto& expRun = getRunList();
77 string expNo = to_string(expRun[0].first);
78 while (expNo.length() < 4) expNo.insert(0, "0");
79 string runNo = to_string(expRun[0].second);
80 while (runNo.length() < 5) runNo.insert(0, "0");
81 string outputFileName = "commonT0-e" + expNo + "-r" + runNo + ".root";
82 auto* file = TFile::Open(outputFileName.c_str(), "recreate");
83
84 auto* tree = new TTree("tree", "common T0 calibration results");
85 tree->Branch<int>("expNum", &m_expNo);
86 tree->Branch<int>("runNum", &m_runNo);
87 tree->Branch<int>("runLast", &m_runLast);
88 tree->Branch<float>("fitted_offset", &m_fittedOffset);
89 tree->Branch<float>("offset", &m_offset);
90 tree->Branch<float>("offsetErr", &m_offsetError);
91 tree->Branch<float>("errorScaling", &m_errorScaling);
92 tree->Branch<int>("nTracks", &m_numTracks);
93 tree->Branch<int>("nEvt", &m_numEvents);
94 tree->Branch<int>("fitStatus", &m_fitStatus);
95
96 m_expNo = expRun[0].first;
97 m_runNo = expRun[0].second;
98 m_runLast = expRun.back().second;
99
100 // determine scaling factor for the error from statistically independent results
101
102 auto h_pulls = new TH1F("pulls", "Pulls of statistically independent results",
103 200, -15.0, 15.0);
104 h_pulls->SetXTitle("pulls");
105 std::vector<double> pos, err;
106 for (auto& finder : finders) {
107 const auto& minimum = finder.getMinimum();
108 if (not minimum.valid) continue;
109 pos.push_back(minimum.position);
110 err.push_back(minimum.error);
111 }
112 for (unsigned i = 0; i < pos.size(); i++) {
113 for (unsigned j = i + 1; j < pos.size(); j++) {
114 double pull = (pos[i] - pos[j]) / sqrt(err[i] * err[i] + err[j] * err[j]);
115 h_pulls->Fill(pull);
116 }
117 }
118 double scaleError = 1;
119 if (h_pulls->GetEntries() > 1) scaleError = h_pulls->GetRMS();
120
121 // merge statistically independent finders and store results into histograms
122
123 auto finder = finders[0];
124 for (unsigned i = 1; i < numSets; i++) {
125 finder.add(finders[i]);
126 }
127
128 auto h_commonT0 = new TH1F("commonT0", "Common T0", 1, 0, 1);
129 h_commonT0->SetYTitle("common T0 [ns]");
130
131 const auto& minimum = finder.getMinimum();
132 if (minimum.valid) {
133 m_fittedOffset = minimum.position;
134 m_offset = m_fittedOffset - round(m_fittedOffset / bunchTimeSep) * bunchTimeSep;
135 m_offsetError = minimum.error * scaleError;
136 m_fitStatus = 0;
137 h_commonT0->SetBinContent(1, m_offset);
138 h_commonT0->SetBinError(1, m_offsetError);
139 } else {
140 m_fittedOffset = 0;
141 m_offset = 0;
142 m_offsetError = 0;
143 m_fitStatus = 1;
144 }
145 m_errorScaling = scaleError;
146 m_numTracks = h1->GetSumOfWeights();
147 m_numEvents = h4->GetEntries();
148 tree->Fill();
149
150 // write the results and close the file
151
152 file->Write();
153 auto h = finder.getHistogram("chi2", "chi2 scan; t0 [ns]; -2 logL");
154 h.Write();
155 h1->Write();
156 auto h2 = getObjectPtr<TH1F>("numHits");
157 if (h2) h2->Write();
158 auto h3 = getObjectPtr<TH2F>("timeHits");
159 if (h3) h3->Write();
160 h4->Write();
161 file->Close();
162
163 // check the results and return if not good enough
164
166
167 // otherwise create and import payload to DB
168
169 auto* commonT0 = new TOPCalCommonT0(m_offset, m_offsetError);
170 saveCalibration(commonT0);
171
172 return c_OK;
173 }
174
175 } // end namespace TOP
177} // end namespace Belle2
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
Common T0 calibration constant.
Minimum finder using tabulated chi^2 values in one dimension.
float m_offsetError
error on fitted offset
float m_offset
wrap-around of fitted offset (= common T0)
virtual EResult calibrate() final
algorithm implementation
float m_errorScaling
factor used for scaling the error
double m_minError
minimal commonT0 uncertainty [ns] to declare c_OK
Class to store variables with their name which were sent to the logging service.
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.
STL namespace.