Mantid
Loading...
Searching...
No Matches
NDArrayToVector.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//-----------------------------------------------------------------------------
8// Includes
9//-----------------------------------------------------------------------------
13
14#include <boost/python/extract.hpp>
15#include <boost/python/stl_iterator.hpp>
16#include <boost/python/str.hpp>
17
18#define PY_ARRAY_UNIQUE_SYMBOL CORE_ARRAY_API
19#define NO_IMPORT_ARRAY
20#include <numpy/arrayobject.h>
21
22using boost::python::extract;
23using boost::python::handle;
24using boost::python::object;
25using boost::python::str;
26
28namespace Converters {
29
32#define DECLARE_EXTERN(HeldType) \
33 extern template int NDArrayTypeIndex<HeldType>::typenum; \
34 extern template char NDArrayTypeIndex<HeldType>::typecode;
35
39DECLARE_EXTERN(long long)
40DECLARE_EXTERN(unsigned int)
41DECLARE_EXTERN(unsigned long)
42DECLARE_EXTERN(unsigned long long)
43DECLARE_EXTERN(double)
44DECLARE_EXTERN(float)
45
46} // namespace Converters
47
48namespace {
49
50//-------------------------------------------------------------------------
51// Template helpers
52//-------------------------------------------------------------------------
59template <typename DestElementType> struct CopyToImpl {
61 PyArrayObject *arr) {
62 // Use the iterator API to iterate through the array
63 // and assign each value to the corresponding vector
64 object iter(handle<>(Converters::Impl::func_PyArray_IterNew(arr)));
65 do {
66 void *data = PyArray_ITER_DATA(iter.ptr());
67 *first++ = *static_cast<DestElementType *>(data);
68 PyArray_ITER_NEXT(iter.ptr());
69 } while (PyArray_ITER_NOTDONE(iter.ptr()));
70 }
71};
72
77template <> struct CopyToImpl<std::string> {
78 void operator()(typename std::vector<std::string>::iterator first, PyArrayObject *arr) {
79 object flattened(handle<>(PyArray_Ravel(arr, NPY_CORDER)));
80 const Py_ssize_t nelements = PyArray_Size(flattened.ptr());
81 for (Py_ssize_t i = 0; i < nelements; ++i) {
82 *first++ = extract<std::string>(str(flattened[i]))();
83 }
84 }
85};
86
92template <typename DestElementType> struct CoerceType {
93 NDArray operator()(const NDArray &x) {
95 }
96};
97
102template <> struct CoerceType<std::string> {
103 object operator()(const NDArray &x) { return x; }
104};
105} // namespace
106
107namespace Converters {
108//-------------------------------------------------------------------------
109// NDArrayToVector definitions
110//-------------------------------------------------------------------------
111
116template <typename DestElementType>
117NDArrayToVector<DestElementType>::NDArrayToVector(const NDArray &value) : m_arr(CoerceType<DestElementType>()(value)) {}
118
124template <typename DestElementType>
126 std::vector<DestElementType> cvector(PyArray_SIZE((PyArrayObject *)m_arr.ptr()));
127 copyTo(cvector);
128 return cvector;
129}
130
136template <typename DestElementType> void NDArrayToVector<DestElementType>::copyTo(TypedVector &dest) const {
137 if (PyArray_SIZE((PyArrayObject *)m_arr.ptr()) > 0) {
138 throwIfSizeMismatched(dest);
139 CopyToImpl<DestElementType>()(std::begin(dest), (PyArrayObject *)m_arr.ptr());
140 }
141}
142
149template <typename DestElementType>
151 if (PyArray_SIZE((PyArrayObject *)m_arr.ptr()) == static_cast<ssize_t>(dest.size())) {
152 return;
153 } else {
154 throw std::invalid_argument("Invalid number of elements while copying from ndarray. "
155 "ndarray=" +
156 std::to_string(PyArray_SIZE((PyArrayObject *)m_arr.ptr())) + " destination=(" +
157 std::to_string(dest.size()) + ",)");
158 }
159}
160
161//------------------------------------------------------------------------
162// Explicit instantiations
163//------------------------------------------------------------------------
164#define INSTANTIATE_TOVECTOR(ElementType) template struct DLLExport NDArrayToVector<ElementType>;
165
169INSTANTIATE_TOVECTOR(long long)
170INSTANTIATE_TOVECTOR(unsigned int)
171INSTANTIATE_TOVECTOR(unsigned long)
172INSTANTIATE_TOVECTOR(unsigned long long)
176INSTANTIATE_TOVECTOR(std::string)
178} // namespace Converters
179} // namespace Mantid::PythonInterface
double value
The value of the point.
Definition: FitMW.cpp:51
#define INSTANTIATE_TOVECTOR(ElementType)
#define DECLARE_EXTERN(HeldType)
Macro to declare template instantiations as extern; those are defined in NDArrayTypeIndex....
tagPyArrayObject PyArrayObject
Thin object wrapper around a numpy array.
Definition: NDArray.h:31
MANTID_PYTHONINTERFACE_CORE_DLL PyObject * func_PyArray_IterNew(PyArrayObject *arr)
equivalent to macro PyArray_IterNew
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)
Converter taking an input numpy array and converting it to a std::vector.
void throwIfSizeMismatched(const TypedVector &dest) const
void copyTo(TypedVector &dest) const
Fill the container with data from the array.
TypedVector operator()()
Create a new vector from the contents of the array.
Defines a mapping between C++ type given by the template parameter and numpy type enum NPY_TYPES.