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/python/extract.hpp>
22
24namespace {
25template <typename HeldType> struct StdVectorExtractor {
26 static std::vector<HeldType> extract(const boost::python::object &value) {
27 return boost::python::extract<std::vector<HeldType>>(value.ptr());
28 }
29};
30template <> struct StdVectorExtractor<bool> {
31 static std::vector<bool> extract(const boost::python::object & /*unused*/) {
32 throw std::runtime_error("Unable to supported extracting std::vector<bool> from python object");
33 }
34};
35} // namespace
36
44template <typename ContainerType>
46 const boost::python::object &value) const {
47 using namespace boost::python;
48 using DestElementType = typename ContainerType::value_type;
49
50 // Current workaround for things that still pass back wrapped vectors...
51 const std::string tpName = value.ptr()->ob_type->tp_name;
52 if (tpName.starts_with("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 const std::string tpName = defaultValue.ptr()->ob_type->tp_name;
91 if (tpName.starts_with("std_vector")) {
92 valueInC = StdVectorExtractor<DestElementType>::extract(defaultValue);
93 } else if (PySequence_Check(defaultValue.ptr())) {
94 valueInC = Converters::PySequenceToVector<DestElementType>(defaultValue)();
95 } else // assume it is a scalar and try to convert into a vector of length one
96 {
97 DestElementType scalar = boost::python::extract<DestElementType>(defaultValue.ptr());
98 valueInC = std::vector<DestElementType>(1, scalar);
99 }
100
101 std::unique_ptr<Kernel::Property> valueProp;
102 if (isNone(validator)) {
103 valueProp = std::make_unique<PropertyWithValue<ContainerType>>(name, valueInC, direction);
104 } else {
105 const IValidator *propValidator = extract<IValidator *>(validator);
106 valueProp = std::make_unique<PropertyWithValue<ContainerType>>(name, valueInC, propValidator->clone(), direction);
107 }
108 return valueProp;
109}
110
111//-----------------------------------------------------------------------
112// Concrete instantiations
113//-----------------------------------------------------------------------
115#define INSTANTIATE(ElementType) template struct DLLExport SequenceTypeHandler<std::vector<ElementType>>;
116
117INSTANTIATE(int)
118INSTANTIATE(long)
119INSTANTIATE(long long)
120INSTANTIATE(unsigned int)
121INSTANTIATE(unsigned long)
122INSTANTIATE(unsigned long long)
123INSTANTIATE(double)
124INSTANTIATE(std::string)
125INSTANTIATE(bool)
127} // 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: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(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.