Skip to content

Commit

Permalink
Refs #4399. PyObject->Matrix converter.
Browse files Browse the repository at this point in the history
Removes the last hacky conversion function.
  • Loading branch information
martyngigg committed Feb 23, 2012
1 parent 331f38c commit b4ffba0
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 121 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#ifndef MANTID_PYTHONINERFACE_PYOBJECTTOMATRIX_H_
#define MANTID_PYTHONINERFACE_PYOBJECTTOMATRIX_H_
/**
Copyright © 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
#include "MantidKernel/System.h"
#include "MantidKernel/Matrix.h"
#include <boost/python/object.hpp>

namespace Mantid
{
namespace PythonInterface
{
namespace Converters
{
/**
* Takes a Python object and if it supports
* indexing and is two dimensional it attempts to
* convert it to a Kernel::Matrix object. Note, this
* currently only suuports Matrix<double>
*/
struct DLLExport PyObjectToMatrix
{
PyObjectToMatrix(const boost::python::object & p);
/// Produces a V3D object from the given PyObject
Kernel::Matrix<double> operator()();
private:
/// A reference to the object
const boost::python::object & m_obj;
/// Is the object a wrapped instance of Matrix<double>
bool m_alreadyMatrix;
};
}

}
}

#endif /* MANTID_PYTHONINERFACE_PYOBJECTTOMATRIX_H_ */

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Includes
//-----------------------------------------------------------------------------
#include "MantidPythonInterface/api/CloneMatrixWorkspace.h"
#include "MantidPythonInterface/kernel/NumpyConverters.h"
#include "MantidAPI/MatrixWorkspace.h"

#include <boost/python/extract.hpp>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "MantidGeometry/Crystal/OrientedLattice.h"
#include "MantidPythonInterface/kernel/Converters/MatrixToNDArray.h"
#include "MantidPythonInterface/kernel/Converters/PyObjectToV3D.h"
#include "MantidPythonInterface/kernel/Policies/MatrixToNumpy.h"
#include "MantidPythonInterface/kernel/Converters/PyObjectToMatrix.h"

#include "MantidPythonInterface/kernel/NumpyConverters.h"
#include "MantidPythonInterface/kernel/Policies/MatrixToNumpy.h"
#include <boost/python/class.hpp>

using Mantid::Geometry::OrientedLattice;
Expand All @@ -16,15 +16,15 @@ namespace //<unnamed>
using namespace Mantid::PythonInterface;

/// Set the U vector via a numpy array
void setU(OrientedLattice & self, PyObject *data)
void setU(OrientedLattice & self, object data)
{
self.setU(Numpy::createDoubleMatrix(data));
self.setU(Converters::PyObjectToMatrix(data)());
}

/// Set the U vector via a numpy array
void setUB(OrientedLattice & self, PyObject *data)
void setUB(OrientedLattice & self, object data)
{
self.setUB(Numpy::createDoubleMatrix(data));
self.setUB(Converters::PyObjectToMatrix(data)());
}

/// Set the U matrix from 2 Python objects representing a V3D type. This can be a V3D object, a list
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "MantidGeometry/Crystal/UnitCell.h"
#include "MantidPythonInterface/kernel/Converters/MatrixToNDArray.h"
#include "MantidPythonInterface/kernel/Converters/PyObjectToMatrix.h"
#include "MantidPythonInterface/kernel/Policies/MatrixToNumpy.h"

#include "MantidPythonInterface/kernel/NumpyConverters.h"
#include <boost/python/class.hpp>
#include <boost/python/enum.hpp>
#include <boost/python/scope.hpp>
Expand All @@ -21,10 +21,10 @@ namespace //<unnamed>
using namespace Mantid::PythonInterface;

