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