GooFit  v2.1.3
BinnedDataSet.cpp
Go to the documentation of this file.
1 #include <goofit/BinnedDataSet.h>
2 #include <goofit/Error.h>
3 #include <goofit/Log.h>
4 #include <goofit/Variable.h>
5 
6 #include <functional>
7 #include <numeric>
8 
9 namespace GooFit {
10 
11 // Special constructor for one variable
12 BinnedDataSet::BinnedDataSet(const Observable &var, std::string n)
13  : DataSet(var, n) {
14  collectBins();
15  binvalues.resize(getNumBins());
16 }
17 
18 BinnedDataSet::BinnedDataSet(const std::vector<Observable> &vars, std::string n)
19  : DataSet(vars, n) {
20  collectBins();
21  binvalues.resize(getNumBins());
22 }
23 
24 BinnedDataSet::BinnedDataSet(const std::set<Observable> &vars, std::string n)
25  : DataSet(vars, n) {
26  collectBins();
27  binvalues.resize(getNumBins());
28 }
29 
30 BinnedDataSet::BinnedDataSet(std::initializer_list<Observable> vars, std::string n)
31  : DataSet(vars, n) {
32  collectBins();
33  binvalues.resize(getNumBins());
34 }
35 
37  checkAllVars();
38  size_t ibin = getBinNumber();
39  binvalues.at(ibin) += 1;
41 }
42 
43 void BinnedDataSet::addWeightedEvent(double weight) {
44  checkAllVars();
45  size_t ibin = getBinNumber();
46  binvalues.at(ibin) += weight;
48 }
49 
50 void BinnedDataSet::collectBins() {
51  // Not really intended to be run multiple times, but just in case
52  binsizes.clear();
53 
54  for(const Observable &var : observables)
55  binsizes.push_back(var.getNumBins());
56 }
57 
59  std::vector<fptype> vals = getCurrentValues();
60  std::vector<size_t> locals = convertValuesToBins(vals);
61  return localToGlobal(locals);
62 }
63 
64 size_t BinnedDataSet::localToGlobal(const std::vector<size_t> &locals) const {
65  unsigned int priorMatrixSize = 1;
66  unsigned int ret = 0;
67 
68  for(size_t i = 0; i < observables.size(); i++) {
69  size_t localBin = locals[i];
70  ret += localBin * priorMatrixSize;
71  priorMatrixSize *= binsizes[i];
72  }
73 
74  return ret;
75 }
76 
77 std::vector<size_t> BinnedDataSet::globalToLocal(size_t global) const {
78  std::vector<size_t> locals;
79 
80  // To convert global bin number to (x,y,z...) coordinates: For each dimension, take the mod
81  // with the number of bins in that dimension. Then divide by the number of bins, in effect
82  // collapsing so the grid has one fewer dimension. Rinse and repeat.
83 
84  for(size_t i = 0; i < observables.size(); i++) {
85  size_t localBin = global % binsizes[i];
86  locals.push_back(localBin);
87  global /= binsizes[i];
88  }
89  return locals;
90 }
91 
92 fptype BinnedDataSet::getBinCenter(size_t ivar, size_t bin) const {
93  std::vector<size_t> locals = globalToLocal(bin);
94  size_t localBin = locals.at(ivar);
95 
96  fptype ret = getBinSize(ivar);
97  ret *= (localBin + 0.5);
98  ret += observables[ivar].getLowerLimit();
99  return ret;
100 }
101 
102 fptype BinnedDataSet::getBinCenter(const Observable &var, size_t bin) const {
103  size_t ivar = indexOfVariable(var);
104  return getBinCenter(ivar, bin);
105 }
106 
107 fptype BinnedDataSet::getBinSize(size_t ivar) const {
108  return (observables.at(ivar).getUpperLimit() - observables[ivar].getLowerLimit()) / binsizes[ivar];
109 }
110 
112  fptype ret = 1;
113 
114  for(size_t i = 0; i < observables.size(); i++) {
115  ret *= getBinSize(i);
116  }
117 
118  return ret;
119 }
120 
122  if(0 == binerrors.size())
123  return sqrt(binvalues.at(bin));
124 
125  return binerrors.at(bin);
126 }
127 
128 void BinnedDataSet::setBinError(unsigned int bin, fptype error) {
129  if(0 == binerrors.size())
130  binerrors.resize(binvalues.size());
131 
132  binerrors.at(bin) = error;
133 }
134 
136  return std::accumulate(std::begin(binsizes), std::end(binsizes), 1, std::multiplies<size_t>());
137 }
138 
140  return std::accumulate(std::begin(binvalues), std::end(binvalues), 0);
141 }
142 
143 std::vector<size_t> BinnedDataSet::convertValuesToBins(const std::vector<fptype> &vals) const {
144  if(vals.size() != observables.size())
145  throw GooFit::GeneralError("Incorrect number of bins {} for {} variables", vals.size(), observables.size());
146 
147  std::vector<size_t> localBins;
148  for(size_t i = 0; i < observables.size(); i++) {
149  fptype currval = vals[i];
150  fptype betval = std::min(std::max(currval, observables[i].getLowerLimit()), observables[i].getUpperLimit());
151  if(currval != betval)
152  GOOFIT_INFO("Warning: Value {} outside {} range [{},{}] - clamping to {}",
153  currval,
154  observables[i].getName(),
155  observables[i].getLowerLimit(),
156  observables[i].getUpperLimit(),
157  betval);
158  localBins.push_back(static_cast<size_t>(floor((betval - observables[i].getLowerLimit()) / getBinSize(i))));
159  }
160 
161  return localBins;
162 }
163 } // namespace GooFit
Thrown when a general error is encountered.
Definition: Error.h:10
double fptype
void addEvent() override
#define GOOFIT_INFO(...)
Definition: Log.h:10
std::vector< Observable > observables
Definition: DataSet.h:66
fptype getBinSize(size_t ivar) const
Get the size of a bin.
void checkAllVars() const
Throw an error if any variables are out of range, call in addEvent.
Definition: DataSet.cpp:71
Special class for observables. Used in DataSets.
Definition: Variable.h:109
BinnedDataSet(const Observable &var, std::string n="")
std::string getName() const
Definition: DataSet.h:49
size_t indexOfVariable(const Observable &var) const
Definition: DataSet.cpp:51
fptype getBinError(size_t bin) const
fptype getNumWeightedEvents() const
This includes weights.
fptype getBinCenter(size_t ivar, size_t bin) const
void addWeightedEvent(double weight) override
size_t getBinNumber() const
std::vector< fptype > getCurrentValues() const
Definition: DataSet.cpp:39
fptype getBinVolume(size_t bin) const
size_t getNumBins() const
void setBinError(unsigned int bin, fptype value)
size_t numEventsAdded
Definition: DataSet.h:54