BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
OutputData.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Device/Data/OutputData.cpp
6 //! @brief Implements template specializations of class OutputData.cpp.
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 "Device/Data/OutputData.h"
17 
18 #ifdef BORNAGAIN_PYTHON
19 
20 #include "Base/Utils/PythonCore.h"
21 
22 template <> PyObject* OutputData<double>::getArray() const
23 {
24  std::vector<size_t> dimensions;
25  for (size_t i = 0; i < getRank(); i++)
26  dimensions.push_back(getAxis(i).size());
27 
28  // for rot90 of 2-dim arrays to conform with numpy
29  if (dimensions.size() == 2)
30  std::swap(dimensions[0], dimensions[1]);
31 
32  // creating ndarray objects describing size of dimensions
33  npy_int ndim_numpy = (int)dimensions.size();
34  npy_intp* ndimsizes_numpy = new npy_intp[dimensions.size()];
35  for (size_t i = 0; i < dimensions.size(); i++)
36  ndimsizes_numpy[i] = dimensions[i];
37 
38  // creating standalone numpy array
39  PyObject* pyarray = PyArray_SimpleNew(ndim_numpy, ndimsizes_numpy, NPY_DOUBLE);
40  delete[] ndimsizes_numpy;
41  if (pyarray == nullptr)
42  throw Exceptions::RuntimeErrorException("ExportOutputData() -> Panic in PyArray_SimpleNew");
43 
44  // getting pointer to data buffer of numpy array
45  double* array_buffer = (double*)PyArray_DATA((PyArrayObject*)pyarray);
46 
47  // filling numpy array with output_data
48  if (getRank() == 2) {
49  for (size_t index = 0; index < getAllocatedSize(); ++index) {
50  std::vector<int> axes_indices = getAxesBinIndices(index);
51  size_t offset =
52  axes_indices[0]
53  + m_value_axes[0]->size() * (m_value_axes[1]->size() - 1 - axes_indices[1]);
54  array_buffer[offset] = (*this)[index];
55  }
56 
57  } else {
58  for (size_t index = 0; index < getAllocatedSize(); ++index)
59  *array_buffer++ = (*this)[index];
60  }
61 
62  return pyarray;
63 }
64 
65 #endif // BORNAGAIN_PYTHON
66 
67 template <> double OutputData<double>::getValue(size_t index) const
68 {
69  return (*this)[index];
70 }
71 
72 template <> double OutputData<CumulativeValue>::getValue(size_t index) const
73 {
74  return (*this)[index].getContent();
75 }
Defines class CumulativeValue.
void swap(OutputDataIterator< TValue, TContainer > &left, OutputDataIterator< TValue, TContainer > &right)
make Swappable
Defines and implements template class OutputData.
_object PyObject
Definition: PyObject.h:20
Includes python header and takes care of warnings.
virtual size_t size() const =0
retrieve the number of bins
double getValue(size_t index) const
Returns value or summed value, depending on T.
std::vector< int > getAxesBinIndices(size_t global_index) const
Returns vector of axes indices for given global index.
Definition: OutputData.h:356
size_t getRank() const
Returns number of dimensions.
Definition: OutputData.h:59
const IAxis & getAxis(size_t serial_number) const
returns axis with given serial number
Definition: OutputData.h:314
SafePointerVector< IAxis > m_value_axes
Definition: OutputData.h:234
size_t getAllocatedSize() const
Returns total size of data buffer (product of bin number in every dimension).
Definition: OutputData.h:62
PyObject * getArray() const
returns data as Python numpy array
size_t size() const