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,
14  const double max, const char* label)
15  : min_(min), max_(max), label_(label ? label : ""), nBins_(nbins)
16  {
17  if (!(nBins_ && nBins_ < UINT_MAX/2U - 1U))
18  throw npstat::NpstatInvalidArgument("In npstat::HistoAxis constructor: "
19  "number of bins is out of range");
20  if (min_ > max_)
22  bw_ = (max_ - min_)/nBins_;
23  }
24 
25  HistoAxis HistoAxis::rebin(const unsigned nbins) const
26  {
27  return HistoAxis(nbins, min_, max_, label_.c_str());
28  }
29 
30  bool HistoAxis::isClose(const HistoAxis& r, const double tol) const
31  {
32  return closeWithinTolerance(min_, r.min_, tol) &&
33  closeWithinTolerance(max_, r.max_, tol) &&
34  label_ == r.label_ &&
35  nBins_ == r.nBins_;
36  }
37 
38  bool HistoAxis::operator==(const HistoAxis& r) const
39  {
40  return min_ == r.min_ &&
41  max_ == r.max_ &&
42  label_ == r.label_ &&
43  nBins_ == r.nBins_;
44  }
45 
46  bool HistoAxis::operator!=(const HistoAxis& r) const
47  {
48  return !(*this == r);
49  }
50 
51  int HistoAxis::binNumber(const double x) const
52  {
53  if (bw_)
54  {
55  int binnum = static_cast<int>(floor((x - min_)/bw_));
56  if (x >= max_)
57  {
58  if (binnum < static_cast<int>(nBins_))
59  binnum = nBins_;
60  }
61  else
62  {
63  if (binnum >= static_cast<int>(nBins_))
64  binnum = nBins_ - 1U;
65  }
66  return binnum;
67  }
68  else
69  {
70  if (x < min_)
71  return -1;
72  else
73  return nBins_;
74  }
75  }
76 
77  unsigned HistoAxis::closestValidBin(const double x) const
78  {
79  if (x <= min_)
80  return 0U;
81  else if (bw_ && x < max_)
82  {
83  const unsigned binnum = static_cast<unsigned>(floor((x-min_)/bw_));
84  if (binnum < nBins_)
85  return binnum;
86  }
87  return nBins_ - 1U;
88  }
89 
90  LinearMapper1d HistoAxis::binNumberMapper(const bool mapLeftEdgeTo0) const
91  {
92  if (!bw_) throw npstat::NpstatDomainError(
93  "In npstat::HistoAxis::binNumberMapper: "
94  "bin width is zero. Mapper can not be constructed.");
95  const double base = mapLeftEdgeTo0 ? min_/bw_ : min_/bw_ + 0.5;
96  return LinearMapper1d(1.0/bw_, -base);
97  }
98 
99  CircularMapper1d HistoAxis::kernelScanMapper(const bool doubleRange) const
100  {
101  if (!bw_) throw npstat::NpstatDomainError(
102  "In npstat::HistoAxis::kernelScanMapper: "
103  "bin width is zero. Mapper can not be constructed.");
104  double range = max_ - min_;
105  if (doubleRange)
106  range *= 2.0;
107  return CircularMapper1d(bw_, 0.0, range);
108  }
109 
111  const double x, unsigned* binNumber, double *weight) const
112  {
113  if (x < min_)
114  return 0U;
115  else if (x >= max_)
116  return 2U;
117  else
118  {
119  if (nBins_ <= 1U) throw npstat::NpstatInvalidArgument(
120  "In npstat::HistoAxis::overflowIndexWeighted: "
121  "must have more than one bin");
122  const double dbin = (x - min_)/bw_;
123  if (dbin <= 0.5)
124  {
125  *binNumber = 0;
126  *weight = 1.0;
127  }
128  else if (dbin >= nBins_ - 0.5)
129  {
130  *binNumber = nBins_ - 2;
131  *weight = 0.0;
132  }
133  else
134  {
135  const unsigned bin = static_cast<unsigned>(dbin - 0.5);
136  *binNumber = bin >= nBins_ - 1U ? nBins_ - 2U : bin;
137  *weight = 1.0 - (dbin - 0.5 - *binNumber);
138  }
139  return 1U;
140  }
141  }
142 
143  bool HistoAxis::write(std::ostream& of) const
144  {
145  gs::write_pod(of, min_);
146  gs::write_pod(of, max_);
147  gs::write_pod(of, label_);
148  gs::write_pod(of, nBins_);
149  return !of.fail();
150  }
151 
152  HistoAxis* HistoAxis::read(const gs::ClassId& id, std::istream& in)
153  {
154  static const gs::ClassId current(gs::ClassId::makeId<HistoAxis>());
155  current.ensureSameId(id);
156 
157  double min = 0.0, max = 0.0;
159  unsigned nBins = 0;
160 
161  gs::read_pod(in, &min);
162  gs::read_pod(in, &max);
163  gs::read_pod(in, &label);
164  gs::read_pod(in, &nBins);
165 
166  if (!in.fail())
167  return new HistoAxis(nBins, min, max, label.c_str());
168  else
169  throw gs::IOReadFailure("In npstat::HistoAxis::read: "
170  "input stream failure");
171  }
172 }
bool closeWithinTolerance(const double &a, const double &b, const double &tol)
int binNumber(double x) const
Definition: HistoAxis.cc:51
Definition: weight.py:1
const std::string & label() const
Definition: HistoAxis.h:49
std::string label_
Definition: HistoAxis.h:134
bool operator!=(const HistoAxis &) const
Definition: HistoAxis.cc:46
char const * label
bool write(std::ostream &of) const
Definition: HistoAxis.cc:143
Exceptions for the npstat namespace.
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
static HistoAxis * read(const gs::ClassId &id, std::istream &in)
Definition: HistoAxis.cc:152
HistoAxis rebin(unsigned newBins) const
Definition: HistoAxis.cc:25
unsigned nBins() const
Definition: HistoAxis.h:47
Determine if two doubles are within requested relative tolerance of each other.
bool isClose(const HistoAxis &, double tol) const
Definition: HistoAxis.cc:30
T min(T a, T b)
Definition: MathUtil.h:58
CircularMapper1d kernelScanMapper(bool doubleRange) const
Definition: HistoAxis.cc:99
base
Make Sure CMSSW is Setup ##.
bin
set the eta bin as selection string.
unsigned overflowIndexWeighted(double x, unsigned *binNumber, double *weight) const
Definition: HistoAxis.cc:110
bool operator==(const HistoAxis &) const
Definition: HistoAxis.cc:38
LinearMapper1d binNumberMapper(bool mapLeftEdgeTo0=true) const
Definition: HistoAxis.cc:90
double max() const
Definition: HistoAxis.h:43
unsigned nBins_
Definition: HistoAxis.h:135
unsigned closestValidBin(double x) const
Definition: HistoAxis.cc:77
Histogram axis with equidistant bins.
double min() const
Definition: HistoAxis.h:42