CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GridAxis.cc
Go to the documentation of this file.
1 #include <cmath>
2 #include <algorithm>
4 
5 #include "Alignment/Geners/interface/binaryIO.hh"
6 #include "Alignment/Geners/interface/IOException.hh"
7 
10 
11 namespace npstat {
13  {
14  if (npt_ <= 1U) throw npstat::NpstatInvalidArgument(
15  "In npstat::GridAxis::initialize: insufficient number "
16  "of coordinates (at least 2 are required)");
17  std::sort(coords_.begin(), coords_.end());
18  const double* c = &coords_[0];
19  if (useLogSpace_)
20  {
21  logs_.reserve(npt_);
22  for (unsigned i=0; i<npt_; ++i)
23  {
24  if (c[i] <= 0.0) throw npstat::NpstatInvalidArgument(
25  "In npstat::GridAxis::initialize: in log space"
26  "all coordinates must be positive");
27  logs_.push_back(log(c[i]));
28  }
29  }
30 
31  // Can't have duplicate coordinates
32  for (unsigned i=1; i<npt_; ++i)
33  if (c[i] <= c[i - 1U]) throw npstat::NpstatInvalidArgument(
34  "In npstat::GridAxis::initialize: "
35  "all coordinates must be distinct");
36  }
37 
38  GridAxis::GridAxis(const std::vector<double>& coords,
39  const bool useLogSpace)
40  : coords_(coords),
41  npt_(coords_.size()),
42  useLogSpace_(useLogSpace)
43  {
44  initialize();
45  }
46 
47  GridAxis::GridAxis(const std::vector<double>& coords,
48  const char* label,
49  const bool useLogSpace)
50  : coords_(coords),
51  label_(label ? label : ""),
52  npt_(coords_.size()),
53  useLogSpace_(useLogSpace)
54  {
55  initialize();
56  }
57 
58  std::pair<unsigned,double> GridAxis::getInterval(const double x) const
59  {
60  if (useLogSpace_)
61  if (x <= 0.0) throw npstat::NpstatDomainError(
62  "In GridAxis::getInterval: argument must be positive");
63  const double* c = &coords_[0];
64  if (x <= c[0])
65  return std::pair<unsigned,double>(0U, 1.0);
66  else if (x >= c[npt_ - 1U])
67  return std::pair<unsigned,double>(npt_ - 2U, 0.0);
68  else
69  {
70  unsigned ibnd = lower_bound
71  (coords_.begin(), coords_.end(), x) - coords_.begin();
72  --ibnd;
73  if (useLogSpace_)
74  {
75  const double* l = &logs_[0];
76  const double w = 1.0 - (log(x) - l[ibnd])/
77  (l[ibnd + 1U] - l[ibnd]);
78  return std::pair<unsigned,double>(ibnd, w);
79  }
80  else
81  {
82  const double w = 1.0 - (x - c[ibnd])/(c[ibnd + 1U] - c[ibnd]);
83  return std::pair<unsigned,double>(ibnd, w);
84  }
85  }
86  }
87 
88  std::pair<unsigned,double> GridAxis::linearInterval(const double x) const
89  {
90  if (useLogSpace_)
91  if (x <= 0.0) throw npstat::NpstatDomainError(
92  "In GridAxis::linearInterval: argument must be positive");
93  const double* c = &coords_[0];
94  if (x <= c[0])
95  {
96  if (useLogSpace_)
97  {
98  const double* l = &logs_[0];
99  const double bw = l[1] - l[0];
100  return std::pair<unsigned,double>(0U, 1.0 - (log(x) - l[0])/bw);
101  }
102  else
103  {
104  const double bw = c[1] - c[0];
105  return std::pair<unsigned,double>(0U, 1.0 - (x - c[0])/bw);
106  }
107  }
108  else if (x >= c[npt_ - 1U])
109  {
110  if (useLogSpace_)
111  {
112  const double* l = &logs_[0];
113  const double bw = l[npt_ - 1U] - l[npt_ - 2U];
114  return std::pair<unsigned,double>(
115  npt_ - 2U, (l[npt_ - 1U] - log(x))/bw);
116  }
117  else
118  {
119  const double bw = c[npt_ - 1U] - c[npt_ - 2U];
120  return std::pair<unsigned,double>(
121  npt_ - 2U, (c[npt_ - 1U] - x)/bw);
122  }
123  }
124  else
125  {
126  unsigned ibnd = lower_bound
127  (coords_.begin(), coords_.end(), x) - coords_.begin();
128  --ibnd;
129  if (useLogSpace_)
130  {
131  const double* l = &logs_[0];
132  const double w = 1.0 - (log(x) - l[ibnd])/
133  (l[ibnd + 1U] - l[ibnd]);
134  return std::pair<unsigned,double>(ibnd, w);
135  }
136  else
137  {
138  const double w = 1.0 - (x - c[ibnd])/(c[ibnd + 1U] - c[ibnd]);
139  return std::pair<unsigned,double>(ibnd, w);
140  }
141  }
142  }
143 
144  bool GridAxis::write(std::ostream& of) const
145  {
146  // It is unlikely that this object will be written in isolation.
147  // So, do not bother with too many checks.
148  gs::write_pod_vector(of, coords_);
149  gs::write_pod(of, label_);
150  gs::write_pod(of, useLogSpace_);
151  return !of.fail();
152  }
153 
154  GridAxis* GridAxis::read(const gs::ClassId& id, std::istream& in)
155  {
156  static const gs::ClassId current(gs::ClassId::makeId<GridAxis>());
157  current.ensureSameId(id);
158 
159  std::vector<double> coords;
160  gs::read_pod_vector(in, &coords);
161 
163  gs::read_pod(in, &label);
164 
165  bool useLogSpace;
166  gs::read_pod(in, &useLogSpace);
167 
168  if (in.fail())
169  throw gs::IOReadFailure("In npstat::GridAxis::read: "
170  "input stream failure");
171  return new GridAxis(coords, label.c_str(), useLogSpace);
172  }
173 
174  bool GridAxis::operator==(const GridAxis& r) const
175  {
176  return useLogSpace_ == r.useLogSpace_ &&
177  coords_ == r.coords_ &&
178  label_ == r.label_;
179  }
180 
181  bool GridAxis::isClose(const GridAxis& r, const double tol) const
182  {
183  if (!(useLogSpace_ == r.useLogSpace_ &&
184  label_ == r.label_))
185  return false;
186  const unsigned long n = coords_.size();
187  if (n != r.coords_.size())
188  return false;
189  for (unsigned long i=0; i<n; ++i)
190  if (!closeWithinTolerance(coords_[i], r.coords_[i], tol))
191  return false;
192  return true;
193  }
194 }
void initialize()
Definition: GridAxis.cc:12
std::string label_
Definition: GridAxis.h:128
int i
Definition: DBlmapReader.cc:9
std::pair< unsigned, double > getInterval(double coordinate) const
Definition: GridAxis.cc:58
const std::string & label() const
Definition: GridAxis.h:47
bool closeWithinTolerance(const double &a, const double &b, const double &tol)
bool operator==(const GridAxis &r) const
Definition: GridAxis.cc:174
unsigned npt_
Definition: GridAxis.h:129
Exceptions for the npstat namespace.
Non-uniformly spaced coordinate sets for use in constructing rectangular grids.
Determine if two doubles are within requested relative tolerance of each other.
bool isClose(const GridAxis &r, double tol) const
Definition: GridAxis.cc:181
std::vector< double > logs_
Definition: GridAxis.h:127
static GridAxis * read(const gs::ClassId &id, std::istream &in)
Definition: GridAxis.cc:154
T w() const
const std::vector< double > & coords() const
Definition: GridAxis.h:46
Definition: DDAxes.h:10
bool write(std::ostream &of) const
Definition: GridAxis.cc:144
std::pair< unsigned, double > linearInterval(double coordinate) const
Definition: GridAxis.cc:88
std::vector< double > coords_
Definition: GridAxis.h:126
tuple size
Write out results.