BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ConstKBinAxis.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Base/Axis/ConstKBinAxis.cpp
6 //! @brief Implement class ConstKBinAxis.
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 "Base/Utils/Algorithms.h"
17 #include <iomanip>
18 
19 ConstKBinAxis::ConstKBinAxis(const std::string& name, size_t nbins)
20  : VariableBinAxis(name, nbins), m_start(0), m_end(0)
21 {
22 }
23 
24 ConstKBinAxis::ConstKBinAxis(const std::string& name, size_t nbins, double start, double end)
25  : VariableBinAxis(name, nbins), m_start(start), m_end(end)
26 {
27  if (m_start >= m_end)
28  throw std::runtime_error(
29  "ConstKBinAxis::ConstKBinAxis() -> Error. start >= end is not allowed.");
30 
31  double start_sin = std::sin(m_start);
32  double end_sin = std::sin(m_end);
33  double step = (end_sin - start_sin) / (m_nbins);
34 
35  std::vector<double> bin_boundaries;
36  bin_boundaries.resize(m_nbins + 1, 0.0);
37  for (size_t i = 0; i < bin_boundaries.size(); ++i) {
38  bin_boundaries[i] = std::asin(start_sin + step * i);
39  }
40  setBinBoundaries(bin_boundaries);
41 }
42 
44 {
45  return new ConstKBinAxis(getName(), m_nbins, m_start, m_end);
46 }
47 
48 ConstKBinAxis* ConstKBinAxis::createClippedAxis(double left, double right) const
49 {
50  if (left >= right)
51  throw std::runtime_error(
52  "ConstKBinAxis::createClippedAxis() -> Error. 'left'' should be smaller than 'right'");
53 
54  if (left < lowerBound())
55  left = bin(0).center();
56  if (right >= upperBound())
57  right = bin(size() - 1).center();
58 
59  size_t nbin1 = findClosestIndex(left);
60  size_t nbin2 = findClosestIndex(right);
61 
62  size_t new_nbins = nbin2 - nbin1 + 1;
63  std::vector<double> new_boundaries;
64  std::vector<double> old_boundaries = binBoundaries();
65  for (size_t i = 0; i < new_nbins + 1; ++i) {
66  new_boundaries.push_back(old_boundaries[nbin1 + i]);
67  }
68 
69  ConstKBinAxis* result = new ConstKBinAxis(getName(), new_nbins);
70  result->m_start = new_boundaries.front();
71  result->m_end = new_boundaries.back();
72  result->setBinBoundaries(new_boundaries);
73  return result;
74 }
75 
76 bool ConstKBinAxis::equals(const IAxis& other) const
77 {
78  if (!IAxis::equals(other))
79  return false;
80  if (const ConstKBinAxis* otherAxis = dynamic_cast<const ConstKBinAxis*>(&other)) {
81  if (size() != otherAxis->size())
82  return false;
83  if (!algo::almostEqual(m_start, otherAxis->m_start))
84  return false;
85  if (!algo::almostEqual(m_end, otherAxis->m_end))
86  return false;
87  return true;
88  }
89  return false;
90 }
91 
92 void ConstKBinAxis::print(std::ostream& ostr) const
93 {
94  ostr << "ConstKBinAxis(\"" << getName() << "\", " << size() << ", "
95  << std::setprecision(std::numeric_limits<double>::digits10 + 2) << m_start << ", " << m_end
96  << ")";
97 }
Defines and implements namespace algo with some algorithms.
Defines class ConstKBinAxis.
Axis with fixed bin size in sin(angle) space.
Definition: ConstKBinAxis.h:23
void print(std::ostream &ostr) const override
ConstKBinAxis * createClippedAxis(double left, double right) const override
Creates a new clipped axis.
bool equals(const IAxis &other) const override
ConstKBinAxis(const std::string &name, size_t nbins, double start, double end)
ConstKBinAxis constructor.
ConstKBinAxis * clone() const override
clone function
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 with variable bin size.
double upperBound() const
Returns value of last point of axis.
size_t size() const
retrieve the number of bins
void setBinBoundaries(const std::vector< double > &bin_boundaries)
std::vector< double > binBoundaries() const
Bin1D bin(size_t index) const
retrieve a 1d bin for the given index
double lowerBound() const
Returns value of first point of axis.
size_t findClosestIndex(double value) const
find bin index which is best match for given value
QString const & name(EShape k)
Definition: particles.cpp:21
bool almostEqual(double a, double b)
Returns true if two doubles agree within machine epsilon.
Definition: Algorithms.h:34
double center() const
Definition: Bin.h:25