/// Pass-through function to set the unit cell from a 2D numpy array
void recalculateFromGstar(UnitCell & self, PyObject* values)
void recalculateFromGstar(UnitCell & self, object values)
{
// Create a double matrix and put this in to the unit cell
self.recalculateFromGstar(Numpy::createDoubleMatrix(values));
self.recalculateFromGstar(Converters::PyObjectToMatrix(values)());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ set ( SRC_FILES
src/Converters/NDArrayToVector.cpp
src/Converters/NDArrayTypeIndex.cpp
src/Converters/PyArrayType.cpp
src/Converters/PyObjectToMatrix.cpp
src/Converters/PyObjectToV3D.cpp
src/Converters/VectorToNDArray.cpp
src/Registry/SequenceTypeHandler.cpp
src/Registry/TypeRegistry.cpp
src/Registry/UpcastRegistry.cpp
src/PyEnvironment.cpp
src/NumpyConverters.cpp
src/WrapperHelpers.cpp
)

Expand All @@ -47,6 +47,8 @@ set ( INC_FILES
${HEADER_DIR}/kernel/Converters/NumpyWrapMode.h
${HEADER_DIR}/kernel/Converters/VectorToNDArray.h
${HEADER_DIR}/kernel/Converters/PyArrayType.h
${HEADER_DIR}/kernel/Converters/PyObjectToMatrix.h
${HEADER_DIR}/kernel/Converters/PyObjectToV3D.h
${HEADER_DIR}/kernel/Converters/PySequenceToVector.h
${HEADER_DIR}/kernel/Policies/MatrixToNumpy.h
${HEADER_DIR}/kernel/Policies/VectorToNumpy.h
Expand All @@ -61,7 +63,6 @@ set ( INC_FILES
${HEADER_DIR}/kernel/PropertyWithValue.h
${HEADER_DIR}/kernel/PyEnvironment.h
${HEADER_DIR}/kernel/StlExportDefinitions.h
${HEADER_DIR}/kernel/NumpyConverters.h
${HEADER_DIR}/kernel/WrapperHelpers.h
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//----------------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------------
#include "MantidPythonInterface/kernel/Converters/PyObjectToMatrix.h"
#include <boost/python/extract.hpp>
#include <boost/python/numeric.hpp>

// See http://docs.scipy.org/doc/numpy/reference/c-api.array.html#PY_ARRAY_UNIQUE_SYMBOL
#define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API
#define NO_IMPORT_ARRAY
#include <numpy/arrayobject.h>

namespace Mantid
{
namespace PythonInterface
{
namespace Converters
{
/**
* Construct the converter object with the given Python object
* @param p :: A boost::python object that should support
* the __getitem__ and __len__ protocol or be a wrapped V3D object.
* Throws std::invalid_argument if not
* if that is not the case.
*/
PyObjectToMatrix::PyObjectToMatrix(const boost::python::object & p)
: m_obj(p), m_alreadyMatrix(false)
{
// Is it an already wrapped V3D ?
boost::python::extract<Kernel::Matrix<double> > converter(p);
if( converter.check() )
{
m_alreadyMatrix = true;
return;
}
// Is it a 2D numpy array
if( !PyArray_Check(p.ptr()) )
{
throw std::invalid_argument(std::string("Cannot convert object to Matrix. Expected a numpy array found ")
+ p.ptr()->ob_type->tp_name);
}
}

/**
* Returns a V3D object from the Python object given
* to the converter
* @returns A newly constructed V3D object converted
* from the PyObject.
*/
Kernel::Matrix<double> PyObjectToMatrix::operator ()()
{
using namespace boost::python;
if(m_alreadyMatrix)
{
return extract<Kernel::Matrix<double> >(m_obj)();
}
numeric::array numarray = numeric::array(m_obj);
numarray = (boost::python::numeric::array) numarray.astype('d'); // Force the array to be of double type (in case it was int)
boost::python::tuple shape( numarray.attr("shape") );
if( boost::python::len(shape) != 2 )
{
std::ostringstream msg;
msg << "Error in conversion to Matrix. Expected an array with 2 dimensions but was given array with "
<< boost::python::len(shape) << " dimensions.";
throw std::invalid_argument(msg.str());
}
size_t nx = boost::python::extract<size_t>(shape[0]);
size_t ny = boost::python::extract<size_t>(shape[1]);
Kernel::Matrix<double> matrix(nx,ny);
for( size_t i = 0; i < nx; i++ )
{
for( size_t j = 0; j < ny; j++ )
{
matrix[i][j] = extract<double>( numarray[boost::python::make_tuple( i, j )]);
}
}
return matrix;
}
}
}
}

This file was deleted.

0 comments on commit b4ffba0

Please sign in to comment.