BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
PointwiseAxis.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Base/Axis/PointwiseAxis.cpp
6 //! @brief Implements class PointwiseAxis.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
16 #include <algorithm>
17 #include <iomanip>
18 #include <stdexcept>
19 
20 const size_t min_axis_size = 2;
21 
23 {
24  return new PointwiseAxis(getName(), m_coordinates);
25 }
26 
27 Bin1D PointwiseAxis::bin(size_t index) const
28 {
29  checkIndex(index);
30  return Bin1D(lowerBoundary(index), upperBoundary(index));
31 }
32 
34 {
35  return lowerBoundary(0);
36 }
37 
39 {
40  return upperBoundary(m_coordinates.size() - 1);
41 }
42 
43 double PointwiseAxis::binCenter(size_t index) const
44 {
45  checkIndex(index);
46  return m_coordinates[index];
47 }
48 
49 size_t PointwiseAxis::findClosestIndex(double value) const
50 {
51  if (value <= m_coordinates.front())
52  return 0;
53  if (value >= m_coordinates.back())
54  return m_coordinates.size() - 1;
55 
56  const auto begin = m_coordinates.begin();
57  auto result = std::lower_bound(begin, m_coordinates.end(), value);
58  size_t index = static_cast<size_t>(std::distance(begin, result));
59  return value < lowerBoundary(index) ? index - 1 : index;
60 }
61 
62 std::vector<double> PointwiseAxis::binBoundaries() const
63 {
64  std::vector<double> result;
65  const size_t v_size = m_coordinates.size();
66  result.reserve(v_size + 1);
67  for (size_t i = 0; i < v_size; ++i)
68  result.push_back(lowerBoundary(i));
69  result.push_back(upperBoundary(v_size - 1));
70  return result;
71 }
72 
73 PointwiseAxis* PointwiseAxis::createClippedAxis(double left, double right) const
74 {
75  if (left >= right)
76  throw std::runtime_error("Error in PointwiseAxis::createClippedAxis: "
77  "'left' should be smaller than 'right'");
78 
79  using diff_t = std::vector<double>::iterator::difference_type;
80  auto begin = m_coordinates.begin() + static_cast<diff_t>(findClosestIndex(left));
81  auto end = m_coordinates.begin() + static_cast<diff_t>(findClosestIndex(right)) + 1;
82 
83  return new PointwiseAxis(getName(), std::vector<double>(begin, end));
84 }
85 
86 void PointwiseAxis::print(std::ostream& ostr) const
87 {
88  auto precision = std::setprecision(std::numeric_limits<double>::digits10 + 2);
89  ostr << "PointwiseAxis(\"" << getName() << "\", "
90  << ", [";
91  for (size_t i = 0, fin = m_coordinates.size() - 1; i < fin; ++i)
92  ostr << precision << m_coordinates[i] << ",";
93  ostr << precision << m_coordinates.back() << "])";
94 }
95 
96 bool PointwiseAxis::equals(const IAxis& other) const
97 {
98  if (!IAxis::equals(other))
99  return false;
100  if (const PointwiseAxis* otherAxis = dynamic_cast<const PointwiseAxis*>(&other))
101  return m_coordinates == otherAxis->binCenters();
102  return false;
103 }
104 
105 double PointwiseAxis::lowerBoundary(size_t index) const
106 {
107  if (index == 0)
108  return m_coordinates.front();
109  return 0.5 * (m_coordinates[index] + m_coordinates[index - 1]);
110 }
111 
112 double PointwiseAxis::upperBoundary(size_t index) const
113 {
114  if (index + 1 == m_coordinates.size())
115  return m_coordinates.back();
116  return 0.5 * (m_coordinates[index] + m_coordinates[index + 1]);
117 }
118 
119 void PointwiseAxis::checkIndex(size_t index) const
120 {
121  if (m_coordinates.size() > index)
122  return;
123  std::string message = "Error in PointwiseAxis::binCenter: passed index ";
124  message += std::to_string(index) + " exceeds the size ";
125  message += std::to_string(m_coordinates.size()) + " of the axis";
126  throw std::runtime_error(message);
127 }
128 
130 {
131  if (m_coordinates.size() < min_axis_size)
132  throw std::runtime_error(
133  "Error in PointwiseAxis::PointwiseAxis: the size of passed coordinate array is "
134  "less than minimum acceptable value");
135 
136  const auto begin = m_coordinates.begin();
137  const auto end = m_coordinates.end();
138 
139  if (!std::is_sorted(begin, end))
140  throw std::runtime_error("Error in PointwiseAxis::PointwiseAxis: passed coordinates are "
141  "not sorted in ascending order");
142 
143  if (std::adjacent_find(begin, end) != end)
144  throw std::runtime_error("Error in PointwiseAxis::PointwiseAxis: passed coordinate vector "
145  "contains repeating values");
146 }
const size_t min_axis_size
Defines class PointwiseAxis.
Interface for one-dimensional axes.
Definition: IAxis.h:25
virtual bool equals(const IAxis &other) const
Definition: IAxis.cpp:17
std::string getName() const
retrieve the label of the axis
Definition: IAxis.h:40
Axis containing arbitrary (non-equidistant) coordinate values.
Definition: PointwiseAxis.h:37
double upperBoundary(size_t index) const
double lowerBoundary(size_t index) const
PointwiseAxis(String &&name, Vector &&coordinate_values)
Definition: PointwiseAxis.h:40
PointwiseAxis * clone() const override
clone function
double upperBound() const override
Returns value of last on-axis point.
double binCenter(size_t index) const override
Returns the coordinate corresponding to the given index.
Bin1D bin(size_t index) const override
retrieve a 1d bin for the given index
void checkIndex(size_t index) const
double lowerBound() const override
Returns value of first on-axis point.
std::vector< double > m_coordinates
Definition: PointwiseAxis.h:90
PointwiseAxis * createClippedAxis(double left, double right) const override
Creates a new clipped axis.
size_t findClosestIndex(double value) const override
find index of the coordinate closest to the given value
std::vector< double > binBoundaries() const override
bool equals(const IAxis &other) const override
void print(std::ostream &ostr) const override
void sanityCheck() const
Definition: Bin.h:20