CMS 3D CMS Logo

HistoAxis.cc
Go to the documentation of this file.
1 #include <cmath>
2 #include <climits>
3 #include <algorithm>
5 
6 #include "Alignment/Geners/interface/binaryIO.hh"
7 #include "Alignment/Geners/interface/IOException.hh"
8 
11 
12 namespace npstat {
13  HistoAxis::HistoAxis(const unsigned nbins, const double min, const double max, const char* label)
14  : min_(min), max_(max), label_(label ? label : ""), nBins_(nbins) {
15  if (!(nBins_ && nBins_ < UINT_MAX / 2U - 1U))
17  "In npstat::HistoAxis constructor: "
18  "number of bins is out of range");
19  if (min_ > max_)
21  bw_ = (max_ - min_) / nBins_;
22  }
23 
24  HistoAxis HistoAxis::rebin(const unsigned nbins) const { return HistoAxis(nbins, min_, max_, label_.c_str()); }
25 
26  bool HistoAxis::isClose(const HistoAxis& r, const double tol) const {
27  return closeWithinTolerance(min_, r.min_, tol) && closeWithinTolerance(max_, r.max_, tol) && label_ == r.label_ &&
28  nBins_ == r.nBins_;
29  }
30 
31  bool HistoAxis::operator==(const HistoAxis& r) const {
32  return min_ == r.min_ && max_ == r.max_ && label_ == r.label_ && nBins_ == r.nBins_;
33  }
34 
35  bool HistoAxis::operator!=(const HistoAxis& r) const { return !(*this == r); }
36 
37  int HistoAxis::binNumber(const double x) const {
38  if (bw_) {
39  int binnum = static_cast<int>(floor((x - min_) / bw_));
40  if (x >= max_) {
41  if (binnum < static_cast<int>(nBins_))
42  binnum = nBins_;
43  } else {
44  if (binnum >= static_cast<int>(nBins_))
45  binnum = nBins_ - 1U;
46  }
47  return binnum;
48  } else {
49  if (x < min_)
50  return -1;
51  else
52  return nBins_;
53  }
54  }
55 
56  unsigned HistoAxis::closestValidBin(const double x) const {
57  if (x <= min_)
58  return 0U;
59  else if (bw_ && x < max_) {
60  const unsigned binnum = static_cast<unsigned>(floor((x - min_) / bw_));
61  if (binnum < nBins_)
62  return binnum;
63  }
64  return nBins_ - 1U;
65  }
66 
67  LinearMapper1d HistoAxis::binNumberMapper(const bool mapLeftEdgeTo0) const {
68  if (!bw_)
70  "In npstat::HistoAxis::binNumberMapper: "
71  "bin width is zero. Mapper can not be constructed.");
72  const double base = mapLeftEdgeTo0 ? min_ / bw_ : min_ / bw_ + 0.5;
73  return LinearMapper1d(1.0 / bw_, -base);
74  }
75 
76  CircularMapper1d HistoAxis::kernelScanMapper(const bool doubleRange) const {
77  if (!bw_)
79  "In npstat::HistoAxis::kernelScanMapper: "
80  "bin width is zero. Mapper can not be constructed.");
81  double range = max_ - min_;
82  if (doubleRange)
83  range *= 2.0;
84  return CircularMapper1d(bw_, 0.0, range);
85  }
86 
87  unsigned HistoAxis::overflowIndexWeighted(const double x, unsigned* binNumber, double* weight) const {
88  if (x < min_)
89  return 0U;
90  else if (x >= max_)
91  return 2U;
92  else {
93  if (nBins_ <= 1U)
95  "In npstat::HistoAxis::overflowIndexWeighted: "
96  "must have more than one bin");
97  const double dbin = (x - min_) / bw_;
98  if (dbin <= 0.5) {
99  *binNumber = 0;
100  *weight = 1.0;
101  } else if (dbin >= nBins_ - 0.5) {
102  *binNumber = nBins_ - 2;
103  *weight = 0.0;
104  } else {
105  const unsigned bin = static_cast<unsigned>(dbin - 0.5);
106  *binNumber = bin >= nBins_ - 1U ? nBins_ - 2U : bin;
107  *weight = 1.0 - (dbin - 0.5 - *binNumber);
108  }
109  return 1U;
110  }
111  }
112 
113  bool HistoAxis::write(std::ostream& of) const {
114  gs::write_pod(of, min_);
115  gs::write_pod(of, max_);
116  gs::write_pod(of, label_);
117  gs::write_pod(of, nBins_);
118  return !of.fail();
119  }
120 
121  HistoAxis* HistoAxis::read(const gs::ClassId& id, std::istream& in) {
122  static const gs::ClassId current(gs::ClassId::makeId<HistoAxis>());
123  current.ensureSameId(id);
124 
125  double min = 0.0, max = 0.0;
127  unsigned nBins = 0;
128 
129  gs::read_pod(in, &min);
130  gs::read_pod(in, &max);
131  gs::read_pod(in, &label);
132  gs::read_pod(in, &nBins);
133 
134  if (!in.fail())
135  return new HistoAxis(nBins, min, max, label.c_str());
136  else
137  throw gs::IOReadFailure(
138  "In npstat::HistoAxis::read: "
139  "input stream failure");
140  }
141 } // namespace npstat
bool write(std::ostream &of) const
Definition: HistoAxis.cc:113
LinearMapper1d binNumberMapper(bool mapLeftEdgeTo0=true) const
Definition: HistoAxis.cc:67
unsigned overflowIndexWeighted(double x, unsigned *binNumber, double *weight) const
Definition: HistoAxis.cc:87
const std::string & label() const
Definition: HistoAxis.h:47
bool closeWithinTolerance(const double &a, const double &b, const double &tol)
unsigned closestValidBin(double x) const
Definition: HistoAxis.cc:56
Definition: weight.py:1
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:112
std::string label_
Definition: HistoAxis.h:129
char const * label
Exceptions for the npstat namespace.
def binNumber(station, sl)
HistoAxis rebin(unsigned newBins) const
Definition: HistoAxis.cc:24
static HistoAxis * read(const gs::ClassId &id, std::istream &in)
Definition: HistoAxis.cc:121
double min() const
Definition: HistoAxis.h:41
Determine if two doubles are within requested relative tolerance of each other.
CircularMapper1d kernelScanMapper(bool doubleRange) const
Definition: HistoAxis.cc:76
unsigned nBins() const
Definition: HistoAxis.h:45
float x
double max() const
Definition: HistoAxis.h:42
unsigned nBins_
Definition: HistoAxis.h:130
bool operator==(const HistoAxis &) const
Definition: HistoAxis.cc:31
bool isClose(const HistoAxis &, double tol) const
Definition: HistoAxis.cc:26
Histogram axis with equidistant bins.
bool operator!=(const HistoAxis &) const
Definition: HistoAxis.cc:35
int binNumber(double x) const
Definition: HistoAxis.cc:37