Skip to content

Commit

Permalink
Workaround for a places still wrapping std vectors. Refs #7469
Browse files Browse the repository at this point in the history
  • Loading branch information
martyngigg committed Jul 23, 2013
1 parent 033d971 commit 63b0172
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,35 @@
#include <numpy/arrayobject.h>

#include <boost/python/extract.hpp>
#include <boost/algorithm/string/predicate.hpp>

namespace Mantid
{
namespace PythonInterface
{
namespace Registry
{
namespace
{
template <typename HeldType>
struct StdVectorExtractor
{
static std::vector<HeldType> extract(const boost::python::object & value)
{
return boost::python::extract<std::vector<HeldType>>(value.ptr());
}
};
template <>
struct StdVectorExtractor<bool>
{
static std::vector<bool> extract(const boost::python::object &)
{
throw std::runtime_error("Unable to supported extracting std::vector<bool> from python object");
}
};

}

/**
* Set function to handle Python -> C++ calls to a property manager and get the correct type
* @param alg :: A pointer to an IPropertyManager
Expand All @@ -32,21 +54,24 @@ namespace Mantid
using boost::python::len;
typedef typename ContainerType::value_type DestElementType;

// Current workaround for things that still pass back wrapped vectors...
if(boost::starts_with(value.ptr()->ob_type->tp_name, "std_vector"))
{
alg->setProperty(name, StdVectorExtractor<DestElementType>::extract(value));
}
// numpy arrays requires special handling to extract their types. Hand-off to a more appropriate handler
if( PyArray_Check(value.ptr()) )
else if( PyArray_Check(value.ptr()) )
{
alg->setProperty(name, Converters::NDArrayToVector<DestElementType>(value)());
}
else if( PySequence_Check(value.ptr()) )
else if( PySequence_Check(value.ptr()) )
{
alg->setProperty(name, Converters::PySequenceToVector<DestElementType>(value)());
return;
}
else // assume it is a scalar and try to convert into a vector of length one
{
std::vector<DestElementType> result(1);
result[0] = boost::python::extract<DestElementType>(value.ptr());
alg->setProperty(name, result);
else // assume it is a scalar and try to convert into a vector of length one
{
DestElementType scalar = boost::python::extract<DestElementType>(value.ptr());
alg->setProperty(name, std::vector<DestElementType>(1, scalar));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ def test_set_property_succeeds_with_python_int_lists(self):
for i in range(6):
self.assertEquals(det_list[i], i+2)

def test_set_array_property_with_single_item_correct_type_suceeds(self):
self._mask_dets.setProperty("WorkspaceIndexList", 10)

val = self._mask_dets.getProperty("WorkspaceIndexList").value
self.assertEquals(10, val)

def test_set_property_succeeds_with_python_float_lists(self):
rebin = AlgorithmManager.createUnmanaged("Rebin")
rebin.initialize()
Expand All @@ -82,6 +88,13 @@ def test_set_property_of_vector_double_succeeds_with_numpy_array_of_float_type(s

def test_set_property_of_vector_double_succeeds_with_numpy_array_of_int_type(self):
self._do_vector_double_numpy_test(True)

def test_set_property_using_list_extracted_from_other_property_succeeds(self):
det_list_prop = self._mask_dets.getProperty("DetectorList")
det_list_prop.valueAsStr = "1,2,3,4,5"

det_list = det_list_prop.value
self._mask_dets.setProperty("DetectorList", det_list)

def _do_vector_double_numpy_test(self, int_type=False):
create_ws = AlgorithmManager.createUnmanaged('CreateWorkspace')
Expand Down

0 comments on commit 63b0172

Please sign in to comment.