diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.cpp b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.cpp index eaae205426ad332e7574eec9cbf0148e257ded58..3bcd787ac39cf63a6ea1c07e84c031d879e8ac5a 100644 --- a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.cpp +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.cpp @@ -87,37 +87,50 @@ void ConvFunctionModel::checkConvolution(IFunction_sptr fun) { throw std::runtime_error("Function has wrong structure."); } m_hasTempCorrection = true; - checkConvolution(innerFunction->getFunction(1)); + if (boost::dynamic_pointer_cast<CompositeFunction>( + innerFunction->getFunction(1))) + checkConvolution(innerFunction->getFunction(1)); + else + checkSingleFunction(innerFunction->getFunction(1), isFitTypeSet); } else if (name == "CompositeFunction") { checkConvolution(innerFunction); - } else if (name == "Lorentzian") { - if (isFitTypeSet && m_fitType != FitType::OneLorentzian) { - throw std::runtime_error("Function has wrong structure."); - } - if (isFitTypeSet) - m_fitType = FitType::TwoLorentzians; - else - m_fitType = FitType::OneLorentzian; - m_isQDependentFunction = false; - isFitTypeSet = true; - - } else if (FitTypeStringToEnum.count(name) == 1) { - if (isFitTypeSet) { - throw std::runtime_error( - "Function has wrong structure. More than one fit type set"); - } - m_fitType = FitTypeStringToEnum[name]; - m_isQDependentFunction = FitTypeQDepends[m_fitType]; - isFitTypeSet = true; - } else if (name == "DeltaFunction") { - m_hasDeltaFunction = true; } else { - clear(); + checkSingleFunction(innerFunction, isFitTypeSet); + } + } +} + +void ConvFunctionModel::checkSingleFunction(IFunction_sptr fun, + bool &isFitTypeSet) { + assert(fun->nFunctions() == 0); + auto const name = fun->name(); + if (name == "Lorentzian") { + if (isFitTypeSet && m_fitType != FitType::OneLorentzian) { + throw std::runtime_error("Function has wrong structure."); + } + if (isFitTypeSet) + m_fitType = FitType::TwoLorentzians; + else + m_fitType = FitType::OneLorentzian; + m_isQDependentFunction = false; + isFitTypeSet = true; + + } else if (FitTypeStringToEnum.count(name) == 1) { + if (isFitTypeSet) { throw std::runtime_error( - "Function has wrong structure. Function not recognized"); + "Function has wrong structure. More than one fit type set"); } + m_fitType = FitTypeStringToEnum[name]; + m_isQDependentFunction = FitTypeQDepends[m_fitType]; + isFitTypeSet = true; + } else if (name == "DeltaFunction") { + m_hasDeltaFunction = true; + } else { + clear(); + throw std::runtime_error( + "Function has wrong structure. Function not recognized"); } } diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.h b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.h index 89cf31beb780832b47e8276078cafb541a0816f2..f59e00c287896cfc6a57769e0f20c2e8032801d2 100644 --- a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.h +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.h @@ -132,6 +132,7 @@ private: QStringList makeGlobalList() const; int getNumberOfPeaks() const; void checkConvolution(IFunction_sptr fun); + void checkSingleFunction(IFunction_sptr fun, bool &isFitTypeSet); ConvolutionFunctionModel m_model; FitType m_fitType = FitType::None; diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.cpp b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.cpp index 666ee171e5cf30dbbd1f519d1e18e9c556e8e345..626a5bc065bed8fc935d636d6fbfa0ec2c66fae4 100644 --- a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.cpp +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.cpp @@ -113,6 +113,8 @@ void ConvTemplateBrowser::setGlobalParameters(const QStringList &globals) { void ConvTemplateBrowser::intChanged(QtProperty *) {} void ConvTemplateBrowser::boolChanged(QtProperty *prop) { + if (!m_emitBoolChange) + return; if (prop == m_deltaFunctionOn) { m_presenter.setDeltaFunction(m_boolManager->value(prop)); } else if (prop == m_tempCorrectionOn) { @@ -125,8 +127,9 @@ void ConvTemplateBrowser::setQValues(const std::vector<double> &qValues) { } void ConvTemplateBrowser::addDeltaFunction() { + ScopedFalse _boolBlock(m_emitBoolChange); + ScopedFalse _paramBlock(m_emitParameterValueChange); m_deltaFunctionOn->addSubProperty(m_deltaFunctionHeight); - ScopedFalse _false(m_emitBoolChange); m_boolManager->setValue(m_deltaFunctionOn, true); } @@ -137,8 +140,10 @@ void ConvTemplateBrowser::removeDeltaFunction() { } void ConvTemplateBrowser::addTempCorrection(double value) { + ScopedFalse _boolBlock(m_emitBoolChange); + ScopedFalse _paramBlock(m_emitParameterValueChange); + m_tempCorrectionOn->addSubProperty(m_temperature); - ScopedFalse _false(m_emitBoolChange); m_boolManager->setValue(m_tempCorrectionOn, true); m_parameterManager->setValue(m_temperature, value); m_parameterManager->setGlobal(m_temperature, true); @@ -151,6 +156,8 @@ void ConvTemplateBrowser::removeTempCorrection() { } void ConvTemplateBrowser::enumChanged(QtProperty *prop) { + if (!m_emitEnumChange) + return; auto const index = m_enumManager->value(prop); auto propIt = std::find(m_subTypeProperties.begin(), m_subTypeProperties.end(), prop); @@ -273,6 +280,11 @@ void ConvTemplateBrowser::createFunctionParameterProperties() { } } +void ConvTemplateBrowser::setEnum(size_t subTypeIndex, int enumIndex) { + ScopedFalse _false(m_emitEnumChange); + m_enumManager->setValue(m_subTypeProperties[subTypeIndex], enumIndex); +} + void ConvTemplateBrowser::createDeltaFunctionProperties() { m_deltaFunctionOn = m_boolManager->addProperty("Delta Function"); m_deltaFunctionHeight = diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.h b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.h index 1923e0f2ff73fee0c9081209972c80d01224c758..c4b0905161dee53be1b6a37fda3f7437e5d71e06 100644 --- a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.h +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.h @@ -61,6 +61,7 @@ public: void addTempCorrection(double value); void removeTempCorrection(); void setQValues(const std::vector<double> &qValues) override; + void setEnum(size_t subTypeIndex, int fitType); protected slots: void intChanged(QtProperty *) override; @@ -103,6 +104,7 @@ private: ConvTemplatePresenter m_presenter; bool m_emitParameterValueChange = true; bool m_emitBoolChange = true; + bool m_emitEnumChange = true; friend class ConvTemplatePresenter; }; diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplatePresenter.cpp b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplatePresenter.cpp index 390e4cc902960509a70f1064ffbf0576cb2f90b5..7ba129e6c2909106cd48164cf2a6a63d677406cf 100644 --- a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplatePresenter.cpp +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplatePresenter.cpp @@ -8,9 +8,8 @@ #include "ConvTemplateBrowser.h" #include "MantidQtWidgets/Common/EditLocalParameterDialog.h" #include <QInputDialog> -#include <float.h> - #include <cmath> +#include <float.h> namespace MantidQt { namespace CustomInterfaces { @@ -31,7 +30,7 @@ ConvTemplatePresenter::ConvTemplatePresenter(ConvTemplateBrowser *view) } void ConvTemplatePresenter::setSubType(size_t subTypeIndex, int typeIndex) { - if (subTypeIndex == 0) { + if (subTypeIndex == SubTypeIndex::Fit) { m_model.setFitType(static_cast<FitType>(typeIndex)); } else { m_model.setBackground(static_cast<BackgroundType>(typeIndex)); @@ -92,8 +91,24 @@ int ConvTemplatePresenter::getNumberOfDatasets() const { void ConvTemplatePresenter::setFunction(const QString &funStr) { m_model.setFunctionString(funStr); - m_view->setSubType(0, static_cast<int>(m_model.getFitType())); - m_view->setSubType(1, static_cast<int>(m_model.getBackgroundType())); + + if (m_model.hasDeltaFunction()) + m_view->addDeltaFunction(); + else + m_view->removeDeltaFunction(); + + if (m_model.hasTempCorrection()) + m_view->addTempCorrection(100.0); + else + m_view->removeTempCorrection(); + + m_view->setSubType(SubTypeIndex::Fit, static_cast<int>(m_model.getFitType())); + m_view->setSubType(SubTypeIndex::Background, + static_cast<int>(m_model.getBackgroundType())); + m_view->setEnum(SubTypeIndex::Fit, static_cast<int>(m_model.getFitType())); + m_view->setEnum(SubTypeIndex::Background, + static_cast<int>(m_model.getBackgroundType())); + setErrorsEnabled(false); updateViewParameterNames(); updateViewParameters(); diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTypes.h b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTypes.h index c18b496c0f8202f3a3d750115f2cfd0ce55a9636..e17ce6ae3e415b1b793c09733e2cc83860c4280c 100644 --- a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTypes.h +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTypes.h @@ -99,6 +99,11 @@ inline void applyToParamIDRange(ParamID from, ParamID to, fun(i); } +enum SubTypeIndex { + Fit = 0, + Background = 1, +}; + struct TemplateSubType { virtual QString name() const = 0; virtual QStringList getTypeNames() const = 0; diff --git a/qt/scientific_interfaces/Indirect/test/ConvFunctionModelTest.h b/qt/scientific_interfaces/Indirect/test/ConvFunctionModelTest.h index e87a507ea31760893f78dfcea27658e26763f8e8..67de1704411e0afe4f27b4a7f82a70c033e1b3d6 100644 --- a/qt/scientific_interfaces/Indirect/test/ConvFunctionModelTest.h +++ b/qt/scientific_interfaces/Indirect/test/ConvFunctionModelTest.h @@ -123,6 +123,23 @@ public: TS_ASSERT_EQUALS(m_model->getCurrentFunction()->asString(), func->asString()) + TS_ASSERT_EQUALS(m_model->getBackgroundType(), BackgroundType::None); + TS_ASSERT_EQUALS(m_model->getFitType(), FitType::OneLorentzian); + } + + void + test_setFunction_does_not_throw_for_valid_temperature_function_with_delta() { + m_model->setFitType(FitType::OneLorentzian); + m_model->setTempCorrection(true, 100.0); + m_model->setDeltaFunction(true); + auto func = m_model->getFitFunction(); + + m_model->setFunction(func); + + TS_ASSERT_EQUALS(m_model->getCurrentFunction()->asString(), + func->asString()) + TS_ASSERT_EQUALS(m_model->getBackgroundType(), BackgroundType::None); + TS_ASSERT_EQUALS(m_model->getFitType(), FitType::OneLorentzian); } void @@ -135,6 +152,8 @@ public: TS_ASSERT_EQUALS(m_model->getCurrentFunction()->asString(), func->asString()) + TS_ASSERT_EQUALS(m_model->getBackgroundType(), BackgroundType::None); + TS_ASSERT_EQUALS(m_model->getFitType(), FitType::TwoLorentzians); } void @@ -147,7 +166,9 @@ public: m_model->setFunction(func); TS_ASSERT_EQUALS(m_model->getCurrentFunction()->asString(), - func->asString()) + func->asString()); + TS_ASSERT_EQUALS(m_model->getBackgroundType(), BackgroundType::None); + TS_ASSERT_EQUALS(m_model->getFitType(), FitType::TwoLorentzians); } private: