Belle II Software development
Chi2MinimumFinder1D.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/utilities/Chi2MinimumFinder1D.h>
10
11#include <framework/logging/Logger.h>
12
13#include <math.h>
14
15namespace Belle2 {
20 namespace TOP {
21
22 Chi2MinimumFinder1D::Chi2MinimumFinder1D(int nbins, double xmin, double xmax):
23 m_xmin(xmin), m_xmax(xmax)
24 {
25 if (nbins <= 0) {
26 B2ERROR("Chi2MinimumFinder1D: nbins must be positive integer");
27 return;
28 }
29 if (m_xmax <= m_xmin) {
30 B2ERROR("Chi2MinimumFinder1D: search range max < min");
31 return;
32 }
33 m_dx = (m_xmax - m_xmin) / nbins;
34 double x = m_xmin + m_dx / 2;
35 while (x < m_xmax) {
36 m_x.push_back(x);
37 x += m_dx;
38 }
39 m_chi2.resize(m_x.size(), 0);
40 }
41
42 Chi2MinimumFinder1D::Chi2MinimumFinder1D(const std::shared_ptr<TH1D> h)
43 {
44 m_xmin = h->GetXaxis()->GetXmin();
45 m_xmax = h->GetXaxis()->GetXmax();
46 m_dx = h->GetBinWidth(1);
47 for (int i = 0; i < h->GetNbinsX(); i++) {
48 m_x.push_back(h->GetBinCenter(i + 1));
49 m_chi2.push_back(h->GetBinContent(i + 1));
50 }
51 m_entries = h->GetEntries() / h->GetNbinsX();
52 }
53
55 {
56 for (auto& chi2 : m_chi2) chi2 = 0;
57 m_entries = 0;
58 m_searched = false;
59 }
60
61
62 void Chi2MinimumFinder1D::add(unsigned i, double chi2)
63 {
64 if (i < m_chi2.size()) {
65 m_chi2[i] += chi2;
66 m_searched = false;
67 if (i == 0) m_entries++;
68 } else {
69 B2WARNING("Chi2MinimumFinder1D::add: index out of range");
70 }
71 }
72
73
75 {
76 if (m_x.empty()) {
77 *this = other;
78 } else if (other.getBinCenters().size() == m_x.size() and other.getXmin() == m_xmin and other.getXmax() == m_xmax) {
79 const auto& chi2 = other.getChi2Values();
80 for (unsigned i = 0; i < m_chi2.size(); i++) {
81 m_chi2[i] += chi2[i];
82 }
83 m_entries += other.getEntries();
84 m_searched = false;
85 } else {
86 B2ERROR("Chi2MinimumFinder1D::add: finders with different ranges or binning can't be added");
87 }
88
89 return *this;
90 }
91
92
94 {
95 if (m_chi2.size() < 3) {
97 m_minimum.error = (m_xmax - m_xmin) / 2;
98 return;
99 }
100
101 unsigned i0 = 1;
102 for (unsigned i = i0; i < m_chi2.size() - 1; i++) {
103 if (m_chi2[i] < m_chi2[i0]) i0 = i;
104 }
105 auto x = getMinimum(m_chi2[i0 - 1], m_chi2[i0], m_chi2[i0 + 1]);
106 m_minimum = Minimum(m_x[i0] + x.position * m_dx, x.error * m_dx, x.chi2, x.valid);
107 }
108
109
111 double yCenter,
112 double yRight) const
113 {
114 // parabola: y = ax^2 + bx + c
115 double DL = yLeft - yCenter;
116 double DR = yRight - yCenter;
117 double A = (DR + DL) / 2;
118 if (A <= 0) return Minimum(0, 0, yCenter, false);
119 double B = (DR - DL) / 2;
120 double x = - B / 2 / A;
121 double chi2_min = A * x * x + B * x + yCenter;
122 return Minimum(x, sqrt(1 / A), chi2_min, true);
123 }
124
125
126 TH1F Chi2MinimumFinder1D::getHistogram(std::string name, std::string title) const
127 {
128 TH1F h(name.c_str(), title.c_str(), m_x.size(), m_xmin, m_xmax);
129 for (unsigned i = 0; i < m_chi2.size(); i++) {
130 h.SetBinContent(i + 1, m_chi2[i] - m_minimum.chi2);
131 }
132 return h;
133 }
134
135 } // namespace TOP
137} // namespace Belle2
Minimum finder using tabulated chi^2 values in one dimension.
const std::vector< double > & getBinCenters() const
Returns vector of bin centers.
double m_xmin
lower limit of search region
TH1F getHistogram(std::string name, std::string title) const
Returns chi^2 packed into 1D histogram.
int m_entries
number of entries (counted for bin 0)
Chi2MinimumFinder1D()
Default constructor.
Minimum m_minimum
result: global minimum
void add(unsigned i, double chi2)
Add chi^2 value to bin i.
double m_xmax
upper limit of search region
int getEntries() const
Returns number of entries (counted for bin 0)
double getXmax() const
Returns upper limit of search region.
std::vector< double > m_chi2
chi^2 values at bin centers
const Minimum & getMinimum()
Returns parabolic minimum.
void clear()
Set chi^2 values to zero.
double getXmin() const
Returns lower limit of search region.
std::vector< double > m_x
bin centers
const std::vector< double > & getChi2Values() const
Returns vector of chi^2.
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.
double position
position of the minimum