From e76a022f182c282573a191baeb2d3766ca3c541c Mon Sep 17 00:00:00 2001 From: Applin Date: Fri, 19 Apr 2024 14:05:28 +0100 Subject: [PATCH 01/15] Propagate c++ exception to python output --- qt/python/mantidqt/mantidqt/_common.sip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/python/mantidqt/mantidqt/_common.sip b/qt/python/mantidqt/mantidqt/_common.sip index 24583c80184b..57fb824407ff 100644 --- a/qt/python/mantidqt/mantidqt/_common.sip +++ b/qt/python/mantidqt/mantidqt/_common.sip @@ -351,7 +351,7 @@ public: UserSubWindow *createSubWindow( const QString &interface_name, - QWidget *parent = nullptr); + QWidget *parent = nullptr) throw(std::exception); QStringList getUserSubWindowKeys() const; void showHelpPage(const QString &url=QString()); From b85749cbd40583c854751c802aa9c5e6862bfabc Mon Sep 17 00:00:00 2001 From: Applin Date: Fri, 19 Apr 2024 14:17:57 +0100 Subject: [PATCH 02/15] Add TeixeiraWaterIqt to fit types --- .../Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp | 2 ++ .../Inelastic/QENSFitting/FunctionBrowser/FitTypes.h | 2 +- .../Inelastic/QENSFitting/FunctionBrowser/ParamID.h | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp index 8d5116cf1037..8cf8e319c8f7 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp @@ -25,6 +25,8 @@ std::map TemplateSubTypeImpl diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h index 60747ff8c64c..c7ad097ac663 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h @@ -23,7 +23,7 @@ enum class ExponentialType { TwoExponentials, }; -enum class FitType { None, StretchExponential }; +enum class FitType { None, StretchExponential, TeixeiraWaterIqt }; enum class BackgroundType { None, Flat }; diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ParamID.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ParamID.h index bf2f1d87b90e..0bd9a2260e26 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ParamID.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ParamID.h @@ -23,6 +23,9 @@ enum class ParamID { STRETCH_HEIGHT, STRETCH_LIFETIME, STRETCH_STRETCHING, + TWI_AMPLITUDE, + TWI_TAU, + TWI_GAMMA, LOR1_AMPLITUDE, LOR1_PEAKCENTRE, LOR1_FWHM, @@ -96,6 +99,9 @@ static std::map g_paramName{ {ParamID::STRETCH_HEIGHT, "Height"}, {ParamID::STRETCH_LIFETIME, "Lifetime"}, {ParamID::STRETCH_STRETCHING, "Stretching"}, + {ParamID::TWI_AMPLITUDE, "Amp"}, + {ParamID::TWI_TAU, "Tau1"}, + {ParamID::TWI_GAMMA, "Gamma"}, {ParamID::LOR1_AMPLITUDE, "Amplitude"}, {ParamID::LOR1_PEAKCENTRE, "PeakCentre"}, {ParamID::LOR1_FWHM, "FWHM"}, From f2a0ed3b4cabd170d2234c17520e94f5154addb5 Mon Sep 17 00:00:00 2001 From: Applin Date: Fri, 19 Apr 2024 14:19:31 +0100 Subject: [PATCH 03/15] Add TeixeiraWaterIqt to iqtfunction template model --- .../IqtFunctionTemplateModel.cpp | 52 ++++++++++++++----- .../IqtFunctionTemplateModel.h | 6 ++- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp index b332b5d96c1e..c17526221bda 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp @@ -82,6 +82,8 @@ void IqtFunctionTemplateModel::setFunction(IFunction_sptr fun) { m_exponentialType = ExponentialType::OneExponential; } else if (name == "StretchExp") { m_fitType = FitType::StretchExponential; + } else if (name == "TeixeiraWaterIqt") { + m_fitType = FitType::TeixeiraWaterIqt; } else if (name == "FlatBackground") { m_backgroundType = BackgroundType::Flat; } else { @@ -113,6 +115,10 @@ void IqtFunctionTemplateModel::setFunction(IFunction_sptr fun) { m_fitType = FitType::StretchExponential; areExponentialsSet = true; isStretchSet = true; + } else if (name == "TeixeiraWaterIqt") { + m_fitType = FitType::TeixeiraWaterIqt; + areExponentialsSet = false; + isStretchSet = false; } else if (name == "FlatBackground") { if (isBackgroundSet) { throw std::runtime_error("Function has wrong structure."); @@ -146,10 +152,15 @@ void IqtFunctionTemplateModel::addFunction(std::string const &prefix, std::strin newPrefix = *getExp1Prefix(); } } else if (name == "StretchExp") { - if (hasStretchExponential()) + if (hasFitType(FitType::StretchExponential)) throw std::runtime_error("Cannot add more stretched exponentials."); m_fitType = FitType::StretchExponential; - newPrefix = *getStretchPrefix(); + newPrefix = *getFitTypePrefix(); + } else if (name == "TeixeiraWaterIqt") { + if (hasFitType(FitType::TeixeiraWaterIqt)) + throw std::runtime_error("Cannot add another TeixeiraWaterIqt function."); + m_fitType = FitType::TeixeiraWaterIqt; + newPrefix = *getFitTypePrefix(); } else if (name == "FlatBackground") { if (hasBackground()) throw std::runtime_error("Cannot add more backgrounds."); @@ -213,7 +224,7 @@ void IqtFunctionTemplateModel::removeFunction(std::string const &prefix) { m_exponentialType = ExponentialType::OneExponential; return; } - prefix1 = getStretchPrefix(); + prefix1 = getFitTypePrefix(); if (prefix1 && *prefix1 == prefix) { m_fitType = FitType::None; return; @@ -230,7 +241,9 @@ int IqtFunctionTemplateModel::numberOfExponentials() const { return static_cast< bool IqtFunctionTemplateModel::hasExponential() const { return m_exponentialType != ExponentialType::None; } -bool IqtFunctionTemplateModel::hasStretchExponential() const { return m_fitType == FitType::StretchExponential; } +bool IqtFunctionTemplateModel::hasFitType() const { return m_fitType != FitType::None; } + +bool IqtFunctionTemplateModel::hasFitType(FitType fitType) const { return m_fitType == fitType; } void IqtFunctionTemplateModel::removeBackground() { auto oldValues = getCurrentValues(); @@ -298,8 +311,8 @@ std::optional IqtFunctionTemplateModel::getPrefix(ParamID name) con return getExp1Prefix(); } else if (name <= ParamID::EXP2_LIFETIME) { return getExp2Prefix(); - } else if (name <= ParamID::STRETCH_STRETCHING) { - return getStretchPrefix(); + } else if (name <= ParamID::TWI_GAMMA) { + return getFitTypePrefix(); } else { return getBackgroundPrefix(); } @@ -314,11 +327,16 @@ void IqtFunctionTemplateModel::applyParameterFunction(const std::function0,0" + "0,Tau1>0,Gamma>0)"; +} + std::string IqtFunctionTemplateModel::buildBackgroundFunctionString() const { return "name=FlatBackground,A0=0,constraints=(A0>0)"; } @@ -345,9 +368,12 @@ std::string IqtFunctionTemplateModel::buildFunctionString() const { if (numberOfExponentials() > 1) { functions << QString::fromStdString(buildExpDecayFunctionString()); } - if (hasStretchExponential()) { + if (hasFitType(FitType::StretchExponential)) { functions << QString::fromStdString(buildStretchExpFunctionString()); } + if (hasFitType(FitType::TeixeiraWaterIqt)) { + functions << QString::fromStdString(buildTeixeiraWaterIqtFunctionString()); + } if (hasBackground()) { functions << QString::fromStdString(buildBackgroundFunctionString()); } @@ -357,7 +383,7 @@ std::string IqtFunctionTemplateModel::buildFunctionString() const { std::optional IqtFunctionTemplateModel::getExp1Prefix() const { if (!hasExponential()) return std::optional(); - if (numberOfExponentials() == 1 && !hasStretchExponential() && !hasBackground()) + if (numberOfExponentials() == 1 && !hasFitType() && !hasBackground()) return std::string(""); return std::string("f0."); } @@ -368,8 +394,8 @@ std::optional IqtFunctionTemplateModel::getExp2Prefix() const { return std::string("f1."); } -std::optional IqtFunctionTemplateModel::getStretchPrefix() const { - if (!hasStretchExponential()) +std::optional IqtFunctionTemplateModel::getFitTypePrefix() const { + if (!hasFitType()) return std::optional(); if (!hasExponential() && !hasBackground()) return std::string(""); @@ -379,9 +405,9 @@ std::optional IqtFunctionTemplateModel::getStretchPrefix() const { std::optional IqtFunctionTemplateModel::getBackgroundPrefix() const { if (!hasBackground()) return std::optional(); - if (!hasExponential() && !hasStretchExponential()) + if (!hasExponential() && !hasFitType()) return std::string(""); - return "f" + std::to_string(numberOfExponentials() + (hasStretchExponential() ? 1 : 0)) + "."; + return "f" + std::to_string(numberOfExponentials() + (hasFitType() ? 1 : 0)) + "."; } } // namespace MantidQt::CustomInterfaces::Inelastic diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h index b0990fd1c31f..ad08a4bd45a4 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h @@ -40,7 +40,8 @@ class MANTIDQT_INELASTIC_DLL IqtFunctionTemplateModel : public MultiFunctionTemp int numberOfExponentials() const; bool hasExponential() const; - bool hasStretchExponential() const; + bool hasFitType() const; + bool hasFitType(IqtTypes::FitType fitType) const; void removeBackground(); bool hasBackground() const; void tieIntensities(bool on); @@ -58,12 +59,13 @@ class MANTIDQT_INELASTIC_DLL IqtFunctionTemplateModel : public MultiFunctionTemp std::optional getExp1Prefix() const; std::optional getExp2Prefix() const; - std::optional getStretchPrefix() const; + std::optional getFitTypePrefix() const; std::optional getBackgroundPrefix() const; std::string buildFunctionString() const; std::string buildExpDecayFunctionString() const; std::string buildStretchExpFunctionString() const; + std::string buildTeixeiraWaterIqtFunctionString() const; std::string buildBackgroundFunctionString() const; IqtTypes::ExponentialType m_exponentialType = IqtTypes::ExponentialType::None; From 2fc19cd24a4c794ad8a70d7b5af44f31b2d70e62 Mon Sep 17 00:00:00 2001 From: Applin Date: Fri, 19 Apr 2024 14:42:35 +0100 Subject: [PATCH 04/15] Implement basic q dependency of fit function --- .../QENSFitting/FunctionBrowser/FitTypes.cpp | 7 +++++++ .../QENSFitting/FunctionBrowser/FitTypes.h | 2 ++ .../IqtFunctionTemplateModel.cpp | 18 ++++++++++-------- .../FunctionBrowser/IqtFunctionTemplateModel.h | 2 ++ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp index 8cf8e319c8f7..6104bcc1e873 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp @@ -10,6 +10,13 @@ namespace MantidQt::CustomInterfaces::Inelastic { +namespace IqtTypes { + +std::map FitTypeQDepends = std::map( + {{FitType::None, false}, {FitType::StretchExponential, false}, {FitType::TeixeiraWaterIqt, true}}); + +} + template <> std::map TemplateSubTypeImpl::g_typeMap{ diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h index c7ad097ac663..8a2c5af86437 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h @@ -36,6 +36,8 @@ enum SubTypeIndex { TieIntensities = 3, }; +extern std::map FitTypeQDepends; + struct ExponentialSubType : public TemplateSubTypeImpl { std::string name() const override { return "Exponentials"; } bool isType(const std::type_info &type) const override { return type == typeid(int); } diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp index c17526221bda..b953d2319849 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp @@ -93,7 +93,7 @@ void IqtFunctionTemplateModel::setFunction(IFunction_sptr fun) { return; } bool areExponentialsSet = false; - bool isStretchSet = false; + bool isFitTypeSet = false; bool isBackgroundSet = false; for (size_t i = 0; i < fun->nFunctions(); ++i) { auto f = fun->getFunction(i); @@ -109,23 +109,23 @@ void IqtFunctionTemplateModel::setFunction(IFunction_sptr fun) { areExponentialsSet = true; } } else if (name == "StretchExp") { - if (isStretchSet) { + if (isFitTypeSet) { throw std::runtime_error("Function has wrong structure."); } m_fitType = FitType::StretchExponential; areExponentialsSet = true; - isStretchSet = true; + isFitTypeSet = true; } else if (name == "TeixeiraWaterIqt") { m_fitType = FitType::TeixeiraWaterIqt; - areExponentialsSet = false; - isStretchSet = false; + areExponentialsSet = true; + isFitTypeSet = true; } else if (name == "FlatBackground") { if (isBackgroundSet) { throw std::runtime_error("Function has wrong structure."); } m_backgroundType = BackgroundType::Flat; areExponentialsSet = true; - isStretchSet = true; + isFitTypeSet = true; isBackgroundSet = true; } else { clear(); @@ -291,7 +291,7 @@ void IqtFunctionTemplateModel::setResolution(const std::vector &qValues) { (void)qValues; } +void IqtFunctionTemplateModel::setQValues(const std::vector &qValues) { m_qValues = qValues; } void IqtFunctionTemplateModel::tieIntensities() { auto heightName = getParameterName(ParamID::STRETCH_HEIGHT); @@ -352,7 +352,9 @@ std::string IqtFunctionTemplateModel::buildStretchExpFunctionString() const { } std::string IqtFunctionTemplateModel::buildTeixeiraWaterIqtFunctionString() const { - return "name=TeixeiraWaterIqt,Amp=1,Tau1=0.05,Gamma=1.2,constraints=(Amp>" + auto qValue = m_qValues.empty() ? 0.0 : m_qValues[0]; + return "name=TeixeiraWaterIqt,Q=" + std::to_string(qValue) + + ",Amp=1,Tau1=0.05,Gamma=1.2,constraints=(Amp>" "0,Tau1>0,Gamma>0)"; } diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h index ad08a4bd45a4..1ffb9ab11813 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h @@ -72,6 +72,8 @@ class MANTIDQT_INELASTIC_DLL IqtFunctionTemplateModel : public MultiFunctionTemp IqtTypes::FitType m_fitType = IqtTypes::FitType::None; IqtTypes::BackgroundType m_backgroundType = IqtTypes::BackgroundType::None; IqtTypes::TieIntensitiesType m_tieIntensitiesType = IqtTypes::TieIntensitiesType::False; + + std::vector m_qValues; }; } // namespace Inelastic From 7f649b633522b1f3dbce91c6df0a2c14cd36f55b Mon Sep 17 00:00:00 2001 From: Applin Date: Fri, 19 Apr 2024 15:24:58 +0100 Subject: [PATCH 05/15] Create general method for setting model multi function --- .../ConvFunctionTemplateModel.cpp | 2 -- .../ConvFunctionTemplateModel.h | 5 ++--- .../QENSFitting/FunctionBrowser/FitTypes.cpp | 7 ------- .../QENSFitting/FunctionBrowser/FitTypes.h | 2 -- .../IqtFunctionTemplateModel.cpp | 18 ++++++------------ .../FunctionBrowser/IqtFunctionTemplateModel.h | 9 +++------ .../MultiFunctionTemplateModel.cpp | 18 ++++++++++++++++++ .../MultiFunctionTemplateModel.h | 7 +++++++ 8 files changed, 36 insertions(+), 32 deletions(-) diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ConvFunctionTemplateModel.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ConvFunctionTemplateModel.cpp index 116222dc0f72..ae3f44cb81c0 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ConvFunctionTemplateModel.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ConvFunctionTemplateModel.cpp @@ -159,8 +159,6 @@ void ConvFunctionTemplateModel::checkSingleFunction(const IFunction_sptr &fun, b } } -void ConvFunctionTemplateModel::setQValues(const std::vector &qValues) { m_qValues = qValues; } - void ConvFunctionTemplateModel::addFunction(std::string const &prefix, std::string const &funStr) { if (!prefix.empty()) throw std::runtime_error("Function doesn't have member function with prefix " + prefix); diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ConvFunctionTemplateModel.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ConvFunctionTemplateModel.h index 2fbf58840864..26bfd126845a 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ConvFunctionTemplateModel.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/ConvFunctionTemplateModel.h @@ -41,7 +41,6 @@ class MANTIDQT_INELASTIC_DLL ConvFunctionTemplateModel : public MultiFunctionTem std::map getSubTypes() const override; std::string setBackgroundA0(double value) override; void setResolution(const std::vector> &fitResolutions) override; - void setQValues(const std::vector &qValues) override; bool hasDeltaFunction() const; bool hasTempCorrection() const; @@ -55,7 +54,7 @@ class MANTIDQT_INELASTIC_DLL ConvFunctionTemplateModel : public MultiFunctionTem void applyParameterFunction(const std::function ¶mFun) const override; void clearData(); - void setModel(); + void setModel() override; std::optional getLor1Prefix() const; std::optional getLor2Prefix() const; @@ -63,6 +62,7 @@ class MANTIDQT_INELASTIC_DLL ConvFunctionTemplateModel : public MultiFunctionTem std::optional getDeltaPrefix() const; std::optional getBackgroundPrefix() const; + std::string buildFunctionString(int const domainIndex) const override { return ""; } std::string buildLorentzianFunctionString() const; std::string buildTeixeiraFunctionString() const; std::string buildFickFunctionString() const; @@ -96,7 +96,6 @@ class MANTIDQT_INELASTIC_DLL ConvFunctionTemplateModel : public MultiFunctionTem BackgroundSubType m_backgroundSubtype; std::vector> m_fitResolutions; - std::vector m_qValues; bool m_isQDependentFunction = false; }; diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp index 6104bcc1e873..8cf8e319c8f7 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.cpp @@ -10,13 +10,6 @@ namespace MantidQt::CustomInterfaces::Inelastic { -namespace IqtTypes { - -std::map FitTypeQDepends = std::map( - {{FitType::None, false}, {FitType::StretchExponential, false}, {FitType::TeixeiraWaterIqt, true}}); - -} - template <> std::map TemplateSubTypeImpl::g_typeMap{ diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h index 8a2c5af86437..c7ad097ac663 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/FitTypes.h @@ -36,8 +36,6 @@ enum SubTypeIndex { TieIntensities = 3, }; -extern std::map FitTypeQDepends; - struct ExponentialSubType : public TemplateSubTypeImpl { std::string name() const override { return "Exponentials"; } bool isType(const std::type_info &type) const override { return type == typeid(int); } diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp index b953d2319849..03cb17812c69 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp @@ -64,11 +64,8 @@ void IqtFunctionTemplateModel::clearData() { } void IqtFunctionTemplateModel::setModel() { - m_model->setFunctionString(buildFunctionString()); - m_model->setGlobalParameters(makeGlobalList()); - + MultiFunctionTemplateModel::setModel(); tieIntensities(); - estimateFunctionParameters(); } @@ -248,8 +245,7 @@ bool IqtFunctionTemplateModel::hasFitType(FitType fitType) const { return m_fitT void IqtFunctionTemplateModel::removeBackground() { auto oldValues = getCurrentValues(); m_backgroundType = BackgroundType::None; - m_model->setFunctionString(buildFunctionString()); - m_model->setGlobalParameters(makeGlobalList()); + setModel(); setCurrentValues(oldValues); } @@ -291,8 +287,6 @@ void IqtFunctionTemplateModel::setResolution(const std::vector &qValues) { m_qValues = qValues; } - void IqtFunctionTemplateModel::tieIntensities() { auto heightName = getParameterName(ParamID::STRETCH_HEIGHT); if (!heightName) @@ -351,8 +345,8 @@ std::string IqtFunctionTemplateModel::buildStretchExpFunctionString() const { "0,Lifetime>0,0(m_qValues.size()) ? m_qValues[domainIndex] : 0.4; return "name=TeixeiraWaterIqt,Q=" + std::to_string(qValue) + ",Amp=1,Tau1=0.05,Gamma=1.2,constraints=(Amp>" "0,Tau1>0,Gamma>0)"; @@ -362,7 +356,7 @@ std::string IqtFunctionTemplateModel::buildBackgroundFunctionString() const { return "name=FlatBackground,A0=0,constraints=(A0>0)"; } -std::string IqtFunctionTemplateModel::buildFunctionString() const { +std::string IqtFunctionTemplateModel::buildFunctionString(int const domainIndex) const { QStringList functions; if (hasExponential()) { functions << QString::fromStdString(buildExpDecayFunctionString()); @@ -374,7 +368,7 @@ std::string IqtFunctionTemplateModel::buildFunctionString() const { functions << QString::fromStdString(buildStretchExpFunctionString()); } if (hasFitType(FitType::TeixeiraWaterIqt)) { - functions << QString::fromStdString(buildTeixeiraWaterIqtFunctionString()); + functions << QString::fromStdString(buildTeixeiraWaterIqtFunctionString(domainIndex)); } if (hasBackground()) { functions << QString::fromStdString(buildBackgroundFunctionString()); diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h index 1ffb9ab11813..f3f981adbec0 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h @@ -36,7 +36,6 @@ class MANTIDQT_INELASTIC_DLL IqtFunctionTemplateModel : public MultiFunctionTemp std::map getSubTypes() const override; std::string setBackgroundA0(double value) override; void setResolution(const std::vector> &fitResolutions) override; - void setQValues(const std::vector &qValues) override; int numberOfExponentials() const; bool hasExponential() const; @@ -53,7 +52,7 @@ class MANTIDQT_INELASTIC_DLL IqtFunctionTemplateModel : public MultiFunctionTemp void applyParameterFunction(const std::function ¶mFun) const override; void clearData(); - void setModel(); + void setModel() override; void tieIntensities(); @@ -62,18 +61,16 @@ class MANTIDQT_INELASTIC_DLL IqtFunctionTemplateModel : public MultiFunctionTemp std::optional getFitTypePrefix() const; std::optional getBackgroundPrefix() const; - std::string buildFunctionString() const; + std::string buildFunctionString(int const domainIndex) const override; std::string buildExpDecayFunctionString() const; std::string buildStretchExpFunctionString() const; - std::string buildTeixeiraWaterIqtFunctionString() const; + std::string buildTeixeiraWaterIqtFunctionString(int const domainIndex) const; std::string buildBackgroundFunctionString() const; IqtTypes::ExponentialType m_exponentialType = IqtTypes::ExponentialType::None; IqtTypes::FitType m_fitType = IqtTypes::FitType::None; IqtTypes::BackgroundType m_backgroundType = IqtTypes::BackgroundType::None; IqtTypes::TieIntensitiesType m_tieIntensitiesType = IqtTypes::TieIntensitiesType::False; - - std::vector m_qValues; }; } // namespace Inelastic diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp index 5d985ccffaed..1def9a2a05a5 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp @@ -6,8 +6,10 @@ // SPDX - License - Identifier: GPL - 3.0 + #include "MultiFunctionTemplateModel.h" +#include "MantidAPI/FunctionFactory.h" #include "MantidAPI/IFunction.h" #include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/MultiDomainFunction.h" namespace MantidQt::CustomInterfaces::Inelastic { @@ -175,6 +177,8 @@ void MultiFunctionTemplateModel::setGlobalParameterValue(std::string const ¶ m_model->setGlobalParameterValue(parameterName, value); } +void MultiFunctionTemplateModel::setQValues(const std::vector &qValues) { m_qValues = qValues; } + void MultiFunctionTemplateModel::updateParameterEstimationData(DataForParameterEstimationCollection &&data) { m_estimationData = std::move(data); } @@ -204,6 +208,20 @@ std::map MultiFunctionTemplateModel::getParameterNameMap() con return out; } +void MultiFunctionTemplateModel::setModel() { + auto multiDomainFunction = std::make_shared(); + + for (int i = 0; i < m_model->getNumberDomains(); ++i) { + auto singleDomainFunction = FunctionFactory::Instance().createInitialized(buildFunctionString(i)); + multiDomainFunction->addFunction(std::move(singleDomainFunction)); + multiDomainFunction->setDomainIndex(i, i); + } + + m_model->setFunction(std::move(multiDomainFunction)); + + m_model->setGlobalParameters(makeGlobalList()); +} + std::vector MultiFunctionTemplateModel::makeGlobalList() const { std::vector globals; for (auto const id : m_globals) { diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.h index 80f9f7e3de72..129b241a8b43 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.h @@ -76,6 +76,8 @@ class MANTIDQT_INELASTIC_DLL MultiFunctionTemplateModel : public IFunctionModel virtual void setSubType(std::size_t subTypeIndex, int typeIndex) = 0; virtual std::map getSubTypes() const = 0; + void setQValues(const std::vector &qValues) override; + virtual EstimationDataSelector getEstimationDataSelector() const = 0; void updateParameterEstimationData(DataForParameterEstimationCollection &&data); void estimateFunctionParameters(); @@ -85,6 +87,9 @@ class MANTIDQT_INELASTIC_DLL MultiFunctionTemplateModel : public IFunctionModel std::map getParameterNameMap() const; protected: + virtual void setModel(); + virtual std::string buildFunctionString(int const domainIndex) const = 0; + void setParameter(ParamID name, double value); std::optional getParameterName(ParamID name) const; void setCurrentValues(const std::map &); @@ -93,6 +98,8 @@ class MANTIDQT_INELASTIC_DLL MultiFunctionTemplateModel : public IFunctionModel std::unique_ptr m_model; QList m_globals; + std::vector m_qValues; + private: double getParameter(ParamID name) const; double getParameterError(ParamID name) const; From fcd48d85a8fc054bb2f2e7b8884376d481f4dea2 Mon Sep 17 00:00:00 2001 From: Applin Date: Fri, 19 Apr 2024 15:55:39 +0100 Subject: [PATCH 06/15] Fix the tying of intensities in IqtFit --- .../FunctionBrowser/IqtFunctionTemplateModel.cpp | 14 ++++++++------ .../FunctionBrowser/IqtFunctionTemplateModel.h | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp index 03cb17812c69..7de3706b7477 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.cpp @@ -152,12 +152,12 @@ void IqtFunctionTemplateModel::addFunction(std::string const &prefix, std::strin if (hasFitType(FitType::StretchExponential)) throw std::runtime_error("Cannot add more stretched exponentials."); m_fitType = FitType::StretchExponential; - newPrefix = *getFitTypePrefix(); + newPrefix = *getFitTypePrefix(m_fitType); } else if (name == "TeixeiraWaterIqt") { if (hasFitType(FitType::TeixeiraWaterIqt)) throw std::runtime_error("Cannot add another TeixeiraWaterIqt function."); m_fitType = FitType::TeixeiraWaterIqt; - newPrefix = *getFitTypePrefix(); + newPrefix = *getFitTypePrefix(m_fitType); } else if (name == "FlatBackground") { if (hasBackground()) throw std::runtime_error("Cannot add more backgrounds."); @@ -221,7 +221,7 @@ void IqtFunctionTemplateModel::removeFunction(std::string const &prefix) { m_exponentialType = ExponentialType::OneExponential; return; } - prefix1 = getFitTypePrefix(); + prefix1 = getFitTypePrefix(m_fitType); if (prefix1 && *prefix1 == prefix) { m_fitType = FitType::None; return; @@ -305,8 +305,10 @@ std::optional IqtFunctionTemplateModel::getPrefix(ParamID name) con return getExp1Prefix(); } else if (name <= ParamID::EXP2_LIFETIME) { return getExp2Prefix(); + } else if (name <= ParamID::STRETCH_STRETCHING) { + return getFitTypePrefix(FitType::StretchExponential); } else if (name <= ParamID::TWI_GAMMA) { - return getFitTypePrefix(); + return getFitTypePrefix(FitType::TeixeiraWaterIqt); } else { return getBackgroundPrefix(); } @@ -390,8 +392,8 @@ std::optional IqtFunctionTemplateModel::getExp2Prefix() const { return std::string("f1."); } -std::optional IqtFunctionTemplateModel::getFitTypePrefix() const { - if (!hasFitType()) +std::optional IqtFunctionTemplateModel::getFitTypePrefix(FitType fitType) const { + if (!hasFitType(fitType)) return std::optional(); if (!hasExponential() && !hasBackground()) return std::string(""); diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h index f3f981adbec0..9acb8a214522 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/IqtFunctionTemplateModel.h @@ -58,7 +58,7 @@ class MANTIDQT_INELASTIC_DLL IqtFunctionTemplateModel : public MultiFunctionTemp std::optional getExp1Prefix() const; std::optional getExp2Prefix() const; - std::optional getFitTypePrefix() const; + std::optional getFitTypePrefix(IqtTypes::FitType fitType) const; std::optional getBackgroundPrefix() const; std::string buildFunctionString(int const domainIndex) const override; From 5b9b8184791b9b0130f66b7807569759138b8434 Mon Sep 17 00:00:00 2001 From: Applin Date: Mon, 22 Apr 2024 09:24:23 +0100 Subject: [PATCH 07/15] Add TeixeiraWaterIqt to function strings --- qt/scientific_interfaces/Inelastic/QENSFitting/FitTabConstants.h | 1 + 1 file changed, 1 insertion(+) diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FitTabConstants.h b/qt/scientific_interfaces/Inelastic/QENSFitting/FitTabConstants.h index 65869f518047..6eea73c572cb 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FitTabConstants.h +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FitTabConstants.h @@ -23,6 +23,7 @@ static const auto FUNCTION_STRINGS = {"Lorentzian", "L"}, {"StretchedExpFT", "SFT"}, {"TeixeiraWater", "TxWater"}, + {"TeixeiraWaterIqt", "TxWater"}, {"TeixeiraWaterSQE", "TxWater"}, {"FickDiffusionSQE", "FickDiff"}, {"ChudleyElliotSQE", "ChudElliot"}, From c6780b8cba8bf2c26d7947d56ee6c2d40503bca2 Mon Sep 17 00:00:00 2001 From: Applin Date: Tue, 23 Apr 2024 08:29:06 +0100 Subject: [PATCH 08/15] Remove setAttributeValue and use getAttributeValue --- .../plugins/functions/TeixeiraWaterIqt.py | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py b/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py index 535a10a8dbf3..ef811271d236 100644 --- a/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py +++ b/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py @@ -5,16 +5,10 @@ # & Institut Laue - Langevin # SPDX - License - Identifier: GPL - 3.0 + # pylint: disable=no-init,invalid-name - -""" -@author Spencer Howells, ISIS -@date December 05, 2013 -""" - import numpy as np from mantid.api import IFunction1D, FunctionFactory -from scipy.special import spherical_jn # bessel +from scipy.special import spherical_jn class TeixeiraWaterIqt(IFunction1D): @@ -32,19 +26,17 @@ def init(self): self.declareAttribute("Q", 0.4) self.declareAttribute("a", 0.98) - def setAttributeValue(self, name, value): - if name == "Q": - self.Q = value - if name == "a": - self.radius = value - def function1D(self, xvals): amp = self.getParameterValue("Amp") tau1 = self.getParameterValue("Tau1") gamma = self.getParameterValue("Gamma") + + q_value = self.getAttributeValue("Q") + radius = self.getAttributeValue("a") + xvals = np.array(xvals) - qr = np.array(self.Q * self.radius) + qr = np.array(q_value * radius) j0 = spherical_jn(0, qr) j1 = spherical_jn(1, qr) j2 = spherical_jn(2, qr) @@ -59,7 +51,10 @@ def functionDeriv1D(self, xvals, jacobian): tau1 = self.getParameterValue("Tau1") gamma = self.getParameterValue("Gamma") - qr = np.array(self.Q * self.radius) + q_value = self.getAttributeValue("Q") + radius = self.getAttributeValue("a") + + qr = np.array(q_value * radius) j0 = spherical_jn(0, qr) j1 = spherical_jn(1, qr) j2 = spherical_jn(2, qr) From ae57d9a5c1942dc99aab6efc3afa9f10f98293a1 Mon Sep 17 00:00:00 2001 From: Applin Date: Tue, 23 Apr 2024 08:48:15 +0100 Subject: [PATCH 09/15] Check if function exists before getting parameter or attribute --- qt/widgets/common/src/FunctionModel.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qt/widgets/common/src/FunctionModel.cpp b/qt/widgets/common/src/FunctionModel.cpp index f6e2fd703959..c2abdb4711d5 100644 --- a/qt/widgets/common/src/FunctionModel.cpp +++ b/qt/widgets/common/src/FunctionModel.cpp @@ -174,23 +174,23 @@ void FunctionModel::setParameterError(std::string const ¶meterName, double v } double FunctionModel::getParameter(std::string const ¶meterName) const { - return getCurrentFunction()->getParameter(parameterName); + auto const fun = getCurrentFunction(); + return fun && fun->hasParameter(parameterName) ? fun->getParameter(parameterName) : 0.0; } IFunction::Attribute FunctionModel::getAttribute(std::string const &attrName) const { - return getCurrentFunction()->getAttribute(attrName); + auto const fun = getCurrentFunction(); + return fun && fun->hasAttribute(attrName) ? fun->getAttribute(attrName) : IFunction::Attribute(); } double FunctionModel::getParameterError(std::string const ¶meterName) const { auto fun = getCurrentFunction(); - auto const index = fun->parameterIndex(parameterName); - return fun->getError(index); + return fun && fun->hasParameter(parameterName) ? fun->getError(fun->parameterIndex(parameterName)) : 0.0; } std::string FunctionModel::getParameterDescription(std::string const ¶meterName) const { auto fun = getCurrentFunction(); - auto const index = fun->parameterIndex(parameterName); - return fun->parameterDescription(index); + return fun && fun->hasParameter(parameterName) ? fun->parameterDescription(fun->parameterIndex(parameterName)) : ""; } bool FunctionModel::isParameterFixed(std::string const ¶meterName) const { From c8766cdbcf8f27200686f0a21d4fd692bbee165d Mon Sep 17 00:00:00 2001 From: Applin Date: Tue, 23 Apr 2024 09:45:05 +0100 Subject: [PATCH 10/15] Check for attribute before constructing python object for value --- .../mantid/api/src/FitFunctions/IFunctionAdapter.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunctionAdapter.cpp b/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunctionAdapter.cpp index 94d69465072d..37457ea0db94 100644 --- a/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunctionAdapter.cpp +++ b/Framework/PythonInterface/mantid/api/src/FitFunctions/IFunctionAdapter.cpp @@ -203,11 +203,12 @@ void IFunctionAdapter::setAttributePythonValue(IFunction &self, const std::strin * @param attr An attribute object */ void IFunctionAdapter::setAttribute(const std::string &attName, const Attribute &attr) { - try { + auto self = getSelf(); + if (typeHasAttribute(self, "setAttributeValue")) { object value = object(handle<>(getAttributeValue(*this, attr))); - callMethod(getSelf(), "setAttributeValue", attName, value); + callMethod(self, "setAttributeValue", attName, value); storeAttributeValue(attName, attr); - } catch (UndefinedAttributeError &) { + } else { IFunction::setAttribute(attName, attr); } } From dd73b6ddb4cc98de4a51c2564478e1484a1cb2cb Mon Sep 17 00:00:00 2001 From: Applin Date: Tue, 23 Apr 2024 09:51:50 +0100 Subject: [PATCH 11/15] Do not create domain function if no function selected --- .../FunctionBrowser/MultiFunctionTemplateModel.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp index 1def9a2a05a5..7fad32fad133 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp @@ -212,7 +212,11 @@ void MultiFunctionTemplateModel::setModel() { auto multiDomainFunction = std::make_shared(); for (int i = 0; i < m_model->getNumberDomains(); ++i) { - auto singleDomainFunction = FunctionFactory::Instance().createInitialized(buildFunctionString(i)); + auto domainFunctionString = buildFunctionString(i); + if (domainFunctionString.empty()) { + break; + } + auto singleDomainFunction = FunctionFactory::Instance().createInitialized(domainFunctionString); multiDomainFunction->addFunction(std::move(singleDomainFunction)); multiDomainFunction->setDomainIndex(i, i); } From 899d41b713fba8c2c1aa0de838271e9cf2fb1e5b Mon Sep 17 00:00:00 2001 From: Applin Date: Tue, 23 Apr 2024 09:58:16 +0100 Subject: [PATCH 12/15] Update template function model after datasets are added --- .../FunctionBrowser/MultiFunctionTemplateModel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp index 7fad32fad133..ea5eba5eb293 100644 --- a/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp +++ b/qt/scientific_interfaces/Inelastic/QENSFitting/FunctionBrowser/MultiFunctionTemplateModel.cpp @@ -53,7 +53,10 @@ std::string MultiFunctionTemplateModel::getParameterDescription(std::string cons std::vector MultiFunctionTemplateModel::getParameterNames() const { return m_model->getParameterNames(); } -void MultiFunctionTemplateModel::setNumberDomains(int n) { m_model->setNumberDomains(n); } +void MultiFunctionTemplateModel::setNumberDomains(int n) { + m_model->setNumberDomains(n); + setModel(); +} int MultiFunctionTemplateModel::getNumberDomains() const { return m_model->getNumberDomains(); } From bb9eb08596a89cec258ea160ff77bff92460f7df Mon Sep 17 00:00:00 2001 From: Applin Date: Tue, 23 Apr 2024 10:06:39 +0100 Subject: [PATCH 13/15] Use np.square where possible in fit function --- .../PythonInterface/plugins/functions/TeixeiraWaterIqt.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py b/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py index ef811271d236..b48f4d335f50 100644 --- a/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py +++ b/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py @@ -41,7 +41,7 @@ def function1D(self, xvals): j1 = spherical_jn(1, qr) j2 = spherical_jn(2, qr) with np.errstate(divide="ignore"): - rotational = j0 * j0 + 3 * j1 * j1 * np.exp(-xvals / (3 * tau1)) + 5 * j2 * j2 * np.exp(-xvals / tau1) + rotational = np.square(j0) + 3 * np.square(j1) * np.exp(-xvals / (3 * tau1)) + 5 * np.square(j2) * np.exp(-xvals / tau1) translational = np.exp(-gamma * xvals) iqt = amp * rotational * translational return iqt @@ -60,9 +60,9 @@ def functionDeriv1D(self, xvals, jacobian): j2 = spherical_jn(2, qr) with np.errstate(divide="ignore"): for i, x in enumerate(xvals, start=0): - rotational = j0 * j0 + 3 * j1 * j1 * np.exp(-x / (3 * tau1)) + 5 * j2 * j2 * np.exp(-x / tau1) + rotational = np.square(j0) + 3 * np.square(j1) * np.exp(-x / (3 * tau1)) + 5 * np.square(j2) * np.exp(-x / tau1) translational = np.exp(-gamma * x) - partial_tau = (x / np.square(tau1)) * (j1 * j1 * np.exp(-x / (3 * tau1)) + 5 * j2 * j2 * np.exp(-x / tau1)) + partial_tau = (x / np.square(tau1)) * (np.square(j1) * np.exp(-x / (3 * tau1)) + 5 * np.square(j2) * np.exp(-x / tau1)) jacobian.set(i, 0, rotational * translational) jacobian.set(i, 1, amp * rotational * partial_tau) jacobian.set(i, 2, -x * amp * rotational * translational) From 0c650ec5c7e8271d83682bfd5c262382f7c3403e Mon Sep 17 00:00:00 2001 From: Applin Date: Tue, 23 Apr 2024 11:27:54 +0100 Subject: [PATCH 14/15] Remove functionDeriv1D for TeixeiraWaterIqt --- .../plugins/functions/TeixeiraWaterIqt.py | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py b/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py index b48f4d335f50..83ab6f0ae69b 100644 --- a/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py +++ b/Framework/PythonInterface/plugins/functions/TeixeiraWaterIqt.py @@ -46,27 +46,5 @@ def function1D(self, xvals): iqt = amp * rotational * translational return iqt - def functionDeriv1D(self, xvals, jacobian): - amp = self.getParameterValue("Amp") - tau1 = self.getParameterValue("Tau1") - gamma = self.getParameterValue("Gamma") - - q_value = self.getAttributeValue("Q") - radius = self.getAttributeValue("a") - - qr = np.array(q_value * radius) - j0 = spherical_jn(0, qr) - j1 = spherical_jn(1, qr) - j2 = spherical_jn(2, qr) - with np.errstate(divide="ignore"): - for i, x in enumerate(xvals, start=0): - rotational = np.square(j0) + 3 * np.square(j1) * np.exp(-x / (3 * tau1)) + 5 * np.square(j2) * np.exp(-x / tau1) - translational = np.exp(-gamma * x) - partial_tau = (x / np.square(tau1)) * (np.square(j1) * np.exp(-x / (3 * tau1)) + 5 * np.square(j2) * np.exp(-x / tau1)) - jacobian.set(i, 0, rotational * translational) - jacobian.set(i, 1, amp * rotational * partial_tau) - jacobian.set(i, 2, -x * amp * rotational * translational) - -# Required to have Mantid recognise the new function FunctionFactory.subscribe(TeixeiraWaterIqt) From 214f363fb6025cefa9ee940475c44ae7fcc37d68 Mon Sep 17 00:00:00 2001 From: Applin Date: Tue, 23 Apr 2024 11:30:22 +0100 Subject: [PATCH 15/15] Add to release note --- docs/source/release/v6.10.0/Inelastic/New_features/36502.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/release/v6.10.0/Inelastic/New_features/36502.rst b/docs/source/release/v6.10.0/Inelastic/New_features/36502.rst index 307d11ce3025..ee7b8841219d 100644 --- a/docs/source/release/v6.10.0/Inelastic/New_features/36502.rst +++ b/docs/source/release/v6.10.0/Inelastic/New_features/36502.rst @@ -1 +1 @@ -- Added new `TeixeiraWaterIqt` fitting function, to fit linewidth and molecular residence time in intermediate scattering functions with Teixeira's model for water. \ No newline at end of file +- Added new `TeixeiraWaterIqt` fitting function, to fit linewidth and molecular residence time in intermediate scattering functions with Teixeira's model for water. This is now available in the IqtFit tab of the :ref:`QENS Fitting ` interface.