diff --git a/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.ui b/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.ui index 17cd5c058891..9299bee69d5c 100644 --- a/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.ui +++ b/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.ui @@ -132,40 +132,7 @@ - - - pbAdd - clicked() - IndirectAddWorkspaceDialog - addData() - - - 283 - 157 - - - 248 - 294 - - - - - pbClose - clicked() - IndirectAddWorkspaceDialog - closeDialog() - - - 358 - 160 - - - 354 - 227 - - - - + addData() closeDialog() diff --git a/qt/scientific_interfaces/Inelastic/Analysis/ConvFitAddWorkspaceDialog.h b/qt/scientific_interfaces/Inelastic/Analysis/ConvFitAddWorkspaceDialog.h index 28823935c865..8dae44777076 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/ConvFitAddWorkspaceDialog.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/ConvFitAddWorkspaceDialog.h @@ -5,6 +5,7 @@ // Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS // SPDX - License - Identifier: GPL - 3.0 + #pragma once +#include "DllConfig.h" #include "IAddWorkspaceDialog.h" #include "ui_ConvFitAddWorkspaceDialog.h" @@ -12,7 +13,7 @@ namespace MantidQt { namespace CustomInterfaces { namespace IDA { -class ConvFitAddWorkspaceDialog : public IAddWorkspaceDialog { +class MANTIDQT_INELASTIC_DLL ConvFitAddWorkspaceDialog : public IAddWorkspaceDialog { Q_OBJECT public: explicit ConvFitAddWorkspaceDialog(QWidget *parent); diff --git a/qt/scientific_interfaces/Inelastic/Analysis/ConvFitDataPresenter.cpp b/qt/scientific_interfaces/Inelastic/Analysis/ConvFitDataPresenter.cpp index f7a93274212e..17ea1ab3e842 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/ConvFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/ConvFitDataPresenter.cpp @@ -14,6 +14,15 @@ namespace MantidQt::CustomInterfaces::IDA { ConvFitDataPresenter::ConvFitDataPresenter(IIndirectFitDataModel *model, IIndirectFitDataView *view) : IndirectFitDataPresenter(model, view) {} +bool ConvFitDataPresenter::addWorkspaceFromDialog(IAddWorkspaceDialog const *dialog) { + if (const auto convDialog = dynamic_cast(dialog)) { + addWorkspace(convDialog->workspaceName(), convDialog->workspaceIndices()); + setResolution(convDialog->resolutionName()); + return true; + } + return false; +} + std::unique_ptr ConvFitDataPresenter::getAddWorkspaceDialog(QWidget *parent) const { auto dialog = std::make_unique(parent); dialog->setResolutionWSSuffices(getResolutionWSSuffices()); diff --git a/qt/scientific_interfaces/Inelastic/Analysis/ConvFitDataPresenter.h b/qt/scientific_interfaces/Inelastic/Analysis/ConvFitDataPresenter.h index 5adf4a14e474..f72b530fa4a5 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/ConvFitDataPresenter.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/ConvFitDataPresenter.h @@ -20,6 +20,8 @@ class MANTIDQT_INELASTIC_DLL ConvFitDataPresenter : public IndirectFitDataPresen public: ConvFitDataPresenter(IIndirectFitDataModel *model, IIndirectFitDataView *view); + bool addWorkspaceFromDialog(IAddWorkspaceDialog const *dialog) override; + signals: void modelResolutionAdded(std::string const &name, WorkspaceID const &workspaceID); diff --git a/qt/scientific_interfaces/Inelastic/Analysis/DataAnalysisTabFactory.cpp b/qt/scientific_interfaces/Inelastic/Analysis/DataAnalysisTabFactory.cpp new file mode 100644 index 000000000000..e18ce05efc07 --- /dev/null +++ b/qt/scientific_interfaces/Inelastic/Analysis/DataAnalysisTabFactory.cpp @@ -0,0 +1,72 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2023 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + +#include "DataAnalysisTabFactory.h" + +#include "ConvFitDataPresenter.h" +#include "FitTabConstants.h" +#include "FqFitDataPresenter.h" +#include "FqFitModel.h" +#include "FunctionBrowser/ConvFunctionModel.h" +#include "FunctionBrowser/ConvTemplateBrowser.h" +#include "FunctionBrowser/FqFunctionModel.h" +#include "FunctionBrowser/IqtFunctionModel.h" +#include "FunctionBrowser/IqtTemplateBrowser.h" +#include "FunctionBrowser/MSDFunctionModel.h" +#include "IndirectDataAnalysisTab.h" +#include "IndirectFitDataPresenter.h" +#include "IqtFitModel.h" +#include "MSDFitModel.h" + +namespace MantidQt::CustomInterfaces::IDA { + +DataAnalysisTabFactory::DataAnalysisTabFactory(QTabWidget *tabWidget) : m_tabWidget(tabWidget) {} + +IndirectDataAnalysisTab *DataAnalysisTabFactory::makeMSDFitTab(int const index) const { + auto tab = new IndirectDataAnalysisTab(MSDFit::TAB_NAME, MSDFit::HAS_RESOLUTION, m_tabWidget->widget(index)); + tab->setupFittingModel(); + tab->setupFitPropertyBrowser(MSDFit::HIDDEN_PROPS); + tab->setupFitDataView(); + tab->setupOutputOptionsPresenter(); + tab->setUpFitDataPresenter(); + tab->setupPlotView(); + return tab; +} + +IndirectDataAnalysisTab *DataAnalysisTabFactory::makeIqtFitTab(int const index) const { + auto tab = new IndirectDataAnalysisTab(IqtFit::TAB_NAME, IqtFit::HAS_RESOLUTION, m_tabWidget->widget(index)); + tab->setupFittingModel(); + tab->setupFitPropertyBrowser(IqtFit::HIDDEN_PROPS); + tab->setupFitDataView(); + tab->setupOutputOptionsPresenter(true); + tab->setUpFitDataPresenter(); + tab->setupPlotView(); + return tab; +} + +IndirectDataAnalysisTab *DataAnalysisTabFactory::makeConvFitTab(int const index) const { + auto tab = new IndirectDataAnalysisTab(ConvFit::TAB_NAME, ConvFit::HAS_RESOLUTION, m_tabWidget->widget(index)); + tab->setupFittingModel(); + tab->setupFitPropertyBrowser(ConvFit::HIDDEN_PROPS, true); + tab->setupFitDataView(); + tab->setupOutputOptionsPresenter(true); + tab->setUpFitDataPresenter(); + tab->setupPlotView(); + return tab; +} + +IndirectDataAnalysisTab *DataAnalysisTabFactory::makeFqFitTab(int const index) const { + auto tab = new IndirectDataAnalysisTab(FqFit::TAB_NAME, FqFit::HAS_RESOLUTION, m_tabWidget->widget(index)); + tab->setupFittingModel(); + tab->setupFitPropertyBrowser(FqFit::HIDDEN_PROPS); + tab->setupFitDataView(); + tab->setupOutputOptionsPresenter(); + tab->setUpFitDataPresenter(); + tab->setupPlotView(FqFit::X_BOUNDS); + return tab; +} + +} // namespace MantidQt::CustomInterfaces::IDA \ No newline at end of file diff --git a/qt/scientific_interfaces/Inelastic/Analysis/DataAnalysisTabFactory.h b/qt/scientific_interfaces/Inelastic/Analysis/DataAnalysisTabFactory.h new file mode 100644 index 000000000000..a74b3894eff3 --- /dev/null +++ b/qt/scientific_interfaces/Inelastic/Analysis/DataAnalysisTabFactory.h @@ -0,0 +1,27 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2023 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + +#pragma once + +#include + +namespace MantidQt::CustomInterfaces::IDA { + +class IndirectDataAnalysisTab; + +class DataAnalysisTabFactory { +public: + explicit DataAnalysisTabFactory(QTabWidget *tabWidget); + IndirectDataAnalysisTab *makeMSDFitTab(int const index) const; + IndirectDataAnalysisTab *makeIqtFitTab(int const index) const; + IndirectDataAnalysisTab *makeConvFitTab(int const index) const; + IndirectDataAnalysisTab *makeFqFitTab(int const index) const; + +private: + QTabWidget *m_tabWidget; +}; + +} // namespace MantidQt::CustomInterfaces::IDA \ No newline at end of file diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FQFitConstants.h b/qt/scientific_interfaces/Inelastic/Analysis/FQFitConstants.h deleted file mode 100644 index a6b0ef98cf32..000000000000 --- a/qt/scientific_interfaces/Inelastic/Analysis/FQFitConstants.h +++ /dev/null @@ -1,54 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2020 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#pragma once - -#include -#include -#include - -namespace MantidQt { -namespace CustomInterfaces { -namespace IDA { - -enum class DataType { - WIDTH, - EISF, - ALL, -}; - -static const std::map widthFits{ - {{"None", ""}, - {std::string("ChudleyElliot"), std::string("name=ChudleyElliot, Tau=1, L=1.5, constraints=(Tau>0, L>0)")}, - {std::string("HallRoss"), std::string("name=Hallross, Tau=1, L=0.2, constraints=(Tau>0, L>0)")}, - {std::string("FickDiffusion"), std::string("name=FickDiffusion, D=1, constraints=(D>0)")}, - {std::string("TeixeiraWater"), std::string("name=TeixeiraWater, Tau=1, L=1.5, constraints=(Tau>0, L>0)")}}}; - -static const std::map EISFFits{ - {{"None", ""}, - {std::string("EISFDiffCylinder"), - std::string("name=EISFDiffCylinder, A=1, R=1, L=2, constraints=(A>0, R>0, L>0)")}, - {std::string("EISFDiffSphere"), std::string("name=EISFDiffSphere, A=1, R=1, constraints=(A>0, R>0)")}, - {std::string("EISFDiffSphereAlkyl"), std::string("name=EISFDiffSphereAlkyl, A=1, Rmin=1, Rmax=2, " - "constraints=(A>0, Rmin>0, Rmax>0)")}}}; - -static const std::map AllFits{ - {{"None", ""}, - {std::string("ChudleyElliot"), std::string("name=ChudleyElliot, Tau=1, L=1.5, constraints=(Tau>0, L>0)")}, - {std::string("HallRoss"), std::string("name=Hallross, Tau=1, L=0.2, constraints=(Tau>0, L>0)")}, - {std::string("FickDiffusion"), std::string("name=FickDiffusion, D=1, constraints=(D>0)")}, - {std::string("TeixeiraWater"), std::string("name=TeixeiraWater, Tau=1, L=1.5, constraints=(Tau>0, L>0)")}, - {std::string("EISFDiffCylinder"), - std::string("name=EISFDiffCylinder, A=1, R=1, L=2, constraints=(A>0, R>0, L>0)")}, - {std::string("EISFDiffSphere"), std::string("name=EISFDiffSphere, A=1, R=1, constraints=(A>0, R>0)")}, - {std::string("EISFDiffSphereAlkyl"), std::string("name=EISFDiffSphereAlkyl, A=1, Rmin=1, Rmax=2, " - "constraints=(A>0, Rmin>0, Rmax>0)")}}}; - -static const std::unordered_map> availableFits{ - {{DataType::WIDTH, widthFits}, {DataType::EISF, EISFFits}, {DataType::ALL, AllFits}}}; -} // namespace IDA -} // namespace CustomInterfaces -} // namespace MantidQt diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FitTabConstants.h b/qt/scientific_interfaces/Inelastic/Analysis/FitTabConstants.h new file mode 100644 index 000000000000..d7e978fd9b31 --- /dev/null +++ b/qt/scientific_interfaces/Inelastic/Analysis/FitTabConstants.h @@ -0,0 +1,118 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2023 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + +#pragma once + +#include +#include +#include + +namespace MantidQt::CustomInterfaces::IDA { + +static const auto FUNCTION_STRINGS = + std::unordered_map({{"ExpDecay", "E"}, + {"StretchExp", "S"}, + {"Lorentzian", "L"}, + {"StretchedExpFT", "SFT"}, + {"TeixeiraWater", "TxWater"}, + {"TeixeiraWaterSQE", "TxWater"}, + {"FickDiffusionSQE", "FickDiff"}, + {"ChudleyElliotSQE", "ChudElliot"}, + {"HallRoss", "HallRoss"}, + {"HallRossSQE", "HallRoss"}, + {"DiffRotDiscreteCircle", "DC"}, + {"ElasticDiffRotDiscreteCircle", "EDC"}, + {"InelasticDiffRotDiscreteCircle", "IDC"}, + {"DiffSphere", "DS"}, + {"ElasticDiffSphere", "EDS"}, + {"InelasticDiffSphere", "IDS"}, + {"IsoRotDiff", "IRD"}, + {"ElasticIsoRotDiff", "EIRD"}, + {"InelasticIsoRotDiff", "IIRD"}, + {"MsdGauss", "Gauss"}, + {"MsdPeters", "Peters"}, + {"MsdYi", "Yi"}, + {"FickDiffusion", "FickDiffusion"}, + {"ChudleyElliot", "ChudleyElliot"}, + {"EISFDiffCylinder", "EISFDiffCylinder"}, + {"EISFDiffSphere", "EISFDiffSphere"}, + {"EISFDiffSphereAlkyl", "EISFDiffSphereAlkyl"}}); + +namespace MSDFit { +static const auto TAB_NAME = "MSDFit"; +static const auto HAS_RESOLUTION = false; +static const auto HIDDEN_PROPS = + std::vector({"CreateOutput", "LogValue", "PassWSIndexToFunction", "ConvolveMembers", + "OutputCompositeMembers", "OutputWorkspace", "Output", "PeakRadius", "PlotParameter"}); + +static const auto ALL_FITS = + std::map({{"None", ""}, + {"Gauss", "name=MsdGauss,Height=1,Msd=0.05,constraints=(Height>0, Msd>0)"}, + {"Peters", "name=MsdPeters,Height=1,Msd=0.05,Beta=1,constraints=(Height>0, " + "Msd>0, Beta>0)"}, + {"Yi", "name=MsdYi,Height=1,Msd=0.05,Sigma=1,constraints=(Height>0, Msd>0, " + "Sigma>0)"}}); +} // namespace MSDFit + +namespace IqtFit { +static const auto TAB_NAME = "IqtFit"; +static const auto HAS_RESOLUTION = false; +static const auto HIDDEN_PROPS = + std::vector({"CreateOutput", "LogValue", "PassWSIndexToFunction", "ConvolveMembers", + "OutputCompositeMembers", "OutputWorkspace", "Output", "PeakRadius", "PlotParameter"}); +} // namespace IqtFit + +namespace ConvFit { +static const auto TAB_NAME = "ConvFit"; +static const auto HAS_RESOLUTION = true; +static const auto HIDDEN_PROPS = std::vector( + {"CreateOutput", "LogValue", "PassWSIndexToFunction", "OutputWorkspace", "Output", "PeakRadius", "PlotParameter"}); + +} // namespace ConvFit + +namespace FqFit { +static const auto TAB_NAME = "FQFit"; +static const auto HAS_RESOLUTION = false; +static const auto HIDDEN_PROPS = + std::vector({"CreateOutput", "LogValue", "PassWSIndexToFunction", "ConvolveMembers", + "OutputCompositeMembers", "OutputWorkspace", "Output", "PeakRadius", "PlotParameter"}); +static const auto X_BOUNDS = std::pair{0.0, 2.0}; + +enum class DataType { + WIDTH, + EISF, + ALL, +}; + +static const auto WIDTH_FITS = std::map( + {{"None", ""}, + {"ChudleyElliot", "name=ChudleyElliot, Tau=1, L=1.5, constraints=(Tau>0, L>0)"}, + {"HallRoss", "name=Hallross, Tau=1, L=0.2, constraints=(Tau>0, L>0)"}, + {"FickDiffusion", "name=FickDiffusion, D=1, constraints=(D>0)"}, + {"TeixeiraWater", "name=TeixeiraWater, Tau=1, L=1.5, constraints=(Tau>0, L>0)"}}); + +static const auto EISF_FITS = std::map( + {{"None", ""}, + {"EISFDiffCylinder", "name=EISFDiffCylinder, A=1, R=1, L=2, constraints=(A>0, R>0, L>0)"}, + {"EISFDiffSphere", "name=EISFDiffSphere, A=1, R=1, constraints=(A>0, R>0)"}, + {"EISFDiffSphereAlkyl", "name=EISFDiffSphereAlkyl, A=1, Rmin=1, Rmax=2, constraints=(A>0, Rmin>0, Rmax>0)"}}); + +static const auto ALL_FITS = std::map( + {{"None", ""}, + {"ChudleyElliot", "name=ChudleyElliot, Tau=1, L=1.5, constraints=(Tau>0, L>0)"}, + {"HallRoss", "name=Hallross, Tau=1, L=0.2, constraints=(Tau>0, L>0)"}, + {"FickDiffusion", "name=FickDiffusion, D=1, constraints=(D>0)"}, + {"TeixeiraWater", "name=TeixeiraWater, Tau=1, L=1.5, constraints=(Tau>0, L>0)"}, + {"EISFDiffCylinder", "name=EISFDiffCylinder, A=1, R=1, L=2, constraints=(A>0, R>0, L>0)"}, + {"EISFDiffSphere", "name=EISFDiffSphere, A=1, R=1, constraints=(A>0, R>0)"}, + {"EISFDiffSphereAlkyl", "name=EISFDiffSphereAlkyl, A=1, Rmin=1, Rmax=2, constraints=(A>0, Rmin>0, Rmax>0)"}}); + +static const std::unordered_map> availableFits{ + {{DataType::WIDTH, WIDTH_FITS}, {DataType::EISF, EISF_FITS}, {DataType::ALL, ALL_FITS}}}; + +} // namespace FqFit + +} // namespace MantidQt::CustomInterfaces::IDA diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FqFitAddWorkspaceDialog.h b/qt/scientific_interfaces/Inelastic/Analysis/FqFitAddWorkspaceDialog.h index 0a75d3b0cfa0..1d802e4b65d4 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FqFitAddWorkspaceDialog.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FqFitAddWorkspaceDialog.h @@ -6,6 +6,7 @@ // SPDX - License - Identifier: GPL - 3.0 + #pragma once +#include "DllConfig.h" #include "IAddWorkspaceDialog.h" #include "ui_FqFitAddWorkspaceDialog.h" @@ -13,7 +14,7 @@ namespace MantidQt { namespace CustomInterfaces { namespace IDA { -class FqFitAddWorkspaceDialog : public IAddWorkspaceDialog { +class MANTIDQT_INELASTIC_DLL FqFitAddWorkspaceDialog : public IAddWorkspaceDialog { Q_OBJECT public: explicit FqFitAddWorkspaceDialog(QWidget *parent); diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FqFitDataPresenter.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FqFitDataPresenter.cpp index b39b807ee811..2e9f4411afbc 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FqFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/FqFitDataPresenter.cpp @@ -197,14 +197,30 @@ boost::optional> getParameterSpectrum(const FqFitParame namespace MantidQt::CustomInterfaces::IDA { -FqFitDataPresenter::FqFitDataPresenter(IIndirectFitDataModel *model, IIndirectFitDataView *view, - IFQFitObserver *SingleFunctionTemplateBrowser) +FqFitDataPresenter::FqFitDataPresenter(IIndirectFitDataModel *model, IIndirectFitDataView *view) : IndirectFitDataPresenter(model, view), m_activeParameterType("Width"), m_activeWorkspaceID(WorkspaceID{0}), m_adsInstance(Mantid::API::AnalysisDataService::Instance()) { connect(this, SIGNAL(requestedAddWorkspaceDialog()), this, SLOT(updateActiveWorkspaceID())); +} + +bool FqFitDataPresenter::addWorkspaceFromDialog(IAddWorkspaceDialog const *dialog) { + if (const auto fqFitDialog = dynamic_cast(dialog)) { + addWorkspace(fqFitDialog->workspaceName(), fqFitDialog->parameterType(), fqFitDialog->parameterNameIndex()); + setActiveWorkspaceIDToCurrentWorkspace(fqFitDialog); + + auto const parameterIndex = fqFitDialog->parameterNameIndex(); + if (parameterIndex < 0) { + throw std::runtime_error("No valid parameter was selected."); + } else if (fqFitDialog->parameterType() == "Width") { + setActiveWidth(static_cast(parameterIndex), m_activeWorkspaceID, false); + } else { + setActiveEISF(static_cast(parameterIndex), m_activeWorkspaceID, false); + } - m_notifier = Notifier(); - m_notifier.subscribe(SingleFunctionTemplateBrowser); + updateActiveWorkspaceID(getNumberOfWorkspaces()); + return true; + } + return false; } void FqFitDataPresenter::addWorkspace(const std::string &workspaceName, const std::string ¶mType, diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FqFitDataPresenter.h b/qt/scientific_interfaces/Inelastic/Analysis/FqFitDataPresenter.h index c365e196ec98..2b4545db103b 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FqFitDataPresenter.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FqFitDataPresenter.h @@ -9,7 +9,6 @@ #include "FqFitAddWorkspaceDialog.h" #include "FqFitDataView.h" #include "FunctionBrowser/SingleFunctionTemplateBrowser.h" -#include "IFQFitObserver.h" #include "IndirectFitDataPresenter.h" #include "Notifier.h" @@ -32,8 +31,8 @@ namespace IDA { class MANTIDQT_INELASTIC_DLL FqFitDataPresenter : public IndirectFitDataPresenter { Q_OBJECT public: - FqFitDataPresenter(IIndirectFitDataModel *model, IIndirectFitDataView *view, - IFQFitObserver *SingleFunctionTemplateBrowser); + FqFitDataPresenter(IIndirectFitDataModel *model, IIndirectFitDataView *view); + bool addWorkspaceFromDialog(IAddWorkspaceDialog const *dialog) override; void addWorkspace(const std::string &workspaceName, const std::string ¶mType, const int &spectrum_index) override; void setActiveWidth(std::size_t widthIndex, WorkspaceID dataIndex, bool single = true) override; void setActiveEISF(std::size_t eisfIndex, WorkspaceID dataIndex, bool single = true) override; @@ -61,7 +60,6 @@ private slots: std::string m_activeParameterType; WorkspaceID m_activeWorkspaceID; - Notifier m_notifier; Mantid::API::AnalysisDataServiceImpl &m_adsInstance; }; diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvFunctionModel.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvFunctionModel.cpp index 876477c338f9..2e77b8dbb06f 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvFunctionModel.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvFunctionModel.cpp @@ -246,6 +246,11 @@ void ConvFunctionModel::removeBackground() { bool ConvFunctionModel::hasBackground() const { return m_backgroundType != BackgroundType::None; } +EstimationDataSelector ConvFunctionModel::getEstimationDataSelector() const { + return [](const Mantid::MantidVec &, const Mantid::MantidVec &, + const std::pair) -> DataForParameterEstimation { return DataForParameterEstimation{}; }; +} + void ConvFunctionModel::updateParameterEstimationData(DataForParameterEstimationCollection &&data) { m_estimationData = std::move(data); } diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvFunctionModel.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvFunctionModel.h index 0c5c08b96666..db2c5bc74cd7 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvFunctionModel.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvFunctionModel.h @@ -86,6 +86,7 @@ class MANTIDQT_INELASTIC_DLL ConvFunctionModel : public IFunctionModel { void setBackground(BackgroundType bgType); void removeBackground(); bool hasBackground() const; + EstimationDataSelector getEstimationDataSelector() const; void updateParameterEstimationData(DataForParameterEstimationCollection &&data); void setResolution(const std::vector> &fitResolutions); void setQValues(const std::vector &qValues); diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplateBrowser.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplateBrowser.cpp index 14b87ebdc0c2..4bdcbb0f4c40 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplateBrowser.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplateBrowser.cpp @@ -39,7 +39,8 @@ class ScopedFalse { } // namespace -ConvTemplateBrowser::ConvTemplateBrowser(QWidget *parent) : FunctionTemplateBrowser(parent), m_presenter(this) { +ConvTemplateBrowser::ConvTemplateBrowser(std::unique_ptr functionModel, QWidget *parent) + : FunctionTemplateBrowser(parent), m_presenter(this, std::move(functionModel)) { m_templateSubTypes.emplace_back(std::make_unique()); m_templateSubTypes.emplace_back(std::make_unique()); m_templateSubTypes.emplace_back(std::make_unique()); @@ -323,6 +324,10 @@ void ConvTemplateBrowser::setParameterValueQuiet(ParamID id, double value, doubl m_parameterManager->setError(prop, error); } +EstimationDataSelector ConvTemplateBrowser::getEstimationDataSelector() const { + return m_presenter.getEstimationDataSelector(); +} + void ConvTemplateBrowser::updateParameterEstimationData(DataForParameterEstimationCollection &&) {} void ConvTemplateBrowser::estimateFunctionParameters() {} diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplateBrowser.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplateBrowser.h index f70db9cd3490..4f6684d72f5e 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplateBrowser.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplateBrowser.h @@ -29,7 +29,7 @@ using namespace ConvTypes; class MANTIDQT_INELASTIC_DLL ConvTemplateBrowser : public FunctionTemplateBrowser { Q_OBJECT public: - explicit ConvTemplateBrowser(QWidget *parent = nullptr); + explicit ConvTemplateBrowser(std::unique_ptr functionModel, QWidget *parent = nullptr); void setFunction(const QString &funStr) override; IFunction_sptr getGlobalFunction() const override; IFunction_sptr getFunction() const override; @@ -47,6 +47,7 @@ class MANTIDQT_INELASTIC_DLL ConvTemplateBrowser : public FunctionTemplateBrowse void updateParameterNames(const QMap ¶meterNames) override; void setErrorsEnabled(bool enabled) override; void clear() override; + EstimationDataSelector getEstimationDataSelector() const override; void updateParameterEstimationData(DataForParameterEstimationCollection &&data) override; void estimateFunctionParameters() override; diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplatePresenter.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplatePresenter.cpp index 0aab103dfa04..7cede1c0bdd9 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplatePresenter.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplatePresenter.cpp @@ -31,7 +31,9 @@ using namespace MantidWidgets; * Constructor * @param parent :: The parent widget. */ -ConvTemplatePresenter::ConvTemplatePresenter(ConvTemplateBrowser *view) : QObject(view), m_view(view) { +ConvTemplatePresenter::ConvTemplatePresenter(ConvTemplateBrowser *view, + std::unique_ptr functionModel) + : QObject(view), m_view(view), m_model(std::move(functionModel)) { connect(m_view, SIGNAL(localParameterButtonClicked(const QString &)), this, SLOT(editLocalParameter(const QString &))); connect(m_view, SIGNAL(parameterValueChanged(const QString &, double)), this, @@ -44,11 +46,11 @@ ConvTemplatePresenter::ConvTemplatePresenter(ConvTemplateBrowser *view) : QObjec // itself due to an internal timer occurring within the class void ConvTemplatePresenter::setSubType(size_t subTypeIndex, int typeIndex) { if (subTypeIndex == SubTypeIndex::Fit) { - m_model.setFitType(static_cast(typeIndex)); + m_model->setFitType(static_cast(typeIndex)); } else if (subTypeIndex == SubTypeIndex::Lorentzian) { - m_model.setLorentzianType(static_cast(typeIndex)); + m_model->setLorentzianType(static_cast(typeIndex)); } else { - m_model.setBackground(static_cast(typeIndex)); + m_model->setBackground(static_cast(typeIndex)); } m_view->setSubType(subTypeIndex, typeIndex); setErrorsEnabled(false); @@ -58,9 +60,9 @@ void ConvTemplatePresenter::setSubType(size_t subTypeIndex, int typeIndex) { } void ConvTemplatePresenter::setDeltaFunction(bool on) { - if (on == m_model.hasDeltaFunction()) + if (on == m_model->hasDeltaFunction()) return; - m_model.setDeltaFunction(on); + m_model->setDeltaFunction(on); if (on) m_view->addDeltaFunction(); else @@ -73,9 +75,9 @@ void ConvTemplatePresenter::setDeltaFunction(bool on) { } void ConvTemplatePresenter::setTempCorrection(bool on) { - if (on == m_model.hasTempCorrection()) + if (on == m_model->hasTempCorrection()) return; - double temp = m_model.getTempValue(); + double temp = m_model->getTempValue(); if (on) { bool ok; temp = QInputDialog::getDouble(m_view, "Temperature", "Set Temperature", temp, 0.0, @@ -83,7 +85,7 @@ void ConvTemplatePresenter::setTempCorrection(bool on) { if (!ok) return; } - m_model.setTempCorrection(on, temp); + m_model->setTempCorrection(on, temp); if (on) m_view->addTempCorrection(temp); else @@ -95,22 +97,22 @@ void ConvTemplatePresenter::setTempCorrection(bool on) { emit functionStructureChanged(); } -void ConvTemplatePresenter::setNumberOfDatasets(int n) { m_model.setNumberDomains(n); } +void ConvTemplatePresenter::setNumberOfDatasets(int n) { m_model->setNumberDomains(n); } -int ConvTemplatePresenter::getNumberOfDatasets() const { return m_model.getNumberDomains(); } +int ConvTemplatePresenter::getNumberOfDatasets() const { return m_model->getNumberDomains(); } void ConvTemplatePresenter::setFunction(const QString &funStr) { - m_model.setFunctionString(funStr); + m_model->setFunctionString(funStr); - m_view->updateTemperatureCorrectionAndDelta(m_model.hasTempCorrection(), m_model.hasDeltaFunction()); + m_view->updateTemperatureCorrectionAndDelta(m_model->hasTempCorrection(), m_model->hasDeltaFunction()); - m_view->setSubType(SubTypeIndex::Lorentzian, static_cast(m_model.getLorentzianType())); - m_view->setSubType(SubTypeIndex::Fit, static_cast(m_model.getFitType())); - m_view->setSubType(SubTypeIndex::Background, static_cast(m_model.getBackgroundType())); + m_view->setSubType(SubTypeIndex::Lorentzian, static_cast(m_model->getLorentzianType())); + m_view->setSubType(SubTypeIndex::Fit, static_cast(m_model->getFitType())); + m_view->setSubType(SubTypeIndex::Background, static_cast(m_model->getBackgroundType())); - m_view->setInt(SubTypeIndex::Lorentzian, static_cast(m_model.getLorentzianType())); - m_view->setEnum(SubTypeIndex::Fit, static_cast(m_model.getFitType())); - m_view->setEnum(SubTypeIndex::Background, static_cast(m_model.getBackgroundType())); + m_view->setInt(SubTypeIndex::Lorentzian, static_cast(m_model->getLorentzianType())); + m_view->setEnum(SubTypeIndex::Fit, static_cast(m_model->getFitType())); + m_view->setEnum(SubTypeIndex::Background, static_cast(m_model->getBackgroundType())); setErrorsEnabled(false); updateViewParameterNames(); @@ -118,20 +120,20 @@ void ConvTemplatePresenter::setFunction(const QString &funStr) { emit functionStructureChanged(); } -int ConvTemplatePresenter::getCurrentDataset() { return m_model.currentDomainIndex(); } +int ConvTemplatePresenter::getCurrentDataset() { return m_model->currentDomainIndex(); } -IFunction_sptr ConvTemplatePresenter::getGlobalFunction() const { return m_model.getFitFunction(); } +IFunction_sptr ConvTemplatePresenter::getGlobalFunction() const { return m_model->getFitFunction(); } -IFunction_sptr ConvTemplatePresenter::getFunction() const { return m_model.getCurrentFunction(); } +IFunction_sptr ConvTemplatePresenter::getFunction() const { return m_model->getCurrentFunction(); } -QStringList ConvTemplatePresenter::getGlobalParameters() const { return m_model.getGlobalParameters(); } +QStringList ConvTemplatePresenter::getGlobalParameters() const { return m_model->getGlobalParameters(); } -QStringList ConvTemplatePresenter::getLocalParameters() const { return m_model.getLocalParameters(); } +QStringList ConvTemplatePresenter::getLocalParameters() const { return m_model->getLocalParameters(); } -void ConvTemplatePresenter::setGlobalParameters(const QStringList &globals) { m_model.setGlobalParameters(globals); } +void ConvTemplatePresenter::setGlobalParameters(const QStringList &globals) { m_model->setGlobalParameters(globals); } void ConvTemplatePresenter::setGlobal(const QString &parName, bool on) { - auto globals = m_model.getGlobalParameters(); + auto globals = m_model->getGlobalParameters(); if (on) { if (!globals.contains(parName)) { globals.push_back(parName); @@ -143,80 +145,80 @@ void ConvTemplatePresenter::setGlobal(const QString &parName, bool on) { } void ConvTemplatePresenter::updateMultiDatasetParameters(const IFunction &fun) { - m_model.updateMultiDatasetParameters(fun); + m_model->updateMultiDatasetParameters(fun); updateViewParameters(); } void ConvTemplatePresenter::updateMultiDatasetParameters(const ITableWorkspace ¶mTable) { - m_model.updateMultiDatasetParameters(paramTable); + m_model->updateMultiDatasetParameters(paramTable); updateViewParameters(); } void ConvTemplatePresenter::updateParameters(const IFunction &fun) { - m_model.updateParameters(fun); + m_model->updateParameters(fun); updateViewParameters(); } void ConvTemplatePresenter::setCurrentDataset(int i) { - m_model.setCurrentDomainIndex(i); + m_model->setCurrentDomainIndex(i); updateViewParameters(); } -void ConvTemplatePresenter::setDatasets(const QList &datasets) { m_model.setDatasets(datasets); } +void ConvTemplatePresenter::setDatasets(const QList &datasets) { m_model->setDatasets(datasets); } void ConvTemplatePresenter::setBackgroundA0(double value) { - m_model.setBackgroundA0(value); + m_model->setBackgroundA0(value); updateViewParameters(); } -void ConvTemplatePresenter::setQValues(const std::vector &qValues) { m_model.setQValues(qValues); } +void ConvTemplatePresenter::setQValues(const std::vector &qValues) { m_model->setQValues(qValues); } void ConvTemplatePresenter::setErrorsEnabled(bool enabled) { m_view->setErrorsEnabled(enabled); } void ConvTemplatePresenter::setResolution(const std::vector> &fitResolutions) { - m_model.setResolution(fitResolutions); + m_model->setResolution(fitResolutions); } void ConvTemplatePresenter::updateViewParameters() { - auto values = m_model.getCurrentValues(); - auto errors = m_model.getCurrentErrors(); + auto values = m_model->getCurrentValues(); + auto errors = m_model->getCurrentErrors(); for (auto const id : values.keys()) { m_view->setParameterValueQuiet(id, values[id], errors[id]); } } -QStringList ConvTemplatePresenter::getDatasetNames() const { return m_model.getDatasetNames(); } +QStringList ConvTemplatePresenter::getDatasetNames() const { return m_model->getDatasetNames(); } -QStringList ConvTemplatePresenter::getDatasetDomainNames() const { return m_model.getDatasetDomainNames(); } +QStringList ConvTemplatePresenter::getDatasetDomainNames() const { return m_model->getDatasetDomainNames(); } double ConvTemplatePresenter::getLocalParameterValue(const QString &parName, int i) const { - return m_model.getLocalParameterValue(parName, i); + return m_model->getLocalParameterValue(parName, i); } bool ConvTemplatePresenter::isLocalParameterFixed(const QString &parName, int i) const { - return m_model.isLocalParameterFixed(parName, i); + return m_model->isLocalParameterFixed(parName, i); } QString ConvTemplatePresenter::getLocalParameterTie(const QString &parName, int i) const { - return m_model.getLocalParameterTie(parName, i); + return m_model->getLocalParameterTie(parName, i); } QString ConvTemplatePresenter::getLocalParameterConstraint(const QString &parName, int i) const { - return m_model.getLocalParameterConstraint(parName, i); + return m_model->getLocalParameterConstraint(parName, i); } void ConvTemplatePresenter::setLocalParameterValue(const QString &parName, int i, double value) { - m_model.setLocalParameterValue(parName, i, value); + m_model->setLocalParameterValue(parName, i, value); } void ConvTemplatePresenter::setLocalParameterTie(const QString &parName, int i, const QString &tie) { - m_model.setLocalParameterTie(parName, i, tie); + m_model->setLocalParameterTie(parName, i, tie); } -void ConvTemplatePresenter::updateViewParameterNames() { m_view->updateParameterNames(m_model.getParameterNameMap()); } +void ConvTemplatePresenter::updateViewParameterNames() { m_view->updateParameterNames(m_model->getParameterNameMap()); } void ConvTemplatePresenter::setLocalParameterFixed(const QString &parName, int i, bool fixed) { - m_model.setLocalParameterFixed(parName, i, fixed); + m_model->setLocalParameterFixed(parName, i, fixed); } void ConvTemplatePresenter::editLocalParameter(const QString &parName) { @@ -261,7 +263,7 @@ void ConvTemplatePresenter::editLocalParameterFinish(int result) { } else { setLocalParameterTie(parName, i, ""); } - m_model.setLocalParameterConstraint(parName, i, constraints[i]); + m_model->setLocalParameterConstraint(parName, i, constraints[i]); } } m_editLocalParameterDialog = nullptr; @@ -272,14 +274,14 @@ void ConvTemplatePresenter::editLocalParameterFinish(int result) { void ConvTemplatePresenter::viewChangedParameterValue(const QString &parName, double value) { if (parName.isEmpty()) return; - if (m_model.isGlobal(parName)) { + if (m_model->isGlobal(parName)) { auto const n = getNumberOfDatasets(); for (int i = 0; i < n; ++i) { setLocalParameterValue(parName, i, value); } } else { - auto const i = m_model.currentDomainIndex(); - auto const oldValue = m_model.getLocalParameterValue(parName, i); + auto const i = m_model->currentDomainIndex(); + auto const oldValue = m_model->getLocalParameterValue(parName, i); if (fabs(value - oldValue) > 1e-6) { setErrorsEnabled(false); } @@ -288,4 +290,8 @@ void ConvTemplatePresenter::viewChangedParameterValue(const QString &parName, do emit functionStructureChanged(); } +EstimationDataSelector ConvTemplatePresenter::getEstimationDataSelector() const { + return m_model->getEstimationDataSelector(); +} + } // namespace MantidQt::CustomInterfaces::IDA diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplatePresenter.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplatePresenter.h index af620f1ee2bb..a5e544e944f1 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplatePresenter.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/ConvTemplatePresenter.h @@ -31,7 +31,7 @@ class ConvTemplateBrowser; class MANTIDQT_INELASTIC_DLL ConvTemplatePresenter : public QObject { Q_OBJECT public: - explicit ConvTemplatePresenter(ConvTemplateBrowser *view); + explicit ConvTemplatePresenter(ConvTemplateBrowser *view, std::unique_ptr functionModel); void setSubType(size_t subTypeIndex, int typeIndex); void setDeltaFunction(bool); void setTempCorrection(bool); @@ -54,6 +54,7 @@ class MANTIDQT_INELASTIC_DLL ConvTemplatePresenter : public QObject { void setResolution(const std::vector> &fitResolutions); void setBackgroundA0(double value); void setQValues(const std::vector &qValues); + EstimationDataSelector getEstimationDataSelector() const; signals: void functionStructureChanged(); @@ -76,7 +77,7 @@ private slots: void setLocalParameterTie(const QString &parName, int i, const QString &tie); void updateViewParameterNames(); ConvTemplateBrowser *m_view; - ConvFunctionModel m_model; + std::unique_ptr m_model; EditLocalParameterDialog *m_editLocalParameterDialog; }; diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/FqFunctionModel.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/FqFunctionModel.cpp new file mode 100644 index 000000000000..e11fc54c4cfd --- /dev/null +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/FqFunctionModel.cpp @@ -0,0 +1,56 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2023 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + +#include "FqFunctionModel.h" + +#include "Analysis/FitTabConstants.h" +#include "Analysis/IDAFunctionParameterEstimation.h" +#include "MantidKernel/PhysicalConstants.h" + +#include + +namespace { +using namespace MantidQt::CustomInterfaces::IDA; + +constexpr double HBAR = Mantid::PhysicalConstants::h_bar / Mantid::PhysicalConstants::meV * 1e12; + +auto const chudleyElliot = [](Mantid::MantidVec const &x, Mantid::MantidVec const &y) { + double L = 1.5; + return std::unordered_map{{"L", L}, {"Tau", (HBAR / y[1]) * (1 - sin(x[1] * L) / (L * x[1]))}}; +}; + +auto const hallRoss = [](Mantid::MantidVec const &x, Mantid::MantidVec const &y) { + double L = 0.2; + return std::unordered_map{{"L", L}, + {"Tau", (HBAR / y[1]) * (1 - exp((-x[1] * x[1] * L * L) / 2))}}; +}; + +auto const teixeiraWater = [](Mantid::MantidVec const &x, Mantid::MantidVec const &y) { + double L = 1.5; + double QL = x[1] * L; + return std::unordered_map{{"L", L}, {"Tau", (HBAR / y[1]) * ((QL * QL) / (6 + QL * QL))}}; +}; + +auto const fickDiffusion = [](Mantid::MantidVec const &x, Mantid::MantidVec const &y) { + return std::unordered_map{{"D", y[1] / (x[1] * x[1])}}; +}; + +auto const estimators = std::unordered_map{ + {"ChudleyElliot", chudleyElliot}, + {"HallRoss", hallRoss}, + {"TeixeiraWater", teixeiraWater}, + {"FickDiffusion", fickDiffusion}}; + +} // namespace + +namespace MantidQt::CustomInterfaces::IDA { + +FqFunctionModel::FqFunctionModel() + : SingleFunctionTemplateModel(std::make_unique(estimators)) { + updateAvailableFunctions(FqFit::ALL_FITS); +} + +} // namespace MantidQt::CustomInterfaces::IDA \ No newline at end of file diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/FqFunctionModel.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/FqFunctionModel.h new file mode 100644 index 000000000000..6b9e03288323 --- /dev/null +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/FqFunctionModel.h @@ -0,0 +1,23 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2023 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + +#pragma once + +#include "Analysis/FunctionBrowser/SingleFunctionTemplateModel.h" + +namespace MantidQt { +namespace CustomInterfaces { +namespace IDA { + +class FqFunctionModel : public SingleFunctionTemplateModel { + +public: + FqFunctionModel(); +}; + +} // namespace IDA +} // namespace CustomInterfaces +} // namespace MantidQt \ No newline at end of file diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtFunctionModel.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtFunctionModel.cpp index 918b0cd29199..e9b7ba3fb385 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtFunctionModel.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtFunctionModel.cpp @@ -218,6 +218,17 @@ void IqtFunctionModel::tieIntensities(bool on) { } } +EstimationDataSelector IqtFunctionModel::getEstimationDataSelector() const { + return [](const Mantid::MantidVec &x, const Mantid::MantidVec &y, + const std::pair range) -> DataForParameterEstimation { + (void)range; + size_t const n = 4; + if (y.size() < n + 1) + return DataForParameterEstimation{{}, {}}; + return DataForParameterEstimation{{x[0], x[n]}, {y[0], y[n]}}; + }; +} + void IqtFunctionModel::updateParameterEstimationData(DataForParameterEstimationCollection &&data) { m_estimationData = std::move(data); } diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtFunctionModel.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtFunctionModel.h index 97617bb58a76..16d1e5417b3d 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtFunctionModel.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtFunctionModel.h @@ -77,6 +77,7 @@ class MANTIDQT_INELASTIC_DLL IqtFunctionModel : public IFunctionModel { void removeBackground(); bool hasBackground() const; void tieIntensities(bool on); + EstimationDataSelector getEstimationDataSelector() const; void updateParameterEstimationData(DataForParameterEstimationCollection &&data); enum class ParamID { diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplateBrowser.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplateBrowser.cpp index 960476329044..2903cfa11c8b 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplateBrowser.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplateBrowser.cpp @@ -34,7 +34,8 @@ namespace MantidQt::CustomInterfaces::IDA { * Constructor * @param parent :: The parent widget. */ -IqtTemplateBrowser::IqtTemplateBrowser(QWidget *parent) : FunctionTemplateBrowser(parent), m_presenter(this) { +IqtTemplateBrowser::IqtTemplateBrowser(std::unique_ptr functionModel, QWidget *parent) + : FunctionTemplateBrowser(parent), m_presenter(this, std::move(functionModel)) { connect(&m_presenter, SIGNAL(functionStructureChanged()), this, SIGNAL(functionStructureChanged())); } @@ -294,6 +295,10 @@ void IqtTemplateBrowser::clear() { removeExponentialOne(); } +EstimationDataSelector IqtTemplateBrowser::getEstimationDataSelector() const { + return m_presenter.getEstimationDataSelector(); +} + void IqtTemplateBrowser::updateParameterEstimationData(DataForParameterEstimationCollection &&data) { m_presenter.updateParameterEstimationData(std::move(data)); } diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplateBrowser.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplateBrowser.h index f818dbe0078d..bf32c3643157 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplateBrowser.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplateBrowser.h @@ -27,7 +27,7 @@ namespace IDA { class MANTIDQT_INELASTIC_DLL IqtTemplateBrowser : public FunctionTemplateBrowser { Q_OBJECT public: - explicit IqtTemplateBrowser(QWidget *parent = nullptr); + explicit IqtTemplateBrowser(std::unique_ptr functionModel, QWidget *parent = nullptr); void addExponentialOne(); void removeExponentialOne(); void addExponentialTwo(); @@ -64,6 +64,7 @@ class MANTIDQT_INELASTIC_DLL IqtTemplateBrowser : public FunctionTemplateBrowser void updateParameterDescriptions(const QMap ¶meterNames); // override; void setErrorsEnabled(bool enabled) override; void clear() override; + EstimationDataSelector getEstimationDataSelector() const override; void updateParameterEstimationData(DataForParameterEstimationCollection &&data) override; void estimateFunctionParameters() override; void setBackgroundA0(double value) override; diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplatePresenter.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplatePresenter.cpp index 98cd85743f24..9d474c225921 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplatePresenter.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplatePresenter.cpp @@ -18,7 +18,8 @@ using namespace MantidWidgets; * Constructor * @param parent :: The parent widget. */ -IqtTemplatePresenter::IqtTemplatePresenter(IqtTemplateBrowser *view) : QObject(view), m_view(view) { +IqtTemplatePresenter::IqtTemplatePresenter(IqtTemplateBrowser *view, std::unique_ptr functionModel) + : QObject(view), m_view(view), m_model(std::move(functionModel)) { connect(m_view, SIGNAL(localParameterButtonClicked(const QString &)), this, SLOT(editLocalParameter(const QString &))); connect(m_view, SIGNAL(parameterValueChanged(const QString &, double)), this, @@ -32,7 +33,7 @@ void IqtTemplatePresenter::setNumberOfExponentials(int n) { if (n > 2) { throw std::logic_error("The number of exponents is limited to 2."); } - auto nCurrent = m_model.getNumberOfExponentials(); + auto nCurrent = m_model->getNumberOfExponentials(); if (n == 0) { if (nCurrent == 2) { m_view->removeExponentialTwo(); @@ -61,21 +62,21 @@ void IqtTemplatePresenter::setNumberOfExponentials(int n) { } } assert(nCurrent == n); - m_model.setNumberOfExponentials(n); + m_model->setNumberOfExponentials(n); setErrorsEnabled(false); updateView(); emit functionStructureChanged(); } void IqtTemplatePresenter::setStretchExponential(bool on) { - if (on == m_model.hasStretchExponential()) + if (on == m_model->hasStretchExponential()) return; if (on) { m_view->addStretchExponential(); } else { m_view->removeStretchExponential(); } - m_model.setStretchExponential(on); + m_model->setStretchExponential(on); setErrorsEnabled(false); updateView(); emit functionStructureChanged(); @@ -84,10 +85,10 @@ void IqtTemplatePresenter::setStretchExponential(bool on) { void IqtTemplatePresenter::setBackground(const QString &name) { if (name == "None") { m_view->removeBackground(); - m_model.removeBackground(); + m_model->removeBackground(); } else if (name == "FlatBackground") { m_view->addFlatBackground(); - m_model.setBackground(name); + m_model->setBackground(name); } else { throw std::logic_error("Browser doesn't support background " + name.toStdString()); } @@ -96,21 +97,21 @@ void IqtTemplatePresenter::setBackground(const QString &name) { emit functionStructureChanged(); } -void IqtTemplatePresenter::setNumberOfDatasets(int n) { m_model.setNumberDomains(n); } +void IqtTemplatePresenter::setNumberOfDatasets(int n) { m_model->setNumberDomains(n); } -int IqtTemplatePresenter::getNumberOfDatasets() const { return m_model.getNumberDomains(); } +int IqtTemplatePresenter::getNumberOfDatasets() const { return m_model->getNumberDomains(); } void IqtTemplatePresenter::setFunction(const QString &funStr) { - m_model.setFunctionString(funStr); + m_model->setFunctionString(funStr); m_view->clear(); setErrorsEnabled(false); - if (m_model.hasBackground()) { + if (m_model->hasBackground()) { m_view->addFlatBackground(); } - if (m_model.hasStretchExponential()) { + if (m_model->hasStretchExponential()) { m_view->addStretchExponential(); } - auto const nExp = m_model.getNumberOfExponentials(); + auto const nExp = m_model->getNumberOfExponentials(); if (nExp > 0) { m_view->addExponentialOne(); } @@ -121,50 +122,50 @@ void IqtTemplatePresenter::setFunction(const QString &funStr) { emit functionStructureChanged(); } -IFunction_sptr IqtTemplatePresenter::getGlobalFunction() const { return m_model.getFitFunction(); } +IFunction_sptr IqtTemplatePresenter::getGlobalFunction() const { return m_model->getFitFunction(); } -IFunction_sptr IqtTemplatePresenter::getFunction() const { return m_model.getCurrentFunction(); } +IFunction_sptr IqtTemplatePresenter::getFunction() const { return m_model->getCurrentFunction(); } -QStringList IqtTemplatePresenter::getGlobalParameters() const { return m_model.getGlobalParameters(); } +QStringList IqtTemplatePresenter::getGlobalParameters() const { return m_model->getGlobalParameters(); } -QStringList IqtTemplatePresenter::getLocalParameters() const { return m_model.getLocalParameters(); } +QStringList IqtTemplatePresenter::getLocalParameters() const { return m_model->getLocalParameters(); } void IqtTemplatePresenter::setGlobalParameters(const QStringList &globals) { - m_model.setGlobalParameters(globals); + m_model->setGlobalParameters(globals); m_view->setGlobalParametersQuiet(globals); } void IqtTemplatePresenter::setGlobal(const QString &parName, bool on) { - m_model.setGlobal(parName, on); - m_view->setGlobalParametersQuiet(m_model.getGlobalParameters()); + m_model->setGlobal(parName, on); + m_view->setGlobalParametersQuiet(m_model->getGlobalParameters()); } void IqtTemplatePresenter::updateMultiDatasetParameters(const IFunction &fun) { - m_model.updateMultiDatasetParameters(fun); + m_model->updateMultiDatasetParameters(fun); updateViewParameters(); } void IqtTemplatePresenter::updateMultiDatasetParameters(const ITableWorkspace ¶mTable) { - m_model.updateMultiDatasetParameters(paramTable); + m_model->updateMultiDatasetParameters(paramTable); updateViewParameters(); } void IqtTemplatePresenter::updateParameters(const IFunction &fun) { - m_model.updateParameters(fun); + m_model->updateParameters(fun); updateViewParameters(); } void IqtTemplatePresenter::setCurrentDataset(int i) { - m_model.setCurrentDomainIndex(i); + m_model->setCurrentDomainIndex(i); updateViewParameters(); } -int IqtTemplatePresenter::getCurrentDataset() { return m_model.currentDomainIndex(); } +int IqtTemplatePresenter::getCurrentDataset() { return m_model->currentDomainIndex(); } -void IqtTemplatePresenter::setDatasets(const QList &datasets) { m_model.setDatasets(datasets); } +void IqtTemplatePresenter::setDatasets(const QList &datasets) { m_model->setDatasets(datasets); } void IqtTemplatePresenter::setViewParameterDescriptions() { - m_view->updateParameterDescriptions(m_model.getParameterDescriptionMap()); + m_view->updateParameterDescriptions(m_model->getParameterDescriptionMap()); } void IqtTemplatePresenter::setErrorsEnabled(bool enabled) { m_view->setErrorsEnabled(enabled); } @@ -172,20 +173,24 @@ void IqtTemplatePresenter::setErrorsEnabled(bool enabled) { m_view->setErrorsEna void IqtTemplatePresenter::tieIntensities(bool on) { if (on && !canTieIntensities()) return; - m_model.tieIntensities(on); + m_model->tieIntensities(on); emit functionStructureChanged(); } bool IqtTemplatePresenter::canTieIntensities() const { - return (m_model.hasStretchExponential() || m_model.getNumberOfExponentials() > 0) && m_model.hasBackground(); + return (m_model->hasStretchExponential() || m_model->getNumberOfExponentials() > 0) && m_model->hasBackground(); +} + +EstimationDataSelector IqtTemplatePresenter::getEstimationDataSelector() const { + return m_model->getEstimationDataSelector(); } void IqtTemplatePresenter::updateParameterEstimationData(DataForParameterEstimationCollection &&data) { - m_model.updateParameterEstimationData(std::move(data)); + m_model->updateParameterEstimationData(std::move(data)); } void IqtTemplatePresenter::setBackgroundA0(double value) { - m_model.setBackgroundA0(value); + m_model->setBackgroundA0(value); m_view->setA0(value, 0.0); } @@ -199,42 +204,42 @@ void IqtTemplatePresenter::updateViewParameters() { {IqtFunctionModel::ParamID::STRETCH_LIFETIME, &IqtTemplateBrowser::setStretchLifetime}, {IqtFunctionModel::ParamID::STRETCH_STRETCHING, &IqtTemplateBrowser::setStretchStretching}, {IqtFunctionModel::ParamID::BG_A0, &IqtTemplateBrowser::setA0}}; - auto values = m_model.getCurrentValues(); - auto errors = m_model.getCurrentErrors(); + auto values = m_model->getCurrentValues(); + auto errors = m_model->getCurrentErrors(); for (auto const name : values.keys()) { (m_view->*setters.at(name))(values[name], errors[name]); } } -QStringList IqtTemplatePresenter::getDatasetNames() const { return m_model.getDatasetNames(); } +QStringList IqtTemplatePresenter::getDatasetNames() const { return m_model->getDatasetNames(); } -QStringList IqtTemplatePresenter::getDatasetDomainNames() const { return m_model.getDatasetDomainNames(); } +QStringList IqtTemplatePresenter::getDatasetDomainNames() const { return m_model->getDatasetDomainNames(); } double IqtTemplatePresenter::getLocalParameterValue(const QString &parName, int i) const { - return m_model.getLocalParameterValue(parName, i); + return m_model->getLocalParameterValue(parName, i); } bool IqtTemplatePresenter::isLocalParameterFixed(const QString &parName, int i) const { - return m_model.isLocalParameterFixed(parName, i); + return m_model->isLocalParameterFixed(parName, i); } QString IqtTemplatePresenter::getLocalParameterTie(const QString &parName, int i) const { - return m_model.getLocalParameterTie(parName, i); + return m_model->getLocalParameterTie(parName, i); } QString IqtTemplatePresenter::getLocalParameterConstraint(const QString &parName, int i) const { - return m_model.getLocalParameterConstraint(parName, i); + return m_model->getLocalParameterConstraint(parName, i); } void IqtTemplatePresenter::setLocalParameterValue(const QString &parName, int i, double value) { - m_model.setLocalParameterValue(parName, i, value); + m_model->setLocalParameterValue(parName, i, value); } void IqtTemplatePresenter::setLocalParameterTie(const QString &parName, int i, const QString &tie) { - m_model.setLocalParameterTie(parName, i, tie); + m_model->setLocalParameterTie(parName, i, tie); } -void IqtTemplatePresenter::updateViewParameterNames() { m_view->updateParameterNames(m_model.getParameterNameMap()); } +void IqtTemplatePresenter::updateViewParameterNames() { m_view->updateParameterNames(m_model->getParameterNameMap()); } void IqtTemplatePresenter::updateView() { updateViewParameterNames(); @@ -243,7 +248,7 @@ void IqtTemplatePresenter::updateView() { } void IqtTemplatePresenter::setLocalParameterFixed(const QString &parName, int i, bool fixed) { - m_model.setLocalParameterFixed(parName, i, fixed); + m_model->setLocalParameterFixed(parName, i, fixed); } void IqtTemplatePresenter::editLocalParameter(const QString &parName) { @@ -297,14 +302,14 @@ void IqtTemplatePresenter::editLocalParameterFinish(int result) { void IqtTemplatePresenter::viewChangedParameterValue(const QString &parName, double value) { if (parName.isEmpty()) return; - if (m_model.isGlobal(parName)) { + if (m_model->isGlobal(parName)) { auto const n = getNumberOfDatasets(); for (int i = 0; i < n; ++i) { setLocalParameterValue(parName, i, value); } } else { - auto const i = m_model.currentDomainIndex(); - auto const oldValue = m_model.getLocalParameterValue(parName, i); + auto const i = m_model->currentDomainIndex(); + auto const oldValue = m_model->getLocalParameterValue(parName, i); if (fabs(value - oldValue) > 1e-6) { setErrorsEnabled(false); } diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplatePresenter.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplatePresenter.h index 38ab7e6b2cf9..a1fd753e5ead 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplatePresenter.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/IqtTemplatePresenter.h @@ -31,7 +31,7 @@ class IqtTemplateBrowser; class MANTIDQT_INELASTIC_DLL IqtTemplatePresenter : public QObject { Q_OBJECT public: - explicit IqtTemplatePresenter(IqtTemplateBrowser *view); + explicit IqtTemplatePresenter(IqtTemplateBrowser *view, std::unique_ptr functionModel); void setNumberOfExponentials(int); void setStretchExponential(bool); void setBackground(const QString &name); @@ -54,6 +54,7 @@ class MANTIDQT_INELASTIC_DLL IqtTemplatePresenter : public QObject { void setErrorsEnabled(bool enabled); void tieIntensities(bool on); bool canTieIntensities() const; + EstimationDataSelector getEstimationDataSelector() const; void updateParameterEstimationData(DataForParameterEstimationCollection &&data); void setBackgroundA0(double value); @@ -79,7 +80,7 @@ private slots: void updateViewParameterNames(); void updateView(); IqtTemplateBrowser *m_view; - IqtFunctionModel m_model; + std::unique_ptr m_model; EditLocalParameterDialog *m_editLocalParameterDialog; }; diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/MSDFunctionModel.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/MSDFunctionModel.cpp new file mode 100644 index 000000000000..9d560c6622ed --- /dev/null +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/MSDFunctionModel.cpp @@ -0,0 +1,37 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2023 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + +#include "MSDFunctionModel.h" + +#include "Analysis/FitTabConstants.h" +#include "Analysis/IDAFunctionParameterEstimation.h" + +#include + +namespace { +using namespace MantidQt::CustomInterfaces::IDA; + +auto const msd = [](Mantid::MantidVec const &x, Mantid::MantidVec const &y) { + double Msd = 6 * log(y[0] / y[1]) / (x[1] * x[1]); + // If MSD less than zero, reject the estimate and set to default value of + // 0.05, which leads to a (roughly) flat line + Msd = Msd > 0 ? Msd : 0.05; + return std::unordered_map{{"Msd", Msd}, {"Height", y[0]}}; +}; + +auto const estimators = std::unordered_map{ + {"MsdGauss", msd}, {"MsdPeters", msd}, {"MsdYi", msd}}; + +} // namespace + +namespace MantidQt::CustomInterfaces::IDA { + +MSDFunctionModel::MSDFunctionModel() + : SingleFunctionTemplateModel(std::make_unique(estimators)) { + updateAvailableFunctions(MSDFit::ALL_FITS); +} + +} // namespace MantidQt::CustomInterfaces::IDA \ No newline at end of file diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/MSDFunctionModel.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/MSDFunctionModel.h new file mode 100644 index 000000000000..20dc7e1ebde5 --- /dev/null +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/MSDFunctionModel.h @@ -0,0 +1,23 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2023 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + +#pragma once + +#include "Analysis/FunctionBrowser/SingleFunctionTemplateModel.h" + +namespace MantidQt { +namespace CustomInterfaces { +namespace IDA { + +class MSDFunctionModel : public SingleFunctionTemplateModel { + +public: + MSDFunctionModel(); +}; + +} // namespace IDA +} // namespace CustomInterfaces +} // namespace MantidQt \ No newline at end of file diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateBrowser.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateBrowser.cpp index e25bace83e0c..f166f6ea05c5 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateBrowser.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateBrowser.cpp @@ -35,19 +35,12 @@ namespace MantidQt::CustomInterfaces::IDA { * Constructor * @param parent :: The parent widget. */ -SingleFunctionTemplateBrowser::SingleFunctionTemplateBrowser( - const std::map &functionInitialisationStrings, - std::unique_ptr parameterEstimation, QWidget *parent) - : FunctionTemplateBrowser(parent), - m_presenter(this, functionInitialisationStrings, std::move(parameterEstimation)) { +SingleFunctionTemplateBrowser::SingleFunctionTemplateBrowser(std::unique_ptr functionModel, + QWidget *parent) + : FunctionTemplateBrowser(parent), m_presenter(this, std::move(functionModel)) { connect(&m_presenter, SIGNAL(functionStructureChanged()), this, SIGNAL(functionStructureChanged())); } -void SingleFunctionTemplateBrowser::updateAvailableFunctions( - const std::map &functionInitialisationStrings) { - m_presenter.updateAvailableFunctions(functionInitialisationStrings); -} - void SingleFunctionTemplateBrowser::createProperties() { m_parameterManager->blockSignals(true); m_boolManager->blockSignals(true); @@ -169,6 +162,10 @@ void SingleFunctionTemplateBrowser::clear() { m_parameterNames.clear(); } +EstimationDataSelector SingleFunctionTemplateBrowser::getEstimationDataSelector() const { + return m_presenter.getEstimationDataSelector(); +} + void SingleFunctionTemplateBrowser::updateParameterEstimationData(DataForParameterEstimationCollection &&data) { m_presenter.updateParameterEstimationData(std::move(data)); } diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateBrowser.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateBrowser.h index 90c526ea2446..f7e785408b07 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateBrowser.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateBrowser.h @@ -7,7 +7,6 @@ #pragma once #include "Analysis/FunctionTemplateBrowser.h" -#include "Analysis/IFQFitObserver.h" #include "DllConfig.h" #include "SingleFunctionTemplatePresenter.h" @@ -26,14 +25,12 @@ class IDAFunctionParameterEstimation; * and set properties that can be used to generate a fit function. * */ -class MANTIDQT_INELASTIC_DLL SingleFunctionTemplateBrowser : public FunctionTemplateBrowser, public IFQFitObserver { +class MANTIDQT_INELASTIC_DLL SingleFunctionTemplateBrowser : public FunctionTemplateBrowser { Q_OBJECT public: - explicit SingleFunctionTemplateBrowser(const std::map &functionInitialisationStrings, - std::unique_ptr parameterEstimation, + explicit SingleFunctionTemplateBrowser(std::unique_ptr functionModel, QWidget *parent = nullptr); virtual ~SingleFunctionTemplateBrowser() = default; - void updateAvailableFunctions(const std::map &functionInitialisationStrings) override; void setFunction(const QString &funStr) override; IFunction_sptr getGlobalFunction() const override; IFunction_sptr getFunction() const override; @@ -51,6 +48,7 @@ class MANTIDQT_INELASTIC_DLL SingleFunctionTemplateBrowser : public FunctionTemp void updateParameterDescriptions(const QMap ¶meterNames); void setErrorsEnabled(bool enabled) override; void clear() override; + EstimationDataSelector getEstimationDataSelector() const override; void updateParameterEstimationData(DataForParameterEstimationCollection &&data) override; void estimateFunctionParameters() override; void setBackgroundA0(double) override; diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateModel.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateModel.cpp index 4f0b203efb23..66bb47a9b649 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateModel.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateModel.cpp @@ -95,6 +95,31 @@ void SingleFunctionTemplateModel::setFitType(const QString &type) { QString SingleFunctionTemplateModel::getFitType() { return m_fitType; } +EstimationDataSelector SingleFunctionTemplateModel::getEstimationDataSelector() const { + return [](const std::vector &x, const std::vector &y, + const std::pair range) -> DataForParameterEstimation { + // Find data thats within range + double xmin = range.first; + double xmax = range.second; + if (xmax - xmin < 1e-5) { + return DataForParameterEstimation{}; + } + + const auto startItr = + std::find_if(x.cbegin(), x.cend(), [xmin](const double &val) -> bool { return val >= (xmin - 1e-5); }); + const auto endItr = std::find_if(x.cbegin(), x.cend(), [xmax](const double &val) -> bool { return val > xmax; }); + + if (std::distance(startItr, endItr - 1) < 2) + return DataForParameterEstimation{}; + + size_t first = std::distance(x.cbegin(), startItr); + size_t end = std::distance(x.cbegin(), endItr); + size_t m = first + (end - first) / 2; + + return DataForParameterEstimation{{x[first], x[m]}, {y[first], y[m]}}; + }; +} + void SingleFunctionTemplateModel::updateParameterEstimationData(DataForParameterEstimationCollection &&data) { m_estimationData = std::move(data); } diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateModel.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateModel.h index 0ac4291c573d..85da1ca4b276 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateModel.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplateModel.h @@ -6,7 +6,6 @@ // SPDX - License - Identifier: GPL - 3.0 + #pragma once -#include "Analysis/IFQFitObserver.h" #include "Analysis/ParameterEstimation.h" #include "DllConfig.h" #include "MantidAPI/IFunction_fwd.h" @@ -41,6 +40,7 @@ class MANTIDQT_INELASTIC_DLL SingleFunctionTemplateModel : public FunctionModel int getEnumIndex(); void setGlobal(const QString &name, bool isGlobal); + EstimationDataSelector getEstimationDataSelector() const; void updateParameterEstimationData(DataForParameterEstimationCollection &&data); void estimateFunctionParameters(); diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplatePresenter.cpp b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplatePresenter.cpp index 20ba3710b466..05f54b009ddd 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplatePresenter.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplatePresenter.cpp @@ -18,150 +18,151 @@ using namespace MantidWidgets; * @param parent :: The parent widget. */ SingleFunctionTemplatePresenter::SingleFunctionTemplatePresenter( - SingleFunctionTemplateBrowser *view, const std::map &functionInitialisationStrings, - std::unique_ptr parameterEstimation) - : QObject(view), m_view(view), m_model(std::move(parameterEstimation)) { + SingleFunctionTemplateBrowser *view, std::unique_ptr functionModel) + : QObject(view), m_view(view), m_model(std::move(functionModel)) { connect(m_view, SIGNAL(localParameterButtonClicked(const QString &)), this, SLOT(editLocalParameter(const QString &))); connect(m_view, SIGNAL(parameterValueChanged(const QString &, double)), this, SLOT(viewChangedParameterValue(const QString &, double))); - - m_model.updateAvailableFunctions(functionInitialisationStrings); } void SingleFunctionTemplatePresenter::init() { - m_view->setDataType(m_model.getFunctionList()); - setFitType(m_model.getFitType()); + m_view->setDataType(m_model->getFunctionList()); + setFitType(m_model->getFitType()); } void SingleFunctionTemplatePresenter::updateAvailableFunctions( const std::map &functionInitialisationStrings) { - m_model.updateAvailableFunctions(functionInitialisationStrings); - m_view->setDataType(m_model.getFunctionList()); - setFitType(m_model.getFitType()); + m_model->updateAvailableFunctions(functionInitialisationStrings); + m_view->setDataType(m_model->getFunctionList()); + setFitType(m_model->getFitType()); } void SingleFunctionTemplatePresenter::setFitType(const QString &name) { m_view->clear(); - m_model.setFitType(name); - auto functionParameters = m_model.getParameterNames(); + m_model->setFitType(name); + auto functionParameters = m_model->getParameterNames(); for (auto ¶meter : functionParameters) { - m_view->addParameter(parameter, m_model.getParameterDescription(parameter)); + m_view->addParameter(parameter, m_model->getParameterDescription(parameter)); } setErrorsEnabled(false); updateView(); emit functionStructureChanged(); } -void SingleFunctionTemplatePresenter::setNumberOfDatasets(int n) { m_model.setNumberDomains(n); } +void SingleFunctionTemplatePresenter::setNumberOfDatasets(int n) { m_model->setNumberDomains(n); } -int SingleFunctionTemplatePresenter::getNumberOfDatasets() const { return m_model.getNumberDomains(); } +int SingleFunctionTemplatePresenter::getNumberOfDatasets() const { return m_model->getNumberDomains(); } -int SingleFunctionTemplatePresenter::getCurrentDataset() { return m_model.currentDomainIndex(); } +int SingleFunctionTemplatePresenter::getCurrentDataset() { return m_model->currentDomainIndex(); } void SingleFunctionTemplatePresenter::setFunction(const QString &funStr) { m_view->clear(); - m_model.setFunctionString(funStr); + m_model->setFunctionString(funStr); - if (m_model.getFitType() == "None") + if (m_model->getFitType() == "None") return; - auto functionParameters = m_model.getParameterNames(); + auto functionParameters = m_model->getParameterNames(); for (auto ¶meter : functionParameters) { - m_view->addParameter(parameter, m_model.getParameterDescription(parameter)); + m_view->addParameter(parameter, m_model->getParameterDescription(parameter)); } - m_view->setEnumValue(m_model.getEnumIndex()); + m_view->setEnumValue(m_model->getEnumIndex()); setErrorsEnabled(false); updateView(); emit functionStructureChanged(); } -IFunction_sptr SingleFunctionTemplatePresenter::getGlobalFunction() const { return m_model.getFitFunction(); } +IFunction_sptr SingleFunctionTemplatePresenter::getGlobalFunction() const { return m_model->getFitFunction(); } -IFunction_sptr SingleFunctionTemplatePresenter::getFunction() const { return m_model.getCurrentFunction(); } +IFunction_sptr SingleFunctionTemplatePresenter::getFunction() const { return m_model->getCurrentFunction(); } -QStringList SingleFunctionTemplatePresenter::getGlobalParameters() const { return m_model.getGlobalParameters(); } +QStringList SingleFunctionTemplatePresenter::getGlobalParameters() const { return m_model->getGlobalParameters(); } -QStringList SingleFunctionTemplatePresenter::getLocalParameters() const { return m_model.getLocalParameters(); } +QStringList SingleFunctionTemplatePresenter::getLocalParameters() const { return m_model->getLocalParameters(); } void SingleFunctionTemplatePresenter::setGlobalParameters(const QStringList &globals) { - m_model.setGlobalParameters(globals); + m_model->setGlobalParameters(globals); m_view->setGlobalParametersQuiet(globals); } void SingleFunctionTemplatePresenter::setGlobal(const QString &parName, bool on) { - m_model.setGlobal(parName, on); - m_view->setGlobalParametersQuiet(m_model.getGlobalParameters()); + m_model->setGlobal(parName, on); + m_view->setGlobalParametersQuiet(m_model->getGlobalParameters()); } void SingleFunctionTemplatePresenter::updateMultiDatasetParameters(const IFunction &fun) { - m_model.updateMultiDatasetParameters(fun); + m_model->updateMultiDatasetParameters(fun); updateView(); } void SingleFunctionTemplatePresenter::updateParameters(const IFunction &fun) { - m_model.updateParameters(fun); + m_model->updateParameters(fun); updateView(); } void SingleFunctionTemplatePresenter::setCurrentDataset(int i) { - m_model.setCurrentDomainIndex(i); + m_model->setCurrentDomainIndex(i); updateView(); } void SingleFunctionTemplatePresenter::setDatasets(const QList &datasets) { - m_model.setDatasets(datasets); + m_model->setDatasets(datasets); } void SingleFunctionTemplatePresenter::setErrorsEnabled(bool enabled) { m_view->setErrorsEnabled(enabled); } +EstimationDataSelector SingleFunctionTemplatePresenter::getEstimationDataSelector() const { + return m_model->getEstimationDataSelector(); +} + void SingleFunctionTemplatePresenter::updateParameterEstimationData(DataForParameterEstimationCollection &&data) { - m_model.updateParameterEstimationData(std::move(data)); + m_model->updateParameterEstimationData(std::move(data)); updateView(); } void SingleFunctionTemplatePresenter::estimateFunctionParameters() { - m_model.estimateFunctionParameters(); + m_model->estimateFunctionParameters(); updateView(); } -QStringList SingleFunctionTemplatePresenter::getDatasetNames() const { return m_model.getDatasetNames(); } +QStringList SingleFunctionTemplatePresenter::getDatasetNames() const { return m_model->getDatasetNames(); } -QStringList SingleFunctionTemplatePresenter::getDatasetDomainNames() const { return m_model.getDatasetDomainNames(); } +QStringList SingleFunctionTemplatePresenter::getDatasetDomainNames() const { return m_model->getDatasetDomainNames(); } double SingleFunctionTemplatePresenter::getLocalParameterValue(const QString &parName, int i) const { - return m_model.getLocalParameterValue(parName, i); + return m_model->getLocalParameterValue(parName, i); } bool SingleFunctionTemplatePresenter::isLocalParameterFixed(const QString &parName, int i) const { - return m_model.isLocalParameterFixed(parName, i); + return m_model->isLocalParameterFixed(parName, i); } QString SingleFunctionTemplatePresenter::getLocalParameterTie(const QString &parName, int i) const { - return m_model.getLocalParameterTie(parName, i); + return m_model->getLocalParameterTie(parName, i); } QString SingleFunctionTemplatePresenter::getLocalParameterConstraint(const QString &parName, int i) const { - return m_model.getLocalParameterConstraint(parName, i); + return m_model->getLocalParameterConstraint(parName, i); } void SingleFunctionTemplatePresenter::setLocalParameterValue(const QString &parName, int i, double value) { - m_model.setLocalParameterValue(parName, i, value); + m_model->setLocalParameterValue(parName, i, value); } void SingleFunctionTemplatePresenter::setLocalParameterTie(const QString &parName, int i, const QString &tie) { - m_model.setLocalParameterTie(parName, i, tie); + m_model->setLocalParameterTie(parName, i, tie); } void SingleFunctionTemplatePresenter::updateView() { - if (m_model.getFitType() == "None") + if (m_model->getFitType() == "None") return; - for (auto ¶meterName : m_model.getParameterNames()) { - m_view->setParameterValueQuietly(parameterName, m_model.getParameter(parameterName), - m_model.getParameterError(parameterName)); + for (auto ¶meterName : m_model->getParameterNames()) { + m_view->setParameterValueQuietly(parameterName, m_model->getParameter(parameterName), + m_model->getParameterError(parameterName)); } } void SingleFunctionTemplatePresenter::setLocalParameterFixed(const QString &parName, int i, bool fixed) { - m_model.setLocalParameterFixed(parName, i, fixed); + m_model->setLocalParameterFixed(parName, i, fixed); } void SingleFunctionTemplatePresenter::editLocalParameter(const QString &parName) { @@ -215,14 +216,14 @@ void SingleFunctionTemplatePresenter::editLocalParameterFinish(int result) { void SingleFunctionTemplatePresenter::viewChangedParameterValue(const QString &parName, double value) { if (parName.isEmpty()) return; - if (m_model.isGlobal(parName)) { + if (m_model->isGlobal(parName)) { const auto n = getNumberOfDatasets(); for (int i = 0; i < n; ++i) { setLocalParameterValue(parName, i, value); } } else { - const auto i = m_model.currentDomainIndex(); - const auto oldValue = m_model.getLocalParameterValue(parName, i); + const auto i = m_model->currentDomainIndex(); + const auto oldValue = m_model->getLocalParameterValue(parName, i); if (fabs(value - oldValue) > 1e-6) { setErrorsEnabled(false); } diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplatePresenter.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplatePresenter.h index 0702eeab6628..399cce54a695 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplatePresenter.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionBrowser/SingleFunctionTemplatePresenter.h @@ -7,7 +7,6 @@ #pragma once #include "Analysis/IDAFunctionParameterEstimation.h" -#include "Analysis/IFQFitObserver.h" #include "Analysis/ParameterEstimation.h" #include "DllConfig.h" #include "SingleFunctionTemplateModel.h" @@ -34,8 +33,7 @@ class MANTIDQT_INELASTIC_DLL SingleFunctionTemplatePresenter : public QObject { Q_OBJECT public: explicit SingleFunctionTemplatePresenter(SingleFunctionTemplateBrowser *view, - const std::map &functionInitialisationStrings, - std::unique_ptr parameterEstimation); + std::unique_ptr functionModel); void updateAvailableFunctions(const std::map &functionInitialisationStrings); void setFitType(const QString &name); @@ -56,6 +54,7 @@ class MANTIDQT_INELASTIC_DLL SingleFunctionTemplatePresenter : public QObject { void setCurrentDataset(int i); void setDatasets(const QList &datasets); void setErrorsEnabled(bool enabled); + EstimationDataSelector getEstimationDataSelector() const; void updateParameterEstimationData(DataForParameterEstimationCollection &&data); void estimateFunctionParameters(); @@ -79,7 +78,7 @@ private slots: void setLocalParameterTie(const QString &parName, int i, const QString &tie); void updateView(); SingleFunctionTemplateBrowser *m_view; - SingleFunctionTemplateModel m_model; + std::unique_ptr m_model; EditLocalParameterDialog *m_editLocalParameterDialog; }; diff --git a/qt/scientific_interfaces/Inelastic/Analysis/FunctionTemplateBrowser.h b/qt/scientific_interfaces/Inelastic/Analysis/FunctionTemplateBrowser.h index 8d77b89c677d..bd35e8828970 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/FunctionTemplateBrowser.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/FunctionTemplateBrowser.h @@ -64,6 +64,7 @@ class MANTIDQT_INELASTIC_DLL FunctionTemplateBrowser : public QWidget { virtual void updateParameterNames(const QMap ¶meterNames) = 0; virtual void setErrorsEnabled(bool enabled) = 0; virtual void clear() = 0; + virtual EstimationDataSelector getEstimationDataSelector() const = 0; virtual void updateParameterEstimationData(DataForParameterEstimationCollection &&data) = 0; virtual void estimateFunctionParameters() = 0; virtual void setBackgroundA0(double value) = 0; diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IDAFunctionParameterEstimation.cpp b/qt/scientific_interfaces/Inelastic/Analysis/IDAFunctionParameterEstimation.cpp index 3de24a167d5b..f2eb71b988ee 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/IDAFunctionParameterEstimation.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/IDAFunctionParameterEstimation.cpp @@ -8,16 +8,41 @@ #include "MantidAPI/IFunction.h" #include + namespace MantidQt::CustomInterfaces::IDA { +IDAFunctionParameterEstimation::ParameterEstimateSetter +parameterEstimateSetter(IDAFunctionParameterEstimation::ParameterEstimator estimator) { + return [estimator](Mantid::API::IFunction_sptr &function, const DataForParameterEstimation &estimationData) { + auto const y = estimationData.y; + auto const x = estimationData.x; + if (x.size() != 2 || y.size() != 2) { + return; + } + auto const parameterValues = estimator(x, y); + + for (auto it = parameterValues.cbegin(); it != parameterValues.cend(); ++it) { + function->setParameter(it->first, it->second); + } + }; +} + +IDAFunctionParameterEstimation::IDAFunctionParameterEstimation( + std::unordered_map estimators) { + for (auto it = estimators.cbegin(); it != estimators.cend(); ++it) { + addParameterEstimationFunction(it->first, parameterEstimateSetter(it->second)); + } +} + // Add function name and estimation function to the stored function map. -void IDAFunctionParameterEstimation::addParameterEstimationFunction(std::string name, EstimationFunction function) { - m_funcMap.insert(std::make_pair(std::move(name), std::move(function))); +void IDAFunctionParameterEstimation::addParameterEstimationFunction(std::string const &functionName, + ParameterEstimateSetter function) { + m_funcMap.insert(std::make_pair(functionName, std::move(function))); } // Estimate the function parameters for the input function // If the input function exists in the stored map it will update the function // parameters in-place. -void IDAFunctionParameterEstimation::estimateFunctionParameters(::Mantid::API::IFunction_sptr &function, +void IDAFunctionParameterEstimation::estimateFunctionParameters(Mantid::API::IFunction_sptr &function, const DataForParameterEstimation &estimationData) { if (function) { std::string functionName = function->name(); diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IDAFunctionParameterEstimation.h b/qt/scientific_interfaces/Inelastic/Analysis/IDAFunctionParameterEstimation.h index 2b25db3f4baa..900caf2cf4e8 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/IDAFunctionParameterEstimation.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/IDAFunctionParameterEstimation.h @@ -14,17 +14,22 @@ namespace MantidQt { namespace CustomInterfaces { namespace IDA { class MANTIDQT_INELASTIC_DLL IDAFunctionParameterEstimation { - using EstimationFunction = - std::function; public: - void addParameterEstimationFunction(std::string functionName, EstimationFunction function); - void estimateFunctionParameters(::Mantid::API::IFunction_sptr &function, + using ParameterEstimateSetter = + std::function; + using ParameterEstimator = + std::function(Mantid::MantidVec const &, Mantid::MantidVec const &)>; + + IDAFunctionParameterEstimation(std::unordered_map estimators); + void addParameterEstimationFunction(std::string const &functionName, ParameterEstimateSetter function); + void estimateFunctionParameters(Mantid::API::IFunction_sptr &function, const DataForParameterEstimation &estimationData); private: - std::map m_funcMap; + std::map m_funcMap; }; + } // namespace IDA } // namespace CustomInterfaces } // namespace MantidQt diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IFQFitObserver.h b/qt/scientific_interfaces/Inelastic/Analysis/IFQFitObserver.h deleted file mode 100644 index 93b9c5ac4bba..000000000000 --- a/qt/scientific_interfaces/Inelastic/Analysis/IFQFitObserver.h +++ /dev/null @@ -1,16 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#pragma once - -#include -#include - -class IFQFitObserver { -public: - virtual ~IFQFitObserver() = default; - virtual void updateAvailableFunctions(const std::map &functionInitialisationStrings) = 0; -}; diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysis.cpp b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysis.cpp index a50a9df0c6b6..773bc6cc6699 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysis.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysis.cpp @@ -7,10 +7,8 @@ #include "IndirectDataAnalysis.h" #include "IndirectSettings.h" -#include "IndirectDataAnalysisConvFitTab.h" -#include "IndirectDataAnalysisFqFitTab.h" -#include "IndirectDataAnalysisIqtFitTab.h" -#include "IndirectDataAnalysisMSDFitTab.h" +#include "DataAnalysisTabFactory.h" +#include "IndirectDataAnalysisTab.h" namespace MantidQt::CustomInterfaces::IDA { DECLARE_SUBWINDOW(IndirectDataAnalysis) @@ -20,15 +18,11 @@ IndirectDataAnalysis::IndirectDataAnalysis(QWidget *parent) m_uiForm.setupUi(this); m_uiForm.pbSettings->setIcon(IndirectSettings::icon()); - // Allows us to get a handle on a tab using an enum, for example - // "m_tabs[ELWIN]". - // All tabs MUST appear here to be shown in interface. - // We make the assumption that each map key corresponds to the order in which - // the tabs appear. - m_tabs.emplace(MSD_FIT, new IndirectDataAnalysisMSDFitTab(m_uiForm.twIDATabs->widget(MSD_FIT))); - m_tabs.emplace(IQT_FIT, new IndirectDataAnalysisIqtFitTab(m_uiForm.twIDATabs->widget(IQT_FIT))); - m_tabs.emplace(CONV_FIT, new IndirectDataAnalysisConvFitTab(m_uiForm.twIDATabs->widget(CONV_FIT))); - m_tabs.emplace(FQ_FIT, new IndirectDataAnalysisFqFitTab(m_uiForm.twIDATabs->widget(FQ_FIT))); + auto const tabFactory = std::make_unique(m_uiForm.twIDATabs); + m_tabs.emplace(MSD_FIT, tabFactory->makeMSDFitTab(MSD_FIT)); + m_tabs.emplace(IQT_FIT, tabFactory->makeIqtFitTab(IQT_FIT)); + m_tabs.emplace(CONV_FIT, tabFactory->makeConvFitTab(CONV_FIT)); + m_tabs.emplace(FQ_FIT, tabFactory->makeFqFitTab(FQ_FIT)); } void IndirectDataAnalysis::applySettings(std::map const &settings) { diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisConvFitTab.cpp b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisConvFitTab.cpp deleted file mode 100644 index 9b478e74d2ff..000000000000 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisConvFitTab.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#include "IndirectDataAnalysisConvFitTab.h" -#include "ConvFitAddWorkspaceDialog.h" -#include "ConvFitDataPresenter.h" -#include "FunctionBrowser/ConvTemplateBrowser.h" -#include "IndirectFitPlotView.h" - -#include "MantidAPI/FunctionFactory.h" - -using namespace Mantid; -using namespace Mantid::API; - -namespace { -Mantid::Kernel::Logger g_log("ConvFit"); - -std::vector CONVFIT_HIDDEN_PROPS = std::vector( - {"CreateOutput", "LogValue", "PassWSIndexToFunction", "OutputWorkspace", "Output", "PeakRadius", "PlotParameter"}); -} // namespace - -namespace MantidQt::CustomInterfaces::IDA { - -IndirectDataAnalysisConvFitTab::IndirectDataAnalysisConvFitTab(QWidget *parent) - : IndirectDataAnalysisTab(new ConvFitModel, parent), m_uiForm(new Ui::IndirectFitTab) { - m_uiForm->setupUi(parent); - setOutputOptionsView(m_uiForm->ovOutputOptionsView); - m_uiForm->dockArea->m_fitPropertyBrowser->setFunctionTemplateBrowser(new ConvTemplateBrowser); - setFitPropertyBrowser(m_uiForm->dockArea->m_fitPropertyBrowser); - m_uiForm->dockArea->m_fitPropertyBrowser->setHiddenProperties(CONVFIT_HIDDEN_PROPS); - - m_uiForm->dockArea->setFitDataView(new ConvFitDataView(m_uiForm->dockArea)); - auto dataPresenter = - std::make_unique(m_fittingModel->getFitDataModel(), m_uiForm->dockArea->m_fitDataView); - setFitDataPresenter(std::move(dataPresenter)); - setPlotView(m_uiForm->dockArea->m_fitPlotView); - setRunButton(m_uiForm->pbRun); - - setEditResultVisible(true); - setConvolveMembers(true); - - // Initialise fitTypeStrings - m_fitStrings["Lorentzian"] = "L"; - m_fitStrings["StretchedExpFT"] = "SFT"; - m_fitStrings["TeixeiraWaterSQE"] = "TxWater"; - m_fitStrings["FickDiffusionSQE"] = "FickDiff"; - m_fitStrings["ChudleyElliotSQE"] = "ChudElliot"; - m_fitStrings["HallRossSQE"] = "HallRoss"; - m_fitStrings["DiffRotDiscreteCircle"] = "DC"; - m_fitStrings["ElasticDiffRotDiscreteCircle"] = "EDC"; - m_fitStrings["InelasticDiffRotDiscreteCircle"] = "IDC"; - m_fitStrings["DiffSphere"] = "DS"; - m_fitStrings["ElasticDiffSphere"] = "EDS"; - m_fitStrings["InelasticDiffSphere"] = "IDS"; - m_fitStrings["IsoRotDiff"] = "IRD"; - m_fitStrings["ElasticIsoRotDiff"] = "EIRD"; - m_fitStrings["InelasticIsoRotDiff"] = "IIRD"; -} - -EstimationDataSelector IndirectDataAnalysisConvFitTab::getEstimationDataSelector() const { - return [](const MantidVec &, const MantidVec &, const std::pair) -> DataForParameterEstimation { - return DataForParameterEstimation{}; - }; -} - -void IndirectDataAnalysisConvFitTab::addDataToModel(IAddWorkspaceDialog const *dialog) { - if (const auto convDialog = dynamic_cast(dialog)) { - m_dataPresenter->addWorkspace(convDialog->workspaceName(), convDialog->workspaceIndices()); - m_dataPresenter->setResolution(convDialog->resolutionName()); - m_fittingModel->addDefaultParameters(); - } -} - -/** - * Generate a string to describe the fit type selected by the user. - * Used when naming the resultant workspaces. - * - * Assertions used to guard against any future changes that don't take - * workspace naming into account. - * - * @returns the generated string. - */ -std::string IndirectDataAnalysisConvFitTab::getFitTypeString() const { - std::string fitType; - for (auto fitFunctionName : m_fitStrings) { - auto occurances = getNumberOfCustomFunctions(fitFunctionName.first); - if (occurances > 0) { - fitType += std::to_string(occurances) + fitFunctionName.second; - } - } - - if (getNumberOfCustomFunctions("DeltaFunction") > 0) { - fitType += "Delta"; - } - - return fitType; -} - -} // namespace MantidQt::CustomInterfaces::IDA diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisConvFitTab.h b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisConvFitTab.h deleted file mode 100644 index 250b449a9568..000000000000 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisConvFitTab.h +++ /dev/null @@ -1,42 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#pragma once - -#include "DllConfig.h" -#include "IndirectDataAnalysisTab.h" -#include "ParameterEstimation.h" - -#include "MantidAPI/CompositeFunction.h" -#include "MantidAPI/MatrixWorkspace_fwd.h" -#include "ui_IndirectFitTab.h" - -namespace MantidQt { -namespace CustomInterfaces { -namespace IDA { -class MANTIDQT_INELASTIC_DLL IndirectDataAnalysisConvFitTab : public IndirectDataAnalysisTab { - Q_OBJECT - -public: - IndirectDataAnalysisConvFitTab(QWidget *parent = nullptr); - - std::string getTabName() const override { return "ConvFit"; } - - bool hasResolution() const override { return true; } - -private: - EstimationDataSelector getEstimationDataSelector() const override; - void addDataToModel(IAddWorkspaceDialog const *dialog) override; - std::string getFitTypeString() const override; - - std::unique_ptr m_uiForm; - // ShortHand Naming for fit functions - std::unordered_map m_fitStrings; -}; - -} // namespace IDA -} // namespace CustomInterfaces -} // namespace MantidQt diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisFqFitTab.cpp b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisFqFitTab.cpp deleted file mode 100644 index 656a316cc658..000000000000 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisFqFitTab.cpp +++ /dev/null @@ -1,197 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#include "IndirectDataAnalysisFqFitTab.h" -#include "FQFitConstants.h" -#include "FqFitDataPresenter.h" -#include "FqFitModel.h" -#include "IDAFunctionParameterEstimation.h" - -#include "FunctionBrowser/SingleFunctionTemplateBrowser.h" -#include "MantidAPI/FunctionFactory.h" -#include "MantidAPI/IFunction.h" -#include "MantidAPI/MultiDomainFunction.h" -#include "MantidKernel/PhysicalConstants.h" - -#include - -using namespace Mantid::API; - -namespace MantidQt::CustomInterfaces::IDA { - -namespace { -constexpr double HBAR = Mantid::PhysicalConstants::h / Mantid::PhysicalConstants::meV * 1e12 / (2 * M_PI); -} - -std::vector FQFIT_HIDDEN_PROPS = - std::vector({"CreateOutput", "LogValue", "PassWSIndexToFunction", "ConvolveMembers", - "OutputCompositeMembers", "OutputWorkspace", "Output", "PeakRadius", "PlotParameter"}); - -IndirectDataAnalysisFqFitTab::IndirectDataAnalysisFqFitTab(QWidget *parent) - : IndirectDataAnalysisTab(new FqFitModel, parent), m_uiForm(new Ui::IndirectFitTab) { - m_uiForm->setupUi(parent); - - auto parameterEstimation = createParameterEstimation(); - auto templateBrowser = new SingleFunctionTemplateBrowser( - widthFits, std::make_unique(parameterEstimation)); - - m_uiForm->dockArea->setFitDataView(new FqFitDataView(m_uiForm->dockArea)); - setFitDataPresenter(std::make_unique(m_fittingModel->getFitDataModel(), - m_uiForm->dockArea->m_fitDataView, templateBrowser)); - setPlotView(m_uiForm->dockArea->m_fitPlotView); - m_plotPresenter->setXBounds({0.0, 2.0}); - setOutputOptionsView(m_uiForm->ovOutputOptionsView); - - m_uiForm->dockArea->m_fitPropertyBrowser->setFunctionTemplateBrowser(templateBrowser); - templateBrowser->updateAvailableFunctions(availableFits.at(DataType::ALL)); - setFitPropertyBrowser(m_uiForm->dockArea->m_fitPropertyBrowser); - m_uiForm->dockArea->m_fitPropertyBrowser->setHiddenProperties(FQFIT_HIDDEN_PROPS); - setRunButton(m_uiForm->pbRun); - - setEditResultVisible(false); -} - -std::string IndirectDataAnalysisFqFitTab::getFitTypeString() const { - if (!m_fittingModel->getFitFunction() || m_fittingModel->getFitFunction()->nFunctions() == 0) { - return "NoCurrentFunction"; - } - - auto fun = m_fittingModel->getFitFunction()->getFunction(0); - if (fun->nFunctions() == 0) { - return fun->name(); - } else { - return "UserDefinedCompositeFunction"; - } -} - -EstimationDataSelector IndirectDataAnalysisFqFitTab::getEstimationDataSelector() const { - return [](const std::vector &x, const std::vector &y, - const std::pair range) -> DataForParameterEstimation { - // Find data thats within range - double xmin = range.first; - double xmax = range.second; - - // If the two points are equal return empty data - if (fabs(xmin - xmax) < 1e-7) { - return DataForParameterEstimation{}; - } - - const auto startItr = - std::find_if(x.cbegin(), x.cend(), [xmin](const double &val) -> bool { return val >= (xmin - 1e-7); }); - auto endItr = std::find_if(x.cbegin(), x.cend(), [xmax](const double &val) -> bool { return val > xmax; }); - - if (std::distance(startItr, endItr - 1) < 2) - return DataForParameterEstimation{}; - - size_t first = std::distance(x.cbegin(), startItr); - size_t end = std::distance(x.cbegin(), endItr); - size_t m = first + (end - first) / 2; - - return DataForParameterEstimation{{x[first], x[m]}, {y[first], y[m]}}; - }; -} - -void IndirectDataAnalysisFqFitTab::addDataToModel(IAddWorkspaceDialog const *dialog) { - if (const auto fqFitDialog = dynamic_cast(dialog)) { - m_dataPresenter->addWorkspace(fqFitDialog->workspaceName(), fqFitDialog->parameterType(), - fqFitDialog->parameterNameIndex()); - m_fittingModel->addDefaultParameters(); - setActiveWorkspaceIDToCurrentWorkspace(fqFitDialog); - setModelSpectrum(fqFitDialog->parameterNameIndex(), fqFitDialog->parameterType()); - m_activeWorkspaceID = m_dataPresenter->getNumberOfWorkspaces(); - } -} - -void IndirectDataAnalysisFqFitTab::setActiveWorkspaceIDToCurrentWorkspace(IAddWorkspaceDialog const *dialog) { - // update active data index with correct index based on the workspace name - // and the vector in m_fitDataModel which is in the base class - // indirectFittingModel get table workspace index - const auto wsName = dialog->workspaceName().append("_HWHM"); - // This a vector of workspace names currently loaded - auto wsVector = m_fittingModel->getFitDataModel()->getWorkspaceNames(); - // this is an iterator pointing to the current wsName in wsVector - auto wsIt = std::find(wsVector.begin(), wsVector.end(), wsName); - // this is the index of the workspace. - const auto index = WorkspaceID(std::distance(wsVector.begin(), wsIt)); - m_activeWorkspaceID = index; -} - -void IndirectDataAnalysisFqFitTab::setModelSpectrum(int index, const std::string ¶mType) { - if (index < 0) - throw std::runtime_error("No valid parameter was selected."); - else if (paramType == "Width") - m_dataPresenter->setActiveWidth(static_cast(index), m_activeWorkspaceID, false); - else - m_dataPresenter->setActiveEISF(static_cast(index), m_activeWorkspaceID, false); -} - -namespace { -void estimateChudleyElliot(::Mantid::API::IFunction_sptr &function, const DataForParameterEstimation &estimationData) { - - auto y = estimationData.y; - auto x = estimationData.x; - if (x.size() != 2 || y.size() != 2) { - return; - } - - double L = 1.5; - double tau = (HBAR / y[1]) * (1 - sin(x[1] * L) / (L * x[1])); - - function->setParameter("L", L); - function->setParameter("Tau", tau); -} -void estimateHallRoss(::Mantid::API::IFunction_sptr &function, const DataForParameterEstimation &estimationData) { - - auto y = estimationData.y; - auto x = estimationData.x; - if (x.size() != 2 || y.size() != 2) { - return; - } - - double L = 0.2; - double tau = (HBAR / y[1]) * (1 - exp((-x[1] * x[1] * L * L) / 2)); - - function->setParameter("L", L); - function->setParameter("Tau", tau); -} -void estimateTeixeiraWater(::Mantid::API::IFunction_sptr &function, const DataForParameterEstimation &estimationData) { - - auto y = estimationData.y; - auto x = estimationData.x; - if (x.size() != 2 || y.size() != 2) { - return; - } - - double L = 1.5; - double QL = x[1] * L; - double tau = (HBAR / y[1]) * ((QL * QL) / (6 + QL * QL)); - - function->setParameter("L", L); - function->setParameter("Tau", tau); -} -void estimateFickDiffusion(::Mantid::API::IFunction_sptr &function, const DataForParameterEstimation &estimationData) { - auto y = estimationData.y; - auto x = estimationData.x; - if (x.size() != 2 || y.size() != 2) { - return; - } - - function->setParameter("D", y[1] / (x[1] * x[1])); -} -} // namespace - -IDAFunctionParameterEstimation IndirectDataAnalysisFqFitTab::createParameterEstimation() const { - - IDAFunctionParameterEstimation parameterEstimation; - parameterEstimation.addParameterEstimationFunction("ChudleyElliot", estimateChudleyElliot); - parameterEstimation.addParameterEstimationFunction("HallRoss", estimateHallRoss); - parameterEstimation.addParameterEstimationFunction("TeixeiraWater", estimateTeixeiraWater); - parameterEstimation.addParameterEstimationFunction("FickDiffusion", estimateFickDiffusion); - - return parameterEstimation; -} - -} // namespace MantidQt::CustomInterfaces::IDA diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisFqFitTab.h b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisFqFitTab.h deleted file mode 100644 index 02bbae96bfc0..000000000000 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisFqFitTab.h +++ /dev/null @@ -1,43 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#pragma once - -#include "IndirectDataAnalysisTab.h" -#include "ui_IndirectFitTab.h" - -#include "IFQFitObserver.h" -#include "MantidAPI/IFunction.h" -#include "MantidAPI/TextAxis.h" - -namespace MantidQt { -namespace CustomInterfaces { -namespace IDA { -class IDAFunctionParameterEstimation; - -class MANTIDQT_INELASTIC_DLL IndirectDataAnalysisFqFitTab : public IndirectDataAnalysisTab { - Q_OBJECT - -public: - IndirectDataAnalysisFqFitTab(QWidget *parent = nullptr); - - std::string getTabName() const override { return "FQFit"; } - - bool hasResolution() const override { return false; } - -private: - EstimationDataSelector getEstimationDataSelector() const override; - std::string getFitTypeString() const override; - IDAFunctionParameterEstimation createParameterEstimation() const; - void addDataToModel(IAddWorkspaceDialog const *dialog) override; - void setActiveWorkspaceIDToCurrentWorkspace(IAddWorkspaceDialog const *dialog); - void setModelSpectrum(int index, const std::string ¶mType); - - std::unique_ptr m_uiForm; -}; -} // namespace IDA -} // namespace CustomInterfaces -} // namespace MantidQt diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisIqtFitTab.cpp b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisIqtFitTab.cpp deleted file mode 100644 index 0ef2236bce5d..000000000000 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisIqtFitTab.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#include "IndirectDataAnalysisIqtFitTab.h" -#include "FunctionBrowser/IqtTemplateBrowser.h" -#include "IndirectAddWorkspaceDialog.h" -#include "IndirectFitPlotView.h" -#include "IqtFitModel.h" - -#include "MantidAPI/FunctionFactory.h" - -using namespace Mantid; -using namespace Mantid::API; - -namespace { -Mantid::Kernel::Logger g_log("IqtFit"); -std::vector IQTFIT_HIDDEN_PROPS = - std::vector({"CreateOutput", "LogValue", "PassWSIndexToFunction", "ConvolveMembers", - "OutputCompositeMembers", "OutputWorkspace", "Output", "PeakRadius", "PlotParameter"}); -} // namespace - -namespace MantidQt::CustomInterfaces::IDA { - -IndirectDataAnalysisIqtFitTab::IndirectDataAnalysisIqtFitTab(QWidget *parent) - : IndirectDataAnalysisTab(new IqtFitModel, parent), m_uiForm(new Ui::IndirectFitTab) { - m_uiForm->setupUi(parent); - m_uiForm->dockArea->setFitDataView(new IndirectFitDataView(m_uiForm->dockArea)); - setFitDataPresenter( - std::make_unique(m_fittingModel->getFitDataModel(), m_uiForm->dockArea->m_fitDataView)); - setPlotView(m_uiForm->dockArea->m_fitPlotView); - setOutputOptionsView(m_uiForm->ovOutputOptionsView); - auto templateBrowser = new IqtTemplateBrowser; - m_uiForm->dockArea->m_fitPropertyBrowser->setFunctionTemplateBrowser(templateBrowser); - setFitPropertyBrowser(m_uiForm->dockArea->m_fitPropertyBrowser); - m_uiForm->dockArea->m_fitPropertyBrowser->setHiddenProperties(IQTFIT_HIDDEN_PROPS); - setRunButton(m_uiForm->pbRun); - - setEditResultVisible(true); -} - -EstimationDataSelector IndirectDataAnalysisIqtFitTab::getEstimationDataSelector() const { - return - [](const MantidVec &x, const MantidVec &y, const std::pair range) -> DataForParameterEstimation { - (void)range; - size_t const n = 4; - if (y.size() < n + 1) - return DataForParameterEstimation{{}, {}}; - return DataForParameterEstimation{{x[0], x[n]}, {y[0], y[n]}}; - }; -} - -void IndirectDataAnalysisIqtFitTab::addDataToModel(IAddWorkspaceDialog const *dialog) { - if (const auto indirectDialog = dynamic_cast(dialog)) { - m_dataPresenter->addWorkspace(indirectDialog->workspaceName(), indirectDialog->workspaceIndices()); - m_fittingModel->addDefaultParameters(); - } -} - -std::string IndirectDataAnalysisIqtFitTab::getFitTypeString() const { - const auto numberOfExponential = getNumberOfCustomFunctions("ExpDecay"); - const auto numberOfStretched = getNumberOfCustomFunctions("StretchExp"); - std::string functionType{""}; - if (numberOfExponential > 0) - functionType += std::to_string(numberOfExponential) + "E"; - - if (numberOfStretched > 0) - functionType += std::to_string(numberOfStretched) + "S"; - - return functionType; -} - -} // namespace MantidQt::CustomInterfaces::IDA diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisIqtFitTab.h b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisIqtFitTab.h deleted file mode 100644 index c511898013b0..000000000000 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisIqtFitTab.h +++ /dev/null @@ -1,48 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#pragma once - -#include "IndirectDataAnalysisTab.h" - -#include "MantidAPI/CompositeFunction.h" -#include "MantidAPI/MatrixWorkspace_fwd.h" -#include "ui_IndirectFitTab.h" - -#include - -namespace Mantid { -namespace API { -class IFunction; -class CompositeFunction; -} // namespace API -} // namespace Mantid - -namespace MantidQt { -namespace CustomInterfaces { -namespace IDA { - -class MANTIDQT_INELASTIC_DLL IndirectDataAnalysisIqtFitTab : public IndirectDataAnalysisTab { - Q_OBJECT - -public: - IndirectDataAnalysisIqtFitTab(QWidget *parent = nullptr); - - std::string getTabName() const override { return "IqtFit"; } - - bool hasResolution() const override { return false; } - -private: - std::string getFitTypeString() const override; - EstimationDataSelector getEstimationDataSelector() const override; - void addDataToModel(IAddWorkspaceDialog const *dialog) override; - - std::unique_ptr m_uiForm; - QString m_tiedParameter; -}; -} // namespace IDA -} // namespace CustomInterfaces -} // namespace MantidQt diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisMSDFitTab.cpp b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisMSDFitTab.cpp deleted file mode 100644 index f40fb1e6c3d6..000000000000 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisMSDFitTab.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#include "IndirectDataAnalysisMSDFitTab.h" -#include "IDAFunctionParameterEstimation.h" -#include "IndirectAddWorkspaceDialog.h" -#include "MSDFitModel.h" - -#include "FunctionBrowser/SingleFunctionTemplateBrowser.h" - -#include "MantidQtWidgets/Common/UserInputValidator.h" - -#include "MantidAPI/FunctionFactory.h" - -using namespace Mantid::API; - -namespace { -Mantid::Kernel::Logger g_log("MSDFit"); -std::vector MSDFIT_HIDDEN_PROPS = - std::vector({"CreateOutput", "LogValue", "PassWSIndexToFunction", "ConvolveMembers", - "OutputCompositeMembers", "OutputWorkspace", "Output", "PeakRadius", "PlotParameter"}); - -const std::string MSDGAUSSFUNC{"MsdGauss"}; -const std::string MSDPETERSFUNC{"MsdPeters"}; -const std::string MSDYIFUNC{"MsdYi"}; - -} // namespace - -namespace MantidQt { -namespace CustomInterfaces { -namespace IDA { - -auto msdFunctionStrings = - std::map({{"None", ""}, - {"Gauss", "name=MsdGauss,Height=1,Msd=0.05,constraints=(Height>0, Msd>0)"}, - {"Peters", "name=MsdPeters,Height=1,Msd=0.05,Beta=1,constraints=(Height>0, " - "Msd>0, Beta>0)"}, - {"Yi", "name=MsdYi,Height=1,Msd=0.05,Sigma=1,constraints=(Height>0, Msd>0, " - "Sigma>0)"}}); - -IndirectDataAnalysisMSDFitTab::IndirectDataAnalysisMSDFitTab(QWidget *parent) - : IndirectDataAnalysisTab(new MSDFitModel, parent), m_uiForm(new Ui::IndirectFitTab) { - m_uiForm->setupUi(parent); - - m_uiForm->dockArea->setFitDataView(new IndirectFitDataView(m_uiForm->dockArea)); - setFitDataPresenter( - std::make_unique(m_fittingModel->getFitDataModel(), m_uiForm->dockArea->m_fitDataView)); - setPlotView(m_uiForm->dockArea->m_fitPlotView); - setOutputOptionsView(m_uiForm->ovOutputOptionsView); - auto parameterEstimation = createParameterEstimation(); - auto templateBrowser = new SingleFunctionTemplateBrowser( - msdFunctionStrings, std::make_unique(parameterEstimation)); - m_uiForm->dockArea->m_fitPropertyBrowser->setFunctionTemplateBrowser(templateBrowser); - setFitPropertyBrowser(m_uiForm->dockArea->m_fitPropertyBrowser); - m_uiForm->dockArea->m_fitPropertyBrowser->setHiddenProperties(MSDFIT_HIDDEN_PROPS); - setRunButton(m_uiForm->pbRun); - - setEditResultVisible(false); -} - -EstimationDataSelector IndirectDataAnalysisMSDFitTab::getEstimationDataSelector() const { - - return [](const std::vector &x, const std::vector &y, - const std::pair range) -> DataForParameterEstimation { - // Find data thats within range - double xmin = range.first; - double xmax = range.second; - if (xmin > xmax) { - return DataForParameterEstimation{}; - } - - const auto startItr = - std::find_if(x.cbegin(), x.cend(), [xmin](const double &val) -> bool { return val >= (xmin - 1e-5); }); - auto endItr = std::find_if(x.cbegin(), x.cend(), [xmax](const double &val) -> bool { return val > xmax; }); - - size_t first = std::distance(x.cbegin(), startItr); - size_t end = std::distance(x.cbegin(), endItr); - size_t m = first + (end - first) / 2; - - if (std::distance(startItr, endItr - 1) < 2) - return DataForParameterEstimation{}; - - return DataForParameterEstimation{{x[first], x[m]}, {y[first], y[m]}}; - }; -} - -std::string IndirectDataAnalysisMSDFitTab::getFitTypeString() const { - // This function attempts to work out which fit type is being done. It will - // currently only recognise the three default types. - const auto numberOfGauss = getNumberOfCustomFunctions("MsdGauss"); - const auto numberOfPeters = getNumberOfCustomFunctions("MsdPeters"); - const auto numberOfYi = getNumberOfCustomFunctions("MsdYi"); - - if (numberOfGauss + numberOfPeters + numberOfYi != 1) { - return "UserDefined"; - } - - if (numberOfGauss == 1) - return "Gauss"; - - if (numberOfPeters == 1) - return "Peters"; - - if (numberOfYi == 1) - return "Yi"; - - return "UserDefined"; -} -// Create parameter estimation functions -// These function rely on the data returned from getEstimationDataSelector, -// which should be appropriately configured. -IDAFunctionParameterEstimation IndirectDataAnalysisMSDFitTab::createParameterEstimation() const { - auto estimateMsd = [](::Mantid::API::IFunction_sptr &function, const DataForParameterEstimation &estimationData) { - auto y = estimationData.y; - auto x = estimationData.x; - if (x.size() != 2 || y.size() != 2) { - return; - } - double Msd = 6 * log(y[0] / y[1]) / (x[1] * x[1]); - // If MSD less than zero, reject the estimate and set to default value of - // 0.05, which leads to a (roughly) flat line - Msd = Msd > 0 ? Msd : 0.05; - function->setParameter("Msd", Msd); - function->setParameter("Height", y[0]); - }; - IDAFunctionParameterEstimation parameterEstimation; - - parameterEstimation.addParameterEstimationFunction(MSDGAUSSFUNC, estimateMsd); - parameterEstimation.addParameterEstimationFunction(MSDPETERSFUNC, estimateMsd); - parameterEstimation.addParameterEstimationFunction(MSDYIFUNC, estimateMsd); - - return parameterEstimation; -} - -void IndirectDataAnalysisMSDFitTab::addDataToModel(IAddWorkspaceDialog const *dialog) { - if (const auto indirectDialog = dynamic_cast(dialog)) { - m_dataPresenter->addWorkspace(indirectDialog->workspaceName(), indirectDialog->workspaceIndices()); - m_fittingModel->addDefaultParameters(); - } -} - -} // namespace IDA -} // namespace CustomInterfaces -} // namespace MantidQt diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisMSDFitTab.h b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisMSDFitTab.h deleted file mode 100644 index 359f2ef06934..000000000000 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisMSDFitTab.h +++ /dev/null @@ -1,39 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#pragma once - -#include "IndirectDataAnalysisTab.h" -#include "ui_IndirectFitTab.h" - -#include "MantidAPI/IFunction.h" - -namespace MantidQt { -namespace CustomInterfaces { -namespace IDA { -class IDAFunctionParameterEstimation; - -class MANTIDQT_INELASTIC_DLL IndirectDataAnalysisMSDFitTab : public IndirectDataAnalysisTab { - Q_OBJECT - -public: - IndirectDataAnalysisMSDFitTab(QWidget *parent = nullptr); - - std::string getTabName() const override { return "MSDFit"; } - - bool hasResolution() const override { return false; } - -private: - EstimationDataSelector getEstimationDataSelector() const override; - std::string getFitTypeString() const override; - IDAFunctionParameterEstimation createParameterEstimation() const; - void addDataToModel(IAddWorkspaceDialog const *dialog) override; - - std::unique_ptr m_uiForm; -}; -} // namespace IDA -} // namespace CustomInterfaces -} // namespace MantidQt diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisTab.cpp b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisTab.cpp index 8bed109b28e2..00045ef59d3b 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisTab.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisTab.cpp @@ -7,7 +7,7 @@ #include "IndirectDataAnalysisTab.h" #include "IndirectSettingsHelper.h" -#include "IndirectAddWorkspaceDialog.h" +#include "FitTabConstants.h" #include "MantidAPI/FunctionFactory.h" #include "MantidAPI/MultiDomainFunction.h" #include "MantidAPI/TextAxis.h" @@ -67,11 +67,13 @@ size_t IndirectDataAnalysisTab::getNumberOfSpecificFunctionContained(const std:: } } -IndirectDataAnalysisTab::IndirectDataAnalysisTab(IndirectFittingModel *model, QWidget *parent) - : IndirectTab(parent), m_fittingModel(model), m_runButton() {} +IndirectDataAnalysisTab::IndirectDataAnalysisTab(std::string const &tabName, bool const hasResolution, QWidget *parent) + : IndirectTab(parent), m_uiForm(new Ui::IndirectFitTab), m_tabName(tabName), m_hasResolution(hasResolution) { + m_uiForm->setupUi(parent); +} void IndirectDataAnalysisTab::setup() { - connect(m_runButton, SIGNAL(clicked()), this, SLOT(runTab())); + connect(m_uiForm->pbRun, SIGNAL(clicked()), this, SLOT(runTab())); updateResultOptions(); connect(m_outOptionsPresenter.get(), SIGNAL(plotSpectra()), this, SLOT(plotSelectedSpectra())); @@ -113,31 +115,26 @@ void IndirectDataAnalysisTab::connectFitPropertyBrowser() { connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this, SLOT(respondToFunctionChanged())); } -void IndirectDataAnalysisTab::setFitDataPresenter(std::unique_ptr presenter) { - m_dataPresenter = std::move(presenter); +void IndirectDataAnalysisTab::setupOutputOptionsPresenter(bool const editResults) { + m_outOptionsPresenter = std::make_unique(m_uiForm->ovOutputOptionsView); + m_outOptionsPresenter->setEditResultVisible(editResults); } -void IndirectDataAnalysisTab::setPlotView(IIndirectFitPlotView *view) { - m_plotPresenter = std::make_unique(view); +void IndirectDataAnalysisTab::setupPlotView(std::optional> const &xPlotBounds) { + m_plotPresenter = std::make_unique(m_uiForm->dockArea->m_fitPlotView); m_plotPresenter->setFittingData(m_dataPresenter->getFittingData()); m_plotPresenter->setFitOutput(m_fittingModel->getFitOutput()); + if (xPlotBounds) { + m_plotPresenter->setXBounds(*xPlotBounds); + } m_plotPresenter->updatePlots(); } -void IndirectDataAnalysisTab::setOutputOptionsView(IIndirectFitOutputOptionsView *view) { - m_outOptionsPresenter = std::make_unique(view); -} - -void IndirectDataAnalysisTab::setFitPropertyBrowser(IndirectFitPropertyBrowser *browser) { - browser->init(); - m_fitPropertyBrowser = browser; +void IndirectDataAnalysisTab::setRunIsRunning(bool running) { + m_uiForm->pbRun->setText(running ? "Running..." : "Run"); } -void IndirectDataAnalysisTab::setRunButton(QPushButton *runButton) { m_runButton = runButton; } - -void IndirectDataAnalysisTab::setRunIsRunning(bool running) { m_runButton->setText(running ? "Running..." : "Run"); } - -void IndirectDataAnalysisTab::setRunEnabled(bool enable) { m_runButton->setEnabled(enable); } +void IndirectDataAnalysisTab::setRunEnabled(bool enable) { m_uiForm->pbRun->setEnabled(enable); } void IndirectDataAnalysisTab::setFileExtensionsByName(bool filter) { auto const tab = getTabName(); @@ -525,7 +522,7 @@ void IndirectDataAnalysisTab::setPDFWorkspace(std::string const &workspaceName) void IndirectDataAnalysisTab::updateParameterEstimationData() { m_fitPropertyBrowser->updateParameterEstimationData( - m_dataPresenter->getDataForParameterEstimation(getEstimationDataSelector())); + m_dataPresenter->getDataForParameterEstimation(m_fitPropertyBrowser->getEstimationDataSelector())); const bool isFit = m_fittingModel->isPreviouslyFit(getSelectedDataIndex(), getSelectedSpectrum()); // If we haven't fit the data yet we may update the guess if (!isFit) { @@ -636,7 +633,9 @@ void IndirectDataAnalysisTab::respondToDataChanged() { } void IndirectDataAnalysisTab::respondToDataAdded(IAddWorkspaceDialog const *dialog) { - addDataToModel(dialog); + if (m_dataPresenter->addWorkspaceFromDialog(dialog)) { + m_fittingModel->addDefaultParameters(); + } updateDataReferences(); auto displayNames = m_dataPresenter->createDisplayNames(); m_plotPresenter->appendLastDataToSelection(displayNames); @@ -677,11 +676,25 @@ void IndirectDataAnalysisTab::respondToFunctionChanged() { m_fittingModel->setFitTypeString(getFitTypeString()); } -void IndirectDataAnalysisTab::addDataToModel(IAddWorkspaceDialog const *dialog) { - if (const auto indirectDialog = dynamic_cast(dialog)) { - m_dataPresenter->addWorkspace(indirectDialog->workspaceName(), indirectDialog->workspaceIndices()); - m_fittingModel->addDefaultParameters(); +std::string IndirectDataAnalysisTab::getFitTypeString() const { + auto const multiDomainFunction = m_fittingModel->getFitFunction(); + if (!multiDomainFunction || multiDomainFunction->nFunctions() == 0) { + return "NoCurrentFunction"; + } + + std::string fitType{""}; + for (auto fitFunctionName : FUNCTION_STRINGS) { + auto occurances = getNumberOfCustomFunctions(fitFunctionName.first); + if (occurances > 0) { + fitType += std::to_string(occurances) + fitFunctionName.second; + } } + + if (getNumberOfCustomFunctions("DeltaFunction") > 0) { + fitType += "Delta"; + } + + return fitType; } } // namespace IDA diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisTab.h b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisTab.h index bc92010645a4..4885934caa8e 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisTab.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/IndirectDataAnalysisTab.h @@ -13,6 +13,7 @@ #include "IndirectFitPropertyBrowser.h" #include "IndirectFittingModel.h" #include "IndirectTab.h" +#include "ui_IndirectFitTab.h" #include "MantidQtWidgets/Common/FunctionModelDataset.h" @@ -21,6 +22,7 @@ #include #include +#include #include #include @@ -35,13 +37,33 @@ class MANTIDQT_INELASTIC_DLL IndirectDataAnalysisTab : public IndirectTab { Q_OBJECT public: - IndirectDataAnalysisTab(IndirectFittingModel *model, QWidget *parent = nullptr); + IndirectDataAnalysisTab(std::string const &tabName, bool const hasResolution, QWidget *parent = nullptr); virtual ~IndirectDataAnalysisTab() override = default; - void setFitDataPresenter(std::unique_ptr presenter); - void setPlotView(IIndirectFitPlotView *view); - void setOutputOptionsView(IIndirectFitOutputOptionsView *view); - void setFitPropertyBrowser(IndirectFitPropertyBrowser *browser); + template void setupFittingModel() { m_fittingModel = std::make_unique(); } + + template + void setupFitPropertyBrowser(std::vector const &hiddenProperties, bool const convolveMembers = false) { + auto functionModel = std::make_unique(); + m_uiForm->dockArea->m_fitPropertyBrowser->setFunctionTemplateBrowser(new TemplateBrowser(std::move(functionModel))); + m_uiForm->dockArea->m_fitPropertyBrowser->init(); + m_uiForm->dockArea->m_fitPropertyBrowser->setHiddenProperties(hiddenProperties); + m_fitPropertyBrowser = m_uiForm->dockArea->m_fitPropertyBrowser; + setConvolveMembers(convolveMembers); + } + + template void setupFitDataView() { + m_uiForm->dockArea->setFitDataView(new FitDataView(m_uiForm->dockArea)); + } + + template void setUpFitDataPresenter() { + m_dataPresenter = + std::make_unique(m_fittingModel->getFitDataModel(), m_uiForm->dockArea->m_fitDataView); + } + + void setupOutputOptionsPresenter(bool const editResults = false); + void setupPlotView(std::optional> const &xPlotBounds = std::nullopt); + WorkspaceID getSelectedDataIndex() const; WorkspaceIndex getSelectedSpectrum() const; bool isRangeCurrentlySelected(WorkspaceID workspaceID, WorkspaceIndex spectrum) const; @@ -51,12 +73,11 @@ class MANTIDQT_INELASTIC_DLL IndirectDataAnalysisTab : public IndirectTab { static size_t getNumberOfSpecificFunctionContained(const std::string &functionName, const IFunction *compositeFunction); - virtual std::string getTabName() const = 0; - virtual bool hasResolution() const = 0; + std::string getTabName() const noexcept { return m_tabName; } + bool hasResolution() const noexcept { return m_hasResolution; } void setFileExtensionsByName(bool filter); protected: - void setRunButton(QPushButton *runButton); IndirectFittingModel *getFittingModel() const; void run() override; void setSampleWSSuffixes(const QStringList &suffices); @@ -81,10 +102,11 @@ class MANTIDQT_INELASTIC_DLL IndirectDataAnalysisTab : public IndirectTab { WorkspaceID m_activeWorkspaceID; WorkspaceIndex m_activeSpectrumIndex; + std::unique_ptr m_uiForm; + private: void setup() override; bool validate() override; - virtual EstimationDataSelector getEstimationDataSelector() const = 0; void connectPlotPresenter(); void connectFitPropertyBrowser(); void connectDataPresenter(); @@ -98,12 +120,13 @@ class MANTIDQT_INELASTIC_DLL IndirectDataAnalysisTab : public IndirectTab { void enableOutputOptions(bool enable); void setPDFWorkspace(std::string const &workspaceName); void updateParameterEstimationData(); - virtual void addDataToModel(IAddWorkspaceDialog const *dialog) = 0; - virtual std::string getFitTypeString() const = 0; + std::string getFitTypeString() const; + + std::string m_tabName; + bool m_hasResolution; std::unique_ptr m_outOptionsPresenter; Mantid::API::IAlgorithm_sptr m_fittingAlgorithm; - QPushButton *m_runButton; protected slots: void setModelFitFunction(); diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitDataPresenter.cpp b/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitDataPresenter.cpp index 9a60ce8c3cad..cee42fc5d217 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitDataPresenter.cpp @@ -49,6 +49,14 @@ std::vector *IndirectFitDataPresenter::getFittingData() { retur IIndirectFitDataView const *IndirectFitDataPresenter::getView() const { return m_view; } +bool IndirectFitDataPresenter::addWorkspaceFromDialog(IAddWorkspaceDialog const *dialog) { + if (const auto indirectDialog = dynamic_cast(dialog)) { + addWorkspace(indirectDialog->workspaceName(), indirectDialog->workspaceIndices()); + return true; + } + return false; +} + void IndirectFitDataPresenter::addWorkspace(const std::string &workspaceName, const std::string &spectra) { m_model->addWorkspace(workspaceName, spectra); } diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitDataPresenter.h b/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitDataPresenter.h index ec83976a99a6..57037046b8da 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitDataPresenter.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitDataPresenter.h @@ -29,6 +29,7 @@ class MANTIDQT_INELASTIC_DLL IndirectFitDataPresenter : public QObject, public A IndirectFitDataPresenter(IIndirectFitDataModel *model, IIndirectFitDataView *view); ~IndirectFitDataPresenter(); std::vector *getFittingData(); + virtual bool addWorkspaceFromDialog(IAddWorkspaceDialog const *dialog); void addWorkspace(const std::string &workspaceName, const std::string &spectra); void setResolution(const std::string &name); void setSampleWSSuffices(const QStringList &suffices); diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitPropertyBrowser.cpp b/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitPropertyBrowser.cpp index 9c8b44c9407c..79e97a14000c 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitPropertyBrowser.cpp +++ b/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitPropertyBrowser.cpp @@ -328,6 +328,10 @@ void IndirectFitPropertyBrowser::setErrorsEnabled(bool enabled) { m_templateBrowser->setErrorsEnabled(enabled); } +EstimationDataSelector IndirectFitPropertyBrowser::getEstimationDataSelector() const { + return m_templateBrowser->getEstimationDataSelector(); +} + void IndirectFitPropertyBrowser::updateParameterEstimationData(DataForParameterEstimationCollection &&data) { m_templateBrowser->updateParameterEstimationData(std::move(data)); } diff --git a/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitPropertyBrowser.h b/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitPropertyBrowser.h index 6e5e373d85f9..ad2050ca2991 100644 --- a/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitPropertyBrowser.h +++ b/qt/scientific_interfaces/Inelastic/Analysis/IndirectFitPropertyBrowser.h @@ -79,6 +79,7 @@ class MANTIDQT_INELASTIC_DLL IndirectFitPropertyBrowser : public QDockWidget { const std::vector> &fitResolutions); void updatePlotGuess(const MatrixWorkspace_const_sptr &sampleWorkspace); void setErrorsEnabled(bool enabled); + EstimationDataSelector getEstimationDataSelector() const; void updateParameterEstimationData(DataForParameterEstimationCollection &&data); void estimateFunctionParameters(); void setBackgroundA0(double value); diff --git a/qt/scientific_interfaces/Inelastic/CMakeLists.txt b/qt/scientific_interfaces/Inelastic/CMakeLists.txt index e1b77abd19c7..0bd693c1f33c 100644 --- a/qt/scientific_interfaces/Inelastic/CMakeLists.txt +++ b/qt/scientific_interfaces/Inelastic/CMakeLists.txt @@ -3,12 +3,9 @@ set(SRC_FILES Analysis/ConvFitModel.cpp Analysis/ConvFitDataView.cpp Analysis/ConvFitDataPresenter.cpp + Analysis/DataAnalysisTabFactory.cpp Analysis/IndirectDataAnalysis.cpp Analysis/IndirectDataAnalysisTab.cpp - Analysis/IndirectDataAnalysisMSDFitTab.cpp - Analysis/IndirectDataAnalysisIqtFitTab.cpp - Analysis/IndirectDataAnalysisConvFitTab.cpp - Analysis/IndirectDataAnalysisFqFitTab.cpp Analysis/FqFitAddWorkspaceDialog.cpp Analysis/FqFitDataPresenter.cpp Analysis/FqFitDataView.cpp @@ -37,9 +34,11 @@ set(SRC_FILES Analysis/FunctionBrowser/ConvFunctionModel.cpp Analysis/FunctionBrowser/ConvTemplateBrowser.cpp Analysis/FunctionBrowser/ConvTemplatePresenter.cpp + Analysis/FunctionBrowser/FqFunctionModel.cpp Analysis/FunctionBrowser/IqtFunctionModel.cpp Analysis/FunctionBrowser/IqtTemplateBrowser.cpp Analysis/FunctionBrowser/IqtTemplatePresenter.cpp + Analysis/FunctionBrowser/MSDFunctionModel.cpp Analysis/FunctionBrowser/SingleFunctionTemplateModel.cpp Analysis/FunctionBrowser/SingleFunctionTemplateBrowser.cpp Analysis/FunctionBrowser/SingleFunctionTemplatePresenter.cpp @@ -68,10 +67,6 @@ set(MOC_FILES Analysis/ConvFitDataPresenter.h Analysis/IndirectDataAnalysis.h Analysis/IndirectDataAnalysisTab.h - Analysis/IndirectDataAnalysisMSDFitTab.h - Analysis/IndirectDataAnalysisIqtFitTab.h - Analysis/IndirectDataAnalysisConvFitTab.h - Analysis/IndirectDataAnalysisFqFitTab.h Analysis/FqFitAddWorkspaceDialog.h Analysis/FqFitDataPresenter.h Analysis/FqFitDataView.h @@ -112,13 +107,13 @@ set(MOC_FILES set(INC_FILES DllConfig.h PrecompiledHeader.h + Analysis/DataAnalysisTabFactory.h Analysis/IDAFunctionParameterEstimation.h Analysis/FqFitModel.h - Analysis/IFQFitObserver.h Analysis/IqtFitModel.h Analysis/MSDFitModel.h Analysis/ConvFitModel.h - Analysis/FQFitConstants.h + Analysis/FitTabConstants.h Analysis/IIndirectFitDataModel.h Analysis/IndirectFitDataModel.h Analysis/IIndirectFitOutput.h @@ -131,6 +126,8 @@ set(INC_FILES Analysis/IndirectFittingModel.h Analysis/ParameterEstimation.h Analysis/FunctionBrowser/ConvFunctionModel.h + Analysis/FunctionBrowser/FqFunctionModel.h + Analysis/FunctionBrowser/MSDFunctionModel.h Manipulation/InelasticDataManipulationElwinTabModel.h Manipulation/InelasticDataManipulationIqtTabModel.h Manipulation/InelasticDataManipulationMomentsTabModel.h diff --git a/qt/scientific_interfaces/Inelastic/test/ConvFitDataPresenterTest.h b/qt/scientific_interfaces/Inelastic/test/ConvFitDataPresenterTest.h index 82ca511fbfb1..b3ce10521e49 100644 --- a/qt/scientific_interfaces/Inelastic/test/ConvFitDataPresenterTest.h +++ b/qt/scientific_interfaces/Inelastic/test/ConvFitDataPresenterTest.h @@ -9,9 +9,11 @@ #include #include +#include "Analysis/ConvFitAddWorkspaceDialog.h" #include "Analysis/ConvFitDataPresenter.h" #include "Analysis/ConvFitModel.h" #include "Analysis/IIndirectFitDataView.h" +#include "IndirectAddWorkspaceDialog.h" #include "MantidAPI/FrameworkManager.h" #include "MantidFrameworkTestHelpers/IndirectFitDataCreationHelper.h" @@ -160,6 +162,16 @@ class ConvFitDataPresenterTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(m_dataTable->columnCount(), 6); } + void test_addWorkspaceFromDialog_returns_false_if_the_dialog_is_not_convfit() { + auto dialog = new IndirectAddWorkspaceDialog(nullptr); + TS_ASSERT(!m_presenter->addWorkspaceFromDialog(dialog)); + } + + void test_addWorkspaceFromDialog_returns_true_for_a_valid_dialog() { + auto dialog = new ConvFitAddWorkspaceDialog(nullptr); + TS_ASSERT(m_presenter->addWorkspaceFromDialog(dialog)); + } + void test_updateTableFromModel_clears_table_and_adds_new_row_for_each_entry() { EXPECT_CALL(*m_view, clearTable()).Times(Exactly(1)); EXPECT_CALL(*m_model, getNumberOfDomains()).Times(Exactly(4)).WillRepeatedly(Return(3)); diff --git a/qt/scientific_interfaces/Inelastic/test/FqFitDataPresenterTest.h b/qt/scientific_interfaces/Inelastic/test/FqFitDataPresenterTest.h index e868558231e9..2293652efca6 100644 --- a/qt/scientific_interfaces/Inelastic/test/FqFitDataPresenterTest.h +++ b/qt/scientific_interfaces/Inelastic/test/FqFitDataPresenterTest.h @@ -9,10 +9,12 @@ #include #include +#include "Analysis/FqFitAddWorkspaceDialog.h" #include "Analysis/FqFitDataPresenter.h" #include "Analysis/FqFitModel.h" #include "Analysis/FunctionBrowser/SingleFunctionTemplateBrowser.h" #include "Analysis/IndirectFitDataView.h" +#include "IndirectAddWorkspaceDialog.h" #include "MantidAPI/FrameworkManager.h" #include "MantidFrameworkTestHelpers/IndirectFitDataCreationHelper.h" @@ -116,10 +118,6 @@ class MockIndirectFitDataModel : public IIndirectFitDataModel { MOCK_CONST_METHOD1(getExcludeRegionVector, std::vector(FitDomainIndex index)); }; -class SingleFunctionTemplateBrowserMock : public IFQFitObserver { - MOCK_METHOD1(updateAvailableFunctions, void(const std::map &functionInitialisationStrings)); -}; - /// Mock object to mock the model class MockFqFitModel : public FqFitModel {}; @@ -139,12 +137,10 @@ class FqFitDataPresenterTest : public CxxTest::TestSuite { m_model = std::make_unique>(); m_dataTable = createEmptyTableWidget(6, 5); - m_SingleFunctionTemplateBrowser = std::make_unique(); ON_CALL(*m_view, getDataTable()).WillByDefault(Return(m_dataTable.get())); - m_presenter = std::make_unique(std::move(m_model.get()), std::move(m_view.get()), - m_SingleFunctionTemplateBrowser.get()); + m_presenter = std::make_unique(std::move(m_model.get()), std::move(m_view.get())); m_workspace = createWorkspaceWithTextAxis(6, getTextAxisLabels()); m_ads = std::make_unique("WorkspaceName", m_workspace); } @@ -168,6 +164,11 @@ class FqFitDataPresenterTest : public CxxTest::TestSuite { TS_ASSERT(m_view); } + void test_addWorkspaceFromDialog_returns_false_if_the_dialog_is_not_fqfit() { + auto dialog = new IndirectAddWorkspaceDialog(nullptr); + TS_ASSERT(!m_presenter->addWorkspaceFromDialog(dialog)); + } + void test_addWorkspace_does_not_throw_with_width() { EXPECT_CALL(*m_model, addWorkspace("WorkspaceName_HWHM", FunctionModelSpectra("0"))).Times(Exactly(1)); m_presenter->addWorkspace("WorkspaceName", "Width", 0); @@ -201,7 +202,6 @@ class FqFitDataPresenterTest : public CxxTest::TestSuite { private: std::unique_ptr m_dataTable; - std::unique_ptr m_SingleFunctionTemplateBrowser; std::unique_ptr m_view; std::unique_ptr m_model; diff --git a/qt/scientific_interfaces/Inelastic/test/IDAFunctionParameterEstimationTest.h b/qt/scientific_interfaces/Inelastic/test/IDAFunctionParameterEstimationTest.h index 38f75e5d19fd..9c295c6af3f7 100644 --- a/qt/scientific_interfaces/Inelastic/test/IDAFunctionParameterEstimationTest.h +++ b/qt/scientific_interfaces/Inelastic/test/IDAFunctionParameterEstimationTest.h @@ -16,46 +16,46 @@ using namespace Mantid::API; using namespace MantidQt::CustomInterfaces::IDA; namespace { -DataForParameterEstimation createEstimationData() { - std::vector x(10, 1); - std::vector y(10, 0.981); +DataForParameterEstimation createEstimationData(int const size) { + std::vector x(size, 1); + std::vector y(size, 0.981); return DataForParameterEstimation{x, y}; } -void estimationFunctionForLinearBackground(IFunction_sptr &function, const DataForParameterEstimation &) { - - function->setParameter("A0", 2.00); - function->setParameter("A1", 3.00); -} } // namespace class IDAFunctionParameterEstimationTest : public CxxTest::TestSuite { public: - IDAFunctionParameterEstimationTest() { m_estimationData = createEstimationData(); } + IDAFunctionParameterEstimationTest() { + m_fitFunction = [](Mantid::MantidVec const &x, Mantid::MantidVec const &y) { + (void)x; + (void)y; + return std::unordered_map{{"A0", 2.0}, {"A1", 3.0}}; + }; + } - void test_estimateFunctionParameters_does_nothing_if_fit_esimate_does_not_exist() { - IDAFunctionParameterEstimation parameterEstimation; + void test_estimateFunctionParameters_does_nothing_if_estimate_data_is_too_small() { + IDAFunctionParameterEstimation parameterEstimation({{"LinearBackground", m_fitFunction}}); auto fun = FunctionFactory::Instance().createInitialized("name=LinearBackground,A0=0,A1=0"); auto funCopy = fun->clone(); - parameterEstimation.estimateFunctionParameters(fun, m_estimationData); + parameterEstimation.estimateFunctionParameters(fun, createEstimationData(1)); TS_ASSERT_EQUALS(fun->getParameter("A0"), funCopy->getParameter("A0")) TS_ASSERT_EQUALS(fun->getParameter("A1"), funCopy->getParameter("A1")) } void test_estimateFunctionParameters_correctly_updates_function() { - IDAFunctionParameterEstimation parameterEstimation; + IDAFunctionParameterEstimation parameterEstimation({{"LinearBackground", m_fitFunction}}); auto fun = FunctionFactory::Instance().createInitialized("name=LinearBackground,A0=0,A1=0"); - parameterEstimation.addParameterEstimationFunction("LinearBackground", estimationFunctionForLinearBackground); - parameterEstimation.estimateFunctionParameters(fun, m_estimationData); + parameterEstimation.estimateFunctionParameters(fun, createEstimationData(2)); TS_ASSERT_EQUALS(fun->getParameter("A0"), 2.00) TS_ASSERT_EQUALS(fun->getParameter("A1"), 3.00) } private: - DataForParameterEstimation m_estimationData; + IDAFunctionParameterEstimation::ParameterEstimator m_fitFunction; }; diff --git a/qt/scientific_interfaces/Inelastic/test/IndirectFitDataPresenterTest.h b/qt/scientific_interfaces/Inelastic/test/IndirectFitDataPresenterTest.h index f5d449ddd399..5e56caa99051 100644 --- a/qt/scientific_interfaces/Inelastic/test/IndirectFitDataPresenterTest.h +++ b/qt/scientific_interfaces/Inelastic/test/IndirectFitDataPresenterTest.h @@ -15,6 +15,7 @@ #include "Analysis/IndirectFitDataView.h" #include "Analysis/IndirectFittingModel.h" #include "Analysis/ParameterEstimation.h" +#include "IndirectAddWorkspaceDialog.h" #include "MantidAPI/FrameworkManager.h" #include "MantidFrameworkTestHelpers/IndirectFitDataCreationHelper.h" @@ -50,6 +51,18 @@ struct TableItem { std::string m_str; double m_dbl; }; + +class FakeDialog : public IAddWorkspaceDialog { + +public: + FakeDialog() : IAddWorkspaceDialog(nullptr) {} + virtual std::string workspaceName() const override { return "Name"; } + virtual void setWSSuffices(const QStringList &suffices) override { (void)suffices; } + virtual void setFBSuffices(const QStringList &suffices) override { (void)suffices; } + + virtual void updateSelectedSpectra() override {} +}; + } // namespace GNU_DIAG_OFF_SUGGEST_OVERRIDE @@ -187,6 +200,16 @@ class IndirectFitDataPresenterTest : public CxxTest::TestSuite { /// Unit Tests that test the signals, methods and slots of the presenter ///---------------------------------------------------------------------- + void test_addWorkspaceFromDialog_returns_false_if_the_dialog_is_not_indirect() { + auto dialog = new FakeDialog(); + TS_ASSERT(!m_presenter->addWorkspaceFromDialog(dialog)); + } + + void test_addWorkspaceFromDialog_returns_true_for_a_valid_dialog() { + auto dialog = new IndirectAddWorkspaceDialog(nullptr); + TS_ASSERT(m_presenter->addWorkspaceFromDialog(dialog)); + } + void test_addWorkspace_with_spectra_calls_to_model() { EXPECT_CALL(*m_model, addWorkspace("WorkspaceName", "0-3")).Times(Exactly(1)); m_presenter->addWorkspace("WorkspaceName", "0-3"); diff --git a/qt/scientific_interfaces/Inelastic/test/IndirectFitPropertyBrowserTest.h b/qt/scientific_interfaces/Inelastic/test/IndirectFitPropertyBrowserTest.h index e3bde825b34c..c8c0c85cd853 100644 --- a/qt/scientific_interfaces/Inelastic/test/IndirectFitPropertyBrowserTest.h +++ b/qt/scientific_interfaces/Inelastic/test/IndirectFitPropertyBrowserTest.h @@ -60,6 +60,7 @@ class MockFunctionTemplateBrowser : public FunctionTemplateBrowser { MOCK_METHOD1(updateParameterNames, void(const QMap ¶meterNames)); MOCK_METHOD1(setErrorsEnabled, void(bool enabled)); MOCK_METHOD0(clear, void()); + MOCK_CONST_METHOD0(getEstimationDataSelector, EstimationDataSelector()); MOCK_METHOD1(updateParameterEstimationData, void(DataForParameterEstimationCollection &&data)); MOCK_METHOD0(estimateFunctionParameters, void()); MOCK_METHOD1(setBackgroundA0, void(double value));