Skip to content
Snippets Groups Projects
Commit a3a5ec52 authored by Wuttke, Joachim's avatar Wuttke, Joachim
Browse files

+ Datafield::npErrors

parent 08fc1427
No related branches found
No related tags found
1 merge request!1965SimDataPair: keep uncertainties in experimental data instead of separate Datafield (#737a)
...@@ -19,6 +19,63 @@ ...@@ -19,6 +19,63 @@
#include "Base/Util/Assert.h" #include "Base/Util/Assert.h"
#include <algorithm> #include <algorithm>
#ifdef BORNAGAIN_PYTHON
#include "PyCore/Embed/PyInterpreter.h" // Numpy::arrayND, Numpy::getDataPtr
namespace {
PyObject* npExport(const Frame& frame, const std::vector<double>& flatData)
{
if (flatData.empty())
return nullptr;
// TODO: Thoroughly check this function regarding index manipulations
PyInterpreter::Numpy::initialize();
ASSERT(frame.rank() <= 2);
std::vector<size_t> dimensions;
for (size_t i = 0; i < frame.rank(); i++)
dimensions.push_back(frame.axis(i).size());
// for rot90 of 2-dim arrays to conform with numpy
if (dimensions.size() == 2)
std::swap(dimensions[0], dimensions[1]);
// creating ndarray objects describing size of dimensions
PyObjectPtr pyarray{PyInterpreter::Numpy::arrayND(dimensions)};
ASSERT(pyarray.valid());
// get the pointer to the data buffer of the array (assumed to be C-contiguous)
double* data{PyInterpreter::Numpy::getDataPtr(pyarray.get())};
ASSERT(data);
double* array_buffer = data;
// filling numpy array with output_data
if (frame.rank() == 2) {
for (size_t i = 0; i < frame.size(); ++i) {
std::vector<int> axes_indices = frame.allIndices(i);
size_t offset = axes_indices[0]
+ frame.axis(0).size() * (frame.axis(1).size() - 1 - axes_indices[1]);
array_buffer[offset] = flatData[i];
}
} else if (frame.rank() == 1) {
for (size_t i = 0; i < frame.size(); ++i)
*array_buffer++ = flatData[i];
} else
ASSERT_NEVER;
// returns a _new_ reference; ie. caller is responsible for the ref-count
return pyarray.release();
}
} // namespace
#endif // BORNAGAIN_PYTHON
Datafield::Datafield(std::string title, const Frame* frame, std::vector<double> values, Datafield::Datafield(std::string title, const Frame* frame, std::vector<double> values,
std::vector<double> errSigmas) std::vector<double> errSigmas)
: m_title(std::move(title)) : m_title(std::move(title))
...@@ -224,52 +281,14 @@ Datafield* Datafield::crop(double xmin, double xmax) const ...@@ -224,52 +281,14 @@ Datafield* Datafield::crop(double xmin, double xmax) const
#ifdef BORNAGAIN_PYTHON #ifdef BORNAGAIN_PYTHON
#include "PyCore/Embed/PyInterpreter.h" // Numpy::arrayND, Numpy::getDataPtr
PyObject* Datafield::npArray() const PyObject* Datafield::npArray() const
{ {
// TODO: Thoroughly check this function regarding index manipulations return ::npExport(frame(), flatVector());
}
PyInterpreter::Numpy::initialize();
ASSERT(rank() <= 2);
std::vector<size_t> dimensions;
for (size_t i = 0; i < rank(); i++)
dimensions.push_back(axis(i).size());
// for rot90 of 2-dim arrays to conform with numpy
if (dimensions.size() == 2)
std::swap(dimensions[0], dimensions[1]);
// creating ndarray objects describing size of dimensions
PyObjectPtr pyarray{PyInterpreter::Numpy::arrayND(dimensions)};
if (!pyarray.valid())
return nullptr;
// get the pointer to the data buffer of the array (assumed to be C-contiguous)
double* data{PyInterpreter::Numpy::getDataPtr(pyarray.get())};
if (!data)
return nullptr;
double* array_buffer = data;
// filling numpy array with output_data
if (rank() == 2) {
for (size_t i = 0; i < size(); ++i) {
std::vector<int> axes_indices = frame().allIndices(i);
size_t offset =
axes_indices[0] + axis(0).size() * (axis(1).size() - 1 - axes_indices[1]);
array_buffer[offset] = (*this)[i];
}
} else if (rank() == 1) {
for (size_t i = 0; i < size(); ++i)
*array_buffer++ = (*this)[i];
}
// returns a _new_ reference; ie. caller is responsible for the ref-count PyObject* Datafield::npErrors() const
return pyarray.release(); {
return ::npExport(frame(), errorSigmas());
} }
#endif // BORNAGAIN_PYTHON #endif // BORNAGAIN_PYTHON
......
...@@ -65,6 +65,7 @@ public: ...@@ -65,6 +65,7 @@ public:
#ifdef BORNAGAIN_PYTHON #ifdef BORNAGAIN_PYTHON
//! Returns data as Python numpy array. //! Returns data as Python numpy array.
PyObject* npArray() const; PyObject* npArray() const;
PyObject* npErrors() const;
#endif #endif
//... retrieve basic info //... retrieve basic info
......
...@@ -2093,6 +2093,10 @@ class Datafield(object): ...@@ -2093,6 +2093,10 @@ class Datafield(object):
r"""npArray(Datafield self) -> PyObject *""" r"""npArray(Datafield self) -> PyObject *"""
return _libBornAgainDevice.Datafield_npArray(self) return _libBornAgainDevice.Datafield_npArray(self)
def npErrors(self):
r"""npErrors(Datafield self) -> PyObject *"""
return _libBornAgainDevice.Datafield_npErrors(self)
def frame(self): def frame(self):
r"""frame(Datafield self) -> Frame""" r"""frame(Datafield self) -> Frame"""
return _libBornAgainDevice.Datafield_frame(self) return _libBornAgainDevice.Datafield_frame(self)
......
...@@ -29712,6 +29712,39 @@ fail: ...@@ -29712,6 +29712,39 @@ fail:
} }
   
   
SWIGINTERN PyObject *_wrap_Datafield_npErrors(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
Datafield *arg1 = (Datafield *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
PyObject *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Datafield, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Datafield_npErrors" "', argument " "1"" of type '" "Datafield const *""'");
}
arg1 = reinterpret_cast< Datafield * >(argp1);
{
try {
result = (PyObject *)((Datafield const *)arg1)->npErrors();
} catch (const std::exception& ex) {
// message shown in the Python interpreter
const std::string msg {
"BornAgain C++ Exception: " + std::string(ex.what())
};
SWIG_exception(SWIG_RuntimeError, msg.c_str());
}
}
resultobj = result;
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_Datafield_frame(PyObject *self, PyObject *args) { SWIGINTERN PyObject *_wrap_Datafield_frame(PyObject *self, PyObject *args) {
PyObject *resultobj = 0; PyObject *resultobj = 0;
Datafield *arg1 = (Datafield *) 0 ; Datafield *arg1 = (Datafield *) 0 ;
...@@ -40895,6 +40928,7 @@ static PyMethodDef SwigMethods[] = { ...@@ -40895,6 +40928,7 @@ static PyMethodDef SwigMethods[] = {
{ "Datafield_setAt", _wrap_Datafield_setAt, METH_VARARGS, "Datafield_setAt(Datafield self, size_t i, double val)"}, { "Datafield_setAt", _wrap_Datafield_setAt, METH_VARARGS, "Datafield_setAt(Datafield self, size_t i, double val)"},
{ "Datafield_valAt", _wrap_Datafield_valAt, METH_VARARGS, "Datafield_valAt(Datafield self, size_t i) -> double"}, { "Datafield_valAt", _wrap_Datafield_valAt, METH_VARARGS, "Datafield_valAt(Datafield self, size_t i) -> double"},
{ "Datafield_npArray", _wrap_Datafield_npArray, METH_O, "Datafield_npArray(Datafield self) -> PyObject *"}, { "Datafield_npArray", _wrap_Datafield_npArray, METH_O, "Datafield_npArray(Datafield self) -> PyObject *"},
{ "Datafield_npErrors", _wrap_Datafield_npErrors, METH_O, "Datafield_npErrors(Datafield self) -> PyObject *"},
{ "Datafield_frame", _wrap_Datafield_frame, METH_O, "Datafield_frame(Datafield self) -> Frame"}, { "Datafield_frame", _wrap_Datafield_frame, METH_O, "Datafield_frame(Datafield self) -> Frame"},
{ "Datafield_rank", _wrap_Datafield_rank, METH_O, "Datafield_rank(Datafield self) -> size_t"}, { "Datafield_rank", _wrap_Datafield_rank, METH_O, "Datafield_rank(Datafield self) -> size_t"},
{ "Datafield_axis", _wrap_Datafield_axis, METH_VARARGS, "Datafield_axis(Datafield self, size_t k) -> Scale"}, { "Datafield_axis", _wrap_Datafield_axis, METH_VARARGS, "Datafield_axis(Datafield self, size_t k) -> Scale"},
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment