BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
FixedBinAxis.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Base/Axis/FixedBinAxis.cpp
6 //! @brief Implement class FixedBinAxis.
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 
15 #include "Base/Axis/FixedBinAxis.h"
16 #include "Base/Axis/Bin.h"
17 #include "Base/Util/Algorithms.h"
18 #include <iomanip>
19 #include <limits>
20 
21 FixedBinAxis::FixedBinAxis(const std::string& name, size_t nbins, double start, double end)
22  : IAxis(name)
23  , m_nbins(nbins)
24  , m_start(start)
25  , m_end(end)
26 {
27 }
28 
30 {
31  auto* result = new FixedBinAxis(axisName(), m_nbins, m_start, m_end);
32  return result;
33 }
34 
35 double FixedBinAxis::operator[](size_t index) const
36 {
37  if (index >= m_nbins)
38  throw std::runtime_error("FixedBinAxis::operator[] -> Error. Wrong index.");
39 
40  double step = (m_end - m_start) / m_nbins;
41  return m_start + (index + 0.5) * step;
42 }
43 
44 Bin1D FixedBinAxis::bin(size_t index) const
45 {
46  if (index >= m_nbins)
47  throw std::runtime_error("FixedBinAxis::bin() -> Error. Wrong index.");
48 
49  double step = (m_end - m_start) / m_nbins;
50  Bin1D result(m_start + step * index, m_start + step * (index + 1));
51  return result;
52 }
53 
54 size_t FixedBinAxis::findClosestIndex(double value) const
55 {
56  if (value < min())
57  return 0;
58  if (value >= max())
59  return m_nbins - 1;
60 
61  double step = (m_end - m_start) / m_nbins;
62  return int((value - m_start) / step);
63 }
64 
65 std::vector<double> FixedBinAxis::binCenters() const
66 {
67  std::vector<double> result;
68  result.resize(size(), 0.0);
69  for (size_t i = 0; i < size(); ++i)
70  result[i] = bin(i).center();
71  return result;
72 }
73 
74 std::vector<double> FixedBinAxis::binBoundaries() const
75 {
76  std::vector<double> result;
77  result.resize(size() + 1, 0.0);
78  for (size_t i = 0; i < size(); ++i)
79  result[i] = bin(i).m_lower;
80  result[size()] = bin(size() - 1).m_upper;
81  return result;
82 }
83 
84 void FixedBinAxis::clip(double lower, double upper)
85 {
86  if (lower >= upper)
87  throw std::runtime_error(
88  "FixedBinAxis::clip() -> Error. 'lower' should be smaller than 'upper'");
89 
90  if (lower < min())
91  lower = bin(0).center();
92  if (upper >= max())
93  upper = bin(size() - 1).center();
94 
95  const size_t nbin1 = findClosestIndex(lower);
96  const size_t nbin2 = findClosestIndex(upper);
97 
98  // create tmp vars until everything is calculated, otherwise the calculation will be corrupted
99  // by partially changed values
100  const auto newStart = bin(nbin1).m_lower;
101  const auto newEnd = bin(nbin2).m_upper;
102 
103  m_nbins = nbin2 - nbin1 + 1;
104  m_start = newStart;
105  m_end = newEnd;
106 }
107 
108 void FixedBinAxis::print(std::ostream& ostr) const
109 {
110  ostr << "FixedBinAxis(\"" << axisName() << "\", " << size() << ", "
111  << std::setprecision(std::numeric_limits<double>::digits10 + 2) << min() << ", " << max()
112  << ")";
113 }
114 
115 bool FixedBinAxis::equals(const IAxis& other) const
116 {
117  if (!IAxis::equals(other))
118  return false;
119  if (const auto* otherAxis = dynamic_cast<const FixedBinAxis*>(&other)) {
120  if (size() != otherAxis->size())
121  return false;
122  if (!BaseUtils::algo::almostEqual(m_start, otherAxis->m_start))
123  return false;
124  if (!BaseUtils::algo::almostEqual(m_end, otherAxis->m_end))
125  return false;
126  return true;
127  }
128  return false;
129 }
Defines and implements namespace BaseUtils::algo with some algorithms.
Defines structs Bin1D, Bin1DCVector.
Defines class FixedBinAxis.
Definition: Bin.h:20
double center() const
Definition: Bin.h:30
double m_upper
upper bound of the bin
Definition: Bin.h:29
double m_lower
lower bound of the bin
Definition: Bin.h:28
Axis with fixed bin size.
Definition: FixedBinAxis.h:23
double m_start
Definition: FixedBinAxis.h:60
bool equals(const IAxis &other) const override
void clip(double lower, double upper) override
Clips this axis to the given values.
std::vector< double > binCenters() const override
FixedBinAxis * clone() const override
size_t findClosestIndex(double value) const override
find bin index which is best match for given value
void print(std::ostream &ostr) const override
double operator[](size_t index) const override
indexed accessor retrieves a sample
size_t size() const override
Returns the number of bins.
Definition: FixedBinAxis.h:35
double m_end
Definition: FixedBinAxis.h:61
double max() const override
Returns value of last point of axis.
Definition: FixedBinAxis.h:42
Bin1D bin(size_t index) const override
retrieve a 1d bin for the given index
double min() const override
Returns value of first point of axis.
Definition: FixedBinAxis.h:41
size_t m_nbins
Definition: FixedBinAxis.h:59
std::vector< double > binBoundaries() const override
FixedBinAxis(const std::string &name, size_t nbins, double start, double end)
FixedBinAxis constructor.
Abstract base class for one-dimensional axes.
Definition: IAxis.h:27
virtual bool equals(const IAxis &other) const
Definition: IAxis.cpp:20
std::string axisName() const
Returns the label of the axis.
Definition: IAxis.h:61
bool almostEqual(double a, double b)
Returns true if two doubles agree within machine epsilon.
Definition: Algorithms.h:33