BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
IHistogram.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Device/Histo/IHistogram.cpp
6 //! @brief Implements class IntensityDataObject.
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 
17 #include "Device/Histo/IntensityDataIOFactory.h" // TODO rm
18 #include "Fit/TestEngine/Numeric.h"
19 #include <memory>
20 
21 IHistogram::IHistogram() = default;
22 
24 {
25  m_data.copyFrom(other.m_data);
26 }
27 
29 {
30  m_data.addAxis(axis_x);
31 }
32 
33 IHistogram::IHistogram(const IAxis& axis_x, const IAxis& axis_y)
34 {
35  m_data.addAxis(axis_x);
36  m_data.addAxis(axis_y);
37 }
38 
40 {
41  return m_data.getAllocatedSize();
42 }
43 
45 {
46  check_x_axis();
47  return m_data.getAxis(0);
48 }
49 
51 {
52  check_y_axis();
53  return m_data.getAxis(1);
54 }
55 
56 double IHistogram::getXmin() const
57 {
58  return getXaxis().getMin();
59 }
60 
61 double IHistogram::getXmax() const
62 {
63  return getXaxis().getMax();
64 }
65 
66 size_t IHistogram::getNbinsX() const
67 {
68  return getXaxis().size();
69 }
70 
71 double IHistogram::getYmin() const
72 {
73  return getYaxis().getMin();
74 }
75 
76 double IHistogram::getYmax() const
77 {
78  return getYaxis().getMax();
79 }
80 
81 size_t IHistogram::getNbinsY() const
82 {
83  return getYaxis().size();
84 }
85 
86 size_t IHistogram::getGlobalBin(size_t binx, size_t biny) const
87 {
88  std::vector<unsigned> axes_indices;
89  axes_indices.push_back(static_cast<unsigned>(binx));
90  if (getRank() == 2)
91  axes_indices.push_back(static_cast<unsigned>(biny));
92  return m_data.toGlobalIndex(axes_indices);
93 }
94 
95 size_t IHistogram::findGlobalBin(double x, double y) const
96 {
97  std::vector<double> coordinates;
98  coordinates.push_back(x);
99  if (getRank() == 2)
100  coordinates.push_back(y);
101  return m_data.findGlobalIndex(coordinates);
102 }
103 
104 size_t IHistogram::getXaxisIndex(size_t i) const
105 {
106  return m_data.getAxisBinIndex(i, 0);
107 }
108 
109 size_t IHistogram::getYaxisIndex(size_t i) const
110 {
111  return m_data.getAxisBinIndex(i, 1);
112 }
113 
115 {
116  check_x_axis();
117  return m_data.getAxisValue(i, 0);
118 }
119 
121 {
122  check_y_axis();
123  return m_data.getAxisValue(i, 1);
124 }
125 
126 double IHistogram::getBinContent(size_t i) const
127 {
128  return m_data[i].getContent();
129 }
130 
131 double IHistogram::getBinContent(size_t binx, size_t biny) const
132 {
133  return getBinContent(getGlobalBin(binx, biny));
134 }
135 
136 void IHistogram::setBinContent(size_t i, double value)
137 {
138  m_data[i].setContent(value);
139 }
140 
141 void IHistogram::addBinContent(size_t i, double value)
142 {
143  m_data[i].add(value);
144 }
145 
146 double IHistogram::getBinError(size_t i) const
147 {
148  return m_data[i].getRMS();
149 }
150 
151 double IHistogram::getBinError(size_t binx, size_t biny) const
152 {
153  return getBinError(getGlobalBin(binx, biny));
154 }
155 
156 double IHistogram::getBinAverage(size_t i) const
157 {
158  return m_data[i].getAverage();
159 }
160 
161 double IHistogram::getBinAverage(size_t binx, size_t biny) const
162 {
163  return getBinAverage(getGlobalBin(binx, biny));
164 }
165 
167 {
168  return m_data[i].getNumberOfEntries();
169 }
170 
171 int IHistogram::getBinNumberOfEntries(size_t binx, size_t biny) const
172 {
173  return getBinNumberOfEntries(getGlobalBin(binx, biny));
174 }
175 
177 {
179  return it->getContent();
180 }
181 
183 {
185  return std::distance(m_data.begin(), it);
186 }
187 
189 {
191  return it->getContent();
192 }
193 
195 {
196  return std::distance(m_data.begin(), std::min_element(m_data.begin(), m_data.end()));
197 }
198 
199 void IHistogram::scale(double value)
200 {
201  for (size_t index = 0; index < getTotalNumberOfBins(); ++index) {
202  m_data[index].setContent(value * m_data[index].getContent());
203  }
204 }
205 
206 double IHistogram::integral() const
207 {
208  double result(0.0);
209  for (size_t index = 0; index < getTotalNumberOfBins(); ++index) {
210  result += m_data[index].getContent();
211  }
212  return result;
213 }
214 
215 #ifdef BORNAGAIN_PYTHON
217 {
218  const std::unique_ptr<OutputData<double>> data(createOutputData(dataType));
219  return data->getArray();
220 }
221 
223 {
224  return array(dataType);
225 }
226 #endif // BORNAGAIN_PYTHON
227 
229 {
231 }
232 
234 {
235  if (source.getRank() == 1) {
236  return new Histogram1D(source);
237  } else if (source.getRank() == 2) {
238  return new Histogram2D(source);
239  } else {
240  std::ostringstream message;
241  message << "IHistogram::createHistogram(const OutputData<double>& source) -> Error. ";
242  message << "The rank of source " << source.getRank() << " ";
243  message << "is not suitable for creation neither 1-dim nor 2-dim histograms.";
244  throw Exceptions::LogicErrorException(message.str());
245  }
246 }
247 
249 {
251 }
252 
253 IHistogram* IHistogram::createFrom(const std::vector<std::vector<double>>& data)
254 {
255  return new Histogram2D(data);
256 }
257 
259 {
260  if (getRank() < 1) {
261  std::ostringstream message;
262  message << "IHistogram::check_x_axis() -> Error. X-xis does not exist. ";
263  message << "Rank of histogram " << getRank() << "." << std::endl;
264  throw Exceptions::LogicErrorException(message.str());
265  }
266 }
267 
269 {
270  if (getRank() < 2) {
271  std::ostringstream message;
272  message << "IHistogram::check_y_axis() -> Error. Y-axis does not exist. ";
273  message << "Rank of histogram " << getRank() << "." << std::endl;
274  throw Exceptions::LogicErrorException(message.str());
275  }
276 }
277 
279 {
280  if (getRank() != source.getRank()) {
281  std::ostringstream message;
282  message << "IHistogram::IHistogram(const OutputData<double>& data) -> Error. ";
283  message << "The dimension of this histogram " << getRank() << " ";
284  message << "is differ from the dimension of source " << m_data.getRank() << std::endl;
285  throw Exceptions::LogicErrorException(message.str());
286  }
287 
288  m_data.copyShapeFrom(source);
289  for (size_t i = 0; i < source.getAllocatedSize(); ++i) {
290  m_data[i].add(source[i]);
291  }
292 }
293 
294 //! returns data of requested type for globalbin number
295 double IHistogram::getBinData(size_t i, IHistogram::DataType dataType) const
296 {
297  if (dataType == DataType::INTEGRAL) {
298  return getBinContent(i);
299  } else if (dataType == DataType::AVERAGE) {
300  return getBinAverage(i);
301  } else if (dataType == DataType::STANDARD_ERROR) {
302  return getBinError(i);
303  } else if (dataType == DataType::NENTRIES) {
304  return getBinNumberOfEntries(i);
305  } else
307  "IHistogram::getBinData() -> Error. Unknown data type.");
308 }
309 
310 //! returns vector of values of requested DataType
311 std::vector<double> IHistogram::getDataVector(IHistogram::DataType dataType) const
312 {
313  std::vector<double> result;
314  result.resize(getTotalNumberOfBins(), 0.0);
315  for (size_t index = 0; index < getTotalNumberOfBins(); ++index) {
316  result[index] = getBinData(index, dataType);
317  }
318  return result;
319 }
320 
321 //! Copy content (but not the axes) from other histogram. Dimensions should be the same.
323 {
324  if (!hasSameDimensions(other))
326  "IHistogram::copyContentFrom() -> Error. Can't copy the data of different shape.");
327  reset();
328  for (size_t i = 0; i < getTotalNumberOfBins(); ++i) {
329  m_data[i] = other.m_data[i];
330  }
331 }
332 
333 //! creates new OutputData with histogram's shape and put there values corresponding to DataType
335 {
337  result->copyShapeFrom(m_data);
338  for (size_t i = 0; i < getTotalNumberOfBins(); ++i) {
339  (*result)[i] = getBinData(i, dataType);
340  }
341  return result;
342 }
343 
344 bool IHistogram::hasSameShape(const IHistogram& other) const
345 {
346  return m_data.hasSameShape(other.m_data);
347 }
348 
350 {
351  return m_data.hasSameDimensions(other.m_data);
352 }
353 
355 {
356  if (!hasSameDimensions(right))
358  "IHistogram::operator+=() -> Error. Histograms have different dimension");
359  for (size_t i = 0; i < getTotalNumberOfBins(); ++i)
360  addBinContent(i, right.getBinContent(i));
361  return *this;
362 }
363 
365 {
366  if (!hasSameDimensions(rhs))
367  throw Exceptions::LogicErrorException("IHistogram::relativeDifferenceHistogram() -> Error. "
368  "Histograms have different dimensions");
369 
370  IHistogram* result = this->clone();
371  result->reset();
372 
373  for (size_t i = 0; i < getTotalNumberOfBins(); ++i) {
375  result->setBinContent(i, diff);
376  }
377  return result;
378 }
379 
380 void IHistogram::save(const std::string& filename)
381 {
383 }
384 
385 void IHistogram::load(const std::string& filename)
386 {
387  const std::unique_ptr<IHistogram> hist(IntensityDataIOFactory::readIntensityData(filename));
388  copyContentFrom(*hist);
389 }
Defines class Histogram1D.
Defines class Histogram2D.
Defines class IntensityDataIOFactory.
Defines constants and "almost equal" in namespace Numeric.
_object PyObject
Definition: PyObject.h:20
The cumulative value with average and rms on-the-flight calculations.
One dimensional histogram.
Definition: Histogram1D.h:24
Two dimensional histogram.
Definition: Histogram2D.h:25
Interface for one-dimensional axes.
Definition: IAxis.h:25
virtual double getMin() const =0
Returns value of first point of axis.
virtual size_t size() const =0
retrieve the number of bins
virtual double getMax() const =0
Returns value of last point of axis.
Base class for 1D and 2D histograms holding values of double type.
Definition: IHistogram.h:27
double getYmin() const
Returns y-axis min (lower edge of first bin) for 2D histograms.
Definition: IHistogram.cpp:71
void addBinContent(size_t i, double value)
Add the value to the bin.
Definition: IHistogram.cpp:141
double getYmax() const
Returns y-axis max (upper edge of last bin) for 2D histograms.
Definition: IHistogram.cpp:76
void scale(double value)
Multiply this histogram (every bin content value) by a constant.
Definition: IHistogram.cpp:199
size_t findGlobalBin(double x, double y) const
Returns closest global bin index for given axes coordinates.
Definition: IHistogram.cpp:95
size_t getNbinsY() const
Returns number of bins on y-axis.
Definition: IHistogram.cpp:81
size_t getNbinsX() const
Returns number of bins on x-axis.
Definition: IHistogram.cpp:66
PyObject * getArray(DataType dataType=DataType::INTEGRAL) const
Definition: IHistogram.cpp:222
PyObject * array(DataType dataType=DataType::INTEGRAL) const
Returns numpy array with bin content (accumulated values).
Definition: IHistogram.cpp:216
size_t getGlobalBin(size_t binx, size_t biny=0) const
Returns global bin index for given axes indices. For 1D, just returns binx.
Definition: IHistogram.cpp:86
virtual size_t getRank() const =0
Returns number of histogram dimensions.
double getMinimum() const
Returns histogram minimum value (minimum of getBinContent() over all bins)
Definition: IHistogram.cpp:188
size_t getMinimumBinIndex() const
Returns globalbin index with minimum content.
Definition: IHistogram.cpp:194
void load(const std::string &filename)
Loads histogram from file, the shape of array in file should match Following formats are available: *...
Definition: IHistogram.cpp:385
double getBinData(size_t i, DataType dataType) const
returns data of requested type for globalbin number
Definition: IHistogram.cpp:295
void check_x_axis() const
Definition: IHistogram.cpp:258
double getXmin() const
Returns x-axis min (lower edge of first bin).
Definition: IHistogram.cpp:56
double getYaxisValue(size_t i)
Returns the center of bin i of the y axis.
Definition: IHistogram.cpp:120
OutputData< double > * createOutputData(DataType dataType=DataType::INTEGRAL) const
creates new OutputData with histogram's shape and values corresponding to DataType
Definition: IHistogram.cpp:334
std::vector< double > getDataVector(DataType dataType) const
returns vector of values of requested DataType
Definition: IHistogram.cpp:311
OutputData< CumulativeValue > m_data
Definition: IHistogram.h:193
static IHistogram * createFrom(const std::string &filename)
create new histogram from file content
Definition: IHistogram.cpp:248
void setBinContent(size_t i, double value)
Sets content of the bin corresponding to the globalbin number.
Definition: IHistogram.cpp:136
double integral() const
Returns integral of bins content (computed as a sum of all bin content).
Definition: IHistogram.cpp:206
double getBinContent(size_t i) const
Returns content (accumulated value) of bin i.
Definition: IHistogram.cpp:126
IHistogram * relativeDifferenceHistogram(const IHistogram &rhs)
returns histogram representing relative difference of two histograms.
Definition: IHistogram.cpp:364
size_t getYaxisIndex(size_t i) const
Returns y-axis index for global bin index i.
Definition: IHistogram.cpp:109
void check_y_axis() const
Definition: IHistogram.cpp:268
size_t getTotalNumberOfBins() const
Returns total number of histogram bins.
Definition: IHistogram.cpp:39
size_t getMaximumBinIndex() const
Returns globalbin index with maximum content.
Definition: IHistogram.cpp:182
size_t getXaxisIndex(size_t i) const
Returns x-axis index for global bin index i.
Definition: IHistogram.cpp:104
void copyContentFrom(const IHistogram &other)
Copy content (but not the axes) from other histogram. Dimensions should be the same.
Definition: IHistogram.cpp:322
double getMaximum() const
Returns histogram maximum value (maximum of getBinContent() over all bins)
Definition: IHistogram.cpp:176
void save(const std::string &filename)
Saves histogram in file Following formats are available: *.txt, *.tif, *.int (*.txt....
Definition: IHistogram.cpp:380
double getBinError(size_t i) const
Returns error of the bin with given index.
Definition: IHistogram.cpp:146
virtual IHistogram * clone() const =0
const IAxis & getYaxis() const
returns y-axis for 2D histograms
Definition: IHistogram.cpp:50
int getBinNumberOfEntries(size_t i) const
Returns number of entries in the bin with given index.
Definition: IHistogram.cpp:166
void reset()
Reset histogram content (axes remains)
Definition: IHistogram.cpp:228
double getBinAverage(size_t i) const
Returns average value in the bin with given index.
Definition: IHistogram.cpp:156
static IHistogram * createHistogram(const OutputData< double > &source)
Definition: IHistogram.cpp:233
double getXmax() const
Returns x-axis max (upper edge of last bin).
Definition: IHistogram.cpp:61
bool hasSameDimensions(const IHistogram &other) const
Returns true if object have same rank and number of axes bins.
Definition: IHistogram.cpp:349
bool hasSameShape(const IHistogram &other) const
Returns true if objects a) have same dimensions b) bin boundaries of axes coincide.
Definition: IHistogram.cpp:344
double getXaxisValue(size_t i)
Returns the center of bin i of the x axis.
Definition: IHistogram.cpp:114
const IHistogram & operator+=(const IHistogram &right)
addition-assignment operator for two histograms
Definition: IHistogram.cpp:354
void init_from_data(const OutputData< double > &source)
Definition: IHistogram.cpp:278
const IAxis & getXaxis() const
returns x-axis
Definition: IHistogram.cpp:44
static IHistogram * readIntensityData(const std::string &file_name)
Reads file and returns newly created Histogram object.
static void writeIntensityData(const IHistogram &histogram, const std::string &file_name)
Writes histogram in file.
Template class to store data of any type in multi-dimensional space.
Definition: OutputData.h:33
void copyFrom(const OutputData< T > &x)
Definition: OutputData.h:261
size_t getAxisBinIndex(size_t global_index, size_t i_selected_axis) const
Returns axis bin index for given global index.
Definition: OutputData.h:371
iterator end()
Returns read/write iterator that points to the one past last element.
Definition: OutputData.h:96
size_t toGlobalIndex(const std::vector< unsigned > &axes_indices) const
Returns global index for specified indices of axes.
Definition: OutputData.h:393
bool hasSameShape(const OutputData< U > &right) const
Returns true if objects a) have same dimensions b) bin boundaries of axes coincide.
Definition: OutputData.h:595
void setAllTo(const T &value)
Sets content of output data to specific value.
Definition: OutputData.h:479
size_t findGlobalIndex(const std::vector< double > &coordinates) const
Returns global index for specified axes values.
Definition: OutputData.h:418
void copyShapeFrom(const OutputData< U > &other)
Definition: OutputData.h:271
size_t getRank() const
Returns number of dimensions.
Definition: OutputData.h:59
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
bool hasSameDimensions(const OutputData< U > &right) const
Returns true if object have same dimensions and number of axes bins.
Definition: OutputData.h:578
iterator begin()
Returns read/write iterator that points to the first element.
Definition: OutputData.h:344
size_t getAllocatedSize() const
Returns total size of data buffer (product of bin number in every dimension).
Definition: OutputData.h:62
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
std::string filename(const std::string &path)
Returns path without directory part ("Foo/Bar/Doz.int.gz" -> "Doz.int.gz")
double GetRelativeDifference(double a, double b)
Returns the safe relative difference, which is 2(|a-b|)/(|a|+|b|) except in special cases.
Definition: Numeric.cpp:32