Mantid
Loading...
Searching...
No Matches
SequenceTypeHandler.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//-----------------------------------------------------------------------------
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 KERNEL_ARRAY_API
18#define NO_IMPORT_ARRAY
19#include <numpy/arrayobject.h>
20
21#include <boost/algorithm/string/predicate.hpp>
22#include <boost/python/extract.hpp>
23
25namespace {
26template <typename HeldType> struct StdVectorExtractor {
27 static std::vector<HeldType> extract(const boost::python::object &value) {
28 return boost::python::extract<std::vector<HeldType>>(value.ptr());
29 }
30};
31template <> struct StdVectorExtractor<bool> {
32 static std::vector<bool> extract(const boost::python::object & /*unused*/) {
33 throw std::runtime_error("Unable to supported extracting std::vector<bool> from python object");
34 }
35};
36} // namespace
37
45template <typename ContainerType>
47 const boost::python::object &value) const {
48 using namespace boost::python;
49 using DestElementType = typename ContainerType::value_type;
50
51 // Current workaround for things that still pass back wrapped vectors...
52 if (boost::starts_with(value.ptr()->ob_type->tp_name, "std_vector")) {
53 alg->setProperty(name, StdVectorExtractor<DestElementType>::extract(value));
54 }
55 // numpy arrays requires special handling to extract their types. Hand-off to
56 // a more appropriate handler
57 else if (NDArray::check(value)) {
59 } else if (PySequence_Check(value.ptr())) {
61 } else // assume it is a scalar and try to convert into a vector of length one
62 {
63 DestElementType scalar = boost::python::extract<DestElementType>(value.ptr());
64 alg->setProperty(name, std::vector<DestElementType>(1, scalar));
65 }
66}
67
79template <typename ContainerType>
80std::unique_ptr<Kernel::Property>
81SequenceTypeHandler<ContainerType>::create(const std::string &name, const boost::python::object &defaultValue,
82 const boost::python::object &validator, const unsigned int direction) const {
83 using DestElementType = typename ContainerType::value_type;
84 using boost::python::extract;
87
88 ContainerType valueInC;
89 // Current workaround for things that still pass back wrapped vectors...
90 if (boost::starts_with(defaultValue.ptr()->ob_type->tp_name, "std_vector")) {
91 valueInC = StdVectorExtractor<DestElementType>::extract(defaultValue);
92 } else if (PySequence_Check(defaultValue.ptr())) {
93 valueInC = Converters::PySequenceToVector<DestElementType>(defaultValue)();
94 } else // assume it is a scalar and try to convert into a vector of length one
95 {
96 DestElementType scalar = boost::python::extract<DestElementType>(defaultValue.ptr());
97 valueInC = std::vector<DestElementType>(1, scalar);
98 }
99
100 std::unique_ptr<Kernel::Property> valueProp;
101 if (isNone(validator)) {
102 valueProp = std::make_unique<PropertyWithValue<ContainerType>>(name, valueInC, direction);
103 } else {
104 const IValidator *propValidator = extract<IValidator *>(validator);
105 valueProp = std::make_unique<PropertyWithValue<ContainerType>>(name, valueInC, propValidator->clone(), direction);
106 }
107 return valueProp;
108}
109
110//-----------------------------------------------------------------------
111// Concrete instantiations
112//-----------------------------------------------------------------------
114#define INSTANTIATE(ElementType) template struct DLLExport SequenceTypeHandler<std::vector<ElementType>>;
115
116INSTANTIATE(int)
117INSTANTIATE(long)
118INSTANTIATE(long long)
119INSTANTIATE(unsigned int)
120INSTANTIATE(unsigned long)
121INSTANTIATE(unsigned long long)
122INSTANTIATE(double)
123INSTANTIATE(std::string)
124INSTANTIATE(bool)
126} // namespace Mantid::PythonInterface::Registry
double value
The value of the point.
Definition: FitMW.cpp:51
#define INSTANTIATE(TYPE)
Definition: Statistics.cpp:403
Interface to PropertyManager.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
IValidator is the basic interface for all validators for properties.
Definition: IValidator.h:43
virtual IValidator_sptr clone() const =0
Make a copy of the present type of validator.
The concrete, templated class for properties.
Thin object wrapper around a numpy array.
Definition: NDArray.h:31
static bool check(const boost::python::object &obj)
Check if a python object points to an array type object.
Definition: NDArray.cpp:49
bool isNone(PyObject *ptr)
Definition: IsNone.h:26
Converter taking an input numpy array and converting it to a std::vector.
Converts a Python sequence type to a C++ std::vector, where the element type is defined by the templa...
std::unique_ptr< Kernel::Property > create(const std::string &name, const boost::python::object &defaultValue, const boost::python::object &validator, const unsigned int direction) const override
Call to create a name property where the value is some container type.
void set(Kernel::IPropertyManager *alg, const std::string &name, const boost::python::object &value) const override
Call to set a named property where the value is some container type.