14#include <boost/python/errors.hpp>
15#include <boost/python/extract.hpp>
21#define PY_ARRAY_UNIQUE_SYMBOL API_ARRAY_API
22#define NO_IMPORT_ARRAY
23#include <numpy/arrayobject.h>
32enum DataField { XValues = 0, YValues = 1, EValues = 2, DxValues = 3 };
41template <DataField Field>
decltype(
auto) fieldData(MatrixWorkspace
const &
workspace,
size_t const index) {
44 throw std::logic_error(
"fieldData does not handle this DataField");
47template <>
decltype(
auto) fieldData<XValues>(MatrixWorkspace
const &
workspace,
size_t const index) {
51template <>
decltype(
auto) fieldData<YValues>(MatrixWorkspace
const &
workspace,
size_t const index) {
55template <>
decltype(
auto) fieldData<EValues>(MatrixWorkspace
const &
workspace,
size_t const index) {
59template <>
decltype(
auto) fieldData<DxValues>(MatrixWorkspace
const &
workspace,
size_t const index) {
70template <DataField Field>
size_t fieldSize(MatrixWorkspace
const &
workspace,
size_t const index) {
73 throw std::logic_error(
"fieldSize does not handle this DataField");
76template <>
size_t fieldSize<XValues>(MatrixWorkspace
const &
workspace,
size_t const index) {
80template <>
size_t fieldSize<YValues>(MatrixWorkspace
const &
workspace,
size_t const index) {
84template <>
size_t fieldSize<EValues>(MatrixWorkspace
const &
workspace,
size_t const index) {
88template <>
size_t fieldSize<DxValues>(MatrixWorkspace
const &
workspace,
size_t const index) {
101template <DataField Field>
103 npy_intp
const numHist(endp1 - start);
104 npy_intp
const stride = numHist > 0 ?
static_cast<npy_intp
>(fieldSize<Field>(
workspace, start)) : 0;
107 for (npy_intp i = 1; i < numHist; ++i) {
108 if (
static_cast<npy_intp
>(fieldSize<Field>(
workspace, start + i)) != stride) {
109 throw std::length_error(
"Cannot extract data from a ragged workspace: the histograms do not all have the same "
110 "number of values.");
114 npy_intp arrayDims[2] = {numHist, stride};
116 reinterpret_cast<PyArrayObject *
>(PyArray_NewFromDescr(&PyArray_Type, PyArray_DescrFromType(NPY_DOUBLE),
119 nullptr,
nullptr, 0,
nullptr));
122 if (nparray ==
nullptr) {
123 throw boost::python::error_already_set();
125 auto *dest =
reinterpret_cast<double *
>(PyArray_DATA(nparray));
128 for (npy_intp i = 0; i < numHist; ++i) {
129 auto const &src = fieldData<Field>(
workspace, start + i);
130 std::copy(src.begin(), src.end(), std::next(dest, i * stride));
144 return reinterpret_cast<PyObject *
>(cloneArray<XValues>(self, 0, self.
getNumberHistograms()));
152 return reinterpret_cast<PyObject *
>(cloneArray<YValues>(self, 0, self.
getNumberHistograms()));
161 return reinterpret_cast<PyObject *
>(cloneArray<EValues>(self, 0, self.
getNumberHistograms()));
170 return reinterpret_cast<PyObject *
>(cloneArray<DxValues>(self, 0, self.
getNumberHistograms()));
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
tagPyArrayObject PyArrayObject
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Base MatrixWorkspace Abstract Class.
virtual std::size_t getNumberHistograms() const =0
Returns the number of histograms in the workspace.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
PyObject * cloneE(const API::MatrixWorkspace &self)
Create a numpy array from the E values of the given workspace reference.
PyObject * cloneY(const API::MatrixWorkspace &self)
Create a numpy array from the Y values of the given workspace reference.
PyObject * cloneDx(const API::MatrixWorkspace &self)
Create a numpy array from the E values of the given workspace reference.
PyObject * cloneX(const API::MatrixWorkspace &self)