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