Mantid
Loading...
Searching...
No Matches
UserFunctionMD.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//----------------------------------------------------------------------
13
14#include <boost/tokenizer.hpp>
15
16namespace Mantid::MDAlgorithms {
17
18// Subscribe the function into the factory.
19DECLARE_FUNCTION(UserFunctionMD)
20
21
23 m_vars.resize(4);
24 std::string varNames[] = {"x", "y", "z", "t"};
25 m_varNames.assign(varNames, varNames + m_vars.size());
26 for (size_t i = 0; i < m_vars.size(); ++i) {
27 m_parser.DefineVar(m_varNames[i], &m_vars[i]);
28 }
29}
30
34std::vector<std::string> UserFunctionMD::getAttributeNames() const { return std::vector<std::string>(1, "Formula"); }
35
37bool UserFunctionMD::hasAttribute(const std::string &attName) const { return attName == "Formula"; }
38
41 UNUSED_ARG(attName);
42 return Attribute(m_formula);
43}
44
49void UserFunctionMD::setAttribute(const std::string &attName, const UserFunctionMD::Attribute &attr) {
50 UNUSED_ARG(attName);
51 m_formula = attr.asString();
52 if (!m_vars.empty()) {
53 setFormula();
54 }
55}
61 // if (!getWorkspace()) return;
62 if (m_vars.size() > 4) {
63 m_vars.resize(m_dimensionIndexMap.size());
64 m_varNames.resize(m_dimensionIndexMap.size());
65 for (size_t i = 0; i < m_vars.size(); ++i) {
66 m_varNames[i] = "x" + std::to_string(i);
67 m_parser.DefineVar(m_varNames[i], &m_vars[i]);
68 }
69 }
70 setFormula();
71}
72
78 size_t n = m_dimensions.size();
79 Kernel::VMD center = r.getCenter();
80 double val = 0.0;
82 for (size_t i = 0; i < n; ++i) {
83 m_vars[i] = center[i];
84 }
85 // std::cerr << m_vars[0] << ',' << m_vars[1] << ' ' << m_parser.Eval() <<
86 // '\n';
87 try {
88 val = m_parser.Eval();
89 } catch (mu::Parser::exception_type &e) {
90 std::cerr << "Message: " << e.GetMsg() << "\n";
91 std::cerr << "Formula: " << e.GetExpr() << "\n";
92 std::cerr << "Token: " << e.GetToken() << "\n";
93 std::cerr << "Position: " << e.GetPos() << "\n";
94 std::cerr << "Errc: " << e.GetCode() << "\n";
95 throw;
96 }
97 }
98 return val;
99}
104double *UserFunctionMD::AddVariable(const char *varName, void *pufun) {
105 UserFunctionMD &fun = *reinterpret_cast<UserFunctionMD *>(pufun);
106
107 auto x = std::find(fun.m_varNames.begin(), fun.m_varNames.end(), varName);
108 if (x != fun.m_varNames.end()) {
109 // std::vector<std::string>::difference_type i =
110 // std::distance(fun.m_varNames.begin(),x);
111 throw std::runtime_error("UserFunctionMD variables are not defined");
112 } else {
113 try {
114 fun.declareParameter(varName, 0.0);
115 } catch (...) {
116 }
117 }
118
119 // The returned pointer will never be used. Just returning a valid double
120 // pointer
121 return &fun.m_vars[0];
122}
123
128 // variables must be already defined
129 if (m_vars.empty())
130 return;
131 if (m_formula.empty()) {
132 m_formula = "0";
133 }
134 m_parser.SetVarFactory(AddVariable, this);
135 m_parser.SetExpr(m_formula);
136 // declare function parameters using mu::Parser's implicit variable setting
137 m_parser.Eval();
138 m_parser.ClearVar();
139 // set muParser variables
140 for (size_t i = 0; i < m_vars.size(); ++i) {
141 m_parser.DefineVar(m_varNames[i], &m_vars[i]);
142 }
143 for (size_t i = 0; i < nParams(); i++) {
145 }
146
147 m_parser.SetExpr(m_formula);
148}
149
150} // namespace Mantid::MDAlgorithms
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
#define PARALLEL_CRITICAL(name)
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition: System.h:64
void function(const FunctionDomain &domain, FunctionValues &values) const override
Definition: IFunctionMD.cpp:71
std::vector< std::shared_ptr< const Mantid::Geometry::IMDDimension > > m_dimensions
dimensions used in this function in the expected order
Definition: IFunctionMD.h:76
std::map< std::string, size_t > m_dimensionIndexMap
maps dimension id to its index in m_dimensions
Definition: IFunctionMD.h:74
Attribute is a non-fitting parameter.
Definition: IFunction.h:282
std::string asString() const
Returns string value if attribute is a string, throws exception otherwise.
Definition: IFunction.cpp:660
This is an interface to an iterator of an IMDWorkspace.
Definition: IMDIterator.h:39
virtual Mantid::Kernel::VMD getCenter() const =0
Returns the position of the center of the box pointed to.
virtual double * getParameterAddress(size_t i)
Get the address of the parameter. For use in UserFunction with mu::Parser.
std::string parameterName(size_t i) const override
Returns the name of parameter i.
void declareParameter(const std::string &name, double initValue=0, const std::string &description="") override
Declare a new parameter.
size_t nParams() const override
Total number of parameters.
Definition: ParamFunction.h:53
static double * AddVariable(const char *varName, void *pufun)
Static callback function used by MuParser to initialize variables implicitly.
void setFormula()
Initializes the mu::Parser.
void initDimensions() override
Defining function's parameters here, ie after the workspace is set and the dimensions are known.
Attribute getAttribute(const std::string &attName) const override
Return Formula.
std::vector< std::string > m_varNames
void setAttribute(const std::string &attName, const Attribute &attr) override
Set Formula.
mu::Parser m_parser
Expression parser.
std::vector< std::string > getAttributeNames() const override
bool hasAttribute(const std::string &attName) const override
Has attribute "Formula".
double functionMD(const API::IMDIterator &r) const override
Calculate the function value at a point r in the MD workspace.
std::string to_string(const wide_integer< Bits, Signed > &n)