Mantid
Loading...
Searching...
No Matches
PyObjectToMatrix.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//----------------------------------------------------------------------------
12
13#include <boost/python/extract.hpp>
14
15// See
16// http://docs.scipy.org/doc/numpy/reference/c-api.array.html#PY_ARRAY_UNIQUE_SYMBOL
17#define PY_ARRAY_UNIQUE_SYMBOL CORE_ARRAY_API
18#define NO_IMPORT_ARRAY
19#include <numpy/arrayobject.h>
20
21using boost::python::extract;
22
31PyObjectToMatrix::PyObjectToMatrix(const boost::python::object &p) : m_obj(p), m_alreadyMatrix(false) {
32 // Is it an already wrapped V3D ?
33 extract<Kernel::Matrix<double>> converter(p);
34 if (converter.check()) {
35 m_alreadyMatrix = true;
36 return;
37 }
38 // Is it a 2D numpy array
39 if (!NDArray::check(p)) {
40 std::ostringstream msg;
41 msg << "Cannot convert object to Matrix. Expected numpy array, found " << p.ptr()->ob_type->tp_name;
42 throw std::invalid_argument(msg.str());
43 }
44 const auto ndim = PyArray_NDIM((PyArrayObject *)p.ptr());
45 if (ndim != 2) {
46 std::ostringstream msg;
47 msg << "Error converting numpy array to Matrix. Expected ndim=2, found "
48 "ndim="
49 << ndim << " dimensions.";
50 throw std::invalid_argument(msg.str());
51 }
52}
53
61 if (m_alreadyMatrix) {
62 return extract<Kernel::Matrix<double>>(m_obj)();
63 }
64 auto *ndarray =
65 (PyArrayObject *)PyArray_View((PyArrayObject *)m_obj.ptr(), PyArray_DescrFromType(NPY_DOUBLE), &PyArray_Type);
66 const auto shape = PyArray_DIMS(ndarray);
67 npy_intp nx(shape[0]), ny(shape[1]);
68 Kernel::Matrix<double> matrix(nx, ny);
69 for (npy_intp i = 0; i < nx; i++) {
70 auto row = matrix[i];
71 for (npy_intp j = 0; j < ny; j++) {
72 row[j] = *((double *)PyArray_GETPTR2(ndarray, i, j));
73 }
74 }
75 return matrix;
76}
77} // namespace Mantid::PythonInterface::Converters
tagPyArrayObject PyArrayObject
Numerical Matrix class.
Definition: Matrix.h:42
static bool check(const boost::python::object &obj)
Check if a python object points to an array type object.
Definition: NDArray.cpp:49
const boost::python::object & m_obj
A reference to the object.
Kernel::Matrix< double > operator()()
Produces a V3D object from the given PyObject.
PyObjectToMatrix(const boost::python::object &p)
Construct the converter object with the given Python object.
bool m_alreadyMatrix
Is the object a wrapped instance of Matrix<double>