Belle II Software development
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
14using namespace Belle2;
15
16
17void 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
52void 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
67void 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
79float 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
89float 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
152bool 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
164short 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
171short 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
191short 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.