Belle II Software  release-08-01-10
PIDPriorsTable.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 <analysis/dbobjects/PIDPriorsTable.h>
10 #include <framework/logging/Logger.h>
11 #include <iostream>
12 #include <cfloat>
13 
14 using namespace Belle2;
15 
16 
17 void PIDPriorsTable::setBinEdges(const std::vector<float>& binEdgesX, const std::vector<float>& binEdgesY)
18 {
19  m_binEdgesX = binEdgesX;
20  m_binEdgesY = binEdgesY;
21 
22  // if less than two edges are provided, assumes the maximum range for floats
23  auto checkEdges = [](std::vector<float>& edges, const std::string & axis) {
24  if (edges.size() < 2) {
25  B2WARNING("You provided less than 2 bin edges for the " << axis <<
26  " axis. This is not enough to create one bin, so one will be created with range [-FLT_MAX, +FLT_MAX]");
27  edges = { -FLT_MAX, FLT_MAX};
28  }
29  auto prevVal = edges[0];
30  for (int iBin = 1; iBin < static_cast<int>(edges.size()); iBin++) {
31  auto edge = edges[iBin];
32  if (prevVal >= edge)
33  B2FATAL("Null or negative bin size found on the X axis. Please make sure that all the bin edges are sorted and non-equal");
34  prevVal = edge;
35  }
36  return;
37  };
38 
39  checkEdges(m_binEdgesX, "X");
40  checkEdges(m_binEdgesY, "Y");
41 
42  m_priors.clear();
43  m_errors.clear();
44 
45  m_priors.resize((m_binEdgesY.size() - 1) * (m_binEdgesX.size() - 1), 0.);
46  m_errors.resize((m_binEdgesY.size() - 1) * (m_binEdgesX.size() - 1), 0.);
47  return;
48 };
49 
50 
51 
52 void PIDPriorsTable::setPriorValue(float x, float y, float value)
53 {
54  if (!checkRange("The value is out of range for the X axis", x, m_binEdgesX)
55  || !checkRange("The value is out of range for the Y axis", y, m_binEdgesY)) return;
56  if (value > 1. || value < 0.) {
57  B2WARNING("The value " << value << " you are trying to set for the bin (" << x << ", " << y <<
58  ") does not look like a probability. The table will be filled, but i will not be usable as a proper prior probability table.");
59  }
60  auto binX = findBin(x, m_binEdgesX);
61  auto binY = findBin(y, m_binEdgesY);
62  m_priors[binX + (m_binEdgesX.size() - 1)*binY] = value;
63  return;
64 };
65 
66 
67 void PIDPriorsTable::setErrorValue(float x, float y, float value)
68 {
69  if (!checkRange("The value is out of range for the X axis", x, m_binEdgesX)
70  || !checkRange("The value is out of range for the Y axis", y, m_binEdgesY)) return ;
71 
72  auto binX = findBin(x, m_binEdgesX);
73  auto binY = findBin(y, m_binEdgesY);
74  m_errors[binX + (m_binEdgesX.size() - 1)*binY] = value;
75  return ;
76 };
77 
78 
79 float PIDPriorsTable::getPriorValue(float x, float y) const
80 {
81  if (!checkRange("The value is out of range for the X axis", x, m_binEdgesX)
82  || !checkRange("The value is out of range for the Y axis", y, m_binEdgesY)) return 0;
83  auto binX = findBin(x, m_binEdgesX);
84  auto binY = findBin(y, m_binEdgesY);
85  return getPriorInBin(binX, binY);
86 };
87 
88 
89 float PIDPriorsTable::getErrorValue(float x, float y) const
90 {
91  if (!checkRange("The value is out of range for the X axis", x, m_binEdgesX)
92  || !checkRange("The value is out of range for the Y axis", y, m_binEdgesY)) return 0;
93  auto binX = findBin(x, m_binEdgesX);
94  auto binY = findBin(y, m_binEdgesY);
95  return getErrorInBin(binX, binY);
96 };
97 
98 
100 {
101  std::cout << " --- Prior summary --- " << std::endl;
102  std::cout << " Size : " << m_priors.size() << " (" << m_binEdgesX.size() - 1 << " x " << m_binEdgesY.size() - 1 << ")" <<
103  std::endl;
104  std::cout << " X axis: " ;
105  for (auto edge : m_binEdgesX) {
106  std::cout << " " << edge << " " ;
107  }
108  std::cout << " " << std::endl;
109  std::cout << " Y axis ";
110  for (auto edge : m_binEdgesY) {
111  std::cout << " " << edge << " " ;
112  }
113  std::cout << " " << std::endl;
114  std::cout << " Values " << std::endl;
115  for (int iY = m_binEdgesY.size() - 2; iY >= 0; iY--) {
116  for (int iX = 0; iX < static_cast<int>(m_binEdgesX.size() - 1); iX++) {
117  std::cout << " " << getPriorInBin(iX, iY) << " ";
118  }
119  std::cout << " " << std::endl;
120  }
121  std::cout << " --- End of prior summary --- " << std::endl;
122 };
123 
124 
126 {
127  std::cout << " --- Error summary --- " << std::endl;
128  std::cout << " Size : " << m_errors.size() << " (" << m_binEdgesX.size() - 1 << " x " << m_binEdgesY.size() - 1 << ")" <<
129  std::endl;
130  std::cout << " X axis: " ;
131  for (auto edge : m_binEdgesX) {
132  std::cout << " " << edge << " " ;
133  }
134  std::cout << " " << std::endl;
135  std::cout << " Y axis ";
136  for (auto edge : m_binEdgesY) {
137  std::cout << " " << edge << " " ;
138  }
139  std::cout << " " << std::endl;
140  std::cout << " Values " << std::endl;
141  for (int iY = m_binEdgesY.size() - 2; iY >= 0; iY--) {
142  for (int iX = 0; iX < static_cast<int>(m_binEdgesX.size() - 1); iX++) {
143  std::cout << " " << getErrorInBin(iX, iY) << " ";
144  }
145  std::cout << " " << std::endl;
146  }
147  std::cout << " --- End of error summary --- " << std::endl;
148 };
149 
150 
151 
152 bool PIDPriorsTable::checkRange(const std::string& text, float val, const std::vector<float>& edges) const
153 {
154  const float& min = edges.front();
155  const float& max = edges.back();
156  if (val > max || val < min) {
157  B2WARNING("PriorsTable: " << text << LogVar("value", val) << LogVar("min", min) << LogVar("max", max));
158  return false;
159  }
160  return true;
161 };
162 
163 
164 short PIDPriorsTable::findBin(float val, std::vector<float> array) const
165 {
166  auto it = std::lower_bound(array.cbegin(), array.cend(), val);
167  return std::distance(array.cbegin(), it) - 1;
168 };
169 
170 
171 short PIDPriorsTable::findBinFast(float val, std::vector<float> array) const
172 {
173  // This function searches for the first bin the axis which is above the
174  // value. First it starts assuming the bins are equal, and then moves around
175  // the array until the correct bin is found
176  float averageBinSize = (array.back() - array.front()) / (array.size() - 1);
177  short bin = 1 + (short)((val - array[0]) / averageBinSize);
178  //adjusts forward
179 
180  while (bin < static_cast<short>(array.size()) && array[bin] < val) {
181  bin++;
182  }
183  //adjusts backward
184  while (bin - 1 > 0 && array[bin - 1] > val) {
185  bin--;
186  }
187  return bin - 1;
188 };
189 
190 
191 short PIDPriorsTable::findBinWithFixedWidth(float val, std::vector<float> array) const
192 {
193  float binWidth = (array.back() - array.front()) / (array.size() - 1.);
194  return (short)((val - array.back()) / binWidth);
195 };
void printPrior() const
Prints the content of the table and the axes.
std::vector< float > m_errors
The matrix with the errors on the prior probabilities.
std::vector< float > m_binEdgesY
The array containing the bin edges for the Y axis.
bool checkRange(const std::string &text, float val, const std::vector< float > &edges) const
Checks if a value is within the range of an array.
void setBinEdges(const std::vector< float > &binEdgesX, const std::vector< float > &binEdgesY)
Sets the bin edges arrays.
std::vector< float > m_priors
The matrix with the prior probabilities.
float getPriorValue(float x, float y) const
Returns the prior probability for a given value of (x,y).
void setPriorValue(float x, float y, float value)
Sets the prior value for a single bin.
short findBinFast(float val, std::vector< float > array) const
This function returns the position of a number in a sorted array of bin edges This implementation sho...
void printError() const
Prints the content of the error table and the axes.
float getErrorValue(float x, float y) const
Returns the error on the prior probability for a given value of (x,y).
short findBinWithFixedWidth(float val, std::vector< float > array) const
This function returns the position of a number in a sorted array of bin edges, assuming that the latt...
std::vector< float > m_binEdgesX
The array containing the bin edges for the X axis.
void setErrorValue(float x, float y, float value)
Sets the error on the prior value for a single bin.
float getPriorInBin(int iX, int iY) const
Returns the prior probability for a given bin.
short findBin(float val, std::vector< float > array) const
This function returns the position of a number in a sorted array of bin edges.
float getErrorInBin(int iX, int iY) const
Returns the error on prior probability for a given bin.
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.