CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
NUHistoAxis.cc
Go to the documentation of this file.
1 #include <cmath>
2 #include <cassert>
3 #include <climits>
5 #include <algorithm>
6 
7 #include "Alignment/Geners/interface/binaryIO.hh"
8 #include "Alignment/Geners/interface/IOException.hh"
10 
13 
14 namespace npstat {
15  NUHistoAxis::NUHistoAxis(const std::vector<double>& binEdges,
16  const char* label)
17  : binEdges_(binEdges), nBins_(binEdges.size() - 1U), uniform_(false)
18  {
19  if (!(binEdges_.size() > 1U && binEdges_.size() < UINT_MAX/2U))
20  throw npstat::NpstatInvalidArgument("In npstat::NUHistoAxis constructor: "
21  "number of bin edges is out of range");
22  std::sort(binEdges_.begin(), binEdges_.end());
23  min_ = binEdges_[0];
25  if (label)
26  label_ = std::string(label);
27  }
28 
29  NUHistoAxis::NUHistoAxis(const unsigned nBins,
30  const double min, const double max,
31  const char* label)
32  : min_(min), max_(max), nBins_(nBins), uniform_(true)
33  {
34  if (!(nBins_ && nBins_ < UINT_MAX/2U - 1U))
35  throw npstat::NpstatInvalidArgument("In npstat::NUHistoAxis constructor: "
36  "number of bins is out of range");
37  if (min_ > max_)
40  if (label)
41  label_ = std::string(label);
42  }
43 
44  NUHistoAxis NUHistoAxis::rebin(const unsigned newBins) const
45  {
46  return NUHistoAxis(newBins, min_, max_, label_.c_str());
47  }
48 
49  bool NUHistoAxis::isClose(const NUHistoAxis& r, const double tol) const
50  {
51  if (!(closeWithinTolerance(min_, r.min_, tol) &&
52  closeWithinTolerance(max_, r.max_, tol) &&
53  label_ == r.label_ &&
54  nBins_ == r.nBins_ &&
55  uniform_ == r.uniform_))
56  return false;
57  for (unsigned i=0; i<nBins_; ++i)
58  if (!closeWithinTolerance(binEdges_[i], r.binEdges_[i], tol))
59  return false;
60  return true;
61  }
62 
64  {
65  return min_ == r.min_ &&
66  max_ == r.max_ &&
67  label_ == r.label_ &&
68  nBins_ == r.nBins_ &&
69  binEdges_ == r.binEdges_ &&
70  uniform_ == r.uniform_;
71  }
72 
74  {
75  return !(*this == r);
76  }
77 
78  int NUHistoAxis::binNumber(const double x) const
79  {
80  const int delta = std::upper_bound(binEdges_.begin(), binEdges_.end(), x) -
81  binEdges_.begin();
82  return delta - 1;
83  }
84 
85  double NUHistoAxis::fltBinNumber(const double x, const bool mapLeftEdgeTo0) const
86  {
87  const int delta = std::upper_bound(binEdges_.begin(), binEdges_.end(), x) -
88  binEdges_.begin();
89  const int binnum = delta - 1;
90 
91  if (binnum < 0)
92  {
93  const double left = binEdges_[0];
94  const double right = binEdges_[1];
95  double bval = (x - left)/(right - left);
96  if (!mapLeftEdgeTo0)
97  bval -= 0.5;
98  if (bval < -1.0)
99  bval = -1.0;
100  return bval;
101  }
102  else if (static_cast<unsigned>(binnum) >= nBins_)
103  {
104  const double left = binEdges_[nBins_ - 1U];
105  const double right = binEdges_[nBins_];
106  double bval = nBins_ - 1U + (x - left)/(right - left);
107  if (!mapLeftEdgeTo0)
108  bval -= 0.5;
109  if (bval > static_cast<double>(nBins_))
110  bval = nBins_;
111  return bval;
112  }
113  else
114  {
115  const double left = binEdges_[binnum];
116  const double right = binEdges_[delta];
117  if (mapLeftEdgeTo0)
118  return binnum + (x - left)/(right - left);
119  else
120  {
121  // It is not obvious what is best to do here.
122  // The following works to preserve interpolation
123  // of 0th order. The commented out snippet below
124  // would instead connect bin centers by straight
125  // lines during interpolation.
126  return binnum + (x - left)/(right - left) - 0.5;
127 
128  // Bin center is mapped to binnum.
129  // Bin center of the next bin is mapped to binnum + 1.
130  // Bin center of the previous bin is mapped to binnum - 1.
131  //
132  // const double binCenter = (left + right)/2.0;
133  // if ((binnum == 0 && x <= binCenter) ||
134  // (static_cast<unsigned>(binnum) == nBins_ - 1 && x >= binCenter))
135  // return binnum + (x - left)/(right - left) - 0.5;
136  // else if (x <= binCenter)
137  // {
138  // const double otherBinCenter = (left + binEdges_[binnum - 1])/2.0;
139  // return binnum + (x - binCenter)/(binCenter - otherBinCenter);
140  // }
141  // else
142  // {
143  // const double otherBinCenter = (right + binEdges_[binnum + 2])/2.0;
144  // return binnum + (x - binCenter)/(otherBinCenter - binCenter);
145  // }
146  }
147  }
148  }
149 
150  unsigned NUHistoAxis::closestValidBin(const double x) const
151  {
152  const int delta = std::upper_bound(binEdges_.begin(), binEdges_.end(), x) -
153  binEdges_.begin();
154  int binnum = delta - 1;
155  if (binnum < 0)
156  binnum = 0;
157  else if (static_cast<unsigned>(binnum) >= nBins_)
158  binnum = nBins_ - 1U;
159  return binnum;
160  }
161 
162  bool NUHistoAxis::write(std::ostream& of) const
163  {
164  gs::write_pod_vector(of, binEdges_);
165  gs::write_pod(of, label_);
166  unsigned char c = uniform_;
167  gs::write_pod(of, c);
168  return !of.fail();
169  }
170 
171  NUHistoAxis* NUHistoAxis::read(const gs::ClassId& id, std::istream& in)
172  {
173  static const gs::ClassId current(gs::ClassId::makeId<NUHistoAxis>());
174  current.ensureSameId(id);
175 
176  std::vector<double> binEdges;
178  unsigned char unif;
179  gs::read_pod_vector(in, &binEdges);
180  gs::read_pod(in, &label);
181  gs::read_pod(in, &unif);
182  if (in.fail())
183  throw gs::IOReadFailure("In npstat::UHistoAxis::read: "
184  "input stream failure");
185  NUHistoAxis* result = new NUHistoAxis(binEdges, label.c_str());
186  result->uniform_ = unif;
187  return result;
188  }
189 }
dbl * delta
Definition: mlp_gen.cc:36
unsigned closestValidBin(double x) const
Definition: NUHistoAxis.cc:150
std::vector< double > binEdges_
Definition: NUHistoAxis.h:115
int i
Definition: DBlmapReader.cc:9
int binNumber(double x) const
Definition: NUHistoAxis.cc:78
bool write(std::ostream &of) const
Definition: NUHistoAxis.cc:162
bool closeWithinTolerance(const double &a, const double &b, const double &tol)
Histogram axis with non-uniform bin spacing.
bool operator!=(const NUHistoAxis &) const
Definition: NUHistoAxis.cc:73
Equidistant sequences of points in either linear or log space.
Exceptions for the npstat namespace.
std::string label_
Definition: NUHistoAxis.h:116
NUHistoAxis rebin(unsigned newBins) const
Definition: NUHistoAxis.cc:44
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
tuple result
Definition: query.py:137
Determine if two doubles are within requested relative tolerance of each other.
T min(T a, T b)
Definition: MathUtil.h:58
static NUHistoAxis * read(const gs::ClassId &id, std::istream &in)
Definition: NUHistoAxis.cc:171
bool isClose(const NUHistoAxis &, double tol) const
Definition: NUHistoAxis.cc:49
double fltBinNumber(double x, bool mapLeftEdgeTo0=true) const
Definition: NUHistoAxis.cc:85
bool operator==(const NUHistoAxis &) const
Definition: NUHistoAxis.cc:63
volatile std::atomic< bool > shutdown_flag false
Definition: DDAxes.h:10
tuple size
Write out results.
const std::string & label() const
Definition: NUHistoAxis.h:47