Skip to content

Commit

Permalink
Start exporting methods from MDGeometry to Python.
Browse files Browse the repository at this point in the history
IMDWorkspace now inherits (python side) from both Workspace & MDGeoemetry.
Refs #6027
  • Loading branch information
martyngigg committed Aug 2, 2013
1 parent 0436efd commit 1dcfc55
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ set ( EXPORT_FILES
src/Exports/WorkspaceProperty.cpp
src/Exports/ITableWorkspace.cpp
src/Exports/ITableWorkspaceProperty.cpp
src/Exports/MDGeometry.cpp
src/Exports/IMDWorkspace.cpp
src/Exports/IMDHistoWorkspace.cpp
src/Exports/IMDHistoWorkspaceProperty.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

using Mantid::API::IMDWorkspace;
using Mantid::API::IMDWorkspace_sptr;
using Mantid::API::MDGeometry;
using Mantid::API::Workspace;
using namespace boost::python;

Expand All @@ -14,11 +15,9 @@ void export_IMDWorkspace()
REGISTER_SHARED_PTR_TO_PYTHON(IMDWorkspace);

// EventWorkspace class
class_< IMDWorkspace, bases<Workspace>, boost::noncopyable >("IMDWorkspace", no_init)
class_< IMDWorkspace, bases<Workspace, MDGeometry>, boost::noncopyable >("IMDWorkspace", no_init)
.def("getNPoints", &IMDWorkspace::getNPoints, "Returns the total number of points within the workspace")
.def("getNEvents", &IMDWorkspace::getNEvents, "Returns the total number of events, contributed to the workspace")
.def("getNumDims", &IMDWorkspace::getNumDims, "Returns the number of dimensions in the workspace")
.def("getDimension", &IMDWorkspace::getDimension, "Return the chosen dimension of the workspace")
;

REGISTER_SINGLEVALUE_HANDLER(IMDWorkspace_sptr);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "MantidAPI/MDGeometry.h"
#include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h"

#include <boost/python/class.hpp>
#include <boost/python/list.hpp>
#include <boost/python/return_value_policy.hpp>

using Mantid::API::MDGeometry;
using Mantid::Geometry::IMDDimension_const_sptr;
using Mantid::PythonInterface::Policies::VectorToNumpy;
using namespace boost::python;

namespace
{
/**
* Pass through method to convert a std::vector<IMDimension_sptr> to a Python list
* of IMDimension objects
* @param self The calling MDGeometry object
* @return A python list of objects converted from the return of self.getNonIntegratedDimensions()
*/
boost::python::list getNonIntegratedDimensionsAsPyList(const MDGeometry & self)
{
auto dimensions = self.getNonIntegratedDimensions();

boost::python::list nonIntegrated;
//auto converter = boost::python::to_python_value<IMDDimension_const_sptr>();
for(auto it = dimensions.begin(); it != dimensions.end(); ++it)
{
//auto item = converter(*it);
nonIntegrated.append(*it);
}
return nonIntegrated;
}

}

void export_MDGeometry()
{
class_<MDGeometry,boost::noncopyable>("MDGeometry", no_init)
.def("getNumDims", &MDGeometry::getNumDims, "Returns the number of dimensions present")

.def("getDimension", &MDGeometry::getDimension, (args("index")),
"Returns the description of the dimension at the given index (starts from 0). Raises RuntimeError if index is out of range.")

.def("getDimensionWithId", &MDGeometry::getDimensionWithId, (args("id")),
"Returns the description of the dimension with the given id string. Raises ValueError if the string is not a known id.")

.def("getDimensionIndexByName", &MDGeometry::getDimensionIndexByName, (args("name")),
"Returns the index of the dimension with the given name. Raises RuntimeError if the name does not exist.")

.def("getDimensionIndexById", &MDGeometry::getDimensionIndexById, (args("id")),
"Returns the index of the dimension with the given ID. Raises RuntimeError if the name does not exist.")

.def("getNonIntegratedDimensions", &getNonIntegratedDimensionsAsPyList,
"Returns the description objects of the non-integrated dimension as a python list of IMDDimension.")

.def("estimateResolution", &MDGeometry::estimateResolution, return_value_policy<VectorToNumpy>(),
"Returns a numpy array containing the width of the smallest bin in each dimension")

.def("getXDimension", &MDGeometry::getXDimension,
"Returns the dimension description mapped to X")

.def("getYDimension", &MDGeometry::getYDimension,
"Returns the dimension description mapped to Y")

.def("getZDimension", &MDGeometry::getZDimension,
"Returns the dimension description mapped to Z")

.def("getTDimension", &MDGeometry::getTDimension,
"Returns the dimension description mapped to time")
;
}

Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ set ( TEST_PY_FILES
ITableWorkspaceTest.py
JacobianTest.py
MatrixWorkspaceTest.py
MDGeometryTest.py
MDHistoWorkspaceTest.py
MultipleExperimentInfos.py
MultipleFilePropertyTest.py
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import mantid
from mantid.geometry import IMDDimension
from mantid.api import MDGeometry
import numpy
import unittest

from testhelpers import WorkspaceCreationHelper

class MDGeometryTest(unittest.TestCase):

_test_ndims = 4
_test_mdws = None

def setUp(self):
if self._test_mdws is None:
signal = 3.0
self.__class__._test_mdws = WorkspaceCreationHelper.makeFakeMDHistoWorkspace(signal, self._test_ndims) # A type of MDGeometry

#====================== Success cases ==================================================
def test_numDims_returns_expected_number(self):
self.assertEquals(self._test_ndims, self._test_mdws.getNumDims())

def test_getDimension_by_index_returns_IMDDimension_object_for_valid_index(self):
dimension = self._test_mdws.getDimension(0) # positional
self._check_is_dimension_with_id(dimension, "x")

def test_getDimension_by_id_returns_IMDDimension_object(self):
dimension = self._test_mdws.getDimensionWithId("y")
self._check_is_dimension_with_id(dimension, "y")

def test_getDimensionIndexByName_returns_correct_index_for_valid_name(self):
index = self._test_mdws.getDimensionIndexByName("z")
self.assertEqual(2, index)

def test_getDimensionIndexById_returns_correct_index_for_valid_id(self):
index = self._test_mdws.getDimensionIndexById("y")
self.assertEqual(1, index)

def test_getNonIntegratedDimensions_returns_unintegrated_dimensions_as_python_list(self):
non_integrated = self._test_mdws.getNonIntegratedDimensions()
self.assertTrue(isinstance(non_integrated, list))
self.assertEqual(4, len(non_integrated))

def test_estimateResolution_returns_1d_numpy_array_same_length_as_number_dims(self):
resolution = self._test_mdws.estimateResolution()
self.assertTrue(isinstance(resolution, numpy.ndarray))
self.assertEquals(1, len(resolution.shape))
self.assertEquals(4, resolution.shape[0])

def test_getXDimension_returns_correct_dimension_if_workspace_has_enough_dimensions(self):
dimension = self._test_mdws.getXDimension()
self._check_is_dimension_with_id(dimension, "x")

def test_getYDimension_returns_correct_dimension_if_workspace_has_enough_dimensions(self):
dimension = self._test_mdws.getYDimension()
self._check_is_dimension_with_id(dimension, "y")

def test_getZDimension_returns_correct_dimension_if_workspace_has_enough_dimensions(self):
dimension = self._test_mdws.getZDimension()
self._check_is_dimension_with_id(dimension, "z")

def test_getTDimension_returns_correct_dimension_if_workspace_has_enough_dimensions(self):
dimension = self._test_mdws.getTDimension()
self._check_is_dimension_with_id(dimension, "t")

#====================== Failure cases ==================================================

def test_getDimension_by_index_raises_RuntimeError_for_invalid_index(self):
self.assertRaises(RuntimeError, self._test_mdws.getDimension, index=self._test_ndims+1)

def test_getDimension_by_id_raises_ValueError_for_invalid_id(self):
self.assertRaises(ValueError, self._test_mdws.getDimensionWithId, id="test")

def test_getDimensionIndexByName_raises_RuntimeError_for_invalid_name(self):
self.assertRaises(RuntimeError, self._test_mdws.getDimensionIndexByName, name="NOTANAME")

def test_getDimensionIndexById_raises_ValueError_for_invalid_name(self):
self.assertRaises(RuntimeError, self._test_mdws.getDimensionIndexById, id="NOTANID")

#========================================================================================

def _check_is_dimension_with_id(self, dimension, expected_id):
self.assertTrue(isinstance(dimension, IMDDimension))
self.assertEquals(expected_id,dimension.getDimensionId())

if __name__ == '__main__':
unittest.main()

0 comments on commit 1dcfc55

Please sign in to comment.