HackAnalysis  2
BinnedFn.h
1 // -*- C++ -*-
2 //
3 // This file is part of HEPUtils -- https://bitbucket.org/andybuckley/heputils
4 // Copyright (C) 2013-2018 Andy Buckley <andy.buckley@cern.ch>
5 //
6 // Embedding of HEPUtils code in other projects is permitted provided this
7 // notice is retained and the HEPUtils namespace and include path are changed.
8 //
9 
10 // Duly: HEPUtils namespace changed to HEP
11 #pragma once
12 
13 #include <cstddef>
14 #include <vector>
15 #include <algorithm>
16 #include <stdexcept>
17 #include <cassert>
18 #include <cmath>
19 
20 namespace HEP {
21 
22 
25  template <typename TX=double>
26  class Binning1D {
27  public:
28 
30  Binning1D(const std::vector<TX>& binedges)
31  : edges(binedges)
32  {
33  reset();
34  }
35 
36 
38  size_t num_bins() const {
39  check();
40  return edges.size() - 1;
41  }
43  size_t size() const {
44  return num_bins();
45  }
46 
47 
50  size_t get_index(const TX& x) const {
51  check();
52  if (x < edges.front()) throw std::out_of_range("Bin position underflow");
53  if (x > edges.back()) throw std::out_of_range("Bin position overflow");
54  // Find the closest knot below the requested value, starting with intelligent guesses
55  // First assume linear/uniform binning
56  const TX xfrac = (x - edges.front()) / (edges.back() - edges.front());
57  const size_t iguess = floor( num_bins() * xfrac );
58  if (edges[iguess] <= x && edges[iguess+1] > x) return iguess;
59  // Then we'll try for uniform binning in log space if the vector is big enough to justify the log calls
60  if (edges.size() > 64) { //< @todo Optimise
61  const TX lnxlow = log(edges.front());
62  const TX lnxtot = log(edges.back()) - lnxlow;
63  const TX dlnx = log(x) - lnxlow;
64  const TX xfrac2 = dlnx / lnxtot;
65  const size_t iguess2 = floor( num_bins() * xfrac2 );
66  if (edges[iguess2] <= x && edges[iguess2+1] > x) return iguess2;
67  }
68  // Fall back to something more general
70  size_t i = upper_bound(edges.begin(), edges.end(), x) - edges.begin();
71  if (i == edges.size()) i -= 1; // can't return the last knot index
72  i -= 1; // have to step back to get the knot <= x behaviour
73  return i;
74  }
75 
76 
78  void reset() {
79  assert(edges.size() > 1);
80  check();
81  }
82 
84  void check() const {
85  if (edges.size() <= 1) throw std::length_error("There must be 2 or more bin edges");
86  }
87 
89  std::vector<TX> edges;
90 
91  };
92 
93 
94 
97  template <typename TX=double, typename TY=double>
98  class Binning2D {
99  public:
100 
102  Binning2D(const std::vector<TX>& xbinedges, const std::vector<TY>& ybinedges)
103  : binningX(xbinedges), binningY(ybinedges)
104  {
105  reset();
106  }
107 
109  Binning2D(const Binning1D<TX>& xbinning, const Binning1D<TY>& ybinning)
110  : binningX(xbinning), binningY(ybinning)
111  {
112  reset();
113  }
114 
115 
117  size_t num_bins_x() const {
118  return binningX.num_bins();
119  }
120 
122  size_t num_bins_y() const {
123  return binningY.num_bins();
124  }
125 
127  size_t num_bins() const {
128  return num_bins_x() * num_bins_y();
129  }
131  size_t size() const {
132  return num_bins();
133  }
134 
135 
137  size_t get_index_x(const TX& x) const {
138  return binningX.get_index(x);
139  }
140 
142  size_t get_index_y(const TY& y) const {
143  return binningY.get_index(y);
144  }
145 
147  std::pair<size_t,size_t> get_index_pair(const TX& x, const TY& y) const {
148  return std::make_pair(get_index_x(x), get_index_y(y));
149  }
150 
151 
153  void reset() {
154  binningX.reset();
155  binningY.reset();
156  check();
157  }
158 
160  void check() const {
161  binningX.check();
162  binningY.check();
163  }
164 
167  Binning1D<TY> binningY;
168 
169  };
170 
171 
172 
175  template <typename T, typename TX=double>
176  class BinnedFn1D {
177  public:
178 
180  BinnedFn1D(const std::vector<TX>& binedges)
181  : binning(binedges)
182  {
183  reset();
184  }
185 
187  BinnedFn1D(const std::vector<TX>& binedges, const std::vector<T>& binvalues)
188  : binning(binedges), values(binvalues)
189  {
190  check();
191  }
192 
193 
195  size_t num_bins() const {
196  return binning.num_bins();
197  }
198 
200  size_t get_index(const TX& x) const {
201  return binning.get_index(x);
202  }
203 
205  const T& get_at_index(size_t ix) const {
206  check();
207  return values[ix];
208  }
209 
211  const T& get_at(const TX& x) const {
212  return get_at_index(get_index(x));
213  }
214 
216  void set_at_index(size_t ix, const T& val) {
217  check();
218  values[ix] = val;
219  }
220 
222  void set_at(const TX& x, const T& val) {
223  set_at_index(get_index(x), val);
224  }
225 
226 
228  void reset() {
229  // binning.reset();
230  values.clear();
231  values.resize(num_bins());
232  check();
233  }
234 
236  void check() const {
237  binning.check();
238  if (values.size() < 1) throw std::length_error("There must be 1 or more bin values");
239  if (binning.size() != values.size()) throw std::length_error("There must be one more bin edge than there are bin values");
240  }
241 
242 
245 
247  std::vector<T> values;
248 
249  };
250 
251 
252 
255  template <typename T, typename TX=double, typename TY=double>
256  class BinnedFn2D {
257  public:
258 
260  BinnedFn2D(const std::vector<TX>& xbinedges, const std::vector<TY>& ybinedges)
261  : binning(xbinedges, ybinedges)
262  {
263  reset();
264  }
265 
267  BinnedFn2D(const std::vector<TX>& xbinedges, const std::vector<TY>& ybinedges, const std::vector<T>& binvalues)
268  : binning(xbinedges, ybinedges), values(binvalues)
269  {
270  check();
271  }
272 
273 
275  size_t num_bins() const {
276  return binning.num_bins();
277  }
279  size_t num_bins_x() const {
280  return binning.num_bins_x();
281  }
283  size_t num_bins_y() const {
284  return binning.num_bins_y();
285  }
286 
287 
289  size_t get_index_x(const TX& x) const {
290  return binning.get_index_x(x);
291  }
292 
294  size_t get_index_y(const TY& y) const {
295  return binning.get_index_y(y);
296  }
297 
299  std::pair<size_t,size_t> get_index_pair(const TX& x, const TY& y) const {
300  return binning.get_index_pair(x, y);
301  }
302 
304  size_t get_index(const TX& x, const TY& y) const {
305  return global_index(get_index_pair(x, y));
306  }
307 
308 
310  size_t global_index(size_t ix, size_t iy) const {
311  return ix*num_bins_y() + iy;
312  }
314  size_t global_index(const std::pair<size_t,size_t>& ixiy) const {
315  return global_index(ixiy.first, ixiy.second);
316  }
317 
318 
319 
321  const T& get_at_index(size_t i) const {
322  check();
323  return values[i];
324  }
325 
327  const T& get_at_index(size_t ix, size_t iy) const {
328  return get_at_index(global_index(ix, iy));
329  }
330 
332  const T& get_at(const TX& x, const TY& y) const {
333  return get_at_index(get_index(x, y));
334  }
335 
336 
338  void set_at_index(size_t i, const T& val) {
339  check();
340  values[i] = val;
341  }
342 
344  void set_at_index(size_t ix, size_t iy, const T& val) {
345  set_at_index(global_index(ix, iy), val);
346  }
347 
349  void set_at(const TX& x, const TY& y, const T& val) {
350  set_at_index(get_index(x,y), val);
351  }
352 
353 
355  void reset() {
356  // binning.reset();
357  values.clear();
358  values.resize(num_bins());
359  check();
360  }
361 
363  void check() const {
364  binning.check();
365  if (values.size() < 1) throw std::length_error("There must be 1 or more bin values");
366  if (binning.size() != values.size()) throw std::length_error("There must be one more bin edge than there are bin values");
367  }
368 
369 
372 
374  std::vector<T> values;
375 
376  };
377 
378 
379 }
Definition: BinnedFn.h:176
std::vector< T > values
The list of values.
Definition: BinnedFn.h:247
BinnedFn1D(const std::vector< TX > &binedges, const std::vector< T > &binvalues)
Constructor taking lists of bin edges and values.
Definition: BinnedFn.h:187
size_t get_index(const TX &x) const
Get the bin index enclosing position x.
Definition: BinnedFn.h:200
const T & get_at_index(size_t ix) const
Get the value in bin number ix.
Definition: BinnedFn.h:205
void set_at(const TX &x, const T &val)
Set the value in the bin at position x.
Definition: BinnedFn.h:222
void reset()
Clear the bin contents (but leave the binning intact)
Definition: BinnedFn.h:228
void check() const
Check consistency of the edges and values vectors.
Definition: BinnedFn.h:236
void set_at_index(size_t ix, const T &val)
Set the value in bin number ix.
Definition: BinnedFn.h:216
size_t num_bins() const
Get the number of bins.
Definition: BinnedFn.h:195
BinnedFn1D(const std::vector< TX > &binedges)
Constructor taking a list of bin edges.
Definition: BinnedFn.h:180
const T & get_at(const TX &x) const
Get the value in the bin at position x.
Definition: BinnedFn.h:211
Binning1D< TX > binning
The list of bin edges.
Definition: BinnedFn.h:244
Definition: BinnedFn.h:256
void set_at(const TX &x, const TY &y, const T &val)
Set the value in the bin at position (x,y)
Definition: BinnedFn.h:349
Binning2D< TX, TY > binning
The list of bin edges.
Definition: BinnedFn.h:371
size_t get_index(const TX &x, const TY &y) const
Get the global bin index enclosing position (x,y)
Definition: BinnedFn.h:304
BinnedFn2D(const std::vector< TX > &xbinedges, const std::vector< TY > &ybinedges)
Constructor taking a list of bin edges.
Definition: BinnedFn.h:260
size_t num_bins_x() const
Get the number of bins in x.
Definition: BinnedFn.h:279
const T & get_at_index(size_t i) const
Get the value in global bin number i.
Definition: BinnedFn.h:321
void check() const
Check consistency of the edges and values vectors.
Definition: BinnedFn.h:363
size_t num_bins_y() const
Get the number of bins in y.
Definition: BinnedFn.h:283
size_t global_index(size_t ix, size_t iy) const
Get the global bin index from individual indices ix and iy.
Definition: BinnedFn.h:310
size_t get_index_x(const TX &x) const
Get the x bin index enclosing position x.
Definition: BinnedFn.h:289
void set_at_index(size_t i, const T &val)
Set the value in global bin number ix.
Definition: BinnedFn.h:338
BinnedFn2D(const std::vector< TX > &xbinedges, const std::vector< TY > &ybinedges, const std::vector< T > &binvalues)
Constructor taking lists of bin edges and values.
Definition: BinnedFn.h:267
size_t num_bins() const
Get the number of bins.
Definition: BinnedFn.h:275
const T & get_at_index(size_t ix, size_t iy) const
Get the value in bin number pair (ix, iy)
Definition: BinnedFn.h:327
size_t global_index(const std::pair< size_t, size_t > &ixiy) const
Get the global bin index from individual indices ix and iy.
Definition: BinnedFn.h:314
size_t get_index_y(const TY &y) const
Get the y bin index enclosing position y.
Definition: BinnedFn.h:294
std::vector< T > values
The list of values.
Definition: BinnedFn.h:374
const T & get_at(const TX &x, const TY &y) const
Get the value in the bin at position (x,y)
Definition: BinnedFn.h:332
void set_at_index(size_t ix, size_t iy, const T &val)
Set the value in bin number pair (ix, iy)
Definition: BinnedFn.h:344
std::pair< size_t, size_t > get_index_pair(const TX &x, const TY &y) const
Get the x,y bin index pair enclosing position (x,y)
Definition: BinnedFn.h:299
void reset()
Clear the bin contents (but leave the binning intact)
Definition: BinnedFn.h:355
Definition: BinnedFn.h:26
void check() const
Check consistency.
Definition: BinnedFn.h:84
size_t num_bins() const
Get the number of bins.
Definition: BinnedFn.h:38
Binning1D(const std::vector< TX > &binedges)
Constructor taking a list of bin edges.
Definition: BinnedFn.h:30
size_t get_index(const TX &x) const
Definition: BinnedFn.h:50
std::vector< TX > edges
The list of bin edges.
Definition: BinnedFn.h:89
size_t size() const
Get the number of bins.
Definition: BinnedFn.h:43
void reset()
Clear the bin contents (but leave the binning intact)
Definition: BinnedFn.h:78
Definition: BinnedFn.h:98
Binning1D< TX > binningX
The lists of bin edges.
Definition: BinnedFn.h:166
size_t get_index_x(const TX &x) const
Get the x bin index enclosing position x.
Definition: BinnedFn.h:137
Binning2D(const Binning1D< TX > &xbinning, const Binning1D< TY > &ybinning)
Constructor taking 1D binnings.
Definition: BinnedFn.h:109
size_t get_index_y(const TY &y) const
Get the y bin index enclosing position y.
Definition: BinnedFn.h:142
size_t size() const
Get the total number of bins.
Definition: BinnedFn.h:131
void check() const
Check consistency.
Definition: BinnedFn.h:160
void reset()
Clear the bin contents (but leave the binning intact)
Definition: BinnedFn.h:153
Binning2D(const std::vector< TX > &xbinedges, const std::vector< TY > &ybinedges)
Constructor taking lists of bin edges.
Definition: BinnedFn.h:102
size_t num_bins() const
Get the total number of bins.
Definition: BinnedFn.h:127
std::pair< size_t, size_t > get_index_pair(const TX &x, const TY &y) const
Get the (x,y) bin index pair enclosing position (x,y)
Definition: BinnedFn.h:147
size_t num_bins_y() const
Get the number of bins in y.
Definition: BinnedFn.h:122
size_t num_bins_x() const
Get the number of bins in x.
Definition: BinnedFn.h:117
Modified by Mark Goodsell goodsell@lpthe.jussieu.fr
Definition: ATLAS_SUSY_2018_16.cc:27