30 m_function = std::dynamic_pointer_cast<MultiDomainFunction>(fun);
39 for (
int i = 0; i < nf; ++i) {
50 auto const numberOfFunctions =
m_function->nFunctions();
52 if (numberOfFunctions > 1) {
57 }
else if (numberOfFunctions == 1) {
58 auto const function =
m_function->getFunction(0)->clone();
59 auto const composite = std::dynamic_pointer_cast<CompositeFunction>(function);
61 if (composite && composite->nFunctions() == 1)
62 return composite->getFunction(0);
69 auto function = std::dynamic_pointer_cast<MultiDomainFunction>(
m_function->clone());
73 if (singleFun->hasParameter(paramIter->toStdString())) {
75 for (
auto i = 0u; i <
m_function->nFunctions(); ++i)
77 ties <<
"f" + QString::number(i) +
"." + *paramIter;
79 ties <<
"f" + QString::number(
index) +
"." + *paramIter;
80 function->addTies(ties.join(
"=").toStdString());
102 for (
int i = 0; i < nf; ++i) {
105 auto cf = std::dynamic_pointer_cast<CompositeFunction>(parentFun);
107 cf->addFunction(newFun->clone());
108 }
else if (i == 0 && prefix.isEmpty()) {
112 throw std::runtime_error(
"Function at " + prefix.toStdString() +
" is not composite.");
123 if (prefix.isEmpty() &&
index == -1) {
128 for (
int i = 0; i < nf; ++i) {
131 auto cf = std::dynamic_pointer_cast<CompositeFunction>(parentFun);
133 throw std::runtime_error(
"Function at " + prefix.toStdString() +
" is not composite.");
135 cf->removeFunction(
index);
136 if (cf->nFunctions() == 1 && prefix.isEmpty() && cf->name() ==
"CompositeFunction") {
137 m_function->replaceFunction(i, cf->getFunction(0));
157 throw std::logic_error(
"Function is undefined.");
159 if (fun->hasAttribute(attrName.toStdString())) {
160 fun->setAttribute(attrName.toStdString(),
value);
166 auto const index = fun->parameterIndex(paramName.toStdString());
180 auto const index = fun->parameterIndex(paramName.toStdString());
181 return fun->getError(
index);
186 auto const index = fun->parameterIndex(paramName.toStdString());
187 return QString::fromStdString(fun->parameterDescription(
index));
210 for (
auto const &name : paramNames) {
211 names << QString::fromStdString(name);
220 for (
auto const &name : attributeNames) {
221 names << QString::fromStdString(name);
241 throw std::runtime_error(
"Number of domains shouldn't be less than 0.");
243 auto const nd =
static_cast<size_t>(nDomains);
251 auto const lastIndex = nfOld - 1;
252 auto const nf = nd > 0 ? nd : 1;
254 auto fun =
m_function->getFunction(lastIndex);
255 for (
size_t i = nfOld; i < nf; ++i) {
260 for (
size_t i = lastIndex; i >= nf; --i) {
265 for (
size_t i = 0; i <
m_function->nFunctions(); ++i) {
281 for (
const auto &datasetName : datasetNames)
300 for (
const auto &datasetName : datasetNames)
313 sort(indices.begin(), indices.end(), [](
int a,
int b) { return a > b; });
314 for (
auto i = indices.constBegin(); i != indices.constEnd(); ++i)
321 if (currentIndex >= nDomains)
322 currentIndex =
m_datasets.isEmpty() ? 0 : nDomains - 1;
331 QStringList datasetNames;
333 for (
auto i = 0u; i < dataset.numberOfSpectra(); ++i) {
335 datasetNames << dataset.datasetName();
344 QStringList domainNames;
346 domainNames << dataset.domainNames();
365 auto const parIndex = fun->parameterIndex(parName.toStdString());
366 return fun->isFixed(parIndex);
371 auto const parIndex = fun->parameterIndex(parName.toStdString());
372 auto const tie = fun->getTie(parIndex);
375 auto const tieStr = QString::fromStdString(tie->asString());
376 auto const j = tieStr.indexOf(
'=');
377 return tieStr.mid(j + 1);
382 auto const parIndex = fun->parameterIndex(parName.toStdString());
383 auto const constraint = fun->getConstraint(parIndex);
384 auto const out = (!constraint) ?
"" : QString::fromStdString(constraint->asString());
390 if (function && function->hasParameter(parName.toStdString()))
391 function->setParameter(parName.toStdString(),
value);
396 auto const parIndex = fun->parameterIndex(parName.toStdString());
397 fun->setParameter(parIndex,
value);
398 fun->setError(parIndex,
error);
403 auto const parIndex = fun->parameterIndex(parName.toStdString());
406 }
else if (fun->isFixed(parIndex)) {
407 fun->unfix(parIndex);
412 auto logError = [&parName](
const std::string &msg) {
413 g_log.
error() <<
"Tie " << parName.toStdString() <<
": " << msg <<
'\n';
416 auto const name = parName.toStdString();
418 fun->removeTie(fun->parameterIndex(name));
420 auto const j = tie.indexOf(
'=');
422 fun->tie(name, tie.mid(j + 1).toStdString());
423 }
catch (
const std::invalid_argument &e) {
425 }
catch (
const std::runtime_error &e) {
433 if (constraint !=
"" && parts.second.first ==
"" && parts.second.second ==
"") {
434 g_log.
error(
"Constraint " + parName.toStdString() +
": " + constraint.toStdString() +
" is not a valid constraint");
437 QString prefix, name;
440 if (constraint.isEmpty()) {
441 fun->removeConstraint(name.toStdString());
443 auto newConstraint(constraint);
444 newConstraint.replace(parts.first, name);
445 fun->addConstraints(newConstraint.toStdString());
458 }
catch (std::exception &) {
465 fun->addConstraints(constraint.toStdString());
497 throw std::runtime_error(
"Number of dataset domains doesn't match the number of domains.");
502 return std::accumulate(datasets.cbegin(), datasets.cend(), 0, [](
int lhs,
const auto &dataset) {
503 return lhs + static_cast<int>(dataset.numberOfSpectra());
512 throw std::runtime_error(
"Domain index is out of range: " +
std::to_string(
index) +
" out of " +
544 if (!fun->hasParameter(it->toStdString())) {
553 auto n = fun->getNumberDomains();
559 if (fun->hasAttribute(
"f0.Workspace")) {
560 std::string wsName = fun->getAttribute(
"f0.Workspace").asString();
571 auto analyser = inst->getStringParameter(
"analyser");
572 if (!analyser.empty()) {
573 auto comp = inst->getComponentByName(analyser[0]);
574 if (comp && comp->hasParameter(
"resolution")) {
575 auto params = comp->getNumberParameter(
"resolution",
true);
576 for (
auto param : fun->getParameterNames()) {
577 if (param.find(
"FWHM") != std::string::npos) {
578 fun->setParameter(param, params[0]);
588 std::string foundName;
590 auto getA0 = [](
IFunction const &f) -> std::string {
593 auto const cf = std::dynamic_pointer_cast<CompositeFunction>(fun);
595 if (fun->name() !=
"CompositeFunction")
597 for (
size_t i = 0; i < cf->nFunctions(); ++i) {
598 foundName = getA0(*cf->getFunction(i));
599 if (!foundName.empty()) {
605 foundName = getA0(*fun);
607 if (!foundName.empty()) {
608 fun->setParameter(foundName,
value);
610 return QString::fromStdString(foundName);
double value
The value of the point.
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
An interface to a background function.
Attribute is a non-fitting parameter.
This is an interface to a fitting function - a semi-abstarct class.
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
virtual std::vector< std::string > getAttributeNames() const
Returns a list of attribute names.
virtual size_t nAttributes() const
Returns the number of attributes associated with the function.
Base MatrixWorkspace Abstract Class.
A composite function defined on a CompositeDomain.
bool hasParameter(const std::string &name) const override
Check if function has a parameter with this name.
The Logger class is in charge of the publishing messages from the framework through various channels.
void error(const std::string &msg)
Logs at error level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< MultiDomainFunction > MultiDomainFunction_sptr
Shared pointer to Mantid::API::MultiDomainFunction.
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::string to_string(const wide_integer< Bits, Signed > &n)