Commit 5dc584e3 authored by Harriet Brown's avatar Harriet Brown
Browse files

Add error setter and getter by name in function

This commit add getError and setError overloads for functions to obtain the error value by parameter name instead of index.

re: 29254
parent f754ca24
......@@ -107,8 +107,12 @@ public:
[[nodiscard]] bool isExplicitlySet(size_t i) const override;
/// Get the fitting error for a parameter
[[nodiscard]] double getError(size_t i) const override;
/// Get the fitting error for a parameter by name
[[nodiscard]] double getError(const std::string &name) const override;
/// Set the fitting error for a parameter
void setError(size_t i, double err) override;
/// Set the fitting error for a parameter by name
void setError(const std::string &name, double err) override;
/// Value of i-th active parameter. Override this method to make fitted
/// parameters different from the declared
[[nodiscard]] double activeParameter(size_t i) const override;
......
......@@ -65,8 +65,12 @@ public:
bool isExplicitlySet(size_t i) const override;
/// Get the fitting error for a parameter
double getError(size_t i) const override;
/// Get the fitting error for a parameter by name
double getError(const std::string &name) const override;
/// Set the fitting error for a parameter
void setError(size_t i, double err) override;
/// Set the fitting error for a parameter by name
void setError(const std::string &name, double err) override;
/// Return parameter index from a parameter reference.
size_t getParameterIndex(const ParameterReference &ref) const override;
......
......@@ -75,8 +75,12 @@ public:
bool isExplicitlySet(size_t i) const override;
/// Get the fitting error for a parameter of decorated function.
double getError(size_t i) const override;
/// Get the fitting error for a parameter of decorated function by name.
double getError(const std::string &name) const override;
/// Set the fitting error for a parameter of decorated function.
void setError(size_t i, double err) override;
/// Set the fitting error for a parameter of decorated function by name.
void setError(const std::string &name, double err) override;
/// Return parameter index of decorated function from a parameter reference.
/// Usefull for constraints and ties in composite functions.
......
......@@ -418,8 +418,12 @@ public:
virtual bool isExplicitlySet(size_t i) const = 0;
/// Get the fitting error for a parameter
virtual double getError(size_t i) const = 0;
/// Get the fitting error for a parameter by name
virtual double getError(const std::string &name) const = 0;
/// Set the fitting error for a parameter
virtual void setError(size_t i, double err) = 0;
/// Set the fitting error for a parameter by name
virtual void setError(const std::string &name, double err) = 0;
/// Check if a parameter i is fixed
[[nodiscard]] bool isFixed(size_t i) const;
......
......@@ -64,8 +64,12 @@ public:
bool isExplicitlySet(size_t i) const override;
/// Get the fitting error for a parameter
double getError(size_t i) const override;
/// Get the fitting error for a parameter by name
double getError(const std::string &name) const override;
/// Set the fitting error for a parameter
void setError(size_t i, double err) override;
/// Set the fitting error for a parameter by name
void setError(const std::string &name, double err) override;
/// Return parameter index from a parameter reference. Usefull for constraints
/// and ties in composite functions
......
......@@ -422,6 +422,16 @@ double CompositeFunction::getError(size_t i) const {
return m_functions[iFun]->getError(i - m_paramOffsets[iFun]);
}
/**
* Get the fitting error for a parameter by name.
* @param name :: The name of the parameter.
* @return value of the requested named parameter
*/
double CompositeFunction::getError(const std::string &name) const {
const auto [parameterName, index] = parseName(name);
return getFunction(index)->getError(parameterName);
}
/**
* Set the fitting error for a parameter
* @param i :: The index of a parameter
......@@ -432,6 +442,16 @@ void CompositeFunction::setError(size_t i, double err) {
m_functions[iFun]->setError(i - m_paramOffsets[iFun], err);
}
/**
* Sets the fitting error to a parameter by name.
* @param name :: The name of the parameter.
* @param err :: The error value to set
*/
void CompositeFunction::setError(const std::string &name, double err) {
auto [parameterName, index] = parseName(name);
getFunction(index)->setError(parameterName, err);
}
/// Value of i-th active parameter. Override this method to make fitted
/// parameters different from the declared
double CompositeFunction::activeParameter(size_t i) const {
......
......@@ -151,6 +151,12 @@ double FunctionGenerator::getError(size_t i) const {
}
}
/// Get the fitting error for a parameter by name
double FunctionGenerator::getError(const std::string &name) const {
auto index = parameterIndex(name);
return getError(index);
}
/// Set the fitting error for a parameter
void FunctionGenerator::setError(size_t i, double err) {
if (i < m_nOwnParams) {
......@@ -161,6 +167,12 @@ void FunctionGenerator::setError(size_t i, double err) {
}
}
/// Set the fitting error for a parameter by name
void FunctionGenerator::setError(const std::string &name, double err) {
auto index = parameterIndex(name);
setError(index, err);
}
/// Change status of parameter
void FunctionGenerator::setParameterStatus(size_t i,
IFunction::ParameterStatus status) {
......
......@@ -159,12 +159,22 @@ double FunctionParameterDecorator::getError(size_t i) const {
return m_wrappedFunction->getError(i);
}
double FunctionParameterDecorator::getError(const std::string &name) const {
auto index = parameterIndex(name);
return getError(index);
}
void FunctionParameterDecorator::setError(size_t i, double err) {
throwIfNoFunctionSet();
return m_wrappedFunction->setError(i, err);
}
void FunctionParameterDecorator::setError(const std::string &name, double err) {
auto index = parameterIndex(name);
setError(index, err);
}
size_t FunctionParameterDecorator::getParameterIndex(
const ParameterReference &ref) const {
throwIfNoFunctionSet();
......
......@@ -188,7 +188,7 @@ std::string ParamFunction::parameterDescription(size_t i) const {
}
/**
* Get the fitting error for a parameter
* Get the fitting error for a parameter.
* @param i :: The index of a parameter
* @return :: the error
*/
......@@ -198,7 +198,27 @@ double ParamFunction::getError(size_t i) const {
}
/**
* Set the fitting error for a parameter
* Get the fitting error for a parameter by name.
* @param name :: The name of a parameter
* @return :: the error
*/
double ParamFunction::getError(const std::string &name) const {
auto it = std::find(m_parameterNames.cbegin(), m_parameterNames.cend(), name);
if (it == m_parameterNames.cend()) {
std::ostringstream msg;
msg << "ParamFunction tries to get error of non-existing parameter ("
<< name << ") "
<< "to function " << this->name();
msg << "\nAllowed parameters: ";
for (const auto &parameterName : m_parameterNames)
msg << parameterName << ", ";
throw std::invalid_argument(msg.str());
}
return m_errors[static_cast<int>(it - m_parameterNames.begin())];
}
/**
* Set the fitting error for a parameter.
* @param i :: The index of a parameter
* @param err :: The error value to set
*/
......@@ -207,6 +227,26 @@ void ParamFunction::setError(size_t i, double err) {
m_errors[i] = err;
}
/**
* Get the fitting error for a parameter by name.
* @param name :: The name of a parameter
* @return :: the error
*/
void ParamFunction::setError(const std::string &name, double err) {
auto it = std::find(m_parameterNames.cbegin(), m_parameterNames.cend(), name);
if (it == m_parameterNames.cend()) {
std::ostringstream msg;
msg << "ParamFunction tries to set error of non-existing parameter ("
<< name << ") "
<< "to function " << this->name();
msg << "\nAllowed parameters: ";
for (const auto &parameterName : m_parameterNames)
msg << parameterName << ", ";
throw std::invalid_argument(msg.str());
}
m_errors[static_cast<int>(it - m_parameterNames.begin())] = err;
}
/**
* Declare a new parameter. To used in the implementation'c constructor.
* @param name :: The parameter name.
......
......@@ -61,8 +61,12 @@ public:
bool isExplicitlySet(size_t i) const override;
/// Get the fitting error for a parameter
double getError(size_t i) const override;
/// Get the fitting error for a parameter by name
double getError(const std::string &name) const override;
/// Set the fitting error for a parameter
void setError(size_t i, double err) override;
/// Set the fitting error for a parameter by name
void setError(const std::string &name, double err) override;
/// Return parameter index from a parameter reference.
size_t getParameterIndex(const API::ParameterReference &ref) const override;
......
......@@ -319,6 +319,20 @@ double CrystalFieldFunction::getError(size_t i) const {
}
}
/// Get the fitting error for a parameter
double CrystalFieldFunction::getError(const std::string &name) const {
auto index = parameterIndex(name);
checkSourceFunction();
checkTargetFunction();
if (index < m_nControlParams) {
return m_control.getError(index);
} else if (index < m_nControlSourceParams) {
return m_source->getError(index - m_nControlParams);
} else {
return m_target->getError(index - m_nControlSourceParams);
}
}
/// Set the fitting error for a parameter
void CrystalFieldFunction::setError(size_t i, double err) {
checkSourceFunction();
......@@ -332,6 +346,20 @@ void CrystalFieldFunction::setError(size_t i, double err) {
}
}
/// Set the fitting error for a parameter
void CrystalFieldFunction::setError(const std::string &name, double err) {
auto index = parameterIndex(name);
checkSourceFunction();
checkTargetFunction();
if (index < m_nControlParams) {
m_control.setError(index, err);
} else if (index < m_nControlSourceParams) {
m_source->setError(index - m_nControlParams, err);
} else {
m_target->setError(index - m_nControlSourceParams, err);
}
}
/// Change status of parameter
void CrystalFieldFunction::setParameterStatus(
size_t i, IFunction::ParameterStatus status) {
......
......@@ -46,13 +46,6 @@ PyObject *getCategories(IFunction &self) {
return registered;
}
/**
* Return fitting error for a parameter given its name.
*/
double getError(IFunction &self, std::string const &name) {
return self.getError(self.parameterIndex(name));
}
// -- Set property overloads --
// setProperty(index,value,explicit)
using setParameterType1 = void (IFunction::*)(size_t, const double &, bool);
......@@ -63,11 +56,26 @@ GNU_DIAG_OFF("conversion")
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType1_Overloads,
setParameter, 2, 3)
// setProperty(index,value,explicit)
// setProperty(name,value,explicit)
using setParameterType2 = void (IFunction::*)(const std::string &,
const double &, bool);
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads,
setParameter, 2, 3)
// setError(index,value)
using setErrorType1 = void (IFunction::*)(size_t, double);
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setErrorType1_Overloads, setError, 2, 2)
// setError(name,value)
using setErrorType2 = void (IFunction::*)(const std::string &, double);
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setErrorType2_Overloads, setError, 2, 2)
// getError(index)
using getErrorType1 = double (IFunction::*)(size_t) const;
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getErrorType1_Overloads, getError, 1, 1)
// getError(name)
using getErrorType2 = double (IFunction::*)(const std::string &) const;
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getErrorType2_Overloads, getError, 1, 1)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(tie_Overloads, tie, 2, 3)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(addConstraints_Overloads, addConstraints,
1, 2)
......@@ -147,15 +155,29 @@ void export_IFunction() {
(arg("self"), arg("i"), arg("value"), arg("explicitlySet")),
"Sets the value of the ith parameter"))
.def("setError", &IFunction::setError,
(args("self"), args("i"), args("err")),
"Sets the error on parameter index i")
.def("setParameter", (setParameterType2)&IFunction::setParameter,
setParameterType2_Overloads(
(arg("self"), arg("name"), arg("value"), arg("explicitlySet")),
"Sets the value of the named parameter"))
.def("setError", (setErrorType1)&IFunction::setError,
setErrorType1_Overloads((args("self"), arg("index"), args("err")),
"Sets the error on the indexed parameter"))
.def("setError", (setErrorType2)&IFunction::setError,
setErrorType2_Overloads((args("self"), arg("name"), args("err")),
"Sets the error on the named parameter"))
.def("getError", (getErrorType1)&IFunction::getError,
getErrorType1_Overloads(
(arg("self"), arg("index")),
"Return fitting error of the index parameter"))
.def("getError", (getErrorType2)&IFunction::getError,
getErrorType2_Overloads(
(arg("self"), arg("name")),
"Return fitting error of the named parameter"))
.def("__setitem__", (setParameterType2)&IFunction::setParameter,
setParameterType2_Overloads(
(arg("self"), arg("name"), arg("value"), arg("explicitlySet")),
......@@ -272,10 +294,6 @@ void export_IFunction() {
.def("getParamValue",
(double (IFunction::*)(std::size_t) const) & IFunction::getParameter,
(arg("self"), arg("i")), "Get the value of the ith parameter")
.def("getError", &IFunction::getError, (arg("self"), arg("i")),
"Return fitting error of the ith parameter")
.def("getError", &getError, (arg("self"), arg("name")),
"Return fitting error of the named parameter")
//-- Python special methods --
.def("__repr__", &IFunction::asString, arg("self"),
......
......@@ -123,9 +123,42 @@ void ConvFit::setModelResolution(const std::string &resolutionName,
m_convFittingModel->setResolution(resolutionName, index);
auto fitResolutions = m_convFittingModel->getResolutionsForFit();
m_fitPropertyBrowser->setModelResolution(fitResolutions);
updateParameterValues();
setModelFitFunction();
}
void ConvFit::setDefaultResolution(
const Mantid::API::MatrixWorkspace_const_sptr &ws,
const QPair<double, double> &range) {
auto inst = ws->getInstrument();
auto analyser = inst->getStringParameter("analyser");
if (analyser.size() > 0) {
auto comp = inst->getComponentByName(analyser[0]);
if (comp) {
auto params = comp->getNumberParameter("resolution", true);
// set the default instrument resolution
if (!params.empty()) {
double res = params[0];
m_dblManager->setValue(m_properties["InstrumentResolution"], res);
m_dblManager->setValue(m_properties["IntegrationStart"], -res);
m_dblManager->setValue(m_properties["IntegrationEnd"], res);
m_dblManager->setValue(m_properties["BackgroundStart"], -10 * res);
m_dblManager->setValue(m_properties["BackgroundEnd"], -9 * res);
} else {
m_dblManager->setValue(m_properties["IntegrationStart"], range.first);
m_dblManager->setValue(m_properties["IntegrationEnd"], range.second);
}
} else {
showMessageBox("Warning: The instrument definition file for the input "
"workspace contains an invalid value.");
}
}
}
void ConvFit::fitFunctionChanged() {
m_convFittingModel->setFitTypeString(fitTypeString());
}
......
......@@ -32,6 +32,8 @@ protected slots:
void setModelResolution(const std::string &resolutionName);
void setModelResolution(const std::string &resolutionName,
TableDatasetIndex index);
void setDefaultResolution(const Mantid::API::MatrixWorkspace_const_sptr &ws,
const QPair<double, double> &range);
void runClicked();
void fitFunctionChanged();
......
......@@ -415,10 +415,11 @@ void IndirectFitAnalysisTab::updateParameterValues() {
* @param parameters The parameter values to update the browser with.
*/
void IndirectFitAnalysisTab::updateParameterValues(
const std::unordered_map<std::string, ParameterValue> &) {
const std::unordered_map<std::string, ParameterValue>
params) {
try {
updateFitBrowserParameterValues();
} catch (const std::out_of_range &) {
updateFitBrowserParameterValues(params);
} catch (const std::out_of_range &error) {
g_log.warning(
"Warning issue updating parameter values in fit property browser");
} catch (const std::invalid_argument &) {
......@@ -427,9 +428,13 @@ void IndirectFitAnalysisTab::updateParameterValues(
}
}
void IndirectFitAnalysisTab::updateFitBrowserParameterValues() {
void IndirectFitAnalysisTab::updateFitBrowserParameterValues(
std::unordered_map<std::string, ParameterValue> params) {
IFunction_sptr fun = m_fittingModel->getFittingFunction();
if (fun) {
for (auto pair : params) {
fun->setParameter(pair.first, pair.second.value);
}
if (fun->getNumberDomains() > 1) {
m_fitPropertyBrowser->updateMultiDatasetParameters(*fun);
} else {
......
......@@ -115,8 +115,10 @@ protected slots:
void executeFit();
void updateParameterValues();
void updateParameterValues(
const std::unordered_map<std::string, ParameterValue> &parameters);
void updateFitBrowserParameterValues();
const std::unordered_map<std::string, ParameterValue> parameters);
void updateFitBrowserParameterValues(
std::unordered_map<std::string, ParameterValue> parameters =
std::unordered_map<std::string, ParameterValue>());
void updateFitBrowserParameterValuesFromAlg();
void updateFitStatus();
void updateDataReferences();
......
......@@ -450,14 +450,10 @@ void FunctionModel::checkIndex(int index) const {
void FunctionModel::updateMultiDatasetParameters(const IFunction &fun) {
if (!hasFunction())
return;
if (m_function->nParams() != fun.nParams())
return;
for (size_t i = 0; i < fun.nParams(); ++i) {
m_function->setParameter(i, fun.getParameter(i));
m_function->setError(i, fun.getError(i));
}
copyParametersAndErrors(fun, *m_function);
updateMultiDatasetAttributes(fun);
}
void FunctionModel::updateMultiDatasetAttributes(const IFunction &fun) {
if (!hasFunction())
return;
......
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