Mantid
Loading...
Searching...
No Matches
PropertyHandler.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 +
9
23
25
26#include "MantidQtWidgets/Common/QtPropertyBrowser/ParameterPropertyManager.h"
27#include "MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h"
28#include "MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h"
29
30#include <QMessageBox>
31#include <algorithm>
32#include <regex>
33#include <utility>
34
35using std::size_t;
36
37namespace {
38const std::regex PREFIX_REGEX("(^[f][0-9](.*))");
39inline bool variableIsPrefixed(const std::string &name) { return std::regex_match(name, PREFIX_REGEX); }
40} // namespace
41
43
44// Constructor
46 FitPropertyBrowser *browser, QtBrowserItem *item)
47 : FunctionHandler(fun), m_browser(browser), m_cf(std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun)),
48 m_pf(std::dynamic_pointer_cast<Mantid::API::IPeakFunction>(fun)), m_parent(std::move(parent)), m_type(nullptr),
49 m_item(item), m_isMultispectral(false), m_workspace(nullptr), m_workspaceIndex(nullptr), m_base(0), m_ci(0),
50 m_hasPlot(false) {}
51
54
58 if (m_parent == nullptr) { // the root composite function
60 } else if (m_item == nullptr) {
61 if (!m_parent->getHandler()) {
62 throw std::runtime_error("Parent function handler does not exist");
63 }
64 // PropertyHandler* ph = parentHandler();
65 QtBrowserItem const *pi = parentHandler()->item();
66 // Create group property with function name on it
67 QtProperty *fnProp = m_browser->m_groupManager->addProperty(functionName());
68 pi->property()->addSubProperty(fnProp);
69 // assign m_item
70 QList<QtBrowserItem *> itList = pi->children();
71 const auto it = std::find_if(itList.cbegin(), itList.cend(),
72 [&fnProp](auto browserItem) { return browserItem->property() == fnProp; });
73 if (it != itList.cend()) {
74 m_item = *it;
75 } else {
76 throw std::runtime_error("Browser item not found");
77 }
78
79 if (!m_cf) {
80 m_browser->m_browser->setExpanded(m_item, false);
81 }
82 } else {
83 m_item->property()->setPropertyName(functionName());
84 }
85
86 QtProperty *fnProp = m_item->property();
87
88 // create Type property
89 if (!m_type) {
90 m_type = m_browser->m_enumManager->addProperty("Type");
91
92 fnProp->addSubProperty(m_type);
93 if (m_parent) {
95
96 } else {
97 QStringList functionNames;
98 functionNames << "CompositeFunction"; // << "MultiBG";
99 m_browser->m_enumManager->setEnumNames(m_type, functionNames);
100 }
101 }
102 int itype =
103 static_cast<int>(m_browser->m_enumManager->enumNames(m_type).indexOf(QString::fromStdString(m_fun->name())));
104 m_browser->m_enumManager->setValue(m_type, itype);
105 // create worspace and workspace index properties if parent is a MultiBG
107
108 // create attribute properties
110
111 // create parameter properties
113
114 // set handlers for the child functions
115 if (m_cf && m_cf->nFunctions() > 0) {
116 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
117 Mantid::API::IFunction_sptr f = std::dynamic_pointer_cast<Mantid::API::IFunction>(m_cf->getFunction(i));
118 if (!f) {
119 throw std::runtime_error("IFunction expected but func function of another type");
120 }
121 auto h = std::make_unique<PropertyHandler>(f, m_cf, m_browser);
122 f->setHandler(std::move(h));
123 }
124 initTies(); // populate ties after all child functions handlers have been inititiated (post setHandler)
125 }
126
128}
129
135public:
137 Mantid::Kernel::IValidator_sptr validator = nullptr)
138 : m_browser(browser), m_handler(handler), m_name(std::move(name)) {
139 m_validator = validator;
140 }
141
142protected:
144 QtProperty *apply(const std::string &str) const override {
145 QtProperty *prop;
146
147 // if validator is string list validator, create string list property
148 if (dynamic_cast<Mantid::Kernel::StringListValidator *>(m_validator.get()) != nullptr) {
149 prop = m_browser->addStringListProperty(m_name, m_validator->allowedValues());
150 } else {
152 }
153
154 m_browser->setStringPropertyValue(prop, QString::fromStdString(str));
155 return prop;
156 }
158 QtProperty *apply(const double &d) const override {
159 QtProperty *prop = m_browser->addDoubleProperty(m_name);
160 m_browser->m_doubleManager->setValue(prop, d);
161 return prop;
162 }
164 QtProperty *apply(const int &i) const override {
165 QtProperty *prop = m_browser->m_intManager->addProperty(m_name);
166 m_browser->m_intManager->setValue(prop, i);
167 return prop;
168 }
170 QtProperty *apply(const bool &b) const override {
171 QtProperty *prop = m_browser->m_boolManager->addProperty(m_name);
172 m_browser->m_boolManager->setValue(prop, b);
173 return prop;
174 }
176 QtProperty *apply(const std::vector<double> &b) const override {
177 // throw std::runtime_error("Vector attribute property not implememted.");
178 QtProperty *prop = m_browser->m_vectorManager->addProperty(m_name);
179 m_browser->m_vectorSizeManager->blockSignals(true);
180 QtProperty *sizeProp = m_browser->m_vectorSizeManager->addProperty("Size");
181 m_browser->m_vectorSizeManager->setValue(sizeProp, static_cast<int>(b.size()));
182 prop->addSubProperty(sizeProp);
183 m_handler->m_vectorSizes << sizeProp;
184 // sizeProp->setEnabled(false);
185 m_browser->m_vectorSizeManager->blockSignals(false);
186 m_browser->m_vectorDoubleManager->blockSignals(true);
187 QString dpName = "value[%1]";
188 for (size_t i = 0; i < b.size(); ++i) {
189 QtProperty *dprop = m_browser->addDoubleProperty(dpName.arg(i), m_browser->m_vectorDoubleManager);
190 m_browser->m_vectorDoubleManager->setValue(dprop, b[i]);
191 prop->addSubProperty(dprop);
192 m_handler->m_vectorMembers << dprop;
193 }
194 m_browser->m_vectorDoubleManager->blockSignals(false);
195 return prop;
196 }
197
198private:
201 QString m_name;
202};
203
208 for (size_t iparam = 0; iparam < m_cf->nParams(); iparam++) {
209 const auto *tie = m_cf->getTie(iparam);
210 if (tie) {
211 // get function index from prefix (second element of pair below)
212 const auto nameIndex_pair = m_cf->parseName(m_cf->parameterName(iparam));
214 std::dynamic_pointer_cast<Mantid::API::IFunction>(m_cf->getFunction(nameIndex_pair.second));
215 auto *h = findHandler(f);
216 h->addTie(QString::fromStdString(tie->asString()));
217 }
218 }
219}
220
225 std::vector<std::string> attNames = function()->getAttributeNames();
226 for (auto &attribute : m_attributes) {
227 m_item->property()->removeSubProperty(attribute);
228 }
229 m_attributes.clear();
230 m_vectorMembers.clear();
231 for (const auto &attName : attNames) {
232 if (variableIsPrefixed(attName))
233 continue;
234 QString aName = QString::fromStdString(attName);
235 Mantid::API::IFunction::Attribute att = function()->getAttribute(attName);
237 QtProperty *prop = att.apply(tmp);
238 m_item->property()->addSubProperty(prop);
239 m_attributes << prop;
240 }
241}
242
244 for (auto &parameter : m_parameters) {
245 m_item->property()->removeSubProperty(parameter);
246 }
247 m_parameters.clear();
249
250 for (size_t i = 0; i < function()->nParams(); i++) {
251 QString parName = QString::fromStdString(function()->parameterName(i));
252 if (parName.contains('.'))
253 continue;
254 QtProperty *prop = m_browser->addDoubleProperty(parName, m_browser->m_parameterManager);
255
256 m_browser->m_parameterManager->setDescription(prop, function()->parameterDescription(i));
257 m_browser->m_parameterManager->setValue(prop, function()->getParameter(i));
258
259 m_item->property()->addSubProperty(prop);
260 m_parameters << prop;
261 if (m_fun->isFixed(i)) {
262 fix(parName);
264 }
265 // add constraint properties
266 const Mantid::API::IConstraint *c = m_fun->getConstraint(i);
267 if (c) {
268 QStringList qc = QString::fromStdString(c->asString()).split("<");
269 bool lo = false;
270 bool up = false;
271 double loBound = 0, upBound = 0;
272 if (qc.size() == 2) {
273 if (qc[0].contains(parName)) {
274 up = true;
275 upBound = qc[1].toDouble();
276 } else {
277 lo = true;
278 loBound = qc[0].toDouble();
279 }
280 } else if (qc.size() == 3) {
281 lo = up = true;
282 loBound = qc[0].toDouble();
283 upBound = qc[2].toDouble();
284 } else {
285 continue;
286 }
287 QtProperty *loProp = nullptr;
288 QtProperty *upProp = nullptr;
289 if (lo) {
290 loProp = m_browser->addDoubleProperty("LowerBound");
291 m_browser->m_doubleManager->setValue(loProp, loBound);
292 prop->addSubProperty(loProp);
293 }
294 if (up) {
295 upProp = m_browser->addDoubleProperty("UpperBound");
296 m_browser->m_doubleManager->setValue(upProp, upBound);
297 prop->addSubProperty(upProp);
298 }
299 m_constraints.insert(parName, std::pair<QtProperty *, QtProperty *>(loProp, upProp));
300 }
301 }
302
303 PropertyHandler *pHandler = this->parentHandler();
304 if (pHandler) {
305 for (auto it = m_parameters.cbegin(); it != m_parameters.cend(); ++it) {
306 pHandler->m_paramToPropertyHandlerMap[*it] = this;
307 }
308 }
309}
310
312 if (m_parent && m_parent->name() == "MultiBG") {
313 // m_workspace = m_browser->m_enumManager->addProperty("Workspace");
314 // QtProperty* fnProp = m_item->property();
315 // fnProp->addSubProperty(m_workspace);
316 // m_workspaceIndex = m_browser->m_intManager->addProperty("Workspace
317 // Index");
318 // if (! m_browser->m_workspaceNames.isEmpty() )
319 //{
320 // QStringList names("All");
321 // foreach(QString name,m_browser->m_workspaceNames)
322 // {
323 // names.append(name);
324 // }
325 // m_browser->m_enumManager->setEnumNames(m_workspace, names);
326 // int iWorkspace = 0;
327 // int iWorkspaceIndex = 0;
328 // if (ifun()->getWorkspace())
329 // {
330 // Mantid::API::IFunctionMW* ifmw =
331 // dynamic_cast<Mantid::API::IFunctionMW*>(ifun());
332 // if (ifmw)
333 // {
334 // std::string wsName = ifmw->getMatrixWorkspace()->getName();
335 // iWorkspace = names.indexOf(QString::fromStdString(wsName));
336 // if (iWorkspace >= 0)
337 // {
338 // iWorkspaceIndex = static_cast<int>(ifmw->getWorkspaceIndex());
339 // fnProp->addSubProperty(m_workspaceIndex);
340 // }
341 // else
342 // {
343 // iWorkspace = 0;
344 // }
345 // }
346 // }
347 // m_browser->m_enumManager->setValue(m_workspace,iWorkspace);
348 // m_browser->m_intManager->setValue(m_workspaceIndex,iWorkspaceIndex);
349 //}
350 } else {
351 m_workspace = m_workspaceIndex = nullptr;
352 }
353}
354
361 if (!m_cf)
362 return nullptr;
365 // Create new function
366 if (fnName.find("=") == std::string::npos) { // either from name
367 f = Mantid::API::FunctionFactory::Instance().createFunction(fnName);
368 } else { // of from full initialization expression
369 f = Mantid::API::FunctionFactory::Instance().createInitialized(fnName);
370 }
371
372 // turn off the change slots (doubleChanged() etc) to avoid infinite loop
374 // Check if it's a peak and set its width
375 std::shared_ptr<Mantid::API::IPeakFunction> pf = std::dynamic_pointer_cast<Mantid::API::IPeakFunction>(f);
376 if (pf) {
377 if (!m_browser->workspaceName().empty() && m_browser->workspaceIndex() >= 0 && pf->centre() == 0.) {
378 pf->setCentre((m_browser->startX() + m_browser->endX()) / 2);
379 }
380 }
381
383
384 try {
385 ws = std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
386 Mantid::API::AnalysisDataService::Instance().retrieve(m_browser->workspaceName()));
387 } catch (...) {
388 }
389
390 size_t wi = m_browser->workspaceIndex();
391
392 // if it's a LinearBackground estimate its A0 and A1 parameters
393 // from data values at the ends of the fitting interval
394 if (f->name() == "LinearBackground" && !m_browser->workspaceName().empty()) {
395 if (ws && wi < ws->getNumberHistograms()) {
396 const auto &X = ws->x(wi);
397 size_t istart = 0, iend = 0;
398 for (size_t i = 0; i < X.size() - 1; ++i) {
399 double x = X[i];
400 if (x < m_browser->startX())
401 istart = i;
402 if (x > m_browser->endX()) {
403 iend = i;
404 if (iend > 0)
405 iend--;
406 break;
407 }
408 }
409 if (iend > istart) {
410 const auto &Y = ws->y(wi);
411 double p0 = Y[istart];
412 double p1 = Y[iend];
413 double A1 = (p1 - p0) / (X[iend] - X[istart]);
414 double A0 = p0 - A1 * X[istart];
415 f->setParameter("A0", A0);
416 f->setParameter("A1", A1);
417 }
418 }
419 }
420 if (ws) {
422 }
423
424 size_t nFunctions = m_cf->nFunctions() + 1;
425 m_cf->addFunction(f);
426
427 m_browser->compositeFunction()->checkFunction();
428
429 if (m_cf->nFunctions() != nFunctions) { // this may happen
430 m_browser->reset();
432 return nullptr;
433 }
434
435 f->setHandler(std::make_unique<PropertyHandler>(f, m_cf, m_browser));
436
437 auto h = static_cast<PropertyHandler *>(f->getHandler());
438 h->setAttribute("StartX", m_browser->startX());
439 h->setAttribute("EndX", m_browser->endX());
440
442 if (pf) {
443 m_browser->setDefaultPeakType(f->name());
444 } else {
446 }
447 m_browser->setFocus();
448 auto return_ptr = static_cast<PropertyHandler *>(f->getHandler());
449 m_browser->setCurrentFunction(return_ptr);
450 // enable the change slots
452 return return_ptr;
453}
454
455// Removes handled function from its parent function and
456// properties from the browser
459 if (ph) {
460 if (this == m_browser->m_autoBackground) {
461 m_browser->m_autoBackground = nullptr;
462 }
463 ph->item()->property()->removeSubProperty(m_item->property());
465 for (int i = 0; i < static_cast<int>(cf->nFunctions()); i++) {
466 if (cf->getFunction(i) == function()) {
467 emit m_browser->removePlotSignal(this);
468 cf->removeFunction(i);
469 break;
470 }
471 }
472 ph->renameChildren(*cf);
473 m_browser->setFitEnabled(cf->nFunctions() > 0);
474 }
475}
476
479 for (auto it = m_ties.begin(); it != m_ties.end();) {
480 QString parName = it.key();
481 QString fullName = functionPrefix() + "." + parName;
482 QtProperty *prop = it.value();
483 const auto paramIndex = m_browser->compositeFunction()->parameterIndex(fullName.toStdString());
484 const auto status = cf.getParameterStatus(paramIndex);
485 const auto *tie = cf.getTie(paramIndex);
486 if (!tie) {
489 // In this case the tie has been removed from the composite function since it contained a reference to
490 // the function which was removed
491 QtProperty *parProp = getParameterProperty(parName);
492 if (parProp != nullptr) {
493 parProp->removeSubProperty(prop);
494 // Don't increment the iterator if we delete the current tie.
495 it = m_ties.erase(it);
496 parProp->setEnabled(true);
497 }
498 } else {
499 ++it;
500 }
501 continue;
502 } else {
503 ++it;
504 }
505 // Refresh gui value in case it has been updated by the composite function re-indexing it's functions
506 // after one is removed
507 QStringList qtie = QString::fromStdString(tie->asString()).split("=");
508 if (qtie.size() < 2)
509 continue;
510 m_browser->m_stringManager->setValue(prop, qtie[1]);
511 }
512 if (!m_cf)
513 return;
514 // rename children
515 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
517 if (!h)
518 continue;
519 QtProperty *nameProp = h->item()->property();
520 nameProp->setPropertyName(h->functionName());
521 h->renameChildren(cf);
522 }
524}
525
529 QString name = functionPrefix();
530 if (!name.isEmpty()) {
531 name += "-";
532 }
533 name += QString::fromStdString(function()->name());
534 return name;
535}
536
538 const PropertyHandler *ph = parentHandler();
539 if (ph) {
540 int iFun = -1;
542 for (int i = 0; i < static_cast<int>(cf->nFunctions()); i++) {
543 if (cf->getFunction(i) == function()) {
544 iFun = i;
545 break;
546 }
547 }
548 QString pref = ph->functionPrefix();
549 if (!pref.isEmpty())
550 pref += ".";
551 return pref + "f" + QString::number(iFun);
552 }
553 return "";
554}
555
556// Return the parent handler
558 if (!m_parent)
559 return nullptr;
560 PropertyHandler *ph = static_cast<PropertyHandler *>(m_parent->getHandler());
561 return ph;
562}
563// Return the child's handler
565 if (!m_cf || i >= m_cf->nFunctions())
566 return nullptr;
567 PropertyHandler *ph = static_cast<PropertyHandler *>(m_cf->getFunction(i)->getHandler());
568 return ph;
569}
575 if (!m_cf)
577 if (item == m_item)
578 return m_cf;
579 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
581 if (res != nullptr)
582 return res;
583 }
585}
591 if (item == m_item)
592 return function();
593 if (!m_cf)
595 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
597 if (res != nullptr)
598 return res;
599 }
601}
602
604 if (prop == nullptr)
605 return nullptr;
606 if (prop == m_item->property())
607 return this;
608 if (prop == m_type)
609 return this;
610 if (prop == m_workspace)
611 return this;
612 if (prop == m_workspaceIndex)
613 return this;
614 if (m_attributes.contains(prop))
615 return this;
616 if (m_parameters.contains(prop))
617 return this;
618 if (m_vectorMembers.contains(prop))
619 return this;
620 if (m_vectorSizes.contains(prop))
621 return this;
622 if (!m_ties.key(prop, "").isEmpty())
623 return this;
624 QMap<QString, std::pair<QtProperty *, QtProperty *>>::iterator it = m_constraints.begin();
625 for (; it != m_constraints.end(); ++it) {
626 if (it.value().first == prop || it.value().second == prop) {
627 return this;
628 }
629 }
630 if (!m_cf)
631 return nullptr;
632 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
634 if (h != nullptr)
635 return h;
636 }
637 return nullptr;
638}
639
641 if (fun == function())
642 return this;
643 if (m_cf) {
644 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
646 if (h)
647 return h;
648 }
649 }
650 return nullptr;
651}
652
654 if (fun == function().get())
655 return this;
656 if (m_cf) {
657 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
659 if (h)
660 return h;
661 }
662 }
663 return nullptr;
664}
665
671bool PropertyHandler::setParameter(QtProperty *prop) {
672 if (m_parameters.contains(prop)) {
673 std::string parName = prop->propertyName().toStdString();
674 double parValue = m_browser->m_parameterManager->value(prop);
675 m_fun->setParameter(parName, parValue);
676 // If the parameter is fixed, re-fix to update the subproperty.
677 if (m_fun->isFixed(m_fun->parameterIndex(parName))) {
678 const auto subProps = prop->subProperties();
679 if (std::any_of(subProps.cbegin(), subProps.cend(),
680 [](const auto &subProp) { return subProp->propertyName() == "Fix"; })) {
681 fix(prop->propertyName());
682 }
683 }
684
687 return true;
688 }
689 if (m_cf) {
690 auto pit = m_paramToPropertyHandlerMap.find(prop);
691 if (pit != m_paramToPropertyHandlerMap.end()) {
692 bool res = pit.value()->setParameter(prop);
693 if (res) {
694 m_cf->applyTies();
696 return true;
697 }
698 }
699 }
700 return false;
701}
702
708public:
709 SetAttribute(FitPropertyBrowser *browser, QtProperty *prop,
711 : m_browser(browser), m_prop(prop) {
712 m_validator = validator;
713 }
714
715protected:
717 void apply(std::string &str) const override {
718 std::string propValue = m_browser->getStringPropertyValue(m_prop).toStdString();
719
720 evaluateValidator(propValue);
721 str = propValue;
722 }
724 void apply(double &d) const override {
725 double propValue = m_browser->m_doubleManager->value(m_prop);
726
727 evaluateValidator(propValue);
728 d = propValue;
729 }
731 void apply(int &i) const override {
732 int propValue = m_browser->m_intManager->value(m_prop);
733
734 evaluateValidator(propValue);
735 i = propValue;
736 }
738 void apply(bool &b) const override {
739 bool propValue = m_browser->m_boolManager->value(m_prop);
740
741 evaluateValidator(propValue);
742 b = propValue;
743 }
745 void apply(std::vector<double> &v) const override {
746 QList<QtProperty *> members = m_prop->subProperties();
747 if (members.size() < 1) {
748 v.clear();
749 return;
750 }
751
752 int newSize = m_browser->m_vectorSizeManager->value(members[0]);
753 int vectorSize = static_cast<int>(members.size()) - 1;
754 if (vectorSize > newSize) {
755 vectorSize = newSize;
756 }
757
758 // populate new vector
759 std::vector<double> newVec(newSize);
760 for (int i = 1; i < newSize + 1; ++i) {
761 double newVal = (m_validator != Mantid::Kernel::IValidator_sptr())
762 ? m_browser->m_vectorDoubleManager->value(members[vectorSize])
763 : 0.0;
764 if (i < vectorSize + 1) {
765 newVec[i - 1] = m_browser->m_vectorDoubleManager->value(members[i]);
766 } else {
767 newVec[i - 1] = newVal;
768 }
769 }
770
772 evaluateValidator(newVec);
773 }
774
775 v.resize(newSize);
776 std::copy(cbegin(newVec), cend(newVec), begin(v));
777 }
778
779private:
781 QtProperty *m_prop;
782};
783
789public:
790 SetAttributeProperty(FitPropertyBrowser *browser, QtProperty *prop) : m_browser(browser), m_prop(prop) {}
791
792protected:
794 void apply(const std::string &str) const override {
796 m_browser->setStringPropertyValue(m_prop, QString::fromStdString(str));
798 }
800 void apply(const double &d) const override {
802 m_browser->m_doubleManager->setValue(m_prop, d);
804 }
806 void apply(const int &i) const override {
808 m_browser->m_intManager->setValue(m_prop, i);
810 }
812 void apply(const bool &b) const override {
814 m_browser->m_boolManager->setValue(m_prop, b);
816 }
818 void apply(const std::vector<double> & /*unused*/) const override {
819 // this method is supposed to be called when corresponding
820 // property value changes but it doesn't have a value because
821 // it's a group property
822 throw std::runtime_error("Vector attribute not implemented.");
823 }
824
825private:
827 QtProperty *m_prop;
828};
829
837bool PropertyHandler::setAttribute(QtProperty *prop, bool resetProperties) {
838 if (m_attributes.contains(prop)) {
839 QString attName = prop->propertyName();
840 try {
841 Mantid::API::IFunction::Attribute att = m_fun->getAttribute(attName.toStdString());
843 att.apply(tmp);
844 m_fun->setAttribute(attName.toStdString(), att);
845 m_browser->compositeFunction()->checkFunction();
846 if (resetProperties) {
849 }
850 if (this == m_browser->m_autoBackground) {
851 fit();
852 }
853 } catch (Mantid::API::IFunction::ValidationException &ve) { // catch attribute validation error
856
858 ve.what()); // rethrow validation exception so it can be recaught by Fit Property Browser.
859 } catch (std::exception &e) {
862 QMessageBox::critical(m_browser, "Mantid - Error", e.what());
863 return false;
864 }
865 return true;
866 }
867 if (m_cf) {
868 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
869 bool res = getHandler(i)->setAttribute(prop, resetProperties);
870 if (res)
871 return true;
872 }
873 }
874 return false;
875}
876
882void PropertyHandler::setAttribute(QString const &attName, Mantid::API::IFunction::Attribute const &attValue) {
883 auto const attributeType = attValue.type();
884 if (attributeType == "int")
885 setAttribute(attName, attValue.asInt());
886 else if (attributeType == "double")
887 setAttribute(attName, attValue.asDouble());
888 else if (attributeType == "std::string")
889 setAttribute(attName, QString::fromStdString(attValue.asString()));
890}
891
897template <typename AttributeType>
898void PropertyHandler::setAttribute(QString const &attName, AttributeType const &attValue) {
899 if (m_fun->hasAttribute(attName.toStdString())) {
900 try {
901 m_fun->setAttribute(attName.toStdString(), Mantid::API::IFunction::Attribute(attValue));
902 m_browser->compositeFunction()->checkFunction();
903 // Iterate over a copy: initAttributes()/initParameters() rebuild m_attributes,
904 // which would invalidate iteration over the member list directly.
905 const auto attributes = m_attributes;
906 for (const QtProperty *prop : attributes) {
907 if (prop->propertyName() == attName) {
908 // re-insert the attribute and parameter properties as they may
909 // depend on the value of the attribute being set
912 }
913 }
914 } catch (...) {
915 }
916 }
917 if (cfun()) {
918 for (auto i = 0u; i < cfun()->nFunctions(); ++i) {
920 h->setAttribute(attName, attValue);
921 }
922 }
923}
924
930void PropertyHandler::setAttribute(const QString &attName, const QString &attValue) {
931 const std::string name = attName.toStdString();
932 if (m_fun->hasAttribute(name)) {
933 Mantid::API::IFunction::Attribute att = m_fun->getAttribute(name);
934 att.fromString(attValue.toStdString());
935 m_fun->setAttribute(name, att);
936 m_browser->compositeFunction()->checkFunction();
937 for (QtProperty *prop : m_attributes) {
938 if (prop->propertyName() == attName) {
940 att.apply(tmp);
941 }
942 }
943 // re-insert the attribute and parameter properties as they may
944 // depend on the value of the attribute being set
947 }
948}
949
955 for (QtProperty *att : m_attributes) {
956 QList<QtProperty *> subProps = att->subProperties();
957 if (subProps.contains(prop)) {
958 bool resetProperties = m_vectorSizes.contains(prop);
959 setAttribute(att, resetProperties);
960 return;
961 }
962 }
963}
964
971 for (auto attribute : m_attributes) {
972 (this->*(func))(attribute);
973 }
974
975 if (m_cf)
976 for (std::size_t i = 0u; i < m_cf->nFunctions(); ++i)
978}
979
985
989void PropertyHandler::updateAttribute(QtProperty *attribute) {
990 if (m_attributes.contains(attribute)) {
991 auto const attributeValue = function()->getAttribute(attribute->propertyName().toStdString());
992 setAttribute(attribute->propertyName(), attributeValue);
993 }
994}
995
1002 for (auto prop : m_parameters) {
1003 (this->*(func))(prop);
1004 }
1005
1006 if (m_cf) {
1007 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
1009 }
1010 }
1011}
1012
1014
1016
1018
1022void PropertyHandler::updateParameter(QtProperty *prop) {
1023 double const parValue = function()->getParameter(prop->propertyName().toStdString());
1024 m_browser->m_parameterManager->setValue(prop, parValue);
1025}
1026
1030void PropertyHandler::updateError(QtProperty *prop) {
1031 size_t index = function()->parameterIndex(prop->propertyName().toStdString());
1032 double error = function()->getError(index);
1033 m_browser->m_parameterManager->setError(prop, error);
1034}
1035
1039void PropertyHandler::clearError(QtProperty *prop) { m_browser->m_parameterManager->clearError(prop); }
1040
1046 if (prop == m_type) {
1047 // Create new function
1048 int i = m_browser->m_enumManager->value(prop);
1049 QStringList functionNames = m_browser->m_enumManager->enumNames(prop);
1050 const QString &fnName = functionNames[i];
1052 try {
1053 f = Mantid::API::FunctionFactory::Instance().createFunction(fnName.toStdString());
1054
1055 } catch (std::exception &e) {
1056 QMessageBox::critical(nullptr, "Mantid - Error", "Cannot create function " + fnName + "\n" + e.what());
1058 }
1059
1060 // turn of the change slots (doubleChanged() etc) to avoid infinite loop
1062
1063 // Check if it's a peak and set its width
1064 Mantid::API::IPeakFunction *pf = dynamic_cast<Mantid::API::IPeakFunction *>(f.get());
1065 if (pf) {
1066 if (!m_pf) {
1067 if (!m_browser->workspaceName().empty() && m_browser->workspaceIndex() >= 0) {
1068 pf->setCentre((m_browser->startX() + m_browser->endX()) / 2);
1069 }
1070
1071 } else {
1072 pf->setCentre(m_pf->centre());
1073 pf->setHeight(m_pf->height());
1074 pf->setFwhm(m_pf->fwhm());
1075 }
1076 }
1077
1078 if (pf) {
1079 m_browser->setDefaultPeakType(fnName.toStdString());
1080
1081 } else {
1082 m_browser->setDefaultBackgroundType(fnName.toStdString());
1083 }
1084
1085 QList<QtProperty *> subs = m_item->property()->subProperties();
1086 for (QtProperty *sub : subs) {
1087 m_item->property()->removeSubProperty(sub);
1088 }
1089
1091
1092 emit m_browser->removePlotSignal(this);
1093
1095 std::unique_ptr<PropertyHandler> h = std::make_unique<PropertyHandler>(f, m_parent, m_browser, m_item);
1096 if (this == m_browser->m_autoBackground) {
1097 if (dynamic_cast<Mantid::API::IBackgroundFunction *>(f.get())) {
1098 m_browser->m_autoBackground = h.get();
1099 h->fit();
1100
1101 } else {
1102 m_browser->m_autoBackground = nullptr;
1103 }
1104 }
1105 if (m_parent) {
1106 m_parent->replaceFunctionPtr(f_old, f);
1107 }
1108 // calculate the baseline
1109 if (h->pfun()) {
1110 h->setCentre(h->centre()); // this sets m_ci
1111 h->calcBase();
1112 }
1113 f->setHandler(std::move(h));
1114 // at this point this handler does not exist any more. only return is
1115 // possible
1116 return f;
1117
1118 } else if (m_cf) {
1119 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
1121 if (f)
1122 return f;
1123 }
1124 }
1126}
1127
1128bool PropertyHandler::isParameter(QtProperty *prop) { return m_parameters.contains(prop); }
1129
1130QtProperty *PropertyHandler::getParameterProperty(const QString &parName) const {
1131 const auto it = std::find_if(m_parameters.cbegin(), m_parameters.cend(),
1132 [&parName](const auto &parProp) { return parProp->propertyName() == parName; });
1133 if (it != m_parameters.cend()) {
1134 return *it;
1135 }
1136 return nullptr;
1137}
1138
1139QtProperty *PropertyHandler::getParameterProperty(QtProperty *prop) const {
1140 const auto it = std::find_if(m_parameters.cbegin(), m_parameters.cend(),
1141 [&prop](const auto &parProp) { return parProp->subProperties().contains(prop); });
1142 if (it != m_parameters.cend()) {
1143 return *it;
1144 }
1145 return nullptr;
1146}
1147
1148void PropertyHandler::addTie(const QString &tieStr) {
1149 QStringList parts = tieStr.split("=");
1150 if (parts.size() != 2)
1151 return;
1152 std::string name = parts[0].trimmed().toStdString();
1153 std::string expr = parts[1].trimmed().toStdString();
1154 try {
1155 auto &cfunction = *m_browser->compositeFunction();
1156 cfunction.tie(name, expr);
1157 cfunction.applyTies();
1158 const auto paramIndex = cfunction.parameterIndex(name);
1159 const auto paramStatus = cfunction.getParameterStatus(paramIndex);
1160 const bool fixed = paramStatus == Mantid::API::IFunction::ParameterStatus::Fixed;
1161 const bool recursive = true;
1162 QString parName = QString::fromStdString(cfunction.parameterLocalName(paramIndex, recursive));
1163 QtProperty *parProp = getParameterProperty(parName);
1164 if (!parProp)
1165 return;
1167 QtProperty *tieProp = m_ties[parName];
1168 if (!tieProp) {
1169 const auto tiePropName = fixed ? "Fix" : "Tie";
1170 tieProp = m_browser->m_stringManager->addProperty(tiePropName);
1171 m_ties[parName] = tieProp;
1172 }
1173 m_browser->m_stringManager->setValue(tieProp, QString::fromStdString(expr));
1174 parProp->addSubProperty(tieProp);
1175 if (fixed) {
1176 tieProp->setEnabled(false);
1177 }
1179 if (!fixed) {
1181 }
1182 } catch (const std::exception &exc) {
1183 std::cerr << exc.what();
1184 QMessageBox::critical(m_browser, "Mantid - Error", "Failed to set tie: " + tieStr);
1185 }
1186}
1187
1188void PropertyHandler::fix(const QString &parName) {
1189 const QtProperty *parProp = getParameterProperty(parName);
1190 if (!parProp)
1191 return;
1192 QString parValue = QString::number(m_browser->m_parameterManager->value(parProp));
1193 addTie(functionPrefix() + "." + parName + "=" + parValue);
1194}
1195
1202void PropertyHandler::removeTie(QtProperty *prop, const std::string &globalName) {
1203 QString parName = m_ties.key(prop, "");
1204 if (parName.isEmpty())
1205 return;
1206
1207 QtProperty *parProp = getParameterProperty(parName);
1208 if (parProp) {
1210 auto &compositeFunction = *m_browser->compositeFunction();
1211 auto index = compositeFunction.parameterIndex(globalName);
1212 compositeFunction.removeTie(index);
1213 parProp->removeSubProperty(prop);
1214 m_ties.remove(QString::fromStdString(globalName));
1215 m_ties.remove(parName);
1217 parProp->setEnabled(true);
1218 }
1219}
1224void PropertyHandler::removeTie(QtProperty *prop) {
1225 QString parName = m_ties.key(prop, "");
1226 if (parName.isEmpty())
1227 return;
1228
1229 QtProperty *parProp = getParameterProperty(parName);
1230 if (parProp != nullptr) {
1232 m_fun->removeTie(parName.toStdString());
1233 parProp->removeSubProperty(prop);
1234 m_ties.remove(parName);
1236 parProp->setEnabled(true);
1237 }
1238}
1239
1244void PropertyHandler::removeTie(const QString &parName) {
1245 QtProperty *prop = m_ties[parName];
1246 if (prop)
1247 removeTie(prop);
1248}
1249
1255 double fwhmEstimate = 0.;
1256 auto ws = std::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(m_browser->getWorkspace());
1257 if (ws) {
1258 size_t wi = m_browser->workspaceIndex();
1259 const auto &X = ws->x(wi);
1260 const auto &Y = ws->y(wi);
1261 size_t n = Y.size() - 1;
1262 if (m_ci < 0 || m_ci > static_cast<int>(n)) {
1263 fwhmEstimate = 0.;
1264 } else {
1265 double halfHeight = ((Y[m_ci] - m_base) / 2.) + m_base;
1266 // walk to the right
1267 size_t rightHwhmIndex = m_ci;
1268 while (rightHwhmIndex < n) {
1269 if (Y[rightHwhmIndex++] <= halfHeight) {
1270 break;
1271 }
1272 }
1273
1274 // walk to the left
1275 size_t leftHwhmIndex = m_ci;
1276 while (leftHwhmIndex > 0) {
1277 if (Y[leftHwhmIndex--] <= halfHeight) {
1278 break;
1279 }
1280 }
1281
1282 fwhmEstimate = fabs(X[rightHwhmIndex] - X[leftHwhmIndex]);
1283
1284 // apply a maximum limitation if larger than the fitting region
1285 double fitRange = m_browser->endX() - m_browser->startX();
1286 if (fwhmEstimate > fitRange) {
1287 // set to 10% of fitting region
1288 fwhmEstimate = fitRange * 0.1;
1289 }
1290 }
1291 }
1292 return fwhmEstimate;
1293}
1300 return;
1301
1302 auto ws = std::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(m_browser->getWorkspace());
1303 if (ws) {
1304 size_t wi = m_browser->workspaceIndex();
1305 const auto &X = ws->x(wi);
1306 const auto &Y = ws->y(wi);
1307 int n = static_cast<int>(Y.size()) - 1;
1308 if (m_ci < 0 || m_ci > n || !m_browser->m_autoBackground) {
1309 m_base = 0.;
1310 } else {
1313 m_browser->m_autoBackground->function()->function(x, y);
1314 m_base = y[0];
1315 }
1316 } else {
1317 m_base = 0.;
1318 }
1319}
1320
1328 return;
1329 if (!m_cf)
1330 return;
1331 for (size_t i = 0; i < m_cf->nFunctions(); ++i) {
1333 if (h->pfun()) {
1334 h->calcBase();
1335 } else if (h->cfun()) {
1336 h->calcBaseAll();
1337 }
1338 }
1339}
1340
1344void PropertyHandler::setHeight(const double &h) {
1345 if (m_pf) {
1346 m_pf->setHeight(h - m_base);
1347 }
1348}
1349
1354void PropertyHandler::setCentre(const double &c) {
1355 if (m_pf) {
1356 m_pf->setCentre(c);
1357
1358 // find m_ci: x-index of the peakcentre
1359 auto ws = std::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(m_browser->getWorkspace());
1360 if (ws) {
1361 size_t wi = m_browser->workspaceIndex();
1362 const auto &X = ws->x(wi);
1363 int n = static_cast<int>(X.size()) - 2;
1364 if (m_ci < 0)
1365 m_ci = 0;
1366 if (m_ci > n)
1367 m_ci = n;
1368 double x = X[m_ci];
1369 if (x < c) {
1370 for (; m_ci <= n; ++m_ci) {
1371 x = X[m_ci];
1372 if (x > c)
1373 break;
1374 }
1375 } else {
1376 for (; m_ci >= 0; --m_ci) {
1377 x = X[m_ci];
1378 if (x < c)
1379 break;
1380 }
1381 }
1382 }
1383 }
1384}
1385
1386void PropertyHandler::setFwhm(const double &w) {
1387 if (m_pf) {
1388 m_pf->setFwhm(w);
1389 }
1390}
1391
1393 if (m_pf) {
1394 return m_pf->height();
1395 }
1396 return 0;
1397}
1398
1400 if (m_pf) {
1401 return m_pf->centre();
1402 }
1403 return (m_browser->endX() + m_browser->startX()) / 2;
1404}
1405
1407 if (m_pf) {
1408 return m_pf->fwhm();
1409 }
1410 return 0;
1411}
1412
1414 if (m_pf) {
1415 return m_pf->getWidthParameterName();
1416 }
1417 return "";
1418}
1419
1421 if (m_pf) {
1422 return m_pf->getCentreParameterName();
1423 }
1424 return "";
1425}
1426
1427bool PropertyHandler::isParameterExplicitlySet(const std::string &param) const {
1428 if (m_pf) {
1429 return m_pf->isExplicitlySet(m_pf->parameterIndex(param));
1430 }
1431 return false;
1432}
1433
1437void PropertyHandler::addConstraint(QtProperty *parProp, bool lo, bool up, double loBound, double upBound) {
1438 QMap<QString, std::pair<QtProperty *, QtProperty *>>::iterator old = m_constraints.find(parProp->propertyName());
1439
1440 bool hasLo = false;
1441 bool hasUp = false;
1442
1443 if (old != m_constraints.end()) {
1444 hasLo = old.value().first != NULL;
1445 hasUp = old.value().second != NULL;
1446 if (hasLo && !lo) {
1447 lo = true;
1448 loBound = m_browser->m_doubleManager->value(old.value().first);
1449 }
1450 if (hasUp && !up) {
1451 up = true;
1452 upBound = m_browser->m_doubleManager->value(old.value().second);
1453 }
1454 }
1455
1457 std::pair<QtProperty *, QtProperty *> cnew; //(nullptr,nullptr); - Can't do this in constructor in C++11
1458 // Don't know if these 2 lines are necessary, but this code is hard to
1459 // understand - it could really use some comments!
1460 cnew.first = NULL;
1461 cnew.second = NULL;
1462 std::ostringstream ostr;
1463 if (lo) {
1464 ostr << loBound << "<";
1465 if (!hasLo) {
1466 cnew.first = m_browser->addDoubleProperty("LowerBound");
1467 parProp->addSubProperty(cnew.first);
1468 } else {
1469 cnew.first = old.value().first;
1470 }
1471 m_browser->m_doubleManager->setValue(cnew.first, loBound);
1472 }
1473 ostr << parProp->propertyName().toStdString();
1474 if (up) {
1475 ostr << "<" << upBound;
1476 if (!hasUp) {
1477 cnew.second = m_browser->addDoubleProperty("UpperBound");
1478 parProp->addSubProperty(cnew.second);
1479 } else {
1480 cnew.second = old.value().second;
1481 }
1482 m_browser->m_doubleManager->setValue(cnew.second, upBound);
1483 }
1484
1485 if (old != m_constraints.end()) {
1486 m_constraints.erase(old);
1487 }
1488
1489 m_constraints.insert(parProp->propertyName(), cnew);
1490
1491 auto c = std::unique_ptr<Mantid::API::IConstraint>(
1492 Mantid::API::ConstraintFactory::Instance().createInitialized(m_fun.get(), ostr.str()));
1493 m_fun->addConstraint(std::move(c));
1495}
1496
1497void PropertyHandler::removeConstraint(QtProperty *parProp) {
1498 QMap<QString, std::pair<QtProperty *, QtProperty *>>::iterator it = m_constraints.find(parProp->propertyName());
1499
1500 if (it != m_constraints.end()) {
1501 if (it.value().first) {
1502 parProp->removeSubProperty(it.value().first);
1503 }
1504 if (it.value().second) {
1505 parProp->removeSubProperty(it.value().second);
1506 }
1507 m_fun->removeConstraint(parProp->propertyName().toStdString());
1508 m_constraints.erase(it);
1509 }
1510}
1511
1517 if (m_pf) {
1518 res << this;
1519 }
1520 if (m_cf) {
1521 for (size_t i = 0; i < m_cf->nFunctions(); ++i) {
1523 if (!h)
1524 continue;
1525 if (h->pfun()) {
1526 res << h;
1527 } else if (h->cfun()) {
1528 res << h->getPeakList();
1529 }
1530 }
1531 }
1532 return res;
1533}
1534
1539
1552 QString newTooltip;
1553
1554 if (m_cf && (m_cf->name() == "CompositeFunction" || m_cf->name() == "ProductFunction")) {
1555 QStringList childrenTooltips;
1556
1557 // Update tooltips for all the children first, and use them to build this
1558 // tooltip
1559 for (size_t i = 0; i < m_cf->nFunctions(); ++i) {
1560 if (auto childHandler = getHandler(i)) {
1561 childrenTooltips << childHandler->updateStructureTooltip();
1562 } else {
1563 throw std::runtime_error("Error while building structure tooltip: no handler for child");
1564 }
1565 }
1566
1567 if (childrenTooltips.empty()) {
1568 newTooltip = QString::fromStdString("Empty " + m_cf->name());
1569 } else {
1570 QChar op('+');
1571
1572 if (m_cf->name() == "ProductFunction") {
1573 op = '*';
1574 }
1575
1576 newTooltip = QString("(%1)").arg(childrenTooltips.join(' ' + op + ' '));
1577 }
1578 } else {
1579 newTooltip = QString::fromStdString(function()->name());
1580 }
1581
1582 m_item->property()->setToolTip(newTooltip);
1583 return newTooltip;
1584}
1585
1590 emit m_browser->removePlotSignal(this);
1591 if (m_cf) {
1592 for (size_t i = 0; i < m_cf->nFunctions(); ++i) {
1594 }
1595 }
1596}
1597
1599 try {
1600 if (m_browser->workspaceName().empty())
1601 return;
1602
1603 Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("Fit");
1604 alg->initialize();
1605 alg->setProperty("Function", m_fun);
1606 alg->setPropertyValue("InputWorkspace", m_browser->workspaceName());
1607 alg->setProperty("WorkspaceIndex", m_browser->workspaceIndex());
1608 alg->setProperty("StartX", m_browser->startX());
1609 alg->setProperty("EndX", m_browser->endX());
1610 alg->execute();
1611 Mantid::API::IFunction_sptr f = alg->getProperty("Function");
1612 if (f != m_fun) { // this should never happen, just in case...
1613 for (size_t i = 0; i < f->nParams(); ++i) {
1614 m_fun->setParameter(i, f->getParameter(i));
1615 }
1616 }
1619 } catch (...) {
1620 }
1621}
1622
1623void PropertyHandler::updateWorkspaces(const QStringList &oldWorkspaces) {
1624 if (m_workspace) {
1625 int index = m_browser->m_enumManager->value(m_workspace) - 1;
1626 QString wsName;
1627 if (index >= 0 && index < oldWorkspaces.size()) {
1628 wsName = oldWorkspaces[index];
1629 }
1630 QStringList names("All");
1631 for (const QString &name : m_browser->m_workspaceNames) {
1632 names.append(name);
1633 }
1634 m_browser->m_enumManager->setEnumNames(m_workspace, names);
1635 if (m_browser->m_workspaceNames.contains(wsName)) {
1637 static_cast<int>(m_browser->m_workspaceNames.indexOf(wsName)) + 1);
1638 }
1639 }
1640 if (cfun()) {
1641 for (size_t i = 0; i < cfun()->nFunctions(); ++i) {
1642 getHandler(i)->updateWorkspaces(oldWorkspaces);
1643 }
1644 }
1645}
1646
1648 if (m_workspace) {
1649 int index = m_browser->m_enumManager->value(m_workspace) - 1;
1650 if (index >= 0 && index < m_browser->m_workspaceNames.size()) {
1651 std::string wsName = m_browser->m_workspaceNames[index].toStdString();
1652 Mantid::API::Workspace_sptr ws = Mantid::API::AnalysisDataService::Instance().retrieve(wsName);
1653 int wsIndex = m_browser->m_intManager->value(m_workspaceIndex);
1654 auto mws = std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(ws);
1655 if (mws) {
1656 ifun()->setMatrixWorkspace(mws, size_t(wsIndex), m_browser->startX(), m_browser->endX());
1657 } else {
1658 ifun()->setWorkspace(ws);
1659 }
1660 m_item->property()->insertSubProperty(m_workspaceIndex, m_workspace);
1661 } else {
1662 ifun()->setWorkspace(Mantid::API::Workspace_sptr());
1663 m_item->property()->removeSubProperty(m_workspaceIndex);
1664 }
1665 } else {
1666 ifun()->setWorkspace(Mantid::API::Workspace_sptr());
1667 }
1668}
1669
1670} // namespace MantidQt::MantidWidgets
std::string name
Definition Run.cpp:60
gsl_vector * tmp
size_t istart
double error
std::map< DeltaEMode::Type, std::string > index
#define fabs(x)
Definition Matrix.cpp:22
Attribute visitor to create a QtProperty.
QtProperty * apply(const int &i) const override
Create int property.
QtProperty * apply(const bool &b) const override
Create bool property.
QtProperty * apply(const std::vector< double > &b) const override
Create vector property.
QtProperty * apply(const std::string &str) const override
Create string property.
CreateAttributeProperty(FitPropertyBrowser *browser, PropertyHandler *handler, QString name, Mantid::Kernel::IValidator_sptr validator=nullptr)
QtProperty * apply(const double &d) const override
Create double property.
Class FitPropertyBrowser implements QtPropertyBrowser to display and control fitting function paramet...
void setDefaultPeakType(const std::string &fnType)
Set the default peak type.
QtProperty * addStringListProperty(const QString &name, const std::vector< std::string > &allowed_values) const
Create a string list property.
std::shared_ptr< Mantid::API::CompositeFunction > compositeFunction() const
Get Composite Function.
void setWorkspace(const Mantid::API::IFunction_sptr &function) const
Sets the workspace to a function.
std::string workspaceName() const
Get the input workspace name.
void sendParameterChanged(const Mantid::API::IFunction *f)
QtGroupPropertyManager * m_groupManager
Property managers:
void setStringPropertyValue(QtProperty *prop, const QString &value) const
Set a value to a string property.
virtual void setFitEnabled(bool enable)
Enable/disable the Fit buttons;.
QStringList m_workspaceNames
A list of available workspaces.
void disableUndo()
disable undo when the function changes
void removePlotSignal(MantidQt::MantidWidgets::PropertyHandler *)
bool m_changeSlotsEnabled
If false the change-slots (such as enumChanged(), doubleChanged()) are disabled.
QtBrowserItem * m_functionsGroup
Group for functions.
PropertyHandler * getHandler() const
Get handler to the root composite function.
QString getStringPropertyValue(QtProperty *prop) const
std::shared_ptr< Mantid::API::Workspace > getWorkspace() const
Get the workspace.
void setDefaultBackgroundType(const std::string &fnType)
Set the default background type.
void reset()
reset the function part, renew function, all handlers are new
QtProperty * addStringProperty(const QString &name) const
Create a string property and set some settings.
QStringList m_registeredFunctions
A list of registered functions.
QtProperty * addDoubleProperty(const QString &name, QtDoublePropertyManager *manager=nullptr) const
Create a double property and set some settings.
void setCurrentFunction(PropertyHandler *h) const
Set new current function.
PropertyHandler * m_autoBackground
The autobackground handler.
Helps display and edit functions in FitPropertyBrowser.
void initAttributes()
Create and attach QtProperties for function attributes.
std::shared_ptr< Mantid::API::IPeakFunction > pfun() const
void renameChildren(const Mantid::API::CompositeFunction &cf)
QList< PropertyHandler * > getPeakList()
Make a list of all peaks in this function.
bool setParameter(QtProperty *prop)
Set function parameter value read from a QtProperty.
PropertyHandler * getHandler(std::size_t i) const
void updateParameter(QtProperty *prop)
Sync function parameter value with the manager.
double EstimateFwhm() const
Estimate the FwHM for a peak.
QtProperty * m_workspaceIndex
workspace index for multispectral fitting
void removeTie(QtProperty *prop, const std::string &globalName)
Remove the tie.
bool setAttribute(QtProperty *prop, bool resetProperties=true)
Set function attribute value read from a QtProperty.
std::shared_ptr< Mantid::API::CompositeFunction > m_cf
void clearError(QtProperty *prop)
Clear function parameter error in the manager.
void addConstraint(QtProperty *parProp, bool lo, bool up, double loBound, double upBound)
Add constraint to parameter property parProp.
PropertyHandler * addFunction(const std::string &fnName)
Add a function to the function handled by this handler.
PropertyHandler(const Mantid::API::IFunction_sptr &fun, std::shared_ptr< Mantid::API::CompositeFunction > parent, FitPropertyBrowser *browser, QtBrowserItem *item=nullptr)
void updateErrors()
Set all parameter error values in the manager.
PropertyHandler * findHandler(const Mantid::API::IFunction *fun)
bool isParameterExplicitlySet(const std::string &param) const
std::shared_ptr< Mantid::API::IPeakFunction > m_pf
QMap< QtProperty *, PropertyHandler * > m_paramToPropertyHandlerMap
QtProperties to PropertyHandler map for faster lookup.
void setCentre(const double &c)
Set the centre of the handled peak function.
void setVectorAttribute(QtProperty *prop)
Set function vector attribute value.
void applyToAllParameters(void(PropertyHandler::*func)(QtProperty *))
Applies given function to all the parameter properties recursively.
void calcBaseAll()
If the handled function is composite calculate the peak baselines for all members.
void setHeight(const double &h)
Set the height of the handled peak function.
void removeAllPlots()
Remove all plots including children's.
std::shared_ptr< Mantid::API::IFunction > ifun() const
QString functionName() const
Creates name for this function to be displayed in the browser.
void updateError(QtProperty *prop)
Set function parameter error in the manager.
std::shared_ptr< const Mantid::API::CompositeFunction > findCompositeFunction(QtBrowserItem *item) const
Returns 'this' if item == m_item and this is a composite function or calls findCompositeFunction recu...
std::shared_ptr< const Mantid::API::IFunction > findFunction(QtBrowserItem *item) const
Returns 'this' if item == m_item or calls findFunction recursively with all its children or zero.
std::shared_ptr< Mantid::API::IFunction > changeType(QtProperty *prop)
Change the type of the function (replace the function)
void initTies()
Populate ties on parameter properties of child functions.
void applyToAllAttributes(void(PropertyHandler::*func)(QtProperty *))
Applies given function to all the attribute properties recursively.
void updateAttribute(QtProperty *prop)
Sync function attribute value with the manager.
std::shared_ptr< Mantid::API::CompositeFunction > cfun() const
void plotRemoved()
Remove the reference to the function curve as it has been deleted.
QString updateStructureTooltip()
Update high-level structure tooltip and return it.
void init() override
overrides virtual init() which is called from IFunction::setHandler(...)
void calcBase()
Calculate m_base: the baseline level under the peak (if this function is a peak and auto background i...
void updateWorkspaces(const QStringList &oldWorkspaces)
void clearErrors()
Clear all parameter error values in the manager.
void updateParameters()
Sync all parameter values with the manager.
QMap< QString, std::pair< QtProperty *, QtProperty * > > m_constraints
QMap< QString, QtProperty * > m_ties
QtProperty * getParameterProperty(const QString &parName) const
void updateAttributes()
Sync all parameter values with the manager.
std::shared_ptr< Mantid::API::CompositeFunction > m_parent
Visitor setting new attribute value.
void apply(const std::string &str) const override
Set string property.
SetAttributeProperty(FitPropertyBrowser *browser, QtProperty *prop)
void apply(const bool &b) const override
Set bool property.
void apply(const double &d) const override
Set double property.
void apply(const std::vector< double > &) const override
Set vector property.
void apply(const int &i) const override
Set int property.
Visitor setting new attribute value.
void apply(double &d) const override
Create double property.
SetAttribute(FitPropertyBrowser *browser, QtProperty *prop, Mantid::Kernel::IValidator_sptr validator=Mantid::Kernel::IValidator_sptr())
void apply(std::string &str) const override
Create string property.
void apply(std::vector< double > &v) const override
Create vector property.
void apply(bool &b) const override
Create bool property.
void apply(int &i) const override
Create int property.
A composite function is a function containing other functions.
ParameterTie * getTie(size_t i) const override
Get the tie of i-th parameter.
ParameterStatus getParameterStatus(size_t i) const override
Get status of parameter.
Implements FunctionDomain1D with its own storage in form of a std::vector.
Classes inherited from FunctionHandler will handle the function.
Definition IFunction.h:759
IFunction_sptr function() const
Return the handled function.
Definition IFunction.h:771
IFunction_sptr m_fun
pointer to the handled function
Definition IFunction.h:774
A class to store values calculated by a function.
An interface to a background function.
An interface to a constraint.
Definition IConstraint.h:26
virtual std::string asString() const =0
Return the string that can be used in this->initialize() to recreate this constraint.
virtual void setHeight(const double h)=0
Sets the parameters such that height == h.
virtual void setCentre(const double c)=0
Sets the parameters such that centre == c.
Mantid::Kernel::IValidator_sptr m_validator
Validator against which to evaluate attribute value to set.
Definition IFunction.h:238
void evaluateValidator(T1 &inputData) const
Evaluates the validator associated with attribute this visitor is to visit.
Definition IFunction.h:231
Attribute is a non-fitting parameter.
Definition IFunction.h:285
int asInt() const
Returns int value if attribute is a int, throws exception otherwise.
Kernel::IValidator_sptr getValidator()
Return a clone of the attribute validator;.
Definition IFunction.h:320
std::string asString() const
Returns string value if attribute is a string, throws exception otherwise.
T apply(AttributeVisitor< T > &v)
Apply an attribute visitor.
Definition IFunction.h:303
void fromString(const std::string &str)
Set value from a string.
double asDouble() const
Returns double value if attribute is a double, throws exception otherwise.
std::string type() const
Returns type of the attribute.
Const version of AttributeVisitor.
Definition IFunction.h:244
Mantid::Kernel::IValidator_sptr m_validator
Validator against which to evaluate attribute value to set.
Definition IFunction.h:279
This is an interface to a fitting function - a semi-abstarct class.
Definition IFunction.h:166
An interface to a peak function, which extend the interface of IFunctionWithLocation by adding method...
virtual void setFwhm(const double w)=0
Sets the parameters such that FWHM = w.
ListValidator is a validator that requires the value of a property to be one of a defined list of pos...
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< const CompositeFunction > CompositeFunction_const_sptr
shared pointer to the composite function base class (const version)
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Definition IFunction.h:748
std::shared_ptr< const IFunction > IFunction_const_sptr
shared pointer to the function base class (const version)
Definition IFunction.h:750
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< CompositeFunction > CompositeFunction_sptr
shared pointer to the composite function base class
std::shared_ptr< IValidator > IValidator_sptr
A shared_ptr to an IValidator.
Definition IValidator.h:26
Helper class which provides the Collimation Length for SANS instruments.
STL namespace.
Simple Exception Struct to differentiate validation error from other exceptions.
Definition IFunction.h:171