Belle II Software  release-08-01-10
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 
15 namespace 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) {
96  m_minimum.position = (m_xmin + m_xmax) / 2;
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.
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
const Minimum & getMinimum()
Returns parabolic minimum.
int getEntries() const
Returns number of entries (counted for bin 0)
const std::vector< double > & getChi2Values() const
Returns vector of chi^2.
double getXmax() const
Returns upper limit of search region.
std::vector< double > m_chi2
chi^2 values at bin centers
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 > & getBinCenters() const
Returns vector of bin centers.
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