8#pragma warning(disable : 4250)
15#pragma warning(default : 4250)
21#include <boost/python/bases.hpp>
22#include <boost/python/class.hpp>
23#include <boost/python/dict.hpp>
24#include <boost/python/exception_translator.hpp>
25#include <boost/python/overloads.hpp>
32#pragma warning(disable : 4267)
34#include <boost/python/raw_function.hpp>
38#include <boost/python/register_ptr_to_python.hpp>
39#include <boost/python/scope.hpp>
40#include <boost/variant.hpp>
41#include <boost/variant/static_visitor.hpp>
62using declarePropertyType2 = void (*)(boost::python::object &,
const std::string &,
const boost::python::object &,
63 const boost::python::object &,
const std::string &,
const int);
65using declarePropertyType3 = void (*)(boost::python::object &,
const std::string &,
const boost::python::object &,
66 const std::string &,
const int);
68using declarePropertyType4 = void (*)(boost::python::object &,
const std::string &,
const boost::python::object &,
77BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType1_Overload, PythonAlgorithm::declarePyAlgProperty, 2, 3)
78BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType2_Overload, PythonAlgorithm::declarePyAlgProperty, 3, 6)
79BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType3_Overload, PythonAlgorithm::declarePyAlgProperty, 4, 5)
90void translateCancel(const
Algorithm::CancelException &exc) {
92 PyErr_SetString(PyExc_KeyboardInterrupt,
"");
100void translateH5Exception(
const H5::Exception &exc) {
101 auto handleFrame = [](
unsigned int n,
const H5E_error_t *err,
void *ss_arg) ->
herr_t {
102 std::stringstream &ss_ = *((std::stringstream *)ss_arg);
104 ss_ <<
" #" <<
n <<
": " << err->desc <<
"\n";
109 std::stringstream ss;
110 exc.walkErrorStack(H5E_WALK_DOWNWARD, handleFrame, &ss);
112 PyErr_SetString(PyExc_RuntimeError, ss.str().c_str());
115template <
typename T> std::optional<T> extractArg(ssize_t
index,
const tuple &args) {
116 if (
index < len(args)) {
117 return std::optional<T>(extract<T>(args[
index]));
122template <
typename T>
void extractKwargs(
const dict &kwargs,
const std::string &keyName, std::optional<T> &out) {
123 if (!kwargs.has_key(keyName)) {
126 if (out != std::nullopt) {
127 throw std::invalid_argument(
"Parameter called '" + keyName +
128 "' was specified twice."
129 " This must be either positional or a kwarg, but not both.");
131 out = std::optional<T>(extract<T>(kwargs.get(keyName)));
137 :
m_alg(alg), m_propName(propName) {}
150 using Mantid::PythonInterface::IPyTypeVisitor::operator();
153 template <
typename T>
void setProp(
const T &val)
const {
m_alg->
setProperty(m_propName, val); }
156 std::string
const &m_propName;
160object createChildWithProps(tuple args, dict kwargs) {
162 auto name = extractArg<std::string>(1, args);
163 auto startProgress = extractArg<double>(2, args);
164 auto endProgress = extractArg<double>(3, args);
165 auto enableLogging = extractArg<bool>(4, args);
166 auto version = extractArg<int>(5, args);
168 const std::array<std::string, 6> reservedNames = {
"name",
"startProgress",
"endProgress",
169 "enableLogging",
"version",
"StoreInADS"};
171 extractKwargs<std::string>(kwargs, reservedNames[0],
name);
172 extractKwargs<double>(kwargs, reservedNames[1], startProgress);
173 extractKwargs<double>(kwargs, reservedNames[2], endProgress);
174 extractKwargs<bool>(kwargs, reservedNames[3], enableLogging);
175 extractKwargs<int>(kwargs, reservedNames[4], version);
177 if (!
name.has_value()) {
178 throw std::invalid_argument(
"Please specify the algorithm name");
180 auto childAlg = parentAlg->createChildAlgorithm(
name.value(), startProgress.value_or(-1), endProgress.value_or(-1),
181 enableLogging.value_or(
true), version.value_or(-1));
183 if (kwargs.has_key(reservedNames[5])) {
185 std::optional<bool> storeADS = std::nullopt;
186 extractKwargs<bool>(kwargs, reservedNames[5], storeADS);
187 childAlg->setAlwaysStoreInADS(storeADS.value_or(
false));
190 const list keys = kwargs.keys();
191 for (
int i = 0; i < len(keys); ++i) {
192 const std::string propName = extract<std::string>(keys[i]);
194 if (std::find(reservedNames.cbegin(), reservedNames.cend(), propName) != reservedNames.cend())
197 object curArg = kwargs[keys[i]];
198 if (curArg.is_none())
202 auto nativeObj = PyNativeTypeExtractor::convert(curArg);
204 boost::apply_visitor(SetPropertyVisitor(childAlg, propName), nativeObj);
206 return object(childAlg);
213 register_ptr_to_python<std::shared_ptr<Algorithm>>();
214 register_exception_translator<Algorithm::CancelException>(&translateCancel);
215 register_exception_translator<H5::Exception>(&translateH5Exception);
221 class_<Algorithm, bases<Mantid::API::IAlgorithm>, std::shared_ptr<PythonAlgorithm>, boost::noncopyable>(
222 "Algorithm",
"Base class for all algorithms")
224 .staticmethod(
"fromString")
225 .def(
"createChildAlgorithm", raw_function(&createChildWithProps, std::size_t(1)),
226 "Creates and intializes a named child algorithm. Output workspaces "
227 "are given a dummy name.")
228 .def(
"declareProperty", (declarePropertyType1)&PythonAlgorithm::declarePyAlgProperty,
229 declarePropertyType1_Overload((arg(
"self"), arg(
"prop"), arg(
"doc") =
"")))
231 "Turns history recording on or off for an algorithm.")
233 (arg(
"self"), arg(
"on")),
234 "Turns parent history recording on or off for algorithms that handle group outputs directly.")
235 .def(
"declareProperty", (declarePropertyType2)&PythonAlgorithm::declarePyAlgProperty,
236 declarePropertyType2_Overload((arg(
"self"), arg(
"name"), arg(
"defaultValue"), arg(
"validator") =
object(),
238 "Declares a named property where the type is taken from "
239 "the type of the defaultValue and mapped to an appropriate C++ "
241 .def(
"declareProperty", (declarePropertyType3)&PythonAlgorithm::declarePyAlgProperty,
242 declarePropertyType3_Overload(
243 (arg(
"self"), arg(
"name"), arg(
"defaultValue"), arg(
"doc") =
"", arg(
"direction") =
Direction::Input),
244 "Declares a named property where the type is taken from the "
246 "of the defaultValue and mapped to an appropriate C++ type"))
247 .def(
"declareProperty", (declarePropertyType4)&PythonAlgorithm::declarePyAlgProperty,
248 (arg(
"self"), arg(
"name"), arg(
"defaultValue"), arg(
"direction") =
Direction::Input),
249 "Declares a named property where the type is taken from the type "
250 "of the defaultValue and mapped to an appropriate C++ type")
251 .def(
"declareOrReplaceProperty", &PythonAlgorithm::declareOrReplacePyAlgProperty,
252 (arg(
"self"), arg(
"name"), arg(
"defaultValue"), arg(
"validator") = object(), arg(
"doc") =
"",
254 "Declares or replaces a named property where the type is taken from "
255 "the type of the defaultValue and mapped to an appropriate C++ "
257 .def(
"getLogger", &PythonAlgorithm::getLogger, arg(
"self"), return_value_policy<reference_existing_object>(),
258 "Returns a reference to this algorithm's logger")
259 .def(
"log", &PythonAlgorithm::getLogger, arg(
"self"), return_value_policy<reference_existing_object>(),
260 "Returns a reference to this algorithm's logger")
263 .def(
"setWikiSummary", &PythonAlgorithm::setWikiSummary, (arg(
"self"), arg(
"summary")),
264 "(Deprecated.) Set summary for the help.");
273 scope().attr(
"PythonAlgorithm") = scope().attr(
"Algorithm");
double value
The value of the point.
#define GET_POINTER_SPECIALIZATION(TYPE)
std::map< DeltaEMode::Type, std::string > index
void export_leaf_classes()
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
Base class from which all concrete algorithm classes should be derived.
static IAlgorithm_sptr fromString(const std::string &input)
De-serialize an object from a string.
void setPropertyValue(const std::string &name, const std::string &value) override
Set the value of a property by string N.B.
void enableHistoryRecordingForChild(const bool on) override
Change the state of the history recording flag.
void enableHistoryRecordingForProcessGroups(const bool on) override
Change the state of the processGroups history recording flag.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
Base class for properties.
Provides a layer class for boost::python to allow C++ virtual functions to be overridden in a Python ...
virtual void operator()(bool value) const =0
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
Describes the direction (within an algorithm) of a Property.
@ Input
An input workspace.