Commit 33511af8 authored by Roman Tolchenov's avatar Roman Tolchenov
Browse files

Re #19547. Handle ties correctly for nested composite functions.

parent be614658
......@@ -183,9 +183,9 @@ public:
/// Get the function index
std::size_t functionIndex(std::size_t i) const;
/// Returns the index of parameter i as it declared in its function
size_t parameterLocalIndex(size_t i) const;
size_t parameterLocalIndex(size_t i, bool recursive = false) const;
/// Returns the name of parameter i as it declared in its function
std::string parameterLocalName(size_t i) const;
std::string parameterLocalName(size_t i, bool recursive = false) const;
/// Check the function.
void checkFunction();
/// Remove all member functions
......
......@@ -577,20 +577,39 @@ void CompositeFunction::parseName(const std::string &varName, size_t &index,
/** Returns the index of parameter i as it declared in its function
* @param i :: The parameter index
* @param recursive :: If true call parameterLocalName recusively until
* a non-composite function is reached.
* @return The local index of the parameter
*/
size_t CompositeFunction::parameterLocalIndex(size_t i) const {
size_t CompositeFunction::parameterLocalIndex(size_t i, bool recursive) const {
size_t iFun = functionIndex(i);
return i - m_paramOffsets[iFun];
auto localIndex = i - m_paramOffsets[iFun];
if (recursive) {
auto cf = dynamic_cast<const CompositeFunction*>(m_functions[iFun].get());
if (cf) {
return cf->parameterLocalIndex(localIndex, recursive);
}
}
return localIndex;
}
/** Returns the name of parameter i as it declared in its function
* @param i :: The parameter index
* @param recursive :: If true call parameterLocalName recusively until
* a non-composite function is reached.
* @return The pure parameter name (without the function identifier f#.)
*/
std::string CompositeFunction::parameterLocalName(size_t i) const {
std::string CompositeFunction::parameterLocalName(size_t i, bool recursive) const {
size_t iFun = functionIndex(i);
return m_functions[iFun]->parameterName(i - m_paramOffsets[iFun]);
auto localIndex = i - m_paramOffsets[iFun];
auto localFunction = m_functions[iFun].get();
if (recursive) {
auto cf = dynamic_cast<const CompositeFunction*>(localFunction);
if (cf) {
return cf->parameterLocalName(localIndex, recursive);
}
}
return localFunction->parameterName(localIndex);
}
/**
......
......@@ -1192,6 +1192,31 @@ public:
b = fun->getAttribute("NumDeriv").asBool();
TS_ASSERT(!b);
}
void test_local_name() {
std::string funStr = "name=Linear;(name=Linear;(name=Linear;name=Linear))";
auto fun = boost::dynamic_pointer_cast<CompositeFunction>(
FunctionFactory::Instance().createInitialized(funStr));
TS_ASSERT_EQUALS(fun->parameterLocalIndex(0), 0);
TS_ASSERT_EQUALS(fun->parameterLocalIndex(2), 0);
TS_ASSERT_EQUALS(fun->parameterLocalIndex(4), 2);
TS_ASSERT_EQUALS(fun->parameterLocalIndex(6), 4);
TS_ASSERT_EQUALS(fun->parameterLocalName(0), "a");
TS_ASSERT_EQUALS(fun->parameterLocalName(2), "f0.a");
TS_ASSERT_EQUALS(fun->parameterLocalName(4), "f1.f0.a");
TS_ASSERT_EQUALS(fun->parameterLocalName(6), "f1.f1.a");
TS_ASSERT_EQUALS(fun->parameterLocalIndex(0, true), 0);
TS_ASSERT_EQUALS(fun->parameterLocalIndex(2, true), 0);
TS_ASSERT_EQUALS(fun->parameterLocalIndex(4, true), 0);
TS_ASSERT_EQUALS(fun->parameterLocalIndex(6, true), 0);
TS_ASSERT_EQUALS(fun->parameterLocalName(0, true), "a");
TS_ASSERT_EQUALS(fun->parameterLocalName(2, true), "a");
TS_ASSERT_EQUALS(fun->parameterLocalName(4, true), "a");
TS_ASSERT_EQUALS(fun->parameterLocalName(6, true), "a");
}
};
#endif /*COMPOSITEFUNCTIONTEST_H_*/
......@@ -1531,7 +1531,6 @@ void FitPropertyBrowser::setCurrentFunction(
setCurrentFunction(getHandler()->findHandler(f));
}
//#include "../FitDialog.h"
/**
* Creates an instance of Fit algorithm, sets its properties and launches it.
*/
......
......@@ -1032,8 +1032,9 @@ void PropertyHandler::addTie(const QString &tieStr) {
try {
auto &cfun = *m_browser->compositeFunction();
cfun.tie(name, expr);
const bool recursive = true;
QString parName = QString::fromStdString(
cfun.parameterLocalName(cfun.parameterIndex(name)));
cfun.parameterLocalName(cfun.parameterIndex(name), recursive));
foreach (QtProperty *parProp, m_parameters) {
if (parProp->propertyName() == parName) {
m_browser->m_changeSlotsEnabled = false;
......@@ -1051,6 +1052,7 @@ void PropertyHandler::addTie(const QString &tieStr) {
}
} catch (...) {
}
QMessageBox::critical(m_browser, "Mantid - Error", "Failed to set tie: " + tieStr);
}
void PropertyHandler::fix(const QString &parName) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment