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//-----------------------------------------------------------------------------
15#include "MantidPythonInterface/kernel/DllConfig.h"
16
17// See
18// http://docs.scipy.org/doc/numpy/reference/c-api.array.html#PY_ARRAY_UNIQUE_SYMBOL
19#define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API
20#define NO_IMPORT_ARRAY
21#include <numpy/arrayobject.h>
22
23#include <boost/python/extract.hpp>
24
26namespace {
27template <typename HeldType> struct StdVectorExtractor {
28 static std::vector<HeldType> extract(const boost::python::object &value) {
29 return boost::python::extract<std::vector<HeldType>>(value.ptr());
30 }
31};
32template <> struct StdVectorExtractor<bool> {
33 static std::vector<bool> extract(const boost::python::object & /*unused*/) {
34 throw std::runtime_error("Unable to supported extracting std::vector<bool> from python object");
35 }
36};
37} // namespace
38
46template <typename ContainerType>
48 const boost::python::object &value) const {
49 using namespace boost::python;
50 using DestElementType = typename ContainerType::value_type;
51
52 // Current workaround for things that still pass back wrapped vectors...
53 const std::string tpName = value.ptr()->ob_type->tp_name;
54 if (tpName.starts_with("std_vector")) {
55 alg->setProperty(name, StdVectorExtractor<DestElementType>::extract(value));
56 }
57 // numpy arrays requires special handling to extract their types. Hand-off to
58 // a more appropriate handler
59 else if (NDArray::check(value)) {
61 } else if (PySequence_Check(value.ptr())) {
63 } else // assume it is a scalar and try to convert into a vector of length one
64 {
65 DestElementType scalar = boost::python::extract<DestElementType>(value.ptr());
66 alg->setProperty(name, std::vector<DestElementType>(1, scalar));
67 }
68}
69
81template <typename ContainerType>
82std::unique_ptr<Kernel::Property>
83SequenceTypeHandler<ContainerType>::create(const std::string &name, const boost::python::object &defaultValue,
84 const boost::python::object &validator, const unsigned int direction) const {
85 using DestElementType = typename ContainerType::value_type;
86 using boost::python::extract;
89
90 ContainerType valueInC;
91 // Current workaround for things that still pass back wrapped vectors...
92 const std::string tpName = defaultValue.ptr()->ob_type->tp_name;
93 if (tpName.starts_with("std_vector")) {
94 valueInC = StdVectorExtractor<DestElementType>::extract(defaultValue);
95 } else if (PySequence_Check(defaultValue.ptr())) {
96 valueInC = Converters::PySequenceToVector<DestElementType>(defaultValue)();
97 } else // assume it is a scalar and try to convert into a vector of length one
98 {
99 DestElementType scalar = boost::python::extract<DestElementType>(defaultValue.ptr());
100 valueInC = std::vector<DestElementType>(1, scalar);
101 }
102
103 std::unique_ptr<Kernel::Property> valueProp;
104 if (isNone(validator)) {
105 valueProp = std::make_unique<PropertyWithValue<ContainerType>>(name, valueInC, direction);
106 } else {
107 const IValidator *propValidator = extract<IValidator *>(validator);
108 valueProp = std::make_unique<PropertyWithValue<ContainerType>>(name, valueInC, propValidator->clone(), direction);
109 }
110 return valueProp;
111}
112
113//-----------------------------------------------------------------------
114// Concrete instantiations
115//-----------------------------------------------------------------------
117#define INSTANTIATE(ElementType) template struct PYTHON_KERNEL_DLL SequenceTypeHandler<std::vector<ElementType>>;
118
119INSTANTIATE(int)
120INSTANTIATE(long)
121INSTANTIATE(long long)
122INSTANTIATE(unsigned int)
123INSTANTIATE(unsigned long)
124INSTANTIATE(unsigned long long)
125INSTANTIATE(double)
126INSTANTIATE(std::string)
127INSTANTIATE(bool)
129} // namespace Mantid::PythonInterface::Registry
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
#define INSTANTIATE(TYPE)
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:37
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(const 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.