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();
248 for (size_t i = 0; i < function()->nParams(); i++) {
249 QString parName = QString::fromStdString(function()->parameterName(i));
250 if (parName.contains('.'))
251 continue;
252 QtProperty *prop = m_browser->addDoubleProperty(parName, m_browser->m_parameterManager);
253
254 m_browser->m_parameterManager->setDescription(prop, function()->parameterDescription(i));
255 m_browser->m_parameterManager->setValue(prop, function()->getParameter(i));
256
257 m_item->property()->addSubProperty(prop);
258 m_parameters << prop;
259 if (m_fun->isFixed(i)) {
260 fix(parName);
262 }
263 // add constraint properties
264 const Mantid::API::IConstraint *c = m_fun->getConstraint(i);
265 if (c) {
266 QStringList qc = QString::fromStdString(c->asString()).split("<");
267 bool lo = false;
268 bool up = false;
269 double loBound = 0, upBound = 0;
270 if (qc.size() == 2) {
271 if (qc[0].contains(parName)) {
272 up = true;
273 upBound = qc[1].toDouble();
274 } else {
275 lo = true;
276 loBound = qc[0].toDouble();
277 }
278 } else if (qc.size() == 3) {
279 lo = up = true;
280 loBound = qc[0].toDouble();
281 upBound = qc[2].toDouble();
282 } else {
283 continue;
284 }
285 QtProperty *loProp = nullptr;
286 QtProperty *upProp = nullptr;
287 if (lo) {
288 loProp = m_browser->addDoubleProperty("LowerBound");
289 m_browser->m_doubleManager->setValue(loProp, loBound);
290 prop->addSubProperty(loProp);
291 }
292 if (up) {
293 upProp = m_browser->addDoubleProperty("UpperBound");
294 m_browser->m_doubleManager->setValue(upProp, upBound);
295 prop->addSubProperty(upProp);
296 }
297 m_constraints.insert(parName, std::pair<QtProperty *, QtProperty *>(loProp, upProp));
298 }
299 }
300}
301
303 if (m_parent && m_parent->name() == "MultiBG") {
304 // m_workspace = m_browser->m_enumManager->addProperty("Workspace");
305 // QtProperty* fnProp = m_item->property();
306 // fnProp->addSubProperty(m_workspace);
307 // m_workspaceIndex = m_browser->m_intManager->addProperty("Workspace
308 // Index");
309 // if (! m_browser->m_workspaceNames.isEmpty() )
310 //{
311 // QStringList names("All");
312 // foreach(QString name,m_browser->m_workspaceNames)
313 // {
314 // names.append(name);
315 // }
316 // m_browser->m_enumManager->setEnumNames(m_workspace, names);
317 // int iWorkspace = 0;
318 // int iWorkspaceIndex = 0;
319 // if (ifun()->getWorkspace())
320 // {
321 // Mantid::API::IFunctionMW* ifmw =
322 // dynamic_cast<Mantid::API::IFunctionMW*>(ifun());
323 // if (ifmw)
324 // {
325 // std::string wsName = ifmw->getMatrixWorkspace()->getName();
326 // iWorkspace = names.indexOf(QString::fromStdString(wsName));
327 // if (iWorkspace >= 0)
328 // {
329 // iWorkspaceIndex = static_cast<int>(ifmw->getWorkspaceIndex());
330 // fnProp->addSubProperty(m_workspaceIndex);
331 // }
332 // else
333 // {
334 // iWorkspace = 0;
335 // }
336 // }
337 // }
338 // m_browser->m_enumManager->setValue(m_workspace,iWorkspace);
339 // m_browser->m_intManager->setValue(m_workspaceIndex,iWorkspaceIndex);
340 //}
341 } else {
342 m_workspace = m_workspaceIndex = nullptr;
343 }
344}
345
352 if (!m_cf)
353 return nullptr;
356 // Create new function
357 if (fnName.find("=") == std::string::npos) { // either from name
358 f = Mantid::API::FunctionFactory::Instance().createFunction(fnName);
359 } else { // of from full initialization expression
360 f = Mantid::API::FunctionFactory::Instance().createInitialized(fnName);
361 }
362
363 // turn of the change slots (doubleChanged() etc) to avoid infinite loop
365
366 // Check if it's a peak and set its width
367 std::shared_ptr<Mantid::API::IPeakFunction> pf = std::dynamic_pointer_cast<Mantid::API::IPeakFunction>(f);
368 if (pf) {
369 if (!m_browser->workspaceName().empty() && m_browser->workspaceIndex() >= 0 && pf->centre() == 0.) {
370 pf->setCentre((m_browser->startX() + m_browser->endX()) / 2);
371 }
372 }
373
375
376 try {
377 ws = std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
378 Mantid::API::AnalysisDataService::Instance().retrieve(m_browser->workspaceName()));
379 } catch (...) {
380 }
381
382 size_t wi = m_browser->workspaceIndex();
383
384 // if it's a LinearBackground estimate its A0 and A1 parameters
385 // from data values at the ends of the fitting interval
386 if (f->name() == "LinearBackground" && !m_browser->workspaceName().empty()) {
387 if (ws && wi < ws->getNumberHistograms()) {
388 const auto &X = ws->x(wi);
389 size_t istart = 0, iend = 0;
390 for (size_t i = 0; i < X.size() - 1; ++i) {
391 double x = X[i];
392 if (x < m_browser->startX())
393 istart = i;
394 if (x > m_browser->endX()) {
395 iend = i;
396 if (iend > 0)
397 iend--;
398 break;
399 }
400 }
401 if (iend > istart) {
402 const auto &Y = ws->y(wi);
403 double p0 = Y[istart];
404 double p1 = Y[iend];
405 double A1 = (p1 - p0) / (X[iend] - X[istart]);
406 double A0 = p0 - A1 * X[istart];
407 f->setParameter("A0", A0);
408 f->setParameter("A1", A1);
409 }
410 }
411 }
412 if (ws) {
414 }
415
416 size_t nFunctions = m_cf->nFunctions() + 1;
417 m_cf->addFunction(f);
418 m_browser->compositeFunction()->checkFunction();
419
420 if (m_cf->nFunctions() != nFunctions) { // this may happen
421 m_browser->reset();
422 return nullptr;
423 }
424
425 f->setHandler(std::make_unique<PropertyHandler>(f, m_cf, m_browser));
426 auto h = static_cast<PropertyHandler *>(f->getHandler());
427 h->setAttribute("StartX", m_browser->startX());
428 h->setAttribute("EndX", m_browser->endX());
429
430 // enable the change slots
433 if (pf) {
434 m_browser->setDefaultPeakType(f->name());
435 } else {
437 }
438 m_browser->setFocus();
439 auto return_ptr = static_cast<PropertyHandler *>(f->getHandler());
440 m_browser->setCurrentFunction(return_ptr);
441
442 return return_ptr;
443}
444
445// Removes handled function from its parent function and
446// properties from the browser
449 if (ph) {
450 if (this == m_browser->m_autoBackground) {
451 m_browser->m_autoBackground = nullptr;
452 }
453 ph->item()->property()->removeSubProperty(m_item->property());
455 for (int i = 0; i < static_cast<int>(cf->nFunctions()); i++) {
456 if (cf->getFunction(i) == function()) {
457 emit m_browser->removePlotSignal(this);
458 cf->removeFunction(i);
459 break;
460 }
461 }
462 ph->renameChildren(*cf);
463 m_browser->setFitEnabled(cf->nFunctions() > 0);
464 }
465}
466
469 for (auto it = m_ties.begin(); it != m_ties.end();) {
470 QString parName = it.key();
471 QString fullName = functionPrefix() + "." + parName;
472 QtProperty *prop = it.value();
473 const auto paramIndex = m_browser->compositeFunction()->parameterIndex(fullName.toStdString());
474 const auto status = cf.getParameterStatus(paramIndex);
475 const auto *tie = cf.getTie(paramIndex);
476 if (!tie) {
479 // In this case the tie has been removed from the composite function since it contained a reference to
480 // the function which was removed
481 QtProperty *parProp = getParameterProperty(parName);
482 if (parProp != nullptr) {
483 parProp->removeSubProperty(prop);
484 // Don't increment the iterator if we delete the current tie.
485 it = m_ties.erase(it);
486 parProp->setEnabled(true);
487 }
488 } else {
489 ++it;
490 }
491 continue;
492 } else {
493 ++it;
494 }
495 // Refresh gui value in case it has been updated by the composite function re-indexing it's functions
496 // after one is removed
497 QStringList qtie = QString::fromStdString(tie->asString()).split("=");
498 if (qtie.size() < 2)
499 continue;
500 m_browser->m_stringManager->setValue(prop, qtie[1]);
501 }
502 if (!m_cf)
503 return;
504 // rename children
505 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
507 if (!h)
508 continue;
509 QtProperty *nameProp = h->item()->property();
510 nameProp->setPropertyName(h->functionName());
511 h->renameChildren(cf);
512 }
514}
515
519 QString name = functionPrefix();
520 if (!name.isEmpty()) {
521 name += "-";
522 }
523 name += QString::fromStdString(function()->name());
524 return name;
525}
526
528 const PropertyHandler *ph = parentHandler();
529 if (ph) {
530 int iFun = -1;
532 for (int i = 0; i < static_cast<int>(cf->nFunctions()); i++) {
533 if (cf->getFunction(i) == function()) {
534 iFun = i;
535 break;
536 }
537 }
538 QString pref = ph->functionPrefix();
539 if (!pref.isEmpty())
540 pref += ".";
541 return pref + "f" + QString::number(iFun);
542 }
543 return "";
544}
545
546// Return the parent handler
548 if (!m_parent)
549 return nullptr;
550 PropertyHandler *ph = static_cast<PropertyHandler *>(m_parent->getHandler());
551 return ph;
552}
553// Return the child's handler
555 if (!m_cf || i >= m_cf->nFunctions())
556 return nullptr;
557 PropertyHandler *ph = static_cast<PropertyHandler *>(m_cf->getFunction(i)->getHandler());
558 return ph;
559}
565 if (!m_cf)
567 if (item == m_item)
568 return m_cf;
569 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
571 if (res != nullptr)
572 return res;
573 }
575}
581 if (item == m_item)
582 return function();
583 if (!m_cf)
585 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
587 if (res != nullptr)
588 return res;
589 }
591}
592
594 if (prop == nullptr)
595 return nullptr;
596 if (prop == m_item->property())
597 return this;
598 if (prop == m_type)
599 return this;
600 if (prop == m_workspace)
601 return this;
602 if (prop == m_workspaceIndex)
603 return this;
604 if (m_attributes.contains(prop))
605 return this;
606 if (m_parameters.contains(prop))
607 return this;
608 if (m_vectorMembers.contains(prop))
609 return this;
610 if (m_vectorSizes.contains(prop))
611 return this;
612 if (!m_ties.key(prop, "").isEmpty())
613 return this;
614 QMap<QString, std::pair<QtProperty *, QtProperty *>>::iterator it = m_constraints.begin();
615 for (; it != m_constraints.end(); ++it) {
616 if (it.value().first == prop || it.value().second == prop) {
617 return this;
618 }
619 }
620 if (!m_cf)
621 return nullptr;
622 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
624 if (h != nullptr)
625 return h;
626 }
627 return nullptr;
628}
629
631 if (fun == function())
632 return this;
633 if (m_cf) {
634 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
636 if (h)
637 return h;
638 }
639 }
640 return nullptr;
641}
642
644 if (fun == function().get())
645 return this;
646 if (m_cf) {
647 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
649 if (h)
650 return h;
651 }
652 }
653 return nullptr;
654}
655
661bool PropertyHandler::setParameter(QtProperty *prop) {
662 if (m_parameters.contains(prop)) {
663 std::string parName = prop->propertyName().toStdString();
664 double parValue = m_browser->m_parameterManager->value(prop);
665 m_fun->setParameter(parName, parValue);
666
667 // If the parameter is fixed, re-fix to update the subproperty.
668 if (m_fun->isFixed(m_fun->parameterIndex(parName))) {
669 const auto subProps = prop->subProperties();
670 if (std::any_of(subProps.cbegin(), subProps.cend(),
671 [](const auto &subProp) { return subProp->propertyName() == "Fix"; })) {
672 fix(prop->propertyName());
673 }
674 }
675
678 return true;
679 }
680 if (m_cf) {
681 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
682 bool res = getHandler(i)->setParameter(prop);
683 if (res) {
684 m_cf->applyTies();
686 return true;
687 }
688 }
689 }
690 return false;
691}
692
698public:
699 SetAttribute(FitPropertyBrowser *browser, QtProperty *prop,
701 : m_browser(browser), m_prop(prop) {
702 m_validator = validator;
703 }
704
705protected:
707 void apply(std::string &str) const override {
708 std::string propValue = m_browser->getStringPropertyValue(m_prop).toStdString();
709
710 evaluateValidator(propValue);
711 str = propValue;
712 }
714 void apply(double &d) const override {
715 double propValue = m_browser->m_doubleManager->value(m_prop);
716
717 evaluateValidator(propValue);
718 d = propValue;
719 }
721 void apply(int &i) const override {
722 int propValue = m_browser->m_intManager->value(m_prop);
723
724 evaluateValidator(propValue);
725 i = propValue;
726 }
728 void apply(bool &b) const override {
729 bool propValue = m_browser->m_boolManager->value(m_prop);
730
731 evaluateValidator(propValue);
732 b = propValue;
733 }
735 void apply(std::vector<double> &v) const override {
736 QList<QtProperty *> members = m_prop->subProperties();
737 if (members.size() < 1) {
738 v.clear();
739 return;
740 }
741
742 int newSize = m_browser->m_vectorSizeManager->value(members[0]);
743 int vectorSize = static_cast<int>(members.size()) - 1;
744 if (vectorSize > newSize) {
745 vectorSize = newSize;
746 }
747
748 // populate new vector
749 std::vector<double> newVec(newSize);
750 for (int i = 1; i < newSize + 1; ++i) {
751 double newVal = (m_validator != Mantid::Kernel::IValidator_sptr())
752 ? m_browser->m_vectorDoubleManager->value(members[vectorSize])
753 : 0.0;
754 if (i < vectorSize + 1) {
755 newVec[i - 1] = m_browser->m_vectorDoubleManager->value(members[i]);
756 } else {
757 newVec[i - 1] = newVal;
758 }
759 }
760
762 evaluateValidator(newVec);
763 }
764
765 v.resize(newSize);
766 std::copy(cbegin(newVec), cend(newVec), begin(v));
767 }
768
769private:
771 QtProperty *m_prop;
772};
773
779public:
780 SetAttributeProperty(FitPropertyBrowser *browser, QtProperty *prop) : m_browser(browser), m_prop(prop) {}
781
782protected:
784 void apply(const std::string &str) const override {
786 m_browser->setStringPropertyValue(m_prop, QString::fromStdString(str));
788 }
790 void apply(const double &d) const override {
792 m_browser->m_doubleManager->setValue(m_prop, d);
794 }
796 void apply(const int &i) const override {
798 m_browser->m_intManager->setValue(m_prop, i);
800 }
802 void apply(const bool &b) const override {
804 m_browser->m_boolManager->setValue(m_prop, b);
806 }
808 void apply(const std::vector<double> & /*unused*/) const override {
809 // this method is supposed to be called when corresponding
810 // property value changes but it doesn't have a value because
811 // it's a group property
812 throw std::runtime_error("Vector attribute not implemented.");
813 }
814
815private:
817 QtProperty *m_prop;
818};
819
827bool PropertyHandler::setAttribute(QtProperty *prop, bool resetProperties) {
828 if (m_attributes.contains(prop)) {
829 QString attName = prop->propertyName();
830 try {
831 Mantid::API::IFunction::Attribute att = m_fun->getAttribute(attName.toStdString());
833 att.apply(tmp);
834 m_fun->setAttribute(attName.toStdString(), att);
835 m_browser->compositeFunction()->checkFunction();
836 if (resetProperties) {
839 }
840 if (this == m_browser->m_autoBackground) {
841 fit();
842 }
843 } catch (Mantid::API::IFunction::ValidationException &ve) { // catch attribute validation error
846
848 ve.what()); // rethrow validation exception so it can be recaught by Fit Property Browser.
849 } catch (std::exception &e) {
852 QMessageBox::critical(m_browser, "Mantid - Error", e.what());
853 return false;
854 }
855 return true;
856 }
857 if (m_cf) {
858 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
859 bool res = getHandler(i)->setAttribute(prop, resetProperties);
860 if (res)
861 return true;
862 }
863 }
864 return false;
865}
866
872void PropertyHandler::setAttribute(QString const &attName, Mantid::API::IFunction::Attribute const &attValue) {
873 auto const attributeType = attValue.type();
874 if (attributeType == "int")
875 setAttribute(attName, attValue.asInt());
876 else if (attributeType == "double")
877 setAttribute(attName, attValue.asDouble());
878 else if (attributeType == "std::string")
879 setAttribute(attName, QString::fromStdString(attValue.asString()));
880}
881
887template <typename AttributeType>
888void PropertyHandler::setAttribute(QString const &attName, AttributeType const &attValue) {
889 if (m_fun->hasAttribute(attName.toStdString())) {
890 try {
891 m_fun->setAttribute(attName.toStdString(), Mantid::API::IFunction::Attribute(attValue));
892 m_browser->compositeFunction()->checkFunction();
893 foreach (const QtProperty *prop, m_attributes) {
894 if (prop->propertyName() == attName) {
895 // re-insert the attribute and parameter properties as they may
896 // depend on the value of the attribute being set
899 }
900 }
901 } catch (...) {
902 }
903 }
904 if (cfun()) {
905 for (auto i = 0u; i < cfun()->nFunctions(); ++i) {
907 h->setAttribute(attName, attValue);
908 }
909 }
910}
911
917void PropertyHandler::setAttribute(const QString &attName, const QString &attValue) {
918 const std::string name = attName.toStdString();
919 if (m_fun->hasAttribute(name)) {
920 Mantid::API::IFunction::Attribute att = m_fun->getAttribute(name);
921 att.fromString(attValue.toStdString());
922 m_fun->setAttribute(name, att);
923 m_browser->compositeFunction()->checkFunction();
924 foreach (QtProperty *prop, m_attributes) {
925 if (prop->propertyName() == attName) {
927 att.apply(tmp);
928 }
929 }
930 // re-insert the attribute and parameter properties as they may
931 // depend on the value of the attribute being set
934 }
935}
936
942 foreach (QtProperty *att, m_attributes) {
943 QList<QtProperty *> subProps = att->subProperties();
944 if (subProps.contains(prop)) {
945 bool resetProperties = m_vectorSizes.contains(prop);
946 setAttribute(att, resetProperties);
947 return;
948 }
949 }
950}
951
958 for (auto attribute : m_attributes) {
959 (this->*(func))(attribute);
960 }
961
962 if (m_cf)
963 for (std::size_t i = 0u; i < m_cf->nFunctions(); ++i)
965}
966
972
976void PropertyHandler::updateAttribute(QtProperty *attribute) {
977 if (m_attributes.contains(attribute)) {
978 auto const attributeValue = function()->getAttribute(attribute->propertyName().toStdString());
979 setAttribute(attribute->propertyName(), attributeValue);
980 }
981}
982
989 for (auto prop : m_parameters) {
990 (this->*(func))(prop);
991 }
992
993 if (m_cf) {
994 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
996 }
997 }
998}
999
1001
1003
1005
1009void PropertyHandler::updateParameter(QtProperty *prop) {
1010 double const parValue = function()->getParameter(prop->propertyName().toStdString());
1011 m_browser->m_parameterManager->setValue(prop, parValue);
1012}
1013
1017void PropertyHandler::updateError(QtProperty *prop) {
1018 size_t index = function()->parameterIndex(prop->propertyName().toStdString());
1019 double error = function()->getError(index);
1020 m_browser->m_parameterManager->setError(prop, error);
1021}
1022
1026void PropertyHandler::clearError(QtProperty *prop) { m_browser->m_parameterManager->clearError(prop); }
1027
1033 if (prop == m_type) {
1034 // Create new function
1035 int i = m_browser->m_enumManager->value(prop);
1036 QStringList functionNames = m_browser->m_enumManager->enumNames(prop);
1037 const QString &fnName = functionNames[i];
1039 try {
1040 f = Mantid::API::FunctionFactory::Instance().createFunction(fnName.toStdString());
1041
1042 } catch (std::exception &e) {
1043 QMessageBox::critical(nullptr, "Mantid - Error", "Cannot create function " + fnName + "\n" + e.what());
1045 }
1046
1047 // turn of the change slots (doubleChanged() etc) to avoid infinite loop
1049
1050 // Check if it's a peak and set its width
1051 Mantid::API::IPeakFunction *pf = dynamic_cast<Mantid::API::IPeakFunction *>(f.get());
1052 if (pf) {
1053 if (!m_pf) {
1054 if (!m_browser->workspaceName().empty() && m_browser->workspaceIndex() >= 0) {
1055 pf->setCentre((m_browser->startX() + m_browser->endX()) / 2);
1056 }
1057
1058 } else {
1059 pf->setCentre(m_pf->centre());
1060 pf->setHeight(m_pf->height());
1061 pf->setFwhm(m_pf->fwhm());
1062 }
1063 }
1064
1065 if (pf) {
1066 m_browser->setDefaultPeakType(fnName.toStdString());
1067
1068 } else {
1069 m_browser->setDefaultBackgroundType(fnName.toStdString());
1070 }
1071
1072 QList<QtProperty *> subs = m_item->property()->subProperties();
1073 foreach (QtProperty *sub, subs) {
1074 m_item->property()->removeSubProperty(sub);
1075 }
1076
1078
1079 emit m_browser->removePlotSignal(this);
1080
1082 std::unique_ptr<PropertyHandler> h = std::make_unique<PropertyHandler>(f, m_parent, m_browser, m_item);
1083 if (this == m_browser->m_autoBackground) {
1084 if (dynamic_cast<Mantid::API::IBackgroundFunction *>(f.get())) {
1085 m_browser->m_autoBackground = h.get();
1086 h->fit();
1087
1088 } else {
1089 m_browser->m_autoBackground = nullptr;
1090 }
1091 }
1092 if (m_parent) {
1093 m_parent->replaceFunctionPtr(f_old, f);
1094 }
1095 // calculate the baseline
1096 if (h->pfun()) {
1097 h->setCentre(h->centre()); // this sets m_ci
1098 h->calcBase();
1099 }
1100 f->setHandler(std::move(h));
1101 // at this point this handler does not exist any more. only return is
1102 // possible
1103 return f;
1104
1105 } else if (m_cf) {
1106 for (size_t i = 0; i < m_cf->nFunctions(); i++) {
1108 if (f)
1109 return f;
1110 }
1111 }
1113}
1114
1115bool PropertyHandler::isParameter(QtProperty *prop) { return m_parameters.contains(prop); }
1116
1117QtProperty *PropertyHandler::getParameterProperty(const QString &parName) const {
1118 const auto it = std::find_if(m_parameters.cbegin(), m_parameters.cend(),
1119 [&parName](const auto &parProp) { return parProp->propertyName() == parName; });
1120 if (it != m_parameters.cend()) {
1121 return *it;
1122 }
1123 return nullptr;
1124}
1125
1126QtProperty *PropertyHandler::getParameterProperty(QtProperty *prop) const {
1127 const auto it = std::find_if(m_parameters.cbegin(), m_parameters.cend(),
1128 [&prop](const auto &parProp) { return parProp->subProperties().contains(prop); });
1129 if (it != m_parameters.cend()) {
1130 return *it;
1131 }
1132 return nullptr;
1133}
1134
1135void PropertyHandler::addTie(const QString &tieStr) {
1136 QStringList parts = tieStr.split("=");
1137 if (parts.size() != 2)
1138 return;
1139 std::string name = parts[0].trimmed().toStdString();
1140 std::string expr = parts[1].trimmed().toStdString();
1141 try {
1142 auto &cfunction = *m_browser->compositeFunction();
1143 cfunction.tie(name, expr);
1144 cfunction.applyTies();
1145 const auto paramIndex = cfunction.parameterIndex(name);
1146 const auto paramStatus = cfunction.getParameterStatus(paramIndex);
1147 const bool fixed = paramStatus == Mantid::API::IFunction::ParameterStatus::Fixed;
1148 const bool recursive = true;
1149 QString parName = QString::fromStdString(cfunction.parameterLocalName(paramIndex, recursive));
1150 QtProperty *parProp = getParameterProperty(parName);
1151 if (!parProp)
1152 return;
1154 QtProperty *tieProp = m_ties[parName];
1155 if (!tieProp) {
1156 const auto tiePropName = fixed ? "Fix" : "Tie";
1157 tieProp = m_browser->m_stringManager->addProperty(tiePropName);
1158 m_ties[parName] = tieProp;
1159 }
1160 m_browser->m_stringManager->setValue(tieProp, QString::fromStdString(expr));
1161 parProp->addSubProperty(tieProp);
1162 if (fixed) {
1163 tieProp->setEnabled(false);
1164 }
1166 if (!fixed) {
1168 }
1169 } catch (const std::exception &exc) {
1170 std::cerr << exc.what();
1171 QMessageBox::critical(m_browser, "Mantid - Error", "Failed to set tie: " + tieStr);
1172 }
1173}
1174
1175void PropertyHandler::fix(const QString &parName) {
1176 const QtProperty *parProp = getParameterProperty(parName);
1177 if (!parProp)
1178 return;
1179 QString parValue = QString::number(m_browser->m_parameterManager->value(parProp));
1180 addTie(functionPrefix() + "." + parName + "=" + parValue);
1181}
1182
1189void PropertyHandler::removeTie(QtProperty *prop, const std::string &globalName) {
1190 QString parName = m_ties.key(prop, "");
1191 if (parName.isEmpty())
1192 return;
1193
1194 QtProperty *parProp = getParameterProperty(parName);
1195 if (parProp) {
1197 auto &compositeFunction = *m_browser->compositeFunction();
1198 auto index = compositeFunction.parameterIndex(globalName);
1199 compositeFunction.removeTie(index);
1200 parProp->removeSubProperty(prop);
1201 m_ties.remove(QString::fromStdString(globalName));
1202 m_ties.remove(parName);
1204 parProp->setEnabled(true);
1205 }
1206}
1211void PropertyHandler::removeTie(QtProperty *prop) {
1212 QString parName = m_ties.key(prop, "");
1213 if (parName.isEmpty())
1214 return;
1215
1216 QtProperty *parProp = getParameterProperty(parName);
1217 if (parProp != nullptr) {
1219 m_fun->removeTie(parName.toStdString());
1220 parProp->removeSubProperty(prop);
1221 m_ties.remove(parName);
1223 parProp->setEnabled(true);
1224 }
1225}
1226
1231void PropertyHandler::removeTie(const QString &parName) {
1232 QtProperty *prop = m_ties[parName];
1233 if (prop)
1234 removeTie(prop);
1235}
1236
1242 double fwhmEstimate = 0.;
1243 auto ws = std::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(m_browser->getWorkspace());
1244 if (ws) {
1245 size_t wi = m_browser->workspaceIndex();
1246 const auto &X = ws->x(wi);
1247 const auto &Y = ws->y(wi);
1248 size_t n = Y.size() - 1;
1249 if (m_ci < 0 || m_ci > static_cast<int>(n)) {
1250 fwhmEstimate = 0.;
1251 } else {
1252 double halfHeight = ((Y[m_ci] - m_base) / 2.) + m_base;
1253 // walk to the right
1254 size_t rightHwhmIndex = m_ci;
1255 while (rightHwhmIndex < n) {
1256 if (Y[rightHwhmIndex++] <= halfHeight) {
1257 break;
1258 }
1259 }
1260
1261 // walk to the left
1262 size_t leftHwhmIndex = m_ci;
1263 while (leftHwhmIndex > 0) {
1264 if (Y[leftHwhmIndex--] <= halfHeight) {
1265 break;
1266 }
1267 }
1268
1269 fwhmEstimate = fabs(X[rightHwhmIndex] - X[leftHwhmIndex]);
1270
1271 // apply a maximum limitation if larger than the fitting region
1272 double fitRange = m_browser->endX() - m_browser->startX();
1273 if (fwhmEstimate > fitRange) {
1274 // set to 10% of fitting region
1275 fwhmEstimate = fitRange * 0.1;
1276 }
1277 }
1278 }
1279 return fwhmEstimate;
1280}
1287 return;
1288
1289 auto ws = std::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(m_browser->getWorkspace());
1290 if (ws) {
1291 size_t wi = m_browser->workspaceIndex();
1292 const auto &X = ws->x(wi);
1293 const auto &Y = ws->y(wi);
1294 int n = static_cast<int>(Y.size()) - 1;
1295 if (m_ci < 0 || m_ci > n || !m_browser->m_autoBackground) {
1296 m_base = 0.;
1297 } else {
1300 m_browser->m_autoBackground->function()->function(x, y);
1301 m_base = y[0];
1302 }
1303 } else {
1304 m_base = 0.;
1305 }
1306}
1307
1315 return;
1316 if (!m_cf)
1317 return;
1318 for (size_t i = 0; i < m_cf->nFunctions(); ++i) {
1320 if (h->pfun()) {
1321 h->calcBase();
1322 } else if (h->cfun()) {
1323 h->calcBaseAll();
1324 }
1325 }
1326}
1327
1331void PropertyHandler::setHeight(const double &h) {
1332 if (m_pf) {
1333 m_pf->setHeight(h - m_base);
1334 }
1335}
1336
1341void PropertyHandler::setCentre(const double &c) {
1342 if (m_pf) {
1343 m_pf->setCentre(c);
1344
1345 // find m_ci: x-index of the peakcentre
1346 auto ws = std::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(m_browser->getWorkspace());
1347 if (ws) {
1348 size_t wi = m_browser->workspaceIndex();
1349 const auto &X = ws->x(wi);
1350 int n = static_cast<int>(X.size()) - 2;
1351 if (m_ci < 0)
1352 m_ci = 0;
1353 if (m_ci > n)
1354 m_ci = n;
1355 double x = X[m_ci];
1356 if (x < c) {
1357 for (; m_ci <= n; ++m_ci) {
1358 x = X[m_ci];
1359 if (x > c)
1360 break;
1361 }
1362 } else {
1363 for (; m_ci >= 0; --m_ci) {
1364 x = X[m_ci];
1365 if (x < c)
1366 break;
1367 }
1368 }
1369 }
1370 }
1371}
1372
1373void PropertyHandler::setFwhm(const double &w) {
1374 if (m_pf) {
1375 m_pf->setFwhm(w);
1376 }
1377}
1378
1380 if (m_pf) {
1381 return m_pf->height();
1382 }
1383 return 0;
1384}
1385
1387 if (m_pf) {
1388 return m_pf->centre();
1389 }
1390 return (m_browser->endX() + m_browser->startX()) / 2;
1391}
1392
1394 if (m_pf) {
1395 return m_pf->fwhm();
1396 }
1397 return 0;
1398}
1399
1401 if (m_pf) {
1402 return m_pf->getWidthParameterName();
1403 }
1404 return "";
1405}
1406
1408 if (m_pf) {
1409 return m_pf->getCentreParameterName();
1410 }
1411 return "";
1412}
1413
1414bool PropertyHandler::isParameterExplicitlySet(const std::string &param) const {
1415 if (m_pf) {
1416 return m_pf->isExplicitlySet(m_pf->parameterIndex(param));
1417 }
1418 return false;
1419}
1420
1424void PropertyHandler::addConstraint(QtProperty *parProp, bool lo, bool up, double loBound, double upBound) {
1425 QMap<QString, std::pair<QtProperty *, QtProperty *>>::iterator old = m_constraints.find(parProp->propertyName());
1426
1427 bool hasLo = false;
1428 bool hasUp = false;
1429
1430 if (old != m_constraints.end()) {
1431 hasLo = old.value().first != NULL;
1432 hasUp = old.value().second != NULL;
1433 if (hasLo && !lo) {
1434 lo = true;
1435 loBound = m_browser->m_doubleManager->value(old.value().first);
1436 }
1437 if (hasUp && !up) {
1438 up = true;
1439 upBound = m_browser->m_doubleManager->value(old.value().second);
1440 }
1441 }
1442
1444 std::pair<QtProperty *, QtProperty *> cnew; //(nullptr,nullptr); - Can't do this in constructor in C++11
1445 // Don't know if these 2 lines are necessary, but this code is hard to
1446 // understand - it could really use some comments!
1447 cnew.first = NULL;
1448 cnew.second = NULL;
1449 std::ostringstream ostr;
1450 if (lo) {
1451 ostr << loBound << "<";
1452 if (!hasLo) {
1453 cnew.first = m_browser->addDoubleProperty("LowerBound");
1454 parProp->addSubProperty(cnew.first);
1455 } else {
1456 cnew.first = old.value().first;
1457 }
1458 m_browser->m_doubleManager->setValue(cnew.first, loBound);
1459 }
1460 ostr << parProp->propertyName().toStdString();
1461 if (up) {
1462 ostr << "<" << upBound;
1463 if (!hasUp) {
1464 cnew.second = m_browser->addDoubleProperty("UpperBound");
1465 parProp->addSubProperty(cnew.second);
1466 } else {
1467 cnew.second = old.value().second;
1468 }
1469 m_browser->m_doubleManager->setValue(cnew.second, upBound);
1470 }
1471
1472 if (old != m_constraints.end()) {
1473 m_constraints.erase(old);
1474 }
1475
1476 m_constraints.insert(parProp->propertyName(), cnew);
1477
1478 auto c = std::unique_ptr<Mantid::API::IConstraint>(
1479 Mantid::API::ConstraintFactory::Instance().createInitialized(m_fun.get(), ostr.str()));
1480 m_fun->addConstraint(std::move(c));
1482}
1483
1484void PropertyHandler::removeConstraint(QtProperty *parProp) {
1485 QMap<QString, std::pair<QtProperty *, QtProperty *>>::iterator it = m_constraints.find(parProp->propertyName());
1486
1487 if (it != m_constraints.end()) {
1488 if (it.value().first) {
1489 parProp->removeSubProperty(it.value().first);
1490 }
1491 if (it.value().second) {
1492 parProp->removeSubProperty(it.value().second);
1493 }
1494 m_fun->removeConstraint(parProp->propertyName().toStdString());
1495 m_constraints.erase(it);
1496 }
1497}
1498
1504 if (m_pf) {
1505 res << this;
1506 }
1507 if (m_cf) {
1508 for (size_t i = 0; i < m_cf->nFunctions(); ++i) {
1510 if (!h)
1511 continue;
1512 if (h->pfun()) {
1513 res << h;
1514 } else if (h->cfun()) {
1515 res << h->getPeakList();
1516 }
1517 }
1518 }
1519 return res;
1520}
1521
1526
1539 QString newTooltip;
1540
1541 if (m_cf && (m_cf->name() == "CompositeFunction" || m_cf->name() == "ProductFunction")) {
1542 QStringList childrenTooltips;
1543
1544 // Update tooltips for all the children first, and use them to build this
1545 // tooltip
1546 for (size_t i = 0; i < m_cf->nFunctions(); ++i) {
1547 if (auto childHandler = getHandler(i)) {
1548 childrenTooltips << childHandler->updateStructureTooltip();
1549 } else {
1550 throw std::runtime_error("Error while building structure tooltip: no handler for child");
1551 }
1552 }
1553
1554 if (childrenTooltips.empty()) {
1555 newTooltip = QString::fromStdString("Empty " + m_cf->name());
1556 } else {
1557 QChar op('+');
1558
1559 if (m_cf->name() == "ProductFunction") {
1560 op = '*';
1561 }
1562
1563 newTooltip = QString("(%1)").arg(childrenTooltips.join(' ' + op + ' '));
1564 }
1565 } else {
1566 newTooltip = QString::fromStdString(function()->name());
1567 }
1568
1569 m_item->property()->setToolTip(newTooltip);
1570 return newTooltip;
1571}
1572
1577 emit m_browser->removePlotSignal(this);
1578 if (m_cf) {
1579 for (size_t i = 0; i < m_cf->nFunctions(); ++i) {
1581 }
1582 }
1583}
1584
1586 try {
1587 if (m_browser->workspaceName().empty())
1588 return;
1589
1590 Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("Fit");
1591 alg->initialize();
1592 alg->setProperty("Function", m_fun);
1593 alg->setPropertyValue("InputWorkspace", m_browser->workspaceName());
1594 alg->setProperty("WorkspaceIndex", m_browser->workspaceIndex());
1595 alg->setProperty("StartX", m_browser->startX());
1596 alg->setProperty("EndX", m_browser->endX());
1597 alg->execute();
1598 Mantid::API::IFunction_sptr f = alg->getProperty("Function");
1599 if (f != m_fun) { // this should never happen, just in case...
1600 for (size_t i = 0; i < f->nParams(); ++i) {
1601 m_fun->setParameter(i, f->getParameter(i));
1602 }
1603 }
1606 } catch (...) {
1607 }
1608}
1609
1610void PropertyHandler::updateWorkspaces(const QStringList &oldWorkspaces) {
1611 if (m_workspace) {
1612 int index = m_browser->m_enumManager->value(m_workspace) - 1;
1613 QString wsName;
1614 if (index >= 0 && index < oldWorkspaces.size()) {
1615 wsName = oldWorkspaces[index];
1616 }
1617 QStringList names("All");
1618 foreach (const QString &name, m_browser->m_workspaceNames) {
1619 names.append(name);
1620 }
1621 m_browser->m_enumManager->setEnumNames(m_workspace, names);
1622 if (m_browser->m_workspaceNames.contains(wsName)) {
1624 static_cast<int>(m_browser->m_workspaceNames.indexOf(wsName)) + 1);
1625 }
1626 }
1627 if (cfun()) {
1628 for (size_t i = 0; i < cfun()->nFunctions(); ++i) {
1629 getHandler(i)->updateWorkspaces(oldWorkspaces);
1630 }
1631 }
1632}
1633
1635 if (m_workspace) {
1636 int index = m_browser->m_enumManager->value(m_workspace) - 1;
1637 if (index >= 0 && index < m_browser->m_workspaceNames.size()) {
1638 std::string wsName = m_browser->m_workspaceNames[index].toStdString();
1639 Mantid::API::Workspace_sptr ws = Mantid::API::AnalysisDataService::Instance().retrieve(wsName);
1640 int wsIndex = m_browser->m_intManager->value(m_workspaceIndex);
1641 auto mws = std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(ws);
1642 if (mws) {
1643 ifun()->setMatrixWorkspace(mws, size_t(wsIndex), m_browser->startX(), m_browser->endX());
1644 } else {
1645 ifun()->setWorkspace(ws);
1646 }
1647 m_item->property()->insertSubProperty(m_workspaceIndex, m_workspace);
1648 } else {
1649 ifun()->setWorkspace(Mantid::API::Workspace_sptr());
1650 m_item->property()->removeSubProperty(m_workspaceIndex);
1651 }
1652 } else {
1653 ifun()->setWorkspace(Mantid::API::Workspace_sptr());
1654 }
1655}
1656
1657} // namespace MantidQt::MantidWidgets
std::string name
Definition Run.cpp:60
gsl_vector * tmp
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
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:754
IFunction_sptr function() const
Return the handled function.
Definition IFunction.h:766
IFunction_sptr m_fun
pointer to the handled function
Definition IFunction.h:769
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:743
std::shared_ptr< const IFunction > IFunction_const_sptr
shared pointer to the function base class (const version)
Definition IFunction.h:745
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