Mantid
Loading...
Searching...
No Matches
IFunction.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 +
21
22#include <boost/python/class.hpp>
23#include <boost/python/def.hpp>
24#include <boost/python/extract.hpp>
25#include <boost/python/manage_new_object.hpp>
26#include <boost/python/overloads.hpp>
27#include <boost/python/register_ptr_to_python.hpp>
28#include <boost/python/to_python_value.hpp>
29
30#include <memory>
31#include <string>
32
37using namespace boost::python;
38
40
41namespace {
43
50template <typename T> inline T extractValueAndClone(const boost::python::object &value) {
51 return boost::python::extract<T>(value)()->clone();
52}
53
54struct FunctionPropertyValueHandler : public PropertyValueHandler {
55
57 using HeldType = std::shared_ptr<IFunction>;
58
65 void set(Mantid::Kernel::IPropertyManager *alg, const std::string &name,
66 const boost::python::object &value) const override {
67 alg->setProperty<HeldType>(name, extractValueAndClone<HeldType>(value));
68 }
69
81 std::unique_ptr<Mantid::Kernel::Property> create(const std::string &name, const boost::python::object &defaultValue,
82 const boost::python::object &validator,
83 const unsigned int direction) const override {
86 if (Mantid::PythonInterface::isNone(validator)) {
87 return std::make_unique<PropertyWithValue<HeldType>>(name, extractValueAndClone<HeldType>(defaultValue),
88 direction);
89 }
90 const IValidator *propValidator = boost::python::extract<IValidator *>(validator);
91 return std::make_unique<PropertyWithValue<HeldType>>(name, extractValueAndClone<HeldType>(defaultValue),
92 propValidator->clone(), direction);
93 }
94};
95
96//------------------------------------------------------------------------------------------------------
102PyObject *getCategories(const IFunction &self) {
103 const auto categories = self.categories();
104
105 PyObject *registered = PyList_New(0);
106 for (const auto &category : categories) {
107 PyObject *value = to_python_value<const std::string &>()(category);
108 if (PyList_Append(registered, value))
109 throw std::runtime_error("Failed to insert value into PyList");
110 }
111
112 return registered;
113}
114
115// -- Set property overloads --
116// setProperty(index,value,explicit)
117using setParameterType1 = void (IFunction::*)(size_t, const double &, bool);
118GNU_DIAG_OFF("unused-local-typedef")
119// Ignore -Wconversion warnings coming from boost::python
120// Seen with GCC 7.1.1 and Boost 1.63.0
121GNU_DIAG_OFF("conversion")
122
123BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType1_Overloads, setParameter, 2, 3)
124// setProperty(name,value,explicit)
125using setParameterType2 = void (IFunction::*)(const std::string &, const double &, bool);
126BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads, setParameter, 2, 3)
127
128// setError(index,value)
129using setErrorType1 = void (IFunction::*)(size_t, double);
130BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setErrorType1_Overloads, setError, 2, 2)
131// setError(name,value)
132using setErrorType2 = void (IFunction::*)(const std::string &, double);
133BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setErrorType2_Overloads, setError, 2, 2)
134
135// getError(index)
136using getErrorType1 = double (IFunction::*)(size_t) const;
137BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getErrorType1_Overloads, getError, 1, 1)
138// getError(name)
139using getErrorType2 = double (IFunction::*)(const std::string &) const;
140BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getErrorType2_Overloads, getError, 1, 1)
141
142// declareAttribute(name, defaultValue)
143using declareAttributeType1 = void (IFunctionAdapter::*)(const std::string &name,
144 const boost::python::object &defaultValue);
145BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(declareAttributeType1_Overloads, declareAttribute, 2, 2)
146// declareAttribute(name, defaultValue, validator)
147using declareAttributeType2 = void (IFunctionAdapter::*)(const std::string &name,
148 const boost::python::object &defaultValue,
149 const boost::python::object &validator);
150// cppcheck-suppress unknownMacro
151BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(declareAttributeType2_Overloads, declareAttribute, 3, 3)
152
153BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(tie_Overloads, tie, 2, 3)
154BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(addTies_Overloads, addTies, 1, 2)
155BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(addConstraints_Overloads, addConstraints, 1, 2)
156BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fixParameter_Overloads, fixParameter, 1, 2)
157BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fix_Overloads, fix, 1, 2)
158BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fixAll_Overloads, fixAll, 0, 1)
159using removeTieByName = void (IFunction::*)(const std::string &);
160
161GNU_DIAG_ON("conversion")
162GNU_DIAG_ON("unused-local-typedef")
164
165Mantid::API::Jacobian *getFunctionDeriv(IFunction &self, const Mantid::API::FunctionDomain &domain) {
166 auto *out = new Mantid::CurveFitting::Jacobian(domain.size(), self.nParams());
167 self.functionDeriv(domain, *out);
168 return out;
169}
170
171void setMatrixWorkspace(IFunction &self, const boost::python::object &workspace, int wi, float startX, float endX) {
172 Mantid::API::MatrixWorkspace_sptr matWS = std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
174 self.setMatrixWorkspace(matWS, wi, startX, endX);
175}
176
177} // namespace
178
180
181 register_ptr_to_python<std::shared_ptr<IFunction>>();
182
183 class_<IFunction, IFunctionAdapter, boost::noncopyable>("IFunction", "Base class for all functions", no_init)
184 .def("name", &IFunction::name, arg("self"), "Return the name of the function")
185
186 .def("category", &IFunctionAdapter::category, arg("self"),
187 "Return a semi-colon(;) separated string for the categories this "
188 "class should belong to. For sub-categories use a \\ separator")
189
190 .def("clone", &IFunction::clone, arg("self"), "Clones the function")
191
192 .def("initialize", &IFunction::initialize, arg("self"), "Declares any parameters and attributes on the function")
193
194 .def("getCategories", &getCategories, arg("self"), "Returns a list of the categories for an algorithm")
195
196 .def("nAttributes", &IFunction::nAttributes, arg("self"),
197 "Return the number of attributes (non-fitting arguments)")
198
199 .def("attributeNames", &IFunction::getAttributeNames, arg("self"), "The names of all the attributes")
200
201 .def("hasAttribute", &IFunction::hasAttribute, (arg("self"), arg("name")),
202 "Return whether there is an attribute of the given name")
203
204 .def("hasParameter", &IFunction::hasParameter, (arg("self"), arg("name")),
205 "Return whether there is an parameter of the given name")
206
207 .def("nParams", &IFunction::nParams, arg("self"), "Return the number of parameters")
208
209 .def("parameterName", &IFunction::parameterName, (arg("self"), arg("i")), "Return the name of the ith parameter")
210
211 .def("paramDescription", &IFunction::parameterDescription, (arg("self"), arg("i")),
212 "Return a description of the ith parameter")
213
214 .def("isExplicitlySet", &IFunction::isExplicitlySet, (arg("self"), arg("i")),
215 "Return whether the ith parameter needs to be explicitely set")
216
217 .def("getParameterValue", (double (IFunction::*)(size_t) const) & IFunction::getParameter,
218 (arg("self"), arg("i")), "Get the value of the ith parameter")
219
220 .def("getParameterValue", (double (IFunction::*)(const std::string &) const) & IFunction::getParameter,
221 (arg("self"), arg("name")), "Get the value of the named parameter")
222
223 .def("__getitem__", (double (IFunction::*)(const std::string &) const) & IFunction::getParameter,
224 (arg("self"), arg("name")), "Get the value of the named parameter")
225
226 .def("setParameter", (setParameterType1)&IFunction::setParameter,
227 setParameterType1_Overloads((arg("self"), arg("i"), arg("value"), arg("explicitlySet")),
228 "Sets the value of the ith parameter"))
229
230 .def("setParameter", (setParameterType2)&IFunction::setParameter,
231 setParameterType2_Overloads((arg("self"), arg("name"), arg("value"), arg("explicitlySet")),
232 "Sets the value of the named parameter"))
233
234 .def(
235 "setError", (setErrorType1)&IFunction::setError,
236 setErrorType1_Overloads((args("self"), arg("index"), args("err")), "Sets the error on the indexed parameter"))
237
238 .def("setError", (setErrorType2)&IFunction::setError,
239 setErrorType2_Overloads((args("self"), arg("name"), args("err")), "Sets the error on the named parameter"))
240
241 .def("getError", (getErrorType1)&IFunction::getError,
242 getErrorType1_Overloads((arg("self"), arg("index")), "Return fitting error of the index parameter"))
243
244 .def("getError", (getErrorType2)&IFunction::getError,
245 getErrorType2_Overloads((arg("self"), arg("name")), "Return fitting error of the named parameter"))
246
247 .def("__setitem__", (setParameterType2)&IFunction::setParameter,
248 setParameterType2_Overloads((arg("self"), arg("name"), arg("value"), arg("explicitlySet")),
249 "Sets the value of the named parameter"))
250
251 .def("declareAttribute", (declareAttributeType1)&IFunctionAdapter::declareAttribute,
252 declareAttributeType1_Overloads((arg("self"), arg("name"), arg("default_value")),
253 "Declare an attribute with an initial value"))
254
255 .def("declareAttribute", (declareAttributeType2)&IFunctionAdapter::declareAttribute,
256 declareAttributeType2_Overloads((arg("self"), arg("name"), arg("default_value"), arg("validator")),
257 "Declare an attribute with an initial value, with a validator"))
258
259 .def("getAttributeValue",
260 (PyObject * (*)(const IFunction &, const std::string &)) IFunctionAdapter::getAttributeValue,
261 (arg("self"), arg("name")), "Return the value of the named attribute")
262
263 .def("setAttributeValue", &IFunctionAdapter::setAttributePythonValue, (arg("self"), arg("name"), arg("value")),
264 "Set a value of a named attribute")
265
266 .def("declareParameter", &IFunctionAdapter::declareFitParameter,
267 (arg("self"), arg("name"), arg("init_value"), arg("description")),
268 "Declare a fitting parameter settings its default value & "
269 "description")
270
271 .def("declareParameter", &IFunctionAdapter::declareFitParameterNoDescr,
272 (arg("self"), arg("name"), arg("init_value")), "Declare a fitting parameter settings its default value")
273
274 .def("declareParameter", &IFunctionAdapter::declareFitParameterZeroInit, (arg("self"), arg("name")),
275 "Declare a fitting parameter settings its default value to 0.0")
276
277 .def("fixParameter", &IFunction::fix,
278 fix_Overloads((arg("self"), arg("i"), arg("isDefault")), "Fix the ith parameter"))
279
280 .def("fixParameter", &IFunction::fixParameter,
281 fixParameter_Overloads((arg("self"), arg("name"), arg("isDefault")), "Fix the named parameter"))
282
283 .def("freeParameter", &IFunction::unfix, (arg("self"), arg("i")), "Free the ith parameter")
284
285 .def("freeParameter", &IFunction::unfixParameter, (arg("self"), arg("name")), "Free the named parameter")
286
287 .def("isFixed", &IFunction::isFixed, (arg("self"), arg("i")), "Return whether the ith parameter is fixed or tied")
288
289 .def("fixAll", &IFunction::fixAll, fixAll_Overloads((arg("self"), arg("isDefault")), "Fix all parameters"))
290
291 .def("freeAll", &IFunction::unfixAll, (arg("self")), "Free all parameters")
292
293 .def("tie", &IFunction::tie,
294 tie_Overloads((arg("self"), arg("name"), arg("expr"), arg("isDefault")),
295 "Tie a named parameter to an expression"))
296
297 .def("addTies", &IFunction::addTies,
298 addTies_Overloads((arg("self"), arg("ties"), arg("isDefault")), "Add several ties to an IFunction."))
299
300 .def("removeTie", (bool (IFunction::*)(size_t))&IFunction::removeTie, (arg("self"), arg("i")),
301 "Remove the tie of the ith parameter")
302
303 .def("removeTie", (void (IFunction::*)(const std::string &))&IFunction::removeTie, (arg("self"), arg("name")),
304 "Remove the tie of the named parameter")
305
306 .def("getTies", &IFunction::writeTies, arg("self"), "Returns the list of current ties as a string")
307
308 .def("addConstraints", &IFunction::addConstraints,
309 addConstraints_Overloads((arg("self"), arg("constraints"), arg("isDefault")), "Constrain named parameters"))
310
311 .def("removeConstraint", &IFunction::removeConstraint, (arg("self"), arg("name")),
312 "Remove the constraint on the named parameter")
313
314 .def("getConstraints", &IFunction::writeConstraints, arg("self"),
315 "Returns the list of current constraints as a string")
316
317 .def("setConstraintPenaltyFactor", &IFunction::setConstraintPenaltyFactor,
318 (arg("self"), arg("name"), arg("value")), "Set the constraint penalty factor for named parameter")
319
320 .def("getNumberDomains", &IFunction::getNumberDomains, (arg("self")),
321 "Get number of domains of a multi-domain function")
322
323 .def("createEquivalentFunctions", &IFunctionAdapter::createPythonEquivalentFunctions, (arg("self")),
324 "Split this function (if needed) into a list of "
325 "independent functions")
326
327 .def("getFunction", &IFunction::getFunction, (arg("self"), arg("index")),
328 "Returns the pointer to i-th child function")
329
330 .def("nDomains", &IFunction::getNumberDomains, arg("self"), "Get the number of domains.")
331
332 .def("functionDeriv", &getFunctionDeriv, (arg("self"), arg("domain")), return_value_policy<manage_new_object>(),
333 "Calculate the values of the function for the given domain and returns them")
334
335 .def("setMatrixWorkspace", &setMatrixWorkspace,
336 (arg("self"), arg("workspace"), arg("wi"), arg("startX"), arg("endX")),
337 "Set matrix workspace to parse Parameters.xml")
338
339 //-- Deprecated functions that have the wrong names --
340 .def("categories", &getCategories, arg("self"), "Returns a list of the categories for an algorithm")
341 .def("numParams", &IFunction::nParams, arg("self"), "Return the number of parameters")
342 .def("getParamName", &IFunction::parameterName, (arg("self"), arg("i")), "Return the name of the ith parameter")
343 .def("getParamDescr", &IFunction::parameterDescription, (arg("self"), arg("i")),
344 "Return a description of the ith parameter")
345 .def("getParamExplicit", &IFunction::isExplicitlySet, (arg("self"), arg("i")),
346 "Return whether the ith parameter needs to be explicitely set")
347 .def("getParamValue", (double (IFunction::*)(std::size_t) const) & IFunction::getParameter,
348 (arg("self"), arg("i")), "Get the value of the ith parameter")
349 .def("getParameterIndex", &IFunction::parameterIndex, (arg("self"), arg("name")),
350 "Returns the index of the provided parameter.")
351
352 //-- Python special methods --
353 .def("__repr__", &IFunction::asString, arg("self"), "Return a string representation of the function");
354
355 TypeRegistry::subscribe<FunctionPropertyValueHandler>();
356}
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
#define GET_POINTER_SPECIALIZATION(TYPE)
Definition GetPointer.h:17
IPeaksWorkspace_sptr workspace
void export_IFunction()
#define GNU_DIAG_ON(x)
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
Base class that represents the domain of a function.
This is an interface to a fitting function - a semi-abstarct class.
Definition IFunction.h:166
virtual size_t nParams() const =0
Total number of parameters.
virtual void removeConstraint(const std::string &parName)
Remove a constraint.
std::string writeTies() const
Write a parameter tie to a string.
void unfixParameter(const std::string &name)
Free a parameter.
virtual double getParameter(size_t i) const =0
Get i-th parameter.
virtual void initialize()
Iinialize the function.
Definition IFunction.h:425
virtual std::shared_ptr< IFunction > clone() const
Virtual copy constructor.
virtual void tie(const std::string &parName, const std::string &expr, bool isDefault=false)
Tie a parameter to other parameters (or a constant)
virtual bool hasParameter(const std::string &name) const =0
Check if function has a parameter with this name.
virtual void setMatrixWorkspace(std::shared_ptr< const API::MatrixWorkspace > workspace, size_t wi, double startX, double endX)
Set matrix workspace.
virtual void setParameter(size_t, const double &value, bool explicitlySet=true)=0
Set i-th parameter.
virtual void setError(size_t i, double err)=0
Set the fitting error for a parameter.
virtual const std::vector< std::string > categories() const
Function to return all of the categories that contain this algorithm.
virtual std::string parameterDescription(size_t i) const =0
Returns the description of parameter i.
void fixParameter(const std::string &name, bool isDefault=false)
Fix a parameter.
virtual std::vector< std::string > getAttributeNames() const
Returns a list of attribute names.
virtual void setConstraintPenaltyFactor(const std::string &parName, const double &c)
Set a constraint penalty.
virtual void addTies(const std::string &ties, bool isDefault=false)
Add several ties.
std::string asString() const
Writes itself into a string.
void unfix(size_t i)
Restores a declared parameter i to the active status.
virtual std::string parameterName(size_t i) const =0
Returns the name of parameter i.
virtual std::string name() const =0
Returns the function's name.
virtual bool hasAttribute(const std::string &name) const
Check if attribute attName exists.
void unfixAll()
Free all parameters.
virtual std::shared_ptr< IFunction > getFunction(size_t i) const
Returns the pointer to i-th child function.
virtual void addConstraints(const std::string &str, bool isDefault=false)
Add a list of conatraints from a string.
void fixAll(bool isDefault=false)
Fix all parameters.
virtual size_t parameterIndex(const std::string &name) const =0
Returns the index of parameter name.
std::string writeConstraints() const
Write a parameter constraint to a string.
virtual void removeTie(const std::string &parName)
Removes the tie off a parameter.
virtual double getError(size_t i) const =0
Get the fitting error for a parameter.
void fix(size_t i, bool isDefault=false)
Removes a parameter i from the list of active.
bool isFixed(size_t i) const
Check if a parameter i is fixed.
virtual size_t nAttributes() const
Returns the number of attributes associated with the function.
virtual bool isExplicitlySet(size_t i) const =0
Checks if a parameter has been set explicitly.
virtual size_t getNumberDomains() const
Get number of domains required by this function.
Represents the Jacobian in IFitFunction::functionDeriv.
Definition Jacobian.h:22
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.
Provides a layer to hook into the protected functions of IFunction.
void declareFitParameter(const std::string &name, double initValue, const std::string &description)
Declare a named parameter with initial value & description.
static void setAttributePythonValue(IFunction &self, const std::string &name, const boost::python::object &value)
Set the attribute's value.
static boost::python::list createPythonEquivalentFunctions(const IFunction &self)
Split this function (if needed) into a list of independent functions.
void declareFitParameterZeroInit(const std::string &name)
Declare a named parameter with initial value = 0.0.
const std::string category() const override
Specify a category for the function.
void declareFitParameterNoDescr(const std::string &name, double initValue)
Declare a named parameter with initial value.
void declareAttribute(const std::string &name, const boost::python::object &defaultValue)
Declare an attribute with an initial value.
static PyObject * getAttributeValue(const IFunction &self, const std::string &name)
Get a named attribute value.
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Definition IFunction.h:743
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
bool isNone(const PyObject *ptr)
Definition IsNone.h:26
Helper class which provides the Collimation Length for SANS instruments.
STL namespace.
This class provides a base-class objects that are able to take a python object and set it on an algor...