BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
Histogram2D.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Device/Histo/Histogram2D.cpp
6 //! @brief Implements class Histogram2D.
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 
18 #include <memory>
19 
20 Histogram2D::Histogram2D(int nbinsx, double xlow, double xup, int nbinsy, double ylow, double yup)
21 {
22  m_data.addAxis(FixedBinAxis("x-axis", nbinsx, xlow, xup));
23  m_data.addAxis(FixedBinAxis("y-axis", nbinsy, ylow, yup));
24 }
25 
26 Histogram2D::Histogram2D(int nbinsx, const std::vector<double>& xbins, int nbinsy,
27  const std::vector<double>& ybins)
28 {
29  m_data.addAxis(VariableBinAxis("x-axis", nbinsx, xbins));
30  m_data.addAxis(VariableBinAxis("y-axis", nbinsy, ybins));
31 }
32 
33 Histogram2D::Histogram2D(const IAxis& axis_x, const IAxis& axis_y) : IHistogram(axis_x, axis_y) {}
34 
36 {
37  init_from_data(data);
38 }
39 
40 // IMPORTANT intentionally passed by copy to avoid problems on Python side
41 Histogram2D::Histogram2D(std::vector<std::vector<double>> data)
42 {
43  initFromShape(data);
44  this->setContent(data);
45 }
46 
48 {
49  return new Histogram2D(*this);
50 }
51 
52 int Histogram2D::fill(double x, double y, double weight)
53 {
54  if (x < getXaxis().getMin() || x >= getXaxis().getMax())
55  return -1;
56  if (y < getYaxis().getMin() || y >= getYaxis().getMax())
57  return -1;
58  size_t index = m_data.findGlobalIndex({x, y});
59  m_data[index].add(weight);
60  return (int)index;
61 }
62 
64 {
65  return create_projectionX(0, static_cast<int>(getXaxis().size()) - 1);
66 }
67 
69 {
70  int ybin_selected = static_cast<int>(getYaxis().findClosestIndex(yvalue));
71  return create_projectionX(ybin_selected, ybin_selected);
72 }
73 
74 Histogram1D* Histogram2D::projectionX(double ylow, double yup)
75 {
76  int ybinlow = static_cast<int>(getYaxis().findClosestIndex(ylow));
77  int ybinup = static_cast<int>(getYaxis().findClosestIndex(yup));
78  return create_projectionX(ybinlow, ybinup);
79 }
80 
82 {
83  return create_projectionY(0, static_cast<int>(getXaxis().size()) - 1);
84 }
85 
87 {
88  int xbin_selected = static_cast<int>(getXaxis().findClosestIndex(xvalue));
89  return create_projectionY(xbin_selected, xbin_selected);
90 }
91 
92 Histogram1D* Histogram2D::projectionY(double xlow, double xup)
93 {
94  int xbinlow = static_cast<int>(getXaxis().findClosestIndex(xlow));
95  int xbinup = static_cast<int>(getXaxis().findClosestIndex(xup));
96  return create_projectionY(xbinlow, xbinup);
97 }
98 
99 Histogram2D* Histogram2D::crop(double xmin, double ymin, double xmax, double ymax)
100 {
101  const std::unique_ptr<IAxis> xaxis(getXaxis().createClippedAxis(xmin, xmax));
102  const std::unique_ptr<IAxis> yaxis(getYaxis().createClippedAxis(ymin, ymax));
103 
104  Histogram2D* result = new Histogram2D(*xaxis, *yaxis);
106  OutputData<CumulativeValue>::iterator it_result = result->m_data.begin();
107  while (it_origin != m_data.end()) {
108  double x = m_data.getAxisValue(it_origin.getIndex(), 0);
109  double y = m_data.getAxisValue(it_origin.getIndex(), 1);
110  if (result->getXaxis().contains(x) && result->getYaxis().contains(y)) {
111  *it_result = *it_origin;
112  ++it_result;
113  }
114  ++it_origin;
115  }
116  return result;
117 }
118 
119 void Histogram2D::setContent(const std::vector<std::vector<double>>& data)
120 {
121  reset();
122  addContent(data);
123 }
124 
125 void Histogram2D::addContent(const std::vector<std::vector<double>>& data)
126 {
127  auto shape = ArrayUtils::getShape(data);
128  const size_t nrows = shape.first;
129  const size_t ncols = shape.second;
130 
131  if (nrows != m_data.getAxis(1).size() || ncols != m_data.getAxis(0).size()) {
132  std::ostringstream ostr;
133  ostr << "Histogram2D::addContent() -> Shape of input array [" << nrows << ", " << ncols
134  << "] doesn't mach histogram axes. "
135  << "X-axis size: " << m_data.getAxis(0).size()
136  << "Y-axis size: " << m_data.getAxis(1).size();
137  throw Exceptions::LogicErrorException(ostr.str());
138  }
139 
140  for (size_t row = 0; row < nrows; ++row) {
141  for (size_t col = 0; col < ncols; ++col) {
142  size_t globalbin = nrows - row - 1 + col * nrows;
143  m_data[globalbin].add(data[row][col]);
144  }
145  }
146 }
147 
149 {
150  Histogram1D* result = new Histogram1D(this->getXaxis());
151 
152  for (size_t index = 0; index < getTotalNumberOfBins(); ++index) {
153 
154  int ybin = static_cast<int>(getYaxisIndex(index));
155 
156  if (ybin >= ybinlow && ybin <= ybinup) {
157  result->fill(getXaxisValue(index), getBinContent(index));
158  }
159  }
160  return result;
161 }
162 
164 {
165  Histogram1D* result = new Histogram1D(this->getYaxis());
166 
167  for (size_t index = 0; index < getTotalNumberOfBins(); ++index) {
168 
169  int xbin = static_cast<int>(getXaxisIndex(index));
170 
171  if (xbin >= xbinlow && xbin <= xbinup) {
172  result->fill(getYaxisValue(index), getBinContent(index));
173  }
174  }
175  return result;
176 }
Defines class Histogram1D.
Defines class Histogram2D.
Defines class VariableBinAxis.
Axis with fixed bin size.
Definition: FixedBinAxis.h:24
One dimensional histogram.
Definition: Histogram1D.h:24
int fill(double x, double weight=1.0)
Increment bin with abscissa x with a weight.
Definition: Histogram1D.cpp:42
Two dimensional histogram.
Definition: Histogram2D.h:25
Histogram1D * create_projectionY(int xbinlow, int xbinup)
Creates projection along Y.
void setContent(const std::vector< std::vector< double >> &data)
Sets the values in histograms channels from numpy array,.
int fill(double x, double y, double weight=1.0)
Increment bin with abscissa x and ordinate y with a weight.
Definition: Histogram2D.cpp:52
void addContent(const std::vector< std::vector< double >> &data)
Add to values in histograms channels from numpy array,.
Histogram1D * projectionY()
Project a 2D histogram into 1D histogram along Y.
Definition: Histogram2D.cpp:81
void initFromShape(const T &data)
Definition: Histogram2D.h:115
Histogram2D * crop(double xmin, double ymin, double xmax, double ymax)
Creates new histogram by applying rectangular clip.
Definition: Histogram2D.cpp:99
Histogram1D * projectionX()
Project a 2D histogram into 1D histogram along X.
Definition: Histogram2D.cpp:63
Histogram2D(int nbinsx, double xlow, double xup, int nbinsy, double ylow, double yup)
Constructor for fix bin size histograms.
Definition: Histogram2D.cpp:20
Histogram1D * create_projectionX(int ybinlow, int ybinup)
Creates projection along X.
Histogram2D * clone() const
Returns clone of other histogram.
Definition: Histogram2D.cpp:47
Interface for one-dimensional axes.
Definition: IAxis.h:25
virtual bool contains(double value) const
Returns true if axis contains given point.
Definition: IAxis.cpp:40
virtual size_t findClosestIndex(double value) const =0
find bin index which is best match for given value
virtual size_t size() const =0
retrieve the number of bins
Base class for 1D and 2D histograms holding values of double type.
Definition: IHistogram.h:27
double getYaxisValue(size_t i)
Returns the center of bin i of the y axis.
Definition: IHistogram.cpp:120
OutputData< CumulativeValue > m_data
Definition: IHistogram.h:193
double getBinContent(size_t i) const
Returns content (accumulated value) of bin i.
Definition: IHistogram.cpp:126
size_t getYaxisIndex(size_t i) const
Returns y-axis index for global bin index i.
Definition: IHistogram.cpp:109
size_t getTotalNumberOfBins() const
Returns total number of histogram bins.
Definition: IHistogram.cpp:39
size_t getXaxisIndex(size_t i) const
Returns x-axis index for global bin index i.
Definition: IHistogram.cpp:104
const IAxis & getYaxis() const
returns y-axis for 2D histograms
Definition: IHistogram.cpp:50
void reset()
Reset histogram content (axes remains)
Definition: IHistogram.cpp:228
double getXaxisValue(size_t i)
Returns the center of bin i of the x axis.
Definition: IHistogram.cpp:114
void init_from_data(const OutputData< double > &source)
Definition: IHistogram.cpp:278
const IAxis & getXaxis() const
returns x-axis
Definition: IHistogram.cpp:44
iterator end()
Returns read/write iterator that points to the one past last element.
Definition: OutputData.h:96
size_t findGlobalIndex(const std::vector< double > &coordinates) const
Returns global index for specified axes values.
Definition: OutputData.h:418
void addAxis(const IAxis &new_axis)
Definition: OutputData.h:289
const IAxis & getAxis(size_t serial_number) const
returns axis with given serial number
Definition: OutputData.h:314
iterator begin()
Returns read/write iterator that points to the first element.
Definition: OutputData.h:344
double getAxisValue(size_t global_index, size_t i_selected_axis) const
Returns the value of selected axis for given global_index.
Definition: OutputData.h:433
Axis with variable bin size.
std::pair< size_t, size_t > getShape(const T &data)
Returns shape nrows, ncols of 2D array.
Definition: ArrayUtils.h:123