diff --git a/qt/scientific_interfaces/Indirect/ConvFit.cpp b/qt/scientific_interfaces/Indirect/ConvFit.cpp index ab3b816fc6eff0dbe4d26e9baa13b9c75d7e37e8..3eacac55992e4793438b3365952725ce7e9f32a8 100644 --- a/qt/scientific_interfaces/Indirect/ConvFit.cpp +++ b/qt/scientific_interfaces/Indirect/ConvFit.cpp @@ -6,6 +6,7 @@ // SPDX - License - Identifier: GPL - 3.0 + #include "ConvFit.h" #include "ConvFitDataPresenter.h" +#include "IndirectFunctionBrowser/ConvTemplateBrowser.h" #include "MantidQtWidgets/Common/UserInputValidator.h" @@ -22,6 +23,10 @@ #include <QDoubleValidator> #include <QMenu> +#include <qwt_plot.h> +#include <qwt_plot_curve.h> + +using namespace Mantid; using namespace Mantid::API; namespace { @@ -33,23 +38,30 @@ namespace CustomInterfaces { namespace IDA { ConvFit::ConvFit(QWidget *parent) - : IndirectFitAnalysisTabLegacy(new ConvFitModel, parent), + : IndirectFitAnalysisTab(new ConvFitModel, parent), m_uiForm(new Ui::ConvFit) { m_uiForm->setupUi(parent); m_convFittingModel = dynamic_cast<ConvFitModel *>(fittingModel()); - - setFitDataPresenter(std::make_unique<ConvFitDataPresenter>( - m_convFittingModel, m_uiForm->fitDataView)); setPlotView(m_uiForm->pvFitPlotView); setSpectrumSelectionView(m_uiForm->svSpectrumView); setOutputOptionsView(m_uiForm->ovOutputOptionsView); + m_uiForm->fitPropertyBrowser->setFunctionTemplateBrowser( + new ConvTemplateBrowser); setFitPropertyBrowser(m_uiForm->fitPropertyBrowser); + auto dataPresenter = std::make_unique<ConvFitDataPresenter>( + m_convFittingModel, m_uiForm->fitDataView); + connect( + dataPresenter.get(), + SIGNAL(modelResolutionAdded(std::string const &, DatasetIndex const &)), + this, + SLOT(setModelResolution(std::string const &, DatasetIndex const &))); + setFitDataPresenter(std::move(dataPresenter)); setEditResultVisible(true); } void ConvFit::setupFitTab() { - setDefaultPeakType("Lorentzian"); + // setDefaultPeakType("Lorentzian"); setConvolveMembers(true); // Initialise fitTypeStrings @@ -80,27 +92,27 @@ void ConvFit::setupFitTab() { auto deltaFunction = functionFactory.createFunction("DeltaFunction"); - addCheckBoxFunctionGroup("Use Delta Function", {deltaFunction}); + // addCheckBoxFunctionGroup("Use Delta Function", {deltaFunction}); - addComboBoxFunctionGroup("One Lorentzian", {lorentzian}); - addComboBoxFunctionGroup("Two Lorentzians", {lorentzian, lorentzian}); - addComboBoxFunctionGroup("Teixeira Water", {teixeiraWater}); - addComboBoxFunctionGroup("InelasticDiffSphere", {inelasticDiffSphere}); - addComboBoxFunctionGroup("InelasticDiffRotDiscreteCircle", - {inelasticDiffRotDiscCircle}); - addComboBoxFunctionGroup("ElasticDiffSphere", {elasticDiffSphere}); - addComboBoxFunctionGroup("ElasticDiffRotDiscreteCircle", - {elasticDiffRotDiscCircle}); - addComboBoxFunctionGroup("StretchedExpFT", {stretchedExpFT}); + // addComboBoxFunctionGroup("One Lorentzian", {lorentzian}); + // addComboBoxFunctionGroup("Two Lorentzians", {lorentzian, lorentzian}); + // addComboBoxFunctionGroup("Teixeira Water", {teixeiraWater}); + // addComboBoxFunctionGroup("InelasticDiffSphere", {inelasticDiffSphere}); + // addComboBoxFunctionGroup("InelasticDiffRotDiscreteCircle", + // {inelasticDiffRotDiscCircle}); + // addComboBoxFunctionGroup("ElasticDiffSphere", {elasticDiffSphere}); + // addComboBoxFunctionGroup("ElasticDiffRotDiscreteCircle", + // {elasticDiffRotDiscCircle}); + // addComboBoxFunctionGroup("StretchedExpFT", {stretchedExpFT}); - // Set available background options - setBackgroundOptions({"None", "FlatBackground", "LinearBackground"}); + //// Set available background options + // setBackgroundOptions({"None", "FlatBackground", "LinearBackground"}); - addBoolCustomSetting("ExtractMembers", "Extract Members"); - addOptionalDoubleSetting("TempCorrection", "Temp. Correction", - "UseTempCorrection", "Use Temp. Correction"); - setCustomSettingChangesFunction("TempCorrection", true); - setCustomSettingChangesFunction("UseTempCorrection", true); + // addBoolCustomSetting("ExtractMembers", "Extract Members"); + // addOptionalDoubleSetting("TempCorrection", "Temp. Correction", + // "UseTempCorrection", "Use Temp. Correction"); + // setCustomSettingChangesFunction("TempCorrection", true); + // setCustomSettingChangesFunction("UseTempCorrection", true); // Instrument resolution m_properties["InstrumentResolution"] = @@ -112,20 +124,33 @@ void ConvFit::setupFitTab() { } void ConvFit::setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm) { - if (boolSettingValue("UseTempCorrection")) - m_convFittingModel->setTemperature(doubleSettingValue("TempCorrection")); - else - m_convFittingModel->setTemperature(boost::none); - fitAlgorithm->setProperty("ExtractMembers", - boolSettingValue("ExtractMembers")); - IndirectFitAnalysisTabLegacy::setupFit(fitAlgorithm); + // if (boolSettingValue("UseTempCorrection")) + // m_convFittingModel->setTemperature(doubleSettingValue("TempCorrection")); + // else + // m_convFittingModel->setTemperature(boost::none); + // fitAlgorithm->setProperty("ExtractMembers", + // boolSettingValue("ExtractMembers")); + IndirectFitAnalysisTab::setupFit(fitAlgorithm); +} + +EstimationDataSelector ConvFit::getEstimationDataSelector() const { + return + [](const MantidVec &, const MantidVec &) -> DataForParameterEstimation { + return DataForParameterEstimation{}; + }; +} + +void ConvFit::setModelResolution(const std::string &resolutionName) { + setModelResolution(resolutionName, DatasetIndex{0}); } -void ConvFit::setModelResolution(const QString &resolutionName) { - const auto name = resolutionName.toStdString(); +void ConvFit::setModelResolution(const std::string &resolutionName, + DatasetIndex index) { const auto resolution = - AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(name); - m_convFittingModel->setResolution(resolution, 0); + AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( + resolutionName); + m_convFittingModel->setResolution(resolution, index); + m_uiForm->fitPropertyBrowser->setModelResolution(resolutionName, index); setModelFitFunction(); } diff --git a/qt/scientific_interfaces/Indirect/ConvFit.h b/qt/scientific_interfaces/Indirect/ConvFit.h index 9caa438a6171e383309a34b40efec981951b670b..0fcd325f75ca43e175bd4348bc23292aeb909db9 100644 --- a/qt/scientific_interfaces/Indirect/ConvFit.h +++ b/qt/scientific_interfaces/Indirect/ConvFit.h @@ -8,8 +8,9 @@ #define MANTIDQTCUSTOMINTERFACESIDA_CONVFIT_H_ #include "ConvFitModel.h" -#include "IndirectFitAnalysisTabLegacy.h" -#include "IndirectSpectrumSelectionPresenterLegacy.h" +#include "IndirectFitAnalysisTab.h" +#include "IndirectSpectrumSelectionPresenter.h" +#include "ParameterEstimation.h" #include "MantidAPI/CompositeFunction.h" #include "MantidAPI/MatrixWorkspace_fwd.h" @@ -18,7 +19,7 @@ namespace MantidQt { namespace CustomInterfaces { namespace IDA { -class DLLExport ConvFit : public IndirectFitAnalysisTabLegacy { +class DLLExport ConvFit : public IndirectFitAnalysisTab { Q_OBJECT public: @@ -29,7 +30,9 @@ public: bool hasResolution() const override { return true; } protected slots: - void setModelResolution(const QString &resolutionName); + void setModelResolution(const std::string &resolutionName); + void setModelResolution(const std::string &resolutionName, + DatasetIndex index); void runClicked(); void fitFunctionChanged(); @@ -40,6 +43,7 @@ protected: private: void setupFitTab() override; void setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm) override; + EstimationDataSelector getEstimationDataSelector() const override; std::string fitTypeString() const; diff --git a/qt/scientific_interfaces/Indirect/ConvFit.ui b/qt/scientific_interfaces/Indirect/ConvFit.ui index 58fc9dbe4d5c2d37990814d4b768d1ec17042b98..87e1da640fc769c6ce4e9fe267388e445a630edf 100644 --- a/qt/scientific_interfaces/Indirect/ConvFit.ui +++ b/qt/scientific_interfaces/Indirect/ConvFit.ui @@ -22,7 +22,7 @@ <property name="childrenCollapsible"> <bool>false</bool> </property> - <widget class="MantidQt::CustomInterfaces::IDA::IndirectFitDataViewLegacy" name="fitDataView" native="true"> + <widget class="MantidQt::CustomInterfaces::IDA::IndirectFitDataView" name="fitDataView" native="true"> <property name="minimumSize"> <size> <width>0</width> @@ -38,12 +38,12 @@ <enum>QLayout::SetNoConstraint</enum> </property> <item> - <widget class="MantidQt::MantidWidgets::IndirectFitPropertyBrowserLegacy" name="fitPropertyBrowser"> + <widget class="MantidQt::CustomInterfaces::IDA::IndirectFitPropertyBrowser" name="fitPropertyBrowser"> <widget class="QWidget" name="dockWidgetContents_2"/> </widget> </item> <item> - <widget class="MantidQt::CustomInterfaces::IDA::IndirectFitPlotViewLegacy" name="pvFitPlotView" native="true"/> + <widget class="MantidQt::CustomInterfaces::IDA::IndirectFitPlotView" name="pvFitPlotView" native="true"/> </item> </layout> </item> @@ -71,7 +71,7 @@ <number>0</number> </property> <item> - <widget class="MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionViewLegacy" name="svSpectrumView" native="true"> + <widget class="MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionView" name="svSpectrumView" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>1</horstretch> @@ -150,27 +150,27 @@ </widget> <customwidgets> <customwidget> - <class>MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionViewLegacy</class> + <class>MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionView</class> <extends>QWidget</extends> - <header>IndirectSpectrumSelectionViewLegacy.h</header> + <header>IndirectSpectrumSelectionView.h</header> <container>1</container> </customwidget> <customwidget> - <class>MantidQt::MantidWidgets::IndirectFitPropertyBrowserLegacy</class> + <class>MantidQt::CustomInterfaces::IDA::IndirectFitPropertyBrowser</class> <extends>QDockWidget</extends> - <header>MantidQtWidgets/Common/IndirectFitPropertyBrowserLegacy.h</header> + <header>IndirectFitPropertyBrowser.h</header> <container>1</container> </customwidget> <customwidget> - <class>MantidQt::CustomInterfaces::IDA::IndirectFitPlotViewLegacy</class> + <class>MantidQt::CustomInterfaces::IDA::IndirectFitPlotView</class> <extends>QWidget</extends> - <header>IndirectFitPlotViewLegacy.h</header> + <header>IndirectFitPlotView.h</header> <container>1</container> </customwidget> <customwidget> - <class>MantidQt::CustomInterfaces::IDA::IndirectFitDataViewLegacy</class> + <class>MantidQt::CustomInterfaces::IDA::IndirectFitDataView</class> <extends>QWidget</extends> - <header>IndirectFitDataViewLegacy.h</header> + <header>IndirectFitDataView.h</header> <container>1</container> </customwidget> <customwidget> diff --git a/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.ui b/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.ui index a0a25e0a49091019764c39e960d363c52259d962..602567fff90348a59e4f43ae38bc14d97ebb45d3 100644 --- a/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.ui +++ b/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.ui @@ -100,16 +100,7 @@ <item> <widget class="QFrame" name="frame"> <layout class="QHBoxLayout" name="horizontalLayout"> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> + <property name="margin"> <number>0</number> </property> <item> @@ -152,40 +143,7 @@ </customwidget> </customwidgets> <resources/> - <connections> - <connection> - <sender>pbAdd</sender> - <signal>clicked()</signal> - <receiver>ConvFitAddWorkspaceDialog</receiver> - <slot>addData()</slot> - <hints> - <hint type="sourcelabel"> - <x>276</x> - <y>160</y> - </hint> - <hint type="destinationlabel"> - <x>269</x> - <y>319</y> - </hint> - </hints> - </connection> - <connection> - <sender>pbClose</sender> - <signal>clicked()</signal> - <receiver>ConvFitAddWorkspaceDialog</receiver> - <slot>closeDialog()</slot> - <hints> - <hint type="sourcelabel"> - <x>340</x> - <y>171</y> - </hint> - <hint type="destinationlabel"> - <x>335</x> - <y>251</y> - </hint> - </hints> - </connection> - </connections> + <connections/> <slots> <slot>addData()</slot> <slot>closeDialog()</slot> diff --git a/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.cpp b/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.cpp index 045f78b0462f9d4632cc4acbdfa4195d54d9a6c3..ba5647328188f8e12f7d1b556e610c6f70c18755 100644 --- a/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.cpp @@ -24,11 +24,10 @@ namespace CustomInterfaces { namespace IDA { ConvFitDataPresenter::ConvFitDataPresenter(ConvFitModel *model, - IIndirectFitDataViewLegacy *view) - : IndirectFitDataPresenterLegacy( - model, view, - std::make_unique<ConvFitDataTablePresenter>(model, - view->getDataTable())), + IIndirectFitDataView *view) + : IndirectFitDataPresenter(model, view, + std::make_unique<ConvFitDataTablePresenter>( + model, view->getDataTable())), m_convModel(model) { setResolutionHidden(false); @@ -40,15 +39,17 @@ ConvFitDataPresenter::ConvFitDataPresenter(ConvFitModel *model, void ConvFitDataPresenter::setModelResolution(const QString &name) { auto const workspaceCount = m_convModel->numberOfWorkspaces(); - auto const index = - m_convModel->getWorkspace(0) ? workspaceCount - 1 : workspaceCount; + auto const index = m_convModel->getWorkspace(DatasetIndex{0}) + ? workspaceCount - DatasetIndex{1} + : workspaceCount; setModelResolution(name.toStdString(), index); } void ConvFitDataPresenter::setModelResolution(std::string const &name, - std::size_t const &index) { + DatasetIndex const &index) { try { m_convModel->setResolution(name, index); + emit modelResolutionAdded(name, index); } catch (std::exception const &ex) { displayWarning(ex.what()); } @@ -58,21 +59,26 @@ void ConvFitDataPresenter::addDataToModel(IAddWorkspaceDialog const *dialog) { if (const auto convDialog = dynamic_cast<ConvFitAddWorkspaceDialog const *>(dialog)) { addWorkspace(convDialog, m_convModel); - m_convModel->setResolution(convDialog->resolutionName(), - m_convModel->numberOfWorkspaces() - 1); + auto const name = convDialog->resolutionName(); + auto const index = m_convModel->numberOfWorkspaces() - DatasetIndex{1}; + m_convModel->setResolution(name, index); + emit modelResolutionAdded(name, index); } } void ConvFitDataPresenter::addWorkspace(ConvFitAddWorkspaceDialog const *dialog, - IndirectFittingModelLegacy *model) { + IndirectFittingModel *model) { model->addWorkspace(dialog->workspaceName(), dialog->workspaceIndices()); } void ConvFitDataPresenter::addModelData(const std::string &name) { - IndirectFitDataPresenterLegacy::addModelData(name); + IndirectFitDataPresenter::addModelData(name); const auto resolution = getView()->getSelectedResolution(); - if (!resolution.empty() && isWorkspaceLoaded(resolution)) - m_convModel->setResolution(resolution, 0); + if (!resolution.empty() && isWorkspaceLoaded(resolution)) { + auto const index = DatasetIndex{0}; + m_convModel->setResolution(resolution, index); + emit modelResolutionAdded(resolution, index); + } } std::unique_ptr<IAddWorkspaceDialog> diff --git a/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.h b/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.h index 744a5f0239b4ae5557e94e9f9061e883fbe640b1..526397afafdd45d317fa069a795c5127491df07b 100644 --- a/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.h +++ b/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.h @@ -8,7 +8,7 @@ #define MANTIDQTCUSTOMINTERFACESIDA_CONVFITDATAPRESENTER_H_ #include "ConvFitModel.h" -#include "IndirectFitDataPresenterLegacy.h" +#include "IndirectFitDataPresenter.h" namespace MantidQt { namespace CustomInterfaces { @@ -17,10 +17,13 @@ namespace IDA { class ConvFitAddWorkspaceDialog; class MANTIDQT_INDIRECT_DLL ConvFitDataPresenter - : public IndirectFitDataPresenterLegacy { + : public IndirectFitDataPresenter { Q_OBJECT public: - ConvFitDataPresenter(ConvFitModel *model, IIndirectFitDataViewLegacy *view); + ConvFitDataPresenter(ConvFitModel *model, IIndirectFitDataView *view); + +signals: + void modelResolutionAdded(std::string const &name, DatasetIndex const &index); private slots: void setModelResolution(const QString &name); @@ -29,12 +32,12 @@ protected: void addModelData(const std::string &name) override; private: - void setModelResolution(std::string const &name, std::size_t const &index); + void setModelResolution(std::string const &name, DatasetIndex const &index); void addDataToModel(IAddWorkspaceDialog const *dialog) override; std::unique_ptr<IAddWorkspaceDialog> getAddWorkspaceDialog(QWidget *parent) const override; void addWorkspace(ConvFitAddWorkspaceDialog const *dialog, - IndirectFittingModelLegacy *model); + IndirectFittingModel *model); void setMultiInputResolutionFBSuffixes(IAddWorkspaceDialog *dialog) override; void setMultiInputResolutionWSSuffixes(IAddWorkspaceDialog *dialog) override; diff --git a/qt/scientific_interfaces/Indirect/ConvFitDataTablePresenter.cpp b/qt/scientific_interfaces/Indirect/ConvFitDataTablePresenter.cpp index e0d489873ca51f541ea6a34f4611eecce27e4685..d31727338e4ef08bb4b868debcf37606af41bb9f 100644 --- a/qt/scientific_interfaces/Indirect/ConvFitDataTablePresenter.cpp +++ b/qt/scientific_interfaces/Indirect/ConvFitDataTablePresenter.cpp @@ -28,14 +28,10 @@ namespace IDA { ConvFitDataTablePresenter::ConvFitDataTablePresenter(ConvFitModel *model, QTableWidget *dataTable) - : IndirectDataTablePresenterLegacy(model, dataTable, convFitHeaders()), + : IndirectDataTablePresenter(model, dataTable, convFitHeaders()), m_convFitModel(model) { auto header = dataTable->horizontalHeader(); -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) header->setResizeMode(1, QHeaderView::Stretch); -#elif QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - header->setSectionResizeMode(1, QHeaderView::Stretch); -#endif } int ConvFitDataTablePresenter::workspaceIndexColumn() const { return 2; } @@ -46,13 +42,15 @@ int ConvFitDataTablePresenter::endXColumn() const { return 4; } int ConvFitDataTablePresenter::excludeColumn() const { return 5; } -std::string ConvFitDataTablePresenter::getResolutionName(int row) const { +std::string +ConvFitDataTablePresenter::getResolutionName(SpectrumRowIndex row) const { return getString(row, 1); } -void ConvFitDataTablePresenter::addTableEntry(std::size_t dataIndex, - std::size_t spectrum, int row) { - IndirectDataTablePresenterLegacy::addTableEntry(dataIndex, spectrum, row); +void ConvFitDataTablePresenter::addTableEntry(DatasetIndex dataIndex, + WorkspaceIndex spectrum, + SpectrumRowIndex row) { + IndirectDataTablePresenter::addTableEntry(dataIndex, spectrum, row); const auto resolution = m_convFitModel->getResolution(dataIndex); const auto name = resolution ? resolution->getName() : ""; @@ -63,10 +61,10 @@ void ConvFitDataTablePresenter::addTableEntry(std::size_t dataIndex, setCell(std::move(cell), row, 1); } -void ConvFitDataTablePresenter::updateTableEntry(std::size_t dataIndex, - std::size_t spectrum, - int row) { - IndirectDataTablePresenterLegacy::updateTableEntry(dataIndex, spectrum, row); +void ConvFitDataTablePresenter::updateTableEntry(DatasetIndex dataIndex, + WorkspaceIndex spectrum, + SpectrumRowIndex row) { + IndirectDataTablePresenter::updateTableEntry(dataIndex, spectrum, row); const auto &name = m_convFitModel->getResolution(dataIndex)->getName(); setCellText(QString::fromStdString(name), row, 1); diff --git a/qt/scientific_interfaces/Indirect/ConvFitDataTablePresenter.h b/qt/scientific_interfaces/Indirect/ConvFitDataTablePresenter.h index 1baf7f0b9c405862f0a8751b9f2d4ca8f10d1a7f..11c35bce64b65e07a4902131d019c288df13aa8a 100644 --- a/qt/scientific_interfaces/Indirect/ConvFitDataTablePresenter.h +++ b/qt/scientific_interfaces/Indirect/ConvFitDataTablePresenter.h @@ -8,7 +8,7 @@ #define MANTIDQTCUSTOMINTERFACES_CONVFITDATATABLEPRESENTER_H_ #include "ConvFitModel.h" -#include "IndirectDataTablePresenterLegacy.h" +#include "IndirectDataTablePresenter.h" #include <QTableWidget> @@ -22,24 +22,23 @@ namespace IDA { /** Presenter for a table of convolution fitting data. */ -class DLLExport ConvFitDataTablePresenter - : public IndirectDataTablePresenterLegacy { +class DLLExport ConvFitDataTablePresenter : public IndirectDataTablePresenter { Q_OBJECT public: ConvFitDataTablePresenter(ConvFitModel *model, QTableWidget *dataTable); protected: - void addTableEntry(std::size_t dataIndex, std::size_t spectrum, - int row) override; - void updateTableEntry(std::size_t dataIndex, std::size_t spectrum, - int row) override; + void addTableEntry(DatasetIndex dataIndex, WorkspaceIndex spectrum, + SpectrumRowIndex row) override; + void updateTableEntry(DatasetIndex dataIndex, WorkspaceIndex spectrum, + SpectrumRowIndex row) override; private: int workspaceIndexColumn() const override; int startXColumn() const override; int endXColumn() const override; int excludeColumn() const override; - std::string getResolutionName(int row) const; + std::string getResolutionName(SpectrumRowIndex row) const; ConvFitModel *m_convFitModel; }; diff --git a/qt/scientific_interfaces/Indirect/ConvFitModel.cpp b/qt/scientific_interfaces/Indirect/ConvFitModel.cpp index d1b88ccdfc16b9ee6c6b24ee43144915cd7576ca..e1d17e4de6306a1dcf80585ea35aab8f9e93dc91 100644 --- a/qt/scientific_interfaces/Indirect/ConvFitModel.cpp +++ b/qt/scientific_interfaces/Indirect/ConvFitModel.cpp @@ -7,8 +7,8 @@ #include "ConvFitModel.h" #include "MantidAPI/AlgorithmManager.h" -#include "MantidAPI/CompositeFunction.h" #include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/MultiDomainFunction.h" #include "MantidGeometry/Instrument.h" #include <boost/algorithm/string/join.hpp> @@ -28,96 +28,96 @@ bool doesExistInADS(std::string const &workspaceName) { return AnalysisDataService::Instance().doesExist(workspaceName); } -boost::optional<std::size_t> -getFirstInCategory(CompositeFunction_const_sptr composite, - const std::string &category) { - if (!composite) - return boost::none; - - for (auto i = 0u; i < composite->nFunctions(); ++i) { - if (composite->getFunction(i)->category() == category) - return i; - } - return boost::none; -} - -IFunction_sptr removeFunction(CompositeFunction_sptr composite, - std::size_t index) { - auto function = composite->getFunction(index); - composite->removeFunction(index); - return function; -} - -CompositeFunction_sptr shallowCopy(CompositeFunction_sptr composite) { - CompositeFunction_sptr copy(new CompositeFunction); - for (auto i = 0u; i < composite->nFunctions(); ++i) - copy->addFunction(composite->getFunction(i)); - copy->addTies(composite->writeTies()); - return copy; -} - -IFunction_sptr shallowCopy(IFunction_sptr function) { - auto composite = boost::dynamic_pointer_cast<CompositeFunction>(function); - if (composite) - return shallowCopy(composite); - return function; -} - -IFunction_sptr createResolutionFunction(const std::string &resolutionName) { - auto func = FunctionFactory::Instance().createFunction("Resolution"); - // add resolution file - IFunction::Attribute attr(resolutionName); - func->setAttribute("Workspace", attr); - return func; -} - -CompositeFunction_sptr applyTemperatureCorrection(IFunction_sptr function, - IFunction_sptr correction, - double value) { - auto product = boost::dynamic_pointer_cast<CompositeFunction>( - FunctionFactory::Instance().createFunction("ProductFunction")); - product->addFunction(correction); - product->addFunction(function); - product->tie("f0.Temp", std::to_string(value)); - product->applyTies(); - return product; -} - -IFunction_sptr createTemperatureCorrection(double correction) { - // create temperature correction function to multiply with the lorentzians - IFunction_sptr tempFunc; - - // create user function for the exponential correction - // (x*temp) / 1-exp(-(x*temp)) - tempFunc = FunctionFactory::Instance().createFunction("UserFunction"); - // 11.606 is the conversion factor from meV to K - std::string formula = "((x*11.606)/Temp) / (1 - exp(-((x*11.606)/Temp)))"; - IFunction::Attribute att(formula); - tempFunc->setAttribute("Formula", att); - tempFunc->setParameter("Temp", correction); - return tempFunc; -} - -CompositeFunction_sptr addTemperatureCorrection(CompositeFunction_sptr model, - double value) { - auto correction = createTemperatureCorrection(value); - - for (auto i = 0u; i < model->nFunctions(); ++i) { - auto function = model->getFunction(i); - - if (function->name() != "DeltaFunction") { - auto corrected = applyTemperatureCorrection(function, correction, value); - model->replaceFunction(i, corrected); - } - } - return model; -} - -CompositeFunction_sptr addTemperatureCorrection(IFunction_sptr model, - double value) { - auto correction = createTemperatureCorrection(value); - return applyTemperatureCorrection(model, correction, value); -} +// boost::optional<std::size_t> +// getFirstInCategory(CompositeFunction_const_sptr composite, +// const std::string &category) { +// if (!composite) +// return boost::none; +// +// for (auto i = 0u; i < composite->nFunctions(); ++i) { +// if (composite->getFunction(i)->category() == category) +// return i; +// } +// return boost::none; +//} + +// IFunction_sptr removeFunction(CompositeFunction_sptr composite, +// std::size_t index) { +// auto function = composite->getFunction(index); +// composite->removeFunction(index); +// return function; +//} + +// CompositeFunction_sptr shallowCopy(CompositeFunction_sptr composite) { +// CompositeFunction_sptr copy(new CompositeFunction); +// for (auto i = 0u; i < composite->nFunctions(); ++i) +// copy->addFunction(composite->getFunction(i)); +// copy->addTies(composite->writeTies()); +// return copy; +//} +// +// IFunction_sptr shallowCopy(IFunction_sptr function) { +// auto composite = boost::dynamic_pointer_cast<CompositeFunction>(function); +// if (composite) +// return shallowCopy(composite); +// return function; +//} + +// IFunction_sptr createResolutionFunction(const std::string &resolutionName) { +// auto func = FunctionFactory::Instance().createFunction("Resolution"); +// // add resolution file +// IFunction::Attribute attr(resolutionName); +// func->setAttribute("Workspace", attr); +// return func; +//} + +// CompositeFunction_sptr applyTemperatureCorrection(IFunction_sptr function, +// IFunction_sptr correction, +// double value) { +// auto product = boost::dynamic_pointer_cast<CompositeFunction>( +// FunctionFactory::Instance().createFunction("ProductFunction")); +// product->addFunction(correction); +// product->addFunction(function); +// product->tie("f0.Temp", std::to_string(value)); +// product->applyTies(); +// return product; +//} + +// IFunction_sptr createTemperatureCorrection(double correction) { +// // create temperature correction function to multiply with the lorentzians +// IFunction_sptr tempFunc; +// +// // create user function for the exponential correction +// // (x*temp) / 1-exp(-(x*temp)) +// tempFunc = FunctionFactory::Instance().createFunction("UserFunction"); +// // 11.606 is the conversion factor from meV to K +// std::string formula = "((x*11.606)/Temp) / (1 - exp(-((x*11.606)/Temp)))"; +// IFunction::Attribute att(formula); +// tempFunc->setAttribute("Formula", att); +// tempFunc->setParameter("Temp", correction); +// return tempFunc; +//} + +// CompositeFunction_sptr addTemperatureCorrection(CompositeFunction_sptr model, +// double value) { +// auto correction = createTemperatureCorrection(value); +// +// for (auto i = 0u; i < model->nFunctions(); ++i) { +// auto function = model->getFunction(i); +// +// if (function->name() != "DeltaFunction") { +// auto corrected = applyTemperatureCorrection(function, correction, +// value); model->replaceFunction(i, corrected); +// } +// } +// return model; +//} +// +// CompositeFunction_sptr addTemperatureCorrection(IFunction_sptr model, +// double value) { +// auto correction = createTemperatureCorrection(value); +// return applyTemperatureCorrection(model, correction, value); +//} IAlgorithm_sptr loadParameterFileAlgorithm(std::string const &workspaceName, std::string const &filename) { @@ -376,10 +376,10 @@ private: }; std::vector<std::string> -getNames(const std::vector<boost::weak_ptr<Mantid::API::MatrixWorkspace>> +getNames(const MantidQt::CustomInterfaces::IDA::ResolutionCollectionType &workspaces) { std::vector<std::string> names; - names.reserve(workspaces.size()); + names.reserve(workspaces.size().value); std::transform(workspaces.begin(), workspaces.end(), std::back_inserter(names), [](boost::weak_ptr<Mantid::API::MatrixWorkspace> workspace) { @@ -388,53 +388,55 @@ getNames(const std::vector<boost::weak_ptr<Mantid::API::MatrixWorkspace>> return names; } -std::string backgroundString(IFunction_sptr function) { - const auto functionName = function->name(); - - if (functionName == "FlatBackground") { - if (function->isFixed(0)) - return "FixF"; - return "FitF"; - } else if (functionName == "LinearBackground") - return "FitL"; - return ""; -} - -IFunction_sptr createConvolutionFitModel(IFunction_sptr model, - IFunction_sptr background, - boost::optional<double> temperature) { - CompositeFunction_sptr comp(new CompositeFunction); - - if (!(model && - AnalysisDataService::Instance().doesExist("__ConvFitResolution0"))) - return model ? model : comp; - - if (auto compModel = boost::dynamic_pointer_cast<CompositeFunction>(model)) { - if (compModel->nFunctions() == 1) { - model = compModel->getFunction(0); - } - } - - auto conv = boost::dynamic_pointer_cast<CompositeFunction>( - FunctionFactory::Instance().createFunction("Convolution")); - conv->addFunction(createResolutionFunction("__ConvFitResolution0")); - - if (temperature) { - auto compositeModel = boost::dynamic_pointer_cast<CompositeFunction>(model); - if (compositeModel) - model = addTemperatureCorrection(compositeModel, *temperature); - else - model = addTemperatureCorrection(model, *temperature); - } - conv->addFunction(model); - - if (background) { - comp->addFunction(background); - comp->addFunction(conv); - } else - comp = conv; - return comp; -} +// std::string backgroundString(IFunction_sptr function) { +// const auto functionName = function->name(); +// +// if (functionName == "FlatBackground") { +// if (function->isFixed(0)) +// return "FixF"; +// return "FitF"; +// } else if (functionName == "LinearBackground") +// return "FitL"; +// return ""; +//} + +// IFunction_sptr createConvolutionFitModel(IFunction_sptr model, +// IFunction_sptr background, +// boost::optional<double> temperature) +// { +// CompositeFunction_sptr comp(new CompositeFunction); +// +// if (!(model && +// AnalysisDataService::Instance().doesExist("__ConvFitResolution0"))) +// return model ? model : comp; +// +// if (auto compModel = boost::dynamic_pointer_cast<CompositeFunction>(model)) +// { +// if (compModel->nFunctions() == 1) { +// model = compModel->getFunction(0); +// } +// } +// +// auto conv = boost::dynamic_pointer_cast<CompositeFunction>( +// FunctionFactory::Instance().createFunction("Convolution")); +// conv->addFunction(createResolutionFunction("__ConvFitResolution0")); +// +// if (temperature) { +// auto compositeModel = +// boost::dynamic_pointer_cast<CompositeFunction>(model); if (compositeModel) +// model = addTemperatureCorrection(compositeModel, *temperature); +// else +// model = addTemperatureCorrection(model, *temperature); +// } +// conv->addFunction(model); +// +// if (background) { +// comp->addFunction(background); +// comp->addFunction(conv); +// } else +// comp = conv; +// return comp; +//} void setResolutionAttribute(CompositeFunction_sptr convolutionModel, const IFunction::Attribute &attr) { @@ -470,50 +472,52 @@ IAlgorithm_sptr ConvFitModel::simultaneousFitAlgorithm() const { std::string ConvFitModel::sequentialFitOutputName() const { if (isMultiFit()) return "MultiConvFit_" + m_fitType + m_backgroundString + "_Results"; - return createOutputName( - "%1%_conv_" + m_fitType + m_backgroundString + "_s%2%", "_to_", 0); + return createOutputName("%1%_conv_" + m_fitType + m_backgroundString + + "_s%2%", + "_to_", DatasetIndex{0}); } std::string ConvFitModel::simultaneousFitOutputName() const { return sequentialFitOutputName(); } -std::string ConvFitModel::singleFitOutputName(std::size_t index, - std::size_t spectrum) const { +std::string ConvFitModel::singleFitOutputName(DatasetIndex index, + WorkspaceIndex spectrum) const { return createSingleFitOutputName("%1%_conv_" + m_fitType + m_backgroundString + "_s%2%_Results", index, spectrum); } -Mantid::API::IFunction_sptr ConvFitModel::getFittingFunction() const { - auto function = shallowCopy(IndirectFittingModelLegacy::getFittingFunction()); - auto composite = boost::dynamic_pointer_cast<CompositeFunction>(function); +Mantid::API::MultiDomainFunction_sptr ConvFitModel::getFittingFunction() const { + // auto function = shallowCopy(IndirectFittingModel::getFittingFunction()); + // auto composite = boost::dynamic_pointer_cast<CompositeFunction>(function); - IFunction_sptr background(nullptr); - if (composite && m_backgroundIndex) - background = removeFunction(composite, *m_backgroundIndex); - return createConvolutionFitModel(function, background, m_temperature); + // IFunction_sptr background(nullptr); + // if (composite && m_backgroundIndex) + // background = removeFunction(composite, *m_backgroundIndex); + // return createConvolutionFitModel(function, background, m_temperature); + return IndirectFittingModel::getFittingFunction(); } boost::optional<double> -ConvFitModel::getInstrumentResolution(std::size_t dataIndex) const { +ConvFitModel::getInstrumentResolution(DatasetIndex dataIndex) const { if (dataIndex < numberOfWorkspaces()) return instrumentResolution(getWorkspace(dataIndex)); return boost::none; } -std::size_t ConvFitModel::getNumberHistograms(std::size_t index) const { +std::size_t ConvFitModel::getNumberHistograms(DatasetIndex index) const { return getWorkspace(index)->getNumberHistograms(); } -MatrixWorkspace_sptr ConvFitModel::getResolution(std::size_t index) const { +MatrixWorkspace_sptr ConvFitModel::getResolution(DatasetIndex index) const { if (index < m_resolution.size()) return m_resolution[index].lock(); return nullptr; } -CompositeFunction_sptr ConvFitModel::getMultiDomainFunction() const { - auto function = IndirectFittingModelLegacy::getMultiDomainFunction(); +MultiDomainFunction_sptr ConvFitModel::getMultiDomainFunction() const { + auto function = IndirectFittingModel::getMultiDomainFunction(); const std::string base = "__ConvFitResolution"; for (auto i = 0u; i < function->nFunctions(); ++i) @@ -528,18 +532,18 @@ std::vector<std::string> ConvFitModel::getSpectrumDependentAttributes() const { return {"WorkspaceIndex"}; } -void ConvFitModel::setFitFunction(IFunction_sptr function) { - auto const composite = - boost::dynamic_pointer_cast<CompositeFunction>(function); - m_backgroundIndex = getFirstInCategory(composite, "Background"); - setParameterNameChanges(*function, m_backgroundIndex); +void ConvFitModel::setFitFunction(MultiDomainFunction_sptr function) { + // auto const composite = + // boost::dynamic_pointer_cast<CompositeFunction>(function); + // m_backgroundIndex = getFirstInCategory(composite, "Background"); + // setParameterNameChanges(*function, m_backgroundIndex); - IFunction_sptr background(nullptr); - if (composite && m_backgroundIndex) - background = composite->getFunction(*m_backgroundIndex); - m_backgroundString = background ? backgroundString(background) : ""; + // IFunction_sptr background(nullptr); + // if (composite && m_backgroundIndex) + // background = composite->getFunction(*m_backgroundIndex); + // m_backgroundString = background ? backgroundString(background) : ""; - IndirectFittingModelLegacy::setFitFunction(function); + IndirectFittingModel::setFitFunction(function); } void ConvFitModel::setTemperature(const boost::optional<double> &temperature) { @@ -547,32 +551,32 @@ void ConvFitModel::setTemperature(const boost::optional<double> &temperature) { } void ConvFitModel::addWorkspace(MatrixWorkspace_sptr workspace, - const SpectraLegacy &spectra) { - IndirectFittingModelLegacy::addWorkspace(workspace, spectra); + const Spectra &spectra) { + IndirectFittingModel::addWorkspace(workspace, spectra); const auto dataSize = numberOfWorkspaces(); if (m_resolution.size() < dataSize) m_resolution.emplace_back(MatrixWorkspace_sptr()); else if (m_resolution.size() == dataSize && - m_resolution[dataSize - 1].lock() && + m_resolution[dataSize - DatasetIndex{1}].lock() && m_extendedResolution.size() < dataSize) - addExtendedResolution(dataSize - 1); + addExtendedResolution(dataSize - DatasetIndex{1}); } -void ConvFitModel::removeWorkspace(std::size_t index) { - IndirectFittingModelLegacy::removeWorkspace(index); +void ConvFitModel::removeWorkspace(DatasetIndex index) { + IndirectFittingModel::removeWorkspace(index); const auto newSize = numberOfWorkspaces(); while (m_resolution.size() > newSize) - m_resolution.erase(m_resolution.begin() + index); + m_resolution.remove(index); while (m_extendedResolution.size() > newSize) { AnalysisDataService::Instance().remove(m_extendedResolution[index]); - m_extendedResolution.erase(m_extendedResolution.begin() + index); + m_extendedResolution.remove(index); } } -void ConvFitModel::setResolution(const std::string &name, std::size_t index) { +void ConvFitModel::setResolution(const std::string &name, DatasetIndex index) { if (!name.empty() && doesExistInADS(name)) setResolution(getADSMatrixWorkspace(name), index); else @@ -580,21 +584,22 @@ void ConvFitModel::setResolution(const std::string &name, std::size_t index) { } void ConvFitModel::setResolution(MatrixWorkspace_sptr resolution, - std::size_t index) { + DatasetIndex index) { if (m_resolution.size() > index) m_resolution[index] = resolution; else if (m_resolution.size() == index) m_resolution.emplace_back(resolution); else throw std::out_of_range("Provided resolution index '" + - std::to_string(index) + "' was out of range."); + std::to_string(index.value) + + "' was out of range."); if (numberOfWorkspaces() > index) addExtendedResolution(index); } -void ConvFitModel::addExtendedResolution(std::size_t index) { - const std::string name = "__ConvFitResolution" + std::to_string(index); +void ConvFitModel::addExtendedResolution(DatasetIndex index) { + const std::string name = "__ConvFitResolution" + std::to_string(index.value); extendResolutionWorkspace(m_resolution[index].lock(), getNumberHistograms(index), name); @@ -609,31 +614,30 @@ void ConvFitModel::setFitTypeString(const std::string &fitType) { m_fitType = fitType; } -std::unordered_map<std::string, ParameterValueLegacy> -ConvFitModel::createDefaultParameters(std::size_t index) const { - std::unordered_map<std::string, ParameterValueLegacy> defaultValues; - defaultValues["PeakCentre"] = ParameterValueLegacy(0.0); - defaultValues["Centre"] = ParameterValueLegacy(0.0); +std::unordered_map<std::string, ParameterValue> +ConvFitModel::createDefaultParameters(DatasetIndex index) const { + std::unordered_map<std::string, ParameterValue> defaultValues; + defaultValues["PeakCentre"] = ParameterValue(0.0); + defaultValues["Centre"] = ParameterValue(0.0); // Reset all parameters to default of 1 - defaultValues["Amplitude"] = ParameterValueLegacy(1.0); - defaultValues["beta"] = ParameterValueLegacy(1.0); - defaultValues["Decay"] = ParameterValueLegacy(1.0); - defaultValues["Diffusion"] = ParameterValueLegacy(1.0); - defaultValues["Height"] = ParameterValueLegacy(1.0); - defaultValues["Intensity"] = ParameterValueLegacy(1.0); - defaultValues["Radius"] = ParameterValueLegacy(1.0); - defaultValues["Tau"] = ParameterValueLegacy(1.0); + defaultValues["Amplitude"] = ParameterValue(1.0); + defaultValues["beta"] = ParameterValue(1.0); + defaultValues["Decay"] = ParameterValue(1.0); + defaultValues["Diffusion"] = ParameterValue(1.0); + defaultValues["Height"] = ParameterValue(1.0); + defaultValues["Intensity"] = ParameterValue(1.0); + defaultValues["Radius"] = ParameterValue(1.0); + defaultValues["Tau"] = ParameterValue(1.0); auto resolution = getInstrumentResolution(index); if (resolution) - defaultValues["FWHM"] = ParameterValueLegacy(*resolution); + defaultValues["FWHM"] = ParameterValue(*resolution); return defaultValues; } std::unordered_map<std::string, std::string> ConvFitModel::mapDefaultParameterNames() const { - const auto initialMapping = - IndirectFittingModelLegacy::mapDefaultParameterNames(); + const auto initialMapping = IndirectFittingModel::mapDefaultParameterNames(); std::unordered_map<std::string, std::string> mapping; for (const auto &map : initialMapping) { auto mapped = m_parameterNameChanges.find(map.second); @@ -657,53 +661,51 @@ void ConvFitModel::addSampleLogs() { } } -IndirectFitOutputLegacy -ConvFitModel::createFitOutput(WorkspaceGroup_sptr resultGroup, - ITableWorkspace_sptr parameterTable, - WorkspaceGroup_sptr resultWorkspace, - const FitDataIteratorLegacy &fitDataBegin, - const FitDataIteratorLegacy &fitDataEnd) const { - auto output = IndirectFitOutputLegacy( - resultGroup, parameterTable, resultWorkspace, fitDataBegin, fitDataEnd); +IndirectFitOutput ConvFitModel::createFitOutput( + WorkspaceGroup_sptr resultGroup, ITableWorkspace_sptr parameterTable, + WorkspaceGroup_sptr resultWorkspace, const FitDataIterator &fitDataBegin, + const FitDataIterator &fitDataEnd) const { + auto output = IndirectFitOutput(resultGroup, parameterTable, resultWorkspace, + fitDataBegin, fitDataEnd); output.mapParameterNames(m_parameterNameChanges, fitDataBegin, fitDataEnd); return output; } -IndirectFitOutputLegacy +IndirectFitOutput ConvFitModel::createFitOutput(Mantid::API::WorkspaceGroup_sptr resultGroup, Mantid::API::ITableWorkspace_sptr parameterTable, Mantid::API::WorkspaceGroup_sptr resultWorkspace, - IndirectFitDataLegacy *fitData, - std::size_t spectrum) const { - auto output = IndirectFitOutputLegacy(resultGroup, parameterTable, - resultWorkspace, fitData, spectrum); + IndirectFitData *fitData, + WorkspaceIndex spectrum) const { + auto output = IndirectFitOutput(resultGroup, parameterTable, resultWorkspace, + fitData, spectrum); output.mapParameterNames(m_parameterNameChanges, fitData, spectrum); return output; } void ConvFitModel::addOutput(Mantid::API::IAlgorithm_sptr fitAlgorithm) { - IndirectFittingModelLegacy::addOutput(fitAlgorithm); + IndirectFittingModel::addOutput(fitAlgorithm); addSampleLogs(); } -void ConvFitModel::addOutput(IndirectFitOutputLegacy *fitOutput, +void ConvFitModel::addOutput(IndirectFitOutput *fitOutput, WorkspaceGroup_sptr resultGroup, ITableWorkspace_sptr parameterTable, WorkspaceGroup_sptr resultWorkspace, - const FitDataIteratorLegacy &fitDataBegin, - const FitDataIteratorLegacy &fitDataEnd) const { + const FitDataIterator &fitDataBegin, + const FitDataIterator &fitDataEnd) const { fitOutput->addOutput(resultGroup, parameterTable, resultWorkspace, fitDataBegin, fitDataEnd); fitOutput->mapParameterNames(m_parameterNameChanges, fitDataBegin, fitDataEnd); } -void ConvFitModel::addOutput(IndirectFitOutputLegacy *fitOutput, +void ConvFitModel::addOutput(IndirectFitOutput *fitOutput, WorkspaceGroup_sptr resultGroup, ITableWorkspace_sptr parameterTable, WorkspaceGroup_sptr resultWorkspace, - IndirectFitDataLegacy *fitData, - std::size_t spectrum) const { + IndirectFitData *fitData, + WorkspaceIndex spectrum) const { fitOutput->addOutput(resultGroup, parameterTable, resultWorkspace, fitData, spectrum); fitOutput->mapParameterNames(m_parameterNameChanges, fitData, spectrum); diff --git a/qt/scientific_interfaces/Indirect/ConvFitModel.h b/qt/scientific_interfaces/Indirect/ConvFitModel.h index 3502ed51d7e6eb3edef7aa57a379fd079db787a7..bdd62f81a287cc88c2a84f0dbe84c4f5caf8cfda 100644 --- a/qt/scientific_interfaces/Indirect/ConvFitModel.h +++ b/qt/scientific_interfaces/Indirect/ConvFitModel.h @@ -7,35 +7,40 @@ #ifndef MANTIDQTCUSTOMINTERFACESIDA_CONVFITMODEL_H_ #define MANTIDQTCUSTOMINTERFACESIDA_CONVFITMODEL_H_ -#include "IndirectFittingModelLegacy.h" +#include "IndirectFittingModel.h" namespace MantidQt { namespace CustomInterfaces { namespace IDA { -class DLLExport ConvFitModel : public IndirectFittingModelLegacy { +using ResolutionCollectionType = + IndexCollectionType<DatasetIndex, + boost::weak_ptr<Mantid::API::MatrixWorkspace>>; +using ExtendedResolutionType = IndexCollectionType<DatasetIndex, std::string>; + +class DLLExport ConvFitModel : public IndirectFittingModel { public: - using IndirectFittingModelLegacy::addWorkspace; + using IndirectFittingModel::addWorkspace; ConvFitModel(); ~ConvFitModel() override; - Mantid::API::IFunction_sptr getFittingFunction() const override; - boost::optional<double> getInstrumentResolution(std::size_t dataIndex) const; - std::size_t getNumberHistograms(std::size_t index) const; - Mantid::API::MatrixWorkspace_sptr getResolution(std::size_t index) const; + Mantid::API::MultiDomainFunction_sptr getFittingFunction() const override; + boost::optional<double> getInstrumentResolution(DatasetIndex dataIndex) const; + std::size_t getNumberHistograms(DatasetIndex index) const; + Mantid::API::MatrixWorkspace_sptr getResolution(DatasetIndex index) const; std::vector<std::string> getSpectrumDependentAttributes() const override; - void setFitFunction(Mantid::API::IFunction_sptr function) override; + void setFitFunction(Mantid::API::MultiDomainFunction_sptr function) override; void setTemperature(const boost::optional<double> &temperature); void addWorkspace(Mantid::API::MatrixWorkspace_sptr workspace, - const SpectraLegacy &spectra) override; - void removeWorkspace(std::size_t index) override; - void setResolution(const std::string &name, std::size_t index); + const Spectra &spectra) override; + void removeWorkspace(DatasetIndex index) override; + void setResolution(const std::string &name, DatasetIndex index); void setResolution(Mantid::API::MatrixWorkspace_sptr resolution, - std::size_t index); + DatasetIndex index); void setFitTypeString(const std::string &fitType); void addOutput(Mantid::API::IAlgorithm_sptr fitAlgorithm) override; @@ -45,47 +50,47 @@ private: Mantid::API::IAlgorithm_sptr simultaneousFitAlgorithm() const override; std::string sequentialFitOutputName() const override; std::string simultaneousFitOutputName() const override; - std::string singleFitOutputName(std::size_t index, - std::size_t spectrum) const override; - Mantid::API::CompositeFunction_sptr getMultiDomainFunction() const override; - std::unordered_map<std::string, ParameterValueLegacy> - createDefaultParameters(std::size_t index) const override; + std::string singleFitOutputName(DatasetIndex index, + WorkspaceIndex spectrum) const override; + Mantid::API::MultiDomainFunction_sptr getMultiDomainFunction() const override; + std::unordered_map<std::string, ParameterValue> + createDefaultParameters(DatasetIndex index) const override; std::unordered_map<std::string, std::string> mapDefaultParameterNames() const override; - IndirectFitOutputLegacy + IndirectFitOutput createFitOutput(Mantid::API::WorkspaceGroup_sptr resultGroup, Mantid::API::ITableWorkspace_sptr parameterTable, Mantid::API::WorkspaceGroup_sptr resultWorkspace, - const FitDataIteratorLegacy &fitDataBegin, - const FitDataIteratorLegacy &fitDataEnd) const override; - IndirectFitOutputLegacy + const FitDataIterator &fitDataBegin, + const FitDataIterator &fitDataEnd) const override; + IndirectFitOutput createFitOutput(Mantid::API::WorkspaceGroup_sptr resultGroup, Mantid::API::ITableWorkspace_sptr parameterTable, Mantid::API::WorkspaceGroup_sptr resultWorkspace, - IndirectFitDataLegacy *fitData, - std::size_t spectrum) const override; + IndirectFitData *fitData, + WorkspaceIndex spectrum) const override; - void addOutput(IndirectFitOutputLegacy *fitOutput, + void addOutput(IndirectFitOutput *fitOutput, Mantid::API::WorkspaceGroup_sptr resultGroup, Mantid::API::ITableWorkspace_sptr parameterTable, Mantid::API::WorkspaceGroup_sptr resultWorkspace, - const FitDataIteratorLegacy &fitDataBegin, - const FitDataIteratorLegacy &fitDataEnd) const override; - void addOutput(IndirectFitOutputLegacy *fitOutput, + const FitDataIterator &fitDataBegin, + const FitDataIterator &fitDataEnd) const override; + void addOutput(IndirectFitOutput *fitOutput, Mantid::API::WorkspaceGroup_sptr resultGroup, Mantid::API::ITableWorkspace_sptr parameterTable, Mantid::API::WorkspaceGroup_sptr resultWorkspace, - IndirectFitDataLegacy *fitData, - std::size_t spectrum) const override; - void addExtendedResolution(std::size_t index); + IndirectFitData *fitData, + WorkspaceIndex spectrum) const override; + void addExtendedResolution(DatasetIndex index); void addSampleLogs(); void setParameterNameChanges(const Mantid::API::IFunction &model, boost::optional<std::size_t> backgroundIndex); - std::vector<boost::weak_ptr<Mantid::API::MatrixWorkspace>> m_resolution; - std::vector<std::string> m_extendedResolution; + ResolutionCollectionType m_resolution; + ExtendedResolutionType m_extendedResolution; std::unordered_map<std::string, std::string> m_parameterNameChanges; boost::optional<double> m_temperature; boost::optional<std::size_t> m_backgroundIndex; diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.cpp b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f331fff9f2db98be5f2653312bfd7a1a2ad28b2c --- /dev/null +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.cpp @@ -0,0 +1,604 @@ +// 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 +// SPDX - License - Identifier: GPL - 3.0 + +#include "ConvFunctionModel.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/IFunction.h" +#include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/MultiDomainFunction.h" +#include "MantidQtWidgets/Common/FunctionBrowser/FunctionBrowserUtils.h" +#include <map> + +namespace MantidQt { +namespace CustomInterfaces { +namespace IDA { + +using namespace MantidWidgets; +using namespace Mantid::API; + +namespace {} + +ConvFunctionModel::ConvFunctionModel() {} + +void ConvFunctionModel::clearData() { + m_fitType = FitType::None; + m_hasDeltaFunction = false; + m_backgroundType = BackgroundType::None; + m_model.clear(); +} + +void ConvFunctionModel::setModel() { + m_model.setModel(buildBackgroundFunctionString(), m_resolutionName, + m_resolutionIndex.value, buildPeaksFunctionString(), + m_hasDeltaFunction); + m_model.setGlobalParameters(makeGlobalList()); +} + +void ConvFunctionModel::setFunction(IFunction_sptr fun) { + clearData(); + if (!fun) + return; + if (fun->nFunctions() == 0) { + auto const name = fun->name(); + if (name == "Lorentzian") { + m_fitType = FitType::OneLorentzian; + } else if (name == "DeltaFunction") { + m_hasDeltaFunction = true; + } else if (name == "FlatBackground") { + m_backgroundType = BackgroundType::Flat; + } else if (name == "LinearBackground") { + m_backgroundType = BackgroundType::Linear; + } else { + throw std::runtime_error("Cannot set function " + name); + } + m_model.setFunction(fun); + return; + } + bool isFitTypeSet = false; + int numberLorentzians = 0; + bool isBackgroundSet = false; + for (size_t i = 0; i < fun->nFunctions(); ++i) { + auto f = fun->getFunction(i); + auto const name = f->name(); + if (name == "Lorentzian") { + if (isFitTypeSet) { + throw std::runtime_error("Function has wrong structure."); + } + if (numberLorentzians == 0) { + numberLorentzians = 1; + } else { + numberLorentzians = 2; + isFitTypeSet = true; + } + } else if (name == "DeltaFunction") { + if (m_hasDeltaFunction || isBackgroundSet) { + throw std::runtime_error("Function has wrong structure."); + } + m_hasDeltaFunction = true; + isFitTypeSet = true; + } else if (isBackgroundSet) { + throw std::runtime_error("Function has wrong structure."); + } else if (name == "FlatBackground") { + m_backgroundType = BackgroundType::Flat; + isFitTypeSet = true; + isBackgroundSet = true; + } else if (name == "LinearBackground") { + m_backgroundType = BackgroundType::Linear; + isFitTypeSet = true; + isBackgroundSet = true; + } else { + clear(); + throw std::runtime_error("Function has wrong structure."); + } + } + m_model.setFunction(fun); +} + +IFunction_sptr ConvFunctionModel::getFitFunction() const { + return m_model.getFitFunction(); +} + +bool ConvFunctionModel::hasFunction() const { return m_model.hasFunction(); } + +void ConvFunctionModel::addFunction(const QString &prefix, + const QString &funStr) { + if (!prefix.isEmpty()) + throw std::runtime_error( + "Function doesn't have member function with prefix " + + prefix.toStdString()); + auto fun = + FunctionFactory::Instance().createInitialized(funStr.toStdString()); + auto const name = fun->name(); + QString newPrefix; + if (name == "Lorentzian") { + if (m_fitType == FitType::TwoLorentzians) { + throw std::runtime_error("Cannot add more Lorentzians."); + } else if (m_fitType == FitType::OneLorentzian) { + m_fitType = FitType::TwoLorentzians; + newPrefix = *getLor2Prefix(); + } else if (m_fitType == FitType::None) { + m_fitType = FitType::OneLorentzian; + newPrefix = *getLor1Prefix(); + } else { + throw std::runtime_error("Cannot add more Lorentzians."); + } + } else if (name == "DeltaFunction") { + if (m_hasDeltaFunction) + throw std::runtime_error("Cannot add a DeltaFunction."); + setDeltaFunction(true); + newPrefix = *getDeltaPrefix(); + } else if (name == "FlatBackground" || name == "LinearBackground") { + if (hasBackground()) + throw std::runtime_error("Cannot add more backgrounds."); + if (name == "FlatBackground") { + setBackground(BackgroundType::Flat); + } else if (name == "LinearBackground") { + setBackground(BackgroundType::Linear); + } + newPrefix = *getBackgroundPrefix(); + } else { + throw std::runtime_error("Cannot add funtion " + name); + } + auto newFun = getFunctionWithPrefix(newPrefix, getSingleFunction(0)); + copyParametersAndErrors(*fun, *newFun); + if (getNumberLocalFunctions() > 1) { + copyParametersAndErrorsToAllLocalFunctions(*getSingleFunction(0)); + } +} + +void ConvFunctionModel::removeFunction(const QString &prefix) { + if (prefix.isEmpty()) { + clear(); + return; + } + auto prefix1 = getLor1Prefix(); + if (prefix1 && *prefix1 == prefix) { + setFitType(FitType::None); + return; + } + prefix1 = getLor2Prefix(); + if (prefix1 && *prefix1 == prefix) { + setFitType(FitType::OneLorentzian); + return; + } + prefix1 = getDeltaPrefix(); + if (prefix1 && *prefix1 == prefix) { + setDeltaFunction(false); + return; + } + prefix1 = getBackgroundPrefix(); + if (prefix1 && *prefix1 == prefix) { + removeBackground(); + return; + } + throw std::runtime_error( + "Function doesn't have member function with prefix " + + prefix.toStdString()); +} + +void ConvFunctionModel::setDeltaFunction(bool on) { + auto oldValues = getCurrentValues(); + m_hasDeltaFunction = on; + setModel(); + setCurrentValues(oldValues); +} + +bool ConvFunctionModel::hasDeltaFunction() const { return m_hasDeltaFunction; } + +void ConvFunctionModel::setBackground(BackgroundType bgType) { + auto oldValues = getCurrentValues(); + m_backgroundType = bgType; + setModel(); + setCurrentValues(oldValues); +} + +void ConvFunctionModel::removeBackground() { + auto oldValues = getCurrentValues(); + m_backgroundType = BackgroundType::None; + setModel(); + setCurrentValues(oldValues); +} + +bool ConvFunctionModel::hasBackground() const { + return m_backgroundType != BackgroundType::None; +} + +void ConvFunctionModel::updateParameterEstimationData( + DataForParameterEstimationCollection &&data) { + m_estimationData = std::move(data); +} + +void ConvFunctionModel::setResolution(std::string const &name, + DatasetIndex const &index) { + m_resolutionName = name; + m_resolutionIndex = index; + setModel(); +} + +QString ConvFunctionModel::setBackgroundA0(double value) { + if (hasBackground()) { + auto const paramID = (m_backgroundType == BackgroundType::Flat) + ? ParamID::FLAT_BG_A0 + : ParamID::LINEAR_BG_A0; + setParameter(paramID, value); + return *getParameterName(paramID); + } + return ""; +} + +void ConvFunctionModel::setNumberDomains(int n) { m_model.setNumberDomains(n); } + +int ConvFunctionModel::getNumberDomains() const { + return m_model.getNumberDomains(); +} + +void ConvFunctionModel::setParameter(const QString ¶mName, double value) { + m_model.setParameter(paramName, value); +} + +void ConvFunctionModel::setParameterError(const QString ¶mName, + double value) { + m_model.setParameterError(paramName, value); +} + +double ConvFunctionModel::getParameter(const QString ¶mName) const { + return m_model.getParameter(paramName); +} + +double ConvFunctionModel::getParameterError(const QString ¶mName) const { + return m_model.getParameterError(paramName); +} + +QString +ConvFunctionModel::getParameterDescription(const QString ¶mName) const { + return m_model.getParameterDescription(paramName); +} + +QStringList ConvFunctionModel::getParameterNames() const { + return m_model.getParameterNames(); +} + +IFunction_sptr ConvFunctionModel::getSingleFunction(int index) const { + return m_model.getSingleFunction(index); +} + +IFunction_sptr ConvFunctionModel::getCurrentFunction() const { + return m_model.getCurrentFunction(); +} + +QStringList ConvFunctionModel::getGlobalParameters() const { + return m_model.getGlobalParameters(); +} + +QStringList ConvFunctionModel::getLocalParameters() const { + return m_model.getLocalParameters(); +} + +void ConvFunctionModel::setGlobalParameters(const QStringList &globals) { + m_globals.clear(); + for (auto const &name : globals) { + addGlobal(name); + } + auto newGlobals = makeGlobalList(); + m_model.setGlobalParameters(newGlobals); +} + +bool ConvFunctionModel::isGlobal(const QString &parName) const { + return m_model.isGlobal(parName); +} + +void ConvFunctionModel::setGlobal(const QString &parName, bool on) { + if (parName.isEmpty()) + return; + if (on) + addGlobal(parName); + else + removeGlobal(parName); + auto globals = makeGlobalList(); + m_model.setGlobalParameters(globals); +} + +void ConvFunctionModel::addGlobal(const QString &parName) { + auto const pid = getParameterId(parName); + if (pid && !m_globals.contains(*pid)) { + m_globals.push_back(*pid); + } +} + +void ConvFunctionModel::removeGlobal(const QString &parName) { + auto const pid = getParameterId(parName); + if (pid && m_globals.contains(*pid)) { + m_globals.removeOne(*pid); + } +} + +QStringList ConvFunctionModel::makeGlobalList() const { + QStringList globals; + for (auto const id : m_globals) { + auto const name = getParameterName(id); + if (name) + globals << *name; + } + return globals; +} + +void ConvFunctionModel::setFitType(FitType fitType) { + auto oldValues = getCurrentValues(); + m_fitType = fitType; + setModel(); + setCurrentValues(oldValues); +} + +int ConvFunctionModel::getNumberOfPeaks() const { + if (m_fitType == FitType::None) + return 0; + if (m_fitType == FitType::TwoLorentzians) + return 2; + return 1; +} + +void ConvFunctionModel::updateMultiDatasetParameters(const IFunction &fun) { + m_model.updateMultiDatasetParameters(fun); +} + +void ConvFunctionModel::updateMultiDatasetParameters( + const ITableWorkspace ¶mTable) { + auto const nRows = paramTable.rowCount(); + if (nRows == 0) + return; + + auto const globalParameterNames = getGlobalParameters(); + for (auto &&name : globalParameterNames) { + auto valueColumn = paramTable.getColumn((name).toStdString()); + auto errorColumn = paramTable.getColumn((name + "_Err").toStdString()); + m_model.setParameter(name, valueColumn->toDouble(0)); + m_model.setParameterError(name, errorColumn->toDouble(0)); + } + + auto const localParameterNames = getLocalParameters(); + for (auto &&name : localParameterNames) { + auto valueColumn = paramTable.getColumn((name).toStdString()); + auto errorColumn = paramTable.getColumn((name + "_Err").toStdString()); + if (nRows > 1) { + for (size_t i = 0; i < nRows; ++i) { + m_model.setLocalParameterValue(name, static_cast<int>(i), + valueColumn->toDouble(i), + errorColumn->toDouble(i)); + } + } else { + auto const i = m_model.currentDomainIndex(); + m_model.setLocalParameterValue(name, static_cast<int>(i), + valueColumn->toDouble(0), + errorColumn->toDouble(0)); + } + } +} + +void ConvFunctionModel::updateParameters(const IFunction &fun) { + m_model.updateParameters(fun); +} + +void ConvFunctionModel::setCurrentDomainIndex(int i) { + m_model.setCurrentDomainIndex(i); +} + +int ConvFunctionModel::currentDomainIndex() const { + return m_model.currentDomainIndex(); +} + +void ConvFunctionModel::changeTie(const QString ¶mName, + const QString &tie) { + m_model.changeTie(paramName, tie); +} + +void ConvFunctionModel::addConstraint(const QString &functionIndex, + const QString &constraint) { + m_model.addConstraint(functionIndex, constraint); +} + +void ConvFunctionModel::removeConstraint(const QString ¶mName) { + m_model.removeConstraint(paramName); +} + +void ConvFunctionModel::setDatasetNames(const QStringList &names) { + m_model.setDatasetNames(names); +} + +QStringList ConvFunctionModel::getDatasetNames() const { + return m_model.getDatasetNames(); +} + +double ConvFunctionModel::getLocalParameterValue(const QString &parName, + int i) const { + return m_model.getLocalParameterValue(parName, i); +} + +bool ConvFunctionModel::isLocalParameterFixed(const QString &parName, + int i) const { + return m_model.isLocalParameterFixed(parName, i); +} + +QString ConvFunctionModel::getLocalParameterTie(const QString &parName, + int i) const { + return m_model.getLocalParameterTie(parName, i); +} + +QString ConvFunctionModel::getLocalParameterConstraint(const QString &parName, + int i) const { + return m_model.getLocalParameterConstraint(parName, i); +} + +void ConvFunctionModel::setLocalParameterValue(const QString &parName, int i, + double value) { + m_model.setLocalParameterValue(parName, i, value); +} + +void ConvFunctionModel::setLocalParameterValue(const QString &parName, int i, + double value, double error) { + m_model.setLocalParameterValue(parName, i, value, error); +} + +void ConvFunctionModel::setLocalParameterTie(const QString &parName, int i, + const QString &tie) { + m_model.setLocalParameterTie(parName, i, tie); +} + +void ConvFunctionModel::setLocalParameterConstraint(const QString &parName, + int i, + const QString &constraint) { + m_model.setLocalParameterConstraint(parName, i, constraint); +} + +void ConvFunctionModel::setLocalParameterFixed(const QString &parName, int i, + bool fixed) { + m_model.setLocalParameterFixed(parName, i, fixed); +} + +void ConvFunctionModel::setParameter(ParamID name, double value) { + auto const prefix = getPrefix(name); + if (prefix) { + m_model.setParameter(*prefix + paramName(name), value); + } +} + +boost::optional<double> ConvFunctionModel::getParameter(ParamID name) const { + auto const paramName = getParameterName(name); + return paramName ? m_model.getParameter(*paramName) + : boost::optional<double>(); +} + +boost::optional<double> +ConvFunctionModel::getParameterError(ParamID name) const { + auto const paramName = getParameterName(name); + return paramName ? m_model.getParameterError(*paramName) + : boost::optional<double>(); +} + +boost::optional<QString> +ConvFunctionModel::getParameterName(ParamID name) const { + auto const prefix = getPrefix(name); + return prefix ? *prefix + paramName(name) : boost::optional<QString>(); +} + +boost::optional<QString> +ConvFunctionModel::getParameterDescription(ParamID name) const { + auto const paramName = getParameterName(name); + return paramName ? m_model.getParameterDescription(*paramName) + : boost::optional<QString>(); +} + +boost::optional<QString> ConvFunctionModel::getPrefix(ParamID name) const { + if (name >= ParamID::FLAT_BG_A0) { + return m_model.backgroundPrefix(); + } else { + auto const prefixes = m_model.peakPrefixes(); + if (!prefixes) + return boost::optional<QString>(); + auto const index = + name > ParamID::LOR2_FWHM_1 && name <= ParamID::LOR2_FWHM_2 ? 1 : 0; + return m_model.peakPrefixes()->at(index); + } +} + +QMap<ParamID, double> ConvFunctionModel::getCurrentValues() const { + QMap<ParamID, double> values; + auto store = [&values, this](ParamID name) { + values[name] = *getParameter(name); + }; + applyParameterFunction(store); + return values; +} + +QMap<ParamID, double> ConvFunctionModel::getCurrentErrors() const { + QMap<ParamID, double> errors; + auto store = [&errors, this](ParamID name) { + errors[name] = *getParameterError(name); + }; + applyParameterFunction(store); + return errors; +} + +QMap<int, QString> ConvFunctionModel::getParameterNameMap() const { + QMap<int, QString> out; + auto addToMap = [&out, this](ParamID name) { + out[static_cast<int>(name)] = *getParameterName(name); + }; + applyParameterFunction(addToMap); + return out; +} + +void ConvFunctionModel::setCurrentValues(const QMap<ParamID, double> &values) { + for (auto const name : values.keys()) { + setParameter(name, values[name]); + } +} + +void ConvFunctionModel::applyParameterFunction( + std::function<void(ParamID)> paramFun) const { + applyToFitType(m_fitType, paramFun); + applyToBackground(m_backgroundType, paramFun); +} + +boost::optional<ParamID> +ConvFunctionModel::getParameterId(const QString &parName) { + boost::optional<ParamID> result; + auto getter = [&result, parName, this](ParamID pid) { + if (parName == *getParameterName(pid)) + result = pid; + }; + applyParameterFunction(getter); + return result; +} + +std::string ConvFunctionModel::buildLorentzianFunctionString() const { + return "name=Lorentzian,Amplitude=1,FWHM=1,constraints=(Amplitude>0,FWHM>0)"; +} + +std::string ConvFunctionModel::buildTeixeiraFunctionString() const { + return "name=TeixeiraWaterSQE"; +} + +std::string ConvFunctionModel::buildPeaksFunctionString() const { + std::string functions; + if (m_fitType == FitType::OneLorentzian) { + functions.append(buildLorentzianFunctionString()); + } else if (m_fitType == FitType::TwoLorentzians) { + auto const lorentzian = buildLorentzianFunctionString(); + functions.append(lorentzian); + functions.append(";"); + functions.append(lorentzian); + } else if (m_fitType == FitType::TeixeiraWater) { + functions.append(buildTeixeiraFunctionString()); + } + return functions; +} + +std::string ConvFunctionModel::buildBackgroundFunctionString() const { + if (m_backgroundType == BackgroundType::None) + return ""; + return "name=" + m_backgroundSubtype.getFunctionName(m_backgroundType) + + ",A0=0,constraints=(A0>0)"; +} + +boost::optional<QString> ConvFunctionModel::getLor1Prefix() const { + return m_model.peakPrefixes()->at(0); +} + +boost::optional<QString> ConvFunctionModel::getLor2Prefix() const { + return m_model.peakPrefixes()->at(1); +} + +boost::optional<QString> ConvFunctionModel::getDeltaPrefix() const { + return m_model.deltaFunctionPrefix(); +} + +boost::optional<QString> ConvFunctionModel::getBackgroundPrefix() const { + return m_model.backgroundPrefix(); +} + +} // namespace IDA +} // namespace CustomInterfaces +} // namespace MantidQt diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.h b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.h new file mode 100644 index 0000000000000000000000000000000000000000..79faaec62813f572b46d8ff8512ba4ca460ac5bf --- /dev/null +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvFunctionModel.h @@ -0,0 +1,138 @@ +// 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 +// SPDX - License - Identifier: GPL - 3.0 + +#ifndef MANTIDQT_INDIRECT_CONVFUNCTIONMODEL_H_ +#define MANTIDQT_INDIRECT_CONVFUNCTIONMODEL_H_ + +#include "ConvTypes.h" +#include "DllConfig.h" +#include "IndexTypes.h" +#include "MantidAPI/IFunction_fwd.h" +#include "MantidAPI/ITableWorkspace_fwd.h" +#include "MantidQtWidgets/Common/ConvolutionFunctionModel.h" +#include "ParameterEstimation.h" + +#include <QMap> +#include <boost/optional.hpp> + +namespace MantidQt { +namespace CustomInterfaces { +namespace IDA { + +using namespace ConvTypes; +using namespace Mantid::API; +using namespace MantidWidgets; + +class MANTIDQT_INDIRECT_DLL ConvFunctionModel : public IFunctionModel { +public: + ConvFunctionModel(); + void setFunction(IFunction_sptr fun) override; + IFunction_sptr getFitFunction() const override; + bool hasFunction() const override; + void addFunction(const QString &prefix, const QString &funStr) override; + void removeFunction(const QString &prefix) override; + void setParameter(const QString ¶mName, double value) override; + void setParameterError(const QString ¶mName, double value) override; + double getParameter(const QString ¶mName) const override; + double getParameterError(const QString ¶mName) const override; + QString getParameterDescription(const QString ¶mName) const override; + QStringList getParameterNames() const override; + IFunction_sptr getSingleFunction(int index) const override; + IFunction_sptr getCurrentFunction() const override; + void setNumberDomains(int) override; + void setDatasetNames(const QStringList &names) override; + QStringList getDatasetNames() const override; + int getNumberDomains() const override; + void setCurrentDomainIndex(int i) override; + int currentDomainIndex() const override; + void changeTie(const QString ¶mName, const QString &tie) override; + void addConstraint(const QString &functionIndex, + const QString &constraint) override; + void removeConstraint(const QString ¶mName) override; + QStringList getGlobalParameters() const override; + void setGlobalParameters(const QStringList &globals) override; + bool isGlobal(const QString &parName) const override; + void setGlobal(const QString &parName, bool on); + QStringList getLocalParameters() const override; + void updateMultiDatasetParameters(const IFunction &fun) override; + void updateParameters(const IFunction &fun) override; + + double getLocalParameterValue(const QString &parName, int i) const override; + bool isLocalParameterFixed(const QString &parName, int i) const override; + QString getLocalParameterTie(const QString &parName, int i) const override; + QString getLocalParameterConstraint(const QString &parName, + int i) const override; + void setLocalParameterValue(const QString &parName, int i, + double value) override; + void setLocalParameterValue(const QString &parName, int i, double value, + double error) override; + void setLocalParameterFixed(const QString &parName, int i, + bool fixed) override; + void setLocalParameterTie(const QString &parName, int i, + const QString &tie) override; + void setLocalParameterConstraint(const QString &parName, int i, + const QString &constraint) override; + QString setBackgroundA0(double value) override; + + void updateMultiDatasetParameters(const ITableWorkspace ¶mTable); + + void setFitType(FitType fitType); + void setDeltaFunction(bool); + bool hasDeltaFunction() const; + void setBackground(BackgroundType bgType); + void removeBackground(); + bool hasBackground() const; + void + updateParameterEstimationData(DataForParameterEstimationCollection &&data); + void setResolution(std::string const &name, DatasetIndex const &index); + + QMap<ParamID, double> getCurrentValues() const; + QMap<ParamID, double> getCurrentErrors() const; + QMap<int, QString> getParameterNameMap() const; + +private: + void clearData(); + void setModel(); + // QString buildFunctionString() const; + boost::optional<QString> getLor1Prefix() const; + boost::optional<QString> getLor2Prefix() const; + boost::optional<QString> getDeltaPrefix() const; + boost::optional<QString> getBackgroundPrefix() const; + void setParameter(ParamID name, double value); + boost::optional<double> getParameter(ParamID name) const; + boost::optional<double> getParameterError(ParamID name) const; + boost::optional<QString> getParameterName(ParamID name) const; + boost::optional<QString> getParameterDescription(ParamID name) const; + boost::optional<QString> getPrefix(ParamID name) const; + void setCurrentValues(const QMap<ParamID, double> &); + void applyParameterFunction(std::function<void(ParamID)> paramFun) const; + boost::optional<ParamID> getParameterId(const QString &parName); + std::string buildLorentzianFunctionString() const; + std::string buildTeixeiraFunctionString() const; + std::string buildPeaksFunctionString() const; + std::string buildBackgroundFunctionString() const; + void addGlobal(const QString &parName); + void removeGlobal(const QString &parName); + QStringList makeGlobalList() const; + int getNumberOfPeaks() const; + + ConvolutionFunctionModel m_model; + FitType m_fitType = FitType::None; + BackgroundType m_backgroundType = BackgroundType::None; + bool m_hasDeltaFunction = false; + DataForParameterEstimationCollection m_estimationData; + QList<ParamID> m_globals; + FitSubType m_fitSubType; + BackgroundSubType m_backgroundSubtype; + std::string m_resolutionName; + DatasetIndex m_resolutionIndex; +}; + +} // namespace IDA +} // namespace CustomInterfaces +} // namespace MantidQt + +#endif /* MANTIDQT_INDIRECT_CONVFUNCTIONMODEL_H_ */ diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.cpp b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f8966d21d68d8515cc086f795174e19d887ea53 --- /dev/null +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.cpp @@ -0,0 +1,284 @@ +// 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 +// SPDX - License - Identifier: GPL - 3.0 + +#include "ConvTemplateBrowser.h" + +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/IFunction.h" + +#include "MantidQtWidgets/Common/QtPropertyBrowser/ButtonEditorFactory.h" +#include "MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h" +#include "MantidQtWidgets/Common/QtPropertyBrowser/DoubleEditorFactory.h" +#include "MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h" +#include "MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h" +#include "MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h" + +#include <QMessageBox> +#include <QSettings> +#include <QVBoxLayout> + +#include <iostream> +#include <limits> + +namespace MantidQt { +namespace CustomInterfaces { +namespace IDA { + +namespace { +class ScopedFalse { + bool &m_ref; + bool m_oldValue; + +public: + explicit ScopedFalse(bool &variable) : m_ref(variable), m_oldValue(variable) { + m_ref = false; + } + ~ScopedFalse() { m_ref = m_oldValue; } +}; +} // namespace + +ConvTemplateBrowser::ConvTemplateBrowser(QWidget *parent) + : FunctionTemplateBrowser(parent), m_presenter(this) { + m_templateSubTypes.emplace_back(std::make_unique<FitSubType>()); + m_templateSubTypes.emplace_back(std::make_unique<BackgroundSubType>()); + connect(&m_presenter, SIGNAL(functionStructureChanged()), this, + SIGNAL(functionStructureChanged())); +} + +void ConvTemplateBrowser::createProperties() { + m_parameterManager->blockSignals(true); + m_boolManager->blockSignals(true); + m_enumManager->blockSignals(true); + + createFunctionParameterProperties(); + createDeltaFunctionProperties(); + + m_browser->addProperty(m_subTypeProperties[0]); + m_browser->addProperty(m_deltaFunctionOn); + m_browser->addProperty(m_subTypeProperties[1]); + + m_parameterManager->blockSignals(false); + m_enumManager->blockSignals(false); + m_boolManager->blockSignals(false); + // updateState(); +} + +void ConvTemplateBrowser::setFunction(const QString &funStr) { + m_presenter.setFunction(funStr); +} + +IFunction_sptr ConvTemplateBrowser::getGlobalFunction() const { + return m_presenter.getGlobalFunction(); +} + +IFunction_sptr ConvTemplateBrowser::getFunction() const { + return m_presenter.getFunction(); +} + +void ConvTemplateBrowser::setNumberOfDatasets(int n) { + m_presenter.setNumberOfDatasets(n); +} + +int ConvTemplateBrowser::getNumberOfDatasets() const { + return m_presenter.getNumberOfDatasets(); +} + +void ConvTemplateBrowser::setDatasetNames(const QStringList &names) { + m_presenter.setDatasetNames(names); +} + +QStringList ConvTemplateBrowser::getGlobalParameters() const { + return m_presenter.getGlobalParameters(); +} + +QStringList ConvTemplateBrowser::getLocalParameters() const { + return m_presenter.getLocalParameters(); +} + +void ConvTemplateBrowser::setGlobalParameters(const QStringList &globals) { + m_presenter.setGlobalParameters(globals); +} + +void ConvTemplateBrowser::intChanged(QtProperty *prop) {} + +void ConvTemplateBrowser::boolChanged(QtProperty *prop) { + if (prop == m_deltaFunctionOn) { + m_presenter.setDeltaFunction(m_boolManager->value(prop)); + } +} + +void ConvTemplateBrowser::enumChanged(QtProperty *prop) { + auto const index = m_enumManager->value(prop); + auto propIt = + std::find(m_subTypeProperties.begin(), m_subTypeProperties.end(), prop); + if (propIt != m_subTypeProperties.end()) { + auto const subTypeIndex = + std::distance(m_subTypeProperties.begin(), propIt); + m_presenter.setSubType(subTypeIndex, index); + } +} + +void ConvTemplateBrowser::globalChanged(QtProperty *prop, const QString &name, + bool on) { + std::cerr << "Global " << name.toStdString() << ' ' << on << std::endl; +} + +void ConvTemplateBrowser::parameterChanged(QtProperty *prop) { + auto isGlobal = m_parameterManager->isGlobal(prop); + m_presenter.setGlobal(m_actualParameterNames[prop], isGlobal); + if (m_emitParameterValueChange) { + emit parameterValueChanged(m_actualParameterNames[prop], + m_parameterManager->value(prop)); + } +} + +void ConvTemplateBrowser::parameterButtonClicked(QtProperty *prop) { + emit localParameterButtonClicked(m_actualParameterNames[prop]); +} + +void ConvTemplateBrowser::updateMultiDatasetParameters(const IFunction &fun) { + m_presenter.updateMultiDatasetParameters(fun); +} + +void ConvTemplateBrowser::updateMultiDatasetParameters( + const ITableWorkspace ¶mTable) { + m_presenter.updateMultiDatasetParameters(paramTable); +} + +void ConvTemplateBrowser::updateParameters(const IFunction &fun) { + m_presenter.updateParameters(fun); +} + +void ConvTemplateBrowser::setCurrentDataset(int i) { + m_presenter.setCurrentDataset(i); +} + +void ConvTemplateBrowser::updateParameterNames( + const QMap<int, QString> ¶meterNames) { + m_actualParameterNames.clear(); + ScopedFalse _false(m_emitParameterValueChange); + for (auto const prop : m_parameterMap.keys()) { + auto const i = m_parameterMap[prop]; + auto const name = parameterNames[static_cast<int>(i)]; + m_actualParameterNames[prop] = name; + if (!name.isEmpty()) { + prop->setPropertyName(name); + } + } +} + +void ConvTemplateBrowser::setErrorsEnabled(bool enabled) { + ScopedFalse _(m_emitParameterValueChange); + m_parameterManager->setErrorsEnabled(enabled); +} + +void ConvTemplateBrowser::clear() { + // removeBackground(); + // removeStretchExponential(); + // removeExponentialTwo(); + // removeExponentialOne(); +} + +void ConvTemplateBrowser::popupMenu(const QPoint &) { + std::cerr << "Popup" << std::endl; +} + +void ConvTemplateBrowser::setParameterPropertyValue(QtProperty *prop, + double value, + double error) { + if (prop) { + ScopedFalse _(m_emitParameterValueChange); + m_parameterManager->setValue(prop, value); + m_parameterManager->setError(prop, error); + } +} + +void ConvTemplateBrowser::setGlobalParametersQuiet(const QStringList &globals) { + ScopedFalse _(m_emitParameterValueChange); + auto parameterProperies = m_parameterMap.keys(); + for (auto const prop : m_parameterMap.keys()) { + auto const name = m_actualParameterNames[prop]; + if (globals.contains(name)) { + m_parameterManager->setGlobal(prop, true); + parameterProperies.removeOne(prop); + } + } + for (auto const prop : parameterProperies) { + if (!m_actualParameterNames[prop].isEmpty()) { + m_parameterManager->setGlobal(prop, false); + } + } +} + +void ConvTemplateBrowser::createFunctionParameterProperties() { + m_subTypeParameters.resize(m_templateSubTypes.size()); + m_currentSubTypeParameters.resize(m_templateSubTypes.size()); + for (size_t isub = 0; isub < m_templateSubTypes.size(); ++isub) { + auto const &subType = m_templateSubTypes[isub]; + auto ¶meters = m_subTypeParameters[isub]; + for (int index = 0; index < subType->getNTypes(); ++index) { + auto const paramIDs = subType->getParameterIDs(index); + auto const names = subType->getParameterNames(index); + auto const descriptions = subType->getParameterDescriptions(index); + QList<QtProperty *> props; + auto const np = names.size(); + for (int i = 0; i < np; ++i) { + auto prop = m_parameterManager->addProperty(names[i]); + m_parameterManager->setDescription(prop, descriptions[i]); + m_parameterManager->setDecimals(prop, 6); + props.append(prop); + auto const id = paramIDs[i]; + m_parameterMap[prop] = id; + m_parameterReverseMap[id] = prop; + } + parameters[index] = props; + } + auto subTypeProp = m_enumManager->addProperty(subType->name()); + m_enumManager->setEnumNames(subTypeProp, + m_templateSubTypes[isub]->getTypeNames()); + m_subTypeProperties.push_back(subTypeProp); + } +} + +void ConvTemplateBrowser::createDeltaFunctionProperties() { + m_deltaFunctionOn = m_boolManager->addProperty("Delta Function"); +} + +void ConvTemplateBrowser::setSubType(size_t subTypeIndex, int typeIndex) { + auto subTypeProp = m_subTypeProperties[subTypeIndex]; + auto ¤tParameters = m_currentSubTypeParameters[subTypeIndex]; + for (auto &&prop : currentParameters) { + subTypeProp->removeSubProperty(prop); + } + currentParameters.clear(); + auto &subTypeParameters = m_subTypeParameters[subTypeIndex]; + for (auto &&prop : subTypeParameters[typeIndex]) { + subTypeProp->addSubProperty(prop); + currentParameters.append(prop); + } +} + +void ConvTemplateBrowser::setParameterValueQuiet(ParamID id, double value, + double error) { + ScopedFalse _(m_emitParameterValueChange); + auto prop = m_parameterReverseMap[id]; + m_parameterManager->setValue(prop, value); + m_parameterManager->setError(prop, error); +} + +void ConvTemplateBrowser::updateParameterEstimationData( + DataForParameterEstimationCollection &&data) {} + +void ConvTemplateBrowser::setBackgroundA0(double value) {} + +void ConvTemplateBrowser::setResolution(std::string const &name, + DatasetIndex const &index) { + m_presenter.setResolution(name, index); +} + +} // namespace IDA +} // namespace CustomInterfaces +} // namespace MantidQt diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.h b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.h new file mode 100644 index 0000000000000000000000000000000000000000..69185eb6584e3b592f8e023333f7591530b85f08 --- /dev/null +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplateBrowser.h @@ -0,0 +1,99 @@ +// 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 +// SPDX - License - Identifier: GPL - 3.0 + +#ifndef INDIRECT_CONVTEMPLATEBROWSER_H_ +#define INDIRECT_CONVTEMPLATEBROWSER_H_ + +#include "ConvTemplatePresenter.h" +#include "ConvTypes.h" +#include "DllConfig.h" +#include "FunctionTemplateBrowser.h" + +#include <QMap> +#include <QWidget> + +class QtProperty; + +namespace MantidQt { +namespace CustomInterfaces { +namespace IDA { + +using namespace ConvTypes; +/** + * Class FunctionTemplateBrowser implements QtPropertyBrowser to display + * and set properties that can be used to generate a fit function. + * + */ +class MANTIDQT_INDIRECT_DLL ConvTemplateBrowser + : public FunctionTemplateBrowser { + Q_OBJECT +public: + explicit ConvTemplateBrowser(QWidget *parent = nullptr); + void setFunction(const QString &funStr) override; + IFunction_sptr getGlobalFunction() const override; + IFunction_sptr getFunction() const override; + void setNumberOfDatasets(int) override; + int getNumberOfDatasets() const override; + void setDatasetNames(const QStringList &names) override; + QStringList getGlobalParameters() const override; + QStringList getLocalParameters() const override; + void setGlobalParameters(const QStringList &globals) override; + void updateMultiDatasetParameters(const IFunction &fun) override; + void updateMultiDatasetParameters(const ITableWorkspace ¶mTable) override; + void updateParameters(const IFunction &fun) override; + void setCurrentDataset(int i) override; + void updateParameterNames(const QMap<int, QString> ¶meterNames) override; + void setErrorsEnabled(bool enabled) override; + void clear() override; + void updateParameterEstimationData( + DataForParameterEstimationCollection &&data) override; + void setBackgroundA0(double value) override; + void setResolution(std::string const &name, + DatasetIndex const &index) override; + +protected slots: + void intChanged(QtProperty *) override; + void boolChanged(QtProperty *) override; + void enumChanged(QtProperty *) override; + void globalChanged(QtProperty *, const QString &, bool) override; + void parameterChanged(QtProperty *) override; + void parameterButtonClicked(QtProperty *) override; + +private: + void createProperties() override; + void popupMenu(const QPoint &) override; + void setParameterPropertyValue(QtProperty *prop, double value, double error); + void setGlobalParametersQuiet(const QStringList &globals); + void createFunctionParameterProperties(); + void createDeltaFunctionProperties(); + void setSubType(size_t subTypeIndex, int typeIndex); + void setParameterValueQuiet(ParamID id, double value, double error); + + std::vector<std::unique_ptr<TemplateSubType>> m_templateSubTypes; + // Map fit type to a list of function parameters (QtProperties for those + // parameters) + std::vector<QMap<int, QList<QtProperty *>>> m_subTypeParameters; + std::vector<QList<QtProperty *>> m_currentSubTypeParameters; + std::vector<QtProperty *> m_subTypeProperties; + + QtProperty *m_deltaFunctionOn; + + QMap<QtProperty *, ParamID> m_parameterMap; + QMap<ParamID, QtProperty *> m_parameterReverseMap; + QMap<QtProperty *, QString> m_actualParameterNames; + QMap<QtProperty *, std::string> m_parameterDescriptions; + +private: + ConvTemplatePresenter m_presenter; + bool m_emitParameterValueChange = true; + friend class ConvTemplatePresenter; +}; + +} // namespace IDA +} // namespace CustomInterfaces +} // namespace MantidQt + +#endif /*INDIRECT_CONVTEMPLATEBROWSER_H_*/ diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplatePresenter.cpp b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplatePresenter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..81c62dcbedcc7bc315a1f19139ff2c6b70c7a255 --- /dev/null +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplatePresenter.cpp @@ -0,0 +1,276 @@ +// 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 +// SPDX - License - Identifier: GPL - 3.0 + +#include "ConvTemplatePresenter.h" +#include "ConvTemplateBrowser.h" +#include "MantidQtWidgets/Common/EditLocalParameterDialog.h" + +#include <cmath> +#include <iostream> + +namespace MantidQt { +namespace CustomInterfaces { +namespace IDA { + +using namespace MantidWidgets; + +/** + * Constructor + * @param parent :: The parent widget. + */ +ConvTemplatePresenter::ConvTemplatePresenter(ConvTemplateBrowser *view) + : QObject(view), m_view(view) { + 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))); +} + +void ConvTemplatePresenter::setSubType(size_t subTypeIndex, int typeIndex) { + if (subTypeIndex == 0) { + m_model.setFitType(static_cast<FitType>(typeIndex)); + } else { + m_model.setBackground(static_cast<BackgroundType>(typeIndex)); + } + m_view->setSubType(subTypeIndex, typeIndex); + setErrorsEnabled(false); + updateViewParameterNames(); + updateViewParameters(); + emit functionStructureChanged(); +} + +void ConvTemplatePresenter::setDeltaFunction(bool on) { + if (on == m_model.hasDeltaFunction()) + return; + m_model.setDeltaFunction(on); + setErrorsEnabled(false); + updateViewParameterNames(); + updateViewParameters(); + emit functionStructureChanged(); +} + +void ConvTemplatePresenter::setNumberOfDatasets(int n) { + m_model.setNumberDomains(n); +} + +int ConvTemplatePresenter::getNumberOfDatasets() const { + return m_model.getNumberDomains(); +} + +void ConvTemplatePresenter::setFunction(const QString &funStr) { + m_model.setFunctionString(funStr); + m_view->clear(); + setErrorsEnabled(false); + // if (m_model.hasBackground()) { + // m_view->addFlatBackground(); + //} + // if (m_model.hasStretchExponential()) { + // m_view->addStretchExponential(); + //} + // auto const nExp = m_model.getNumberOfExponentials(); + // if (nExp > 0) { + // m_view->addExponentialOne(); + //} + // if (nExp > 1) { + // m_view->addExponentialTwo(); + //} + updateViewParameterNames(); + updateViewParameters(); + emit functionStructureChanged(); +} + +IFunction_sptr ConvTemplatePresenter::getGlobalFunction() const { + return m_model.getFitFunction(); +} + +IFunction_sptr ConvTemplatePresenter::getFunction() const { + return m_model.getCurrentFunction(); +} + +QStringList ConvTemplatePresenter::getGlobalParameters() const { + return m_model.getGlobalParameters(); +} + +QStringList ConvTemplatePresenter::getLocalParameters() const { + return m_model.getLocalParameters(); +} + +void ConvTemplatePresenter::setGlobalParameters(const QStringList &globals) { + m_model.setGlobalParameters(globals); + // if (m_model.hasStretchExponential()) { + // m_view->setGlobalParametersQuiet(globals); + //} +} + +void ConvTemplatePresenter::setGlobal(const QString &parName, bool on) { + auto globals = m_model.getGlobalParameters(); + if (on) { + if (!globals.contains(parName)) { + globals.push_back(parName); + } + } else if (globals.contains(parName)) { + globals.removeOne(parName); + } + setGlobalParameters(globals); +} + +void ConvTemplatePresenter::updateMultiDatasetParameters(const IFunction &fun) { + m_model.updateMultiDatasetParameters(fun); + updateViewParameters(); +} + +void ConvTemplatePresenter::updateMultiDatasetParameters( + const ITableWorkspace ¶mTable) { + m_model.updateMultiDatasetParameters(paramTable); + updateViewParameters(); +} + +void ConvTemplatePresenter::updateParameters(const IFunction &fun) { + m_model.updateParameters(fun); + updateViewParameters(); +} + +void ConvTemplatePresenter::setCurrentDataset(int i) { + m_model.setCurrentDomainIndex(i); + updateViewParameters(); +} + +void ConvTemplatePresenter::setDatasetNames(const QStringList &names) { + m_model.setDatasetNames(names); +} + +void ConvTemplatePresenter::setErrorsEnabled(bool enabled) { + m_view->setErrorsEnabled(enabled); +} + +void ConvTemplatePresenter::setResolution(std::string const &name, + DatasetIndex const &index) { + m_model.setResolution(name, index); +} + +void ConvTemplatePresenter::updateViewParameters() { + 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(); +} + +double ConvTemplatePresenter::getLocalParameterValue(const QString &parName, + int i) const { + return m_model.getLocalParameterValue(parName, i); +} + +bool ConvTemplatePresenter::isLocalParameterFixed(const QString &parName, + int i) const { + return m_model.isLocalParameterFixed(parName, i); +} + +QString ConvTemplatePresenter::getLocalParameterTie(const QString &parName, + int i) const { + return m_model.getLocalParameterTie(parName, i); +} + +QString +ConvTemplatePresenter::getLocalParameterConstraint(const QString &parName, + int i) const { + return m_model.getLocalParameterConstraint(parName, i); +} + +void ConvTemplatePresenter::setLocalParameterValue(const QString &parName, + int i, double value) { + m_model.setLocalParameterValue(parName, i, value); +} + +void ConvTemplatePresenter::setLocalParameterTie(const QString &parName, int i, + const QString &tie) { + m_model.setLocalParameterTie(parName, i, tie); +} + +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); +} + +void ConvTemplatePresenter::editLocalParameter(const QString &parName) { + auto const wsNames = getDatasetNames(); + QList<double> values; + QList<bool> fixes; + QStringList ties; + QStringList constraints; + const int n = wsNames.size(); + for (int i = 0; i < n; ++i) { + const double value = getLocalParameterValue(parName, i); + values.push_back(value); + const bool fixed = isLocalParameterFixed(parName, i); + fixes.push_back(fixed); + const auto tie = getLocalParameterTie(parName, i); + ties.push_back(tie); + const auto constraint = getLocalParameterConstraint(parName, i); + constraints.push_back(constraint); + } + + m_editLocalParameterDialog = new EditLocalParameterDialog( + m_view, parName, wsNames, values, fixes, ties, constraints); + connect(m_editLocalParameterDialog, SIGNAL(finished(int)), this, + SLOT(editLocalParameterFinish(int))); + m_editLocalParameterDialog->open(); +} + +void ConvTemplatePresenter::editLocalParameterFinish(int result) { + if (result == QDialog::Accepted) { + auto parName = m_editLocalParameterDialog->getParameterName(); + auto values = m_editLocalParameterDialog->getValues(); + auto fixes = m_editLocalParameterDialog->getFixes(); + auto ties = m_editLocalParameterDialog->getTies(); + assert(values.size() == getNumberOfDatasets()); + for (int i = 0; i < values.size(); ++i) { + setLocalParameterValue(parName, i, values[i]); + if (!ties[i].isEmpty()) { + setLocalParameterTie(parName, i, ties[i]); + } else if (fixes[i]) { + setLocalParameterFixed(parName, i, fixes[i]); + } else { + setLocalParameterTie(parName, i, ""); + } + } + } + m_editLocalParameterDialog = nullptr; + updateViewParameters(); + emit functionStructureChanged(); +} + +void ConvTemplatePresenter::viewChangedParameterValue(const QString &parName, + double value) { + if (parName.isEmpty()) + return; + 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); + if (fabs(value - oldValue) > 1e-6) { + setErrorsEnabled(false); + } + setLocalParameterValue(parName, i, value); + } + emit functionStructureChanged(); +} + +} // namespace IDA +} // namespace CustomInterfaces +} // namespace MantidQt diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplatePresenter.h b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplatePresenter.h new file mode 100644 index 0000000000000000000000000000000000000000..bdca7a3a17547dd499e8f777e2ef1236ef97c9bf --- /dev/null +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTemplatePresenter.h @@ -0,0 +1,83 @@ +// 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 +// SPDX - License - Identifier: GPL - 3.0 + +#ifndef INDIRECT_CONVTEMPLATEPRESENTER_H_ +#define INDIRECT_CONVTEMPLATEPRESENTER_H_ + +#include "ConvFunctionModel.h" +#include "DllConfig.h" + +#include <QMap> +#include <QWidget> + +class QtProperty; + +namespace MantidQt { +namespace MantidWidgets { +class EditLocalParameterDialog; +} +namespace CustomInterfaces { +namespace IDA { + +class ConvTemplateBrowser; + +/** + * Class FunctionTemplateBrowser implements QtPropertyBrowser to display + * and set properties that can be used to generate a fit function. + * + */ +class MANTIDQT_INDIRECT_DLL ConvTemplatePresenter : public QObject { + Q_OBJECT +public: + explicit ConvTemplatePresenter(ConvTemplateBrowser *view); + void setSubType(size_t subTypeIndex, int typeIndex); + void setDeltaFunction(bool); + void setNumberOfDatasets(int); + int getNumberOfDatasets() const; + void setFunction(const QString &funStr); + IFunction_sptr getGlobalFunction() const; + IFunction_sptr getFunction() const; + QStringList getGlobalParameters() const; + QStringList getLocalParameters() const; + void setGlobalParameters(const QStringList &globals); + void setGlobal(const QString &parName, bool on); + void updateMultiDatasetParameters(const IFunction &fun); + void updateMultiDatasetParameters(const ITableWorkspace ¶mTable); + void updateParameters(const IFunction &fun); + void setCurrentDataset(int i); + void setDatasetNames(const QStringList &names); + void setErrorsEnabled(bool enabled); + void setResolution(std::string const &name, DatasetIndex const &index); + +signals: + void functionStructureChanged(); + +private slots: + void editLocalParameter(const QString &parName); + void editLocalParameterFinish(int result); + void viewChangedParameterValue(const QString &parName, double value); + +private: + void updateViewParameters(); + QStringList getDatasetNames() const; + double getLocalParameterValue(const QString &parName, int i) const; + bool isLocalParameterFixed(const QString &parName, int i) const; + QString getLocalParameterTie(const QString &parName, int i) const; + QString getLocalParameterConstraint(const QString &parName, int i) const; + void setLocalParameterValue(const QString &parName, int i, double value); + void setLocalParameterFixed(const QString &parName, int i, bool fixed); + void setLocalParameterTie(const QString &parName, int i, const QString &tie); + void updateViewParameterNames(); + ConvTemplateBrowser *m_view; + ConvFunctionModel m_model; + EditLocalParameterDialog *m_editLocalParameterDialog; +}; + +} // namespace IDA +} // namespace CustomInterfaces +} // namespace MantidQt + +#endif /*INDIRECT_CONVTEMPLATEPRESENTER_H_*/ diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTypes.cpp b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTypes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..617110e1483cedc1c061e6e9229bb8f019498f03 --- /dev/null +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTypes.cpp @@ -0,0 +1,81 @@ +#include "ConvTypes.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/IFunction.h" + +namespace MantidQt { +namespace CustomInterfaces { +namespace IDA { +namespace ConvTypes { + +using namespace Mantid::API; + +std::map<ParamID, QString> g_paramName{ + {ParamID::LOR1_AMPLITUDE, "Amplitude"}, + {ParamID::LOR1_PEAKCENTRE, "PeakCentre"}, + {ParamID::LOR1_FWHM, "FWHM"}, + {ParamID::LOR2_AMPLITUDE_1, "Amplitude"}, + {ParamID::LOR2_PEAKCENTRE_1, "PeakCentre"}, + {ParamID::LOR2_FWHM_1, "FWHM"}, + {ParamID::LOR2_AMPLITUDE_2, "Amplitude"}, + {ParamID::LOR2_PEAKCENTRE_2, "PeakCentre"}, + {ParamID::LOR2_FWHM_2, "FWHM"}, + {ParamID::TW_HEIGHT, "Height"}, + {ParamID::TW_DIFFCOEFF, "DiffCoeff"}, + {ParamID::TW_TAU, "Tau"}, + {ParamID::TW_CENTRE, "Centre"}, + {ParamID::FLAT_BG_A0, "A0"}, + {ParamID::LINEAR_BG_A0, "A0"}, + {ParamID::LINEAR_BG_A1, "A1"}}; + +template <> +std::map<FitType, TemplateSubTypeDescriptor> + TemplateSubTypeImpl<FitType>::g_typeMap{ + {FitType::None, {"None", "", {ParamID::NONE, ParamID::NONE}}}, + {FitType::OneLorentzian, + {"One Lorentzian", + "Lorentzian", + {ParamID::LOR1_AMPLITUDE, ParamID::LOR1_FWHM}}}, + {FitType::TwoLorentzians, + {"Two Lorentzians", + "Lorentzian", + {ParamID::LOR2_AMPLITUDE_1, ParamID::LOR2_FWHM_1, + ParamID::LOR2_FWHM_2}}}, + {FitType::TeixeiraWater, + {"Teixeira Water", + "TeixeiraWaterSQE", + {ParamID::TW_HEIGHT, ParamID::TW_CENTRE}}}, + }; + +template <> +std::map<BackgroundType, TemplateSubTypeDescriptor> + TemplateSubTypeImpl<BackgroundType>::g_typeMap{ + {BackgroundType::None, {"None", "", {ParamID::NONE, ParamID::NONE}}}, + {BackgroundType::Flat, + {"FlatBackground", + "FlatBackground", + {ParamID::FLAT_BG_A0, ParamID::FLAT_BG_A0}}}, + {BackgroundType::Linear, + {"LinearBackground", + "LinearBackground", + {ParamID::LINEAR_BG_A0, ParamID::LINEAR_BG_A1}}}, + }; + +QString paramName(ParamID id) { return g_paramName.at(id); } + +void applyToFitType(FitType fitType, + const std::function<void(ParamID)> ¶mFun) { + applyToParamIDRange(FitSubType::g_typeMap[fitType].blocks.front(), + FitSubType::g_typeMap[fitType].blocks.back(), paramFun); +} + +void applyToBackground(BackgroundType bgType, + const std::function<void(ParamID)> ¶mFun) { + applyToParamIDRange(BackgroundSubType::g_typeMap[bgType].blocks.front(), + BackgroundSubType::g_typeMap[bgType].blocks.back(), + paramFun); +} + +} // namespace ConvTypes +} // namespace IDA +} // namespace CustomInterfaces +} // namespace MantidQt diff --git a/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTypes.h b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTypes.h new file mode 100644 index 0000000000000000000000000000000000000000..ccea683d412577453da0f315bbf4acab4a590dc1 --- /dev/null +++ b/qt/scientific_interfaces/Indirect/IndirectFunctionBrowser/ConvTypes.h @@ -0,0 +1,153 @@ +// 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 +// SPDX - License - Identifier: GPL - 3.0 + +#ifndef MANTIDQT_INDIRECT_CONVTYPES_H_ +#define MANTIDQT_INDIRECT_CONVTYPES_H_ + +#include "DllConfig.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/IFunction.h" + +#include <QMap> +#include <QStringList> +#include <boost/optional.hpp> + +namespace MantidQt { +namespace CustomInterfaces { +namespace IDA { +namespace ConvTypes { + +using namespace Mantid::API; + +enum class FitType { None, OneLorentzian, TwoLorentzians, TeixeiraWater }; +enum class BackgroundType { None, Flat, Linear }; + +enum class ParamID { + NONE, + LOR1_AMPLITUDE, + LOR1_PEAKCENTRE, + LOR1_FWHM, + LOR2_AMPLITUDE_1, + LOR2_PEAKCENTRE_1, + LOR2_FWHM_1, + LOR2_AMPLITUDE_2, + LOR2_PEAKCENTRE_2, + LOR2_FWHM_2, + TW_HEIGHT, + TW_DIFFCOEFF, + TW_TAU, + TW_CENTRE, + FLAT_BG_A0, + LINEAR_BG_A0, + LINEAR_BG_A1 +}; + +QString paramName(ParamID id); + +inline ParamID &operator++(ParamID &id) { + id = ParamID(static_cast<std::underlying_type<ParamID>::type>(id) + 1); + return id; +} + +inline void applyToParamIDRange(ParamID from, ParamID to, + std::function<void(ParamID)> fun) { + if (from == ParamID::NONE || to == ParamID::NONE) + return; + for (auto i = from; i <= to; ++i) + fun(i); +} + +struct TemplateSubType { + virtual QString name() const = 0; + virtual QStringList getTypeNames() const = 0; + virtual int getTypeIndex(const QString &typeName) const = 0; + virtual int getNTypes() const = 0; + virtual QList<ParamID> getParameterIDs(int typeIndex) const = 0; + virtual QStringList getParameterNames(int typeIndex) const = 0; + virtual QList<std::string> getParameterDescriptions(int typeIndex) const = 0; +}; + +struct TemplateSubTypeDescriptor { + QString name; + std::string function; + std::vector<ParamID> blocks; +}; + +template <class Type> struct TemplateSubTypeImpl : public TemplateSubType { + QStringList getTypeNames() const override { + QStringList out; + for (auto &&it : g_typeMap) { + out << it.second.name; + } + return out; + } + int getTypeIndex(const QString &typeName) const override { + for (auto &&it : g_typeMap) { + if (it.second.name == typeName) + return static_cast<int>(it.first); + } + return static_cast<int>(FitType::None); + } + int getNTypes() const override { return static_cast<int>(g_typeMap.size()); } + QList<ParamID> getParameterIDs(int typeIndex) const override { + QList<ParamID> ids; + auto fillIDs = [&ids](ParamID id) { ids << id; }; + applyToType(static_cast<Type>(typeIndex), fillIDs); + return ids; + } + QStringList getParameterNames(int typeIndex) const override { + QStringList names; + auto fillNames = [&names](ParamID id) { names << paramName(id); }; + applyToType(static_cast<Type>(typeIndex), fillNames); + return names; + } + QList<std::string> getParameterDescriptions(int typeIndex) const override { + auto const type = static_cast<Type>(typeIndex); + QList<std::string> descriptions; + auto const function = g_typeMap[type].function; + if (!function.empty()) { + IFunction_sptr fun = FunctionFactory::Instance().createFunction(function); + auto fillDescriptions = [&descriptions, &fun](ParamID id) { + descriptions << fun->parameterDescription( + fun->parameterIndex(paramName(id).toStdString())); + }; + applyToParamIDRange(g_typeMap[type].blocks.front(), + g_typeMap[type].blocks.back(), fillDescriptions); + } + return descriptions; + } + + std::string getFunctionName(Type type) const { + return g_typeMap[type].function; + } + + void applyToType(Type type, std::function<void(ParamID)> paramFun) const { + applyToParamIDRange(g_typeMap[type].blocks.front(), + g_typeMap[type].blocks.back(), paramFun); + } + + static std::map<Type, TemplateSubTypeDescriptor> g_typeMap; +}; + +struct FitSubType : public TemplateSubTypeImpl<FitType> { + QString name() const override { return "Fit Type"; } +}; + +struct BackgroundSubType : public TemplateSubTypeImpl<BackgroundType> { + QString name() const override { return "Background"; } +}; + +void applyToFitType(FitType fitType, + const std::function<void(ParamID)> ¶mFun); +void applyToBackground(BackgroundType bgType, + const std::function<void(ParamID)> ¶mFun); + +} // namespace ConvTypes +} // namespace IDA +} // namespace CustomInterfaces +} // namespace MantidQt + +#endif /* MANTIDQT_INDIRECT_CONVTYPES_H_ */ diff --git a/qt/scientific_interfaces/Indirect/test/ConvFitDataPresenterTest.h b/qt/scientific_interfaces/Indirect/test/ConvFitDataPresenterTest.h index 52a50add47796edf0559814cba1e3e95aa76e894..1ca85c05a54d2ae753c279b7e7d9af6254be8e43 100644 --- a/qt/scientific_interfaces/Indirect/test/ConvFitDataPresenterTest.h +++ b/qt/scientific_interfaces/Indirect/test/ConvFitDataPresenterTest.h @@ -12,7 +12,7 @@ #include "ConvFitDataPresenter.h" #include "ConvFitModel.h" -#include "IIndirectFitDataViewLegacy.h" +#include "IIndirectFitDataView.h" #include "MantidAPI/FrameworkManager.h" #include "MantidKernel/WarningSuppressions.h" @@ -39,7 +39,7 @@ std::unique_ptr<QTableWidget> createEmptyTableWidget(int columns, int rows) { GNU_DIAG_OFF_SUGGEST_OVERRIDE /// Mock object to mock the view -class MockConvFitDataView : public IIndirectFitDataViewLegacy { +class MockConvFitDataView : public IIndirectFitDataView { public: /// Signals void emitResolutionLoaded(QString const &workspaceName) { @@ -51,7 +51,6 @@ public: MOCK_CONST_METHOD0(isMultipleDataTabSelected, bool()); MOCK_CONST_METHOD0(isResolutionHidden, bool()); MOCK_METHOD1(setResolutionHidden, void(bool hide)); - MOCK_METHOD1(setStartAndEndHidden, void(bool hidden)); MOCK_METHOD0(disableMultipleDataTab, void()); MOCK_CONST_METHOD0(getSelectedSample, std::string()); @@ -73,9 +72,12 @@ public: MOCK_METHOD1(readSettings, void(QSettings const &settings)); MOCK_METHOD1(validate, UserInputValidator &(UserInputValidator &validator)); + MOCK_METHOD1(setXRange, void(std::pair<double, double> const &range)); /// Public slots MOCK_METHOD1(displayWarning, void(std::string const &warning)); + MOCK_METHOD1(setStartX, void(double)); + MOCK_METHOD1(setEndX, void(double)); }; /// Mock object to mock the model @@ -137,7 +139,7 @@ public: void test_that_the_model_contains_the_correct_number_of_workspace_after_instantiation() { - TS_ASSERT_EQUALS(m_model->numberOfWorkspaces(), 1); + TS_ASSERT_EQUALS(m_model->numberOfWorkspaces(), DatasetIndex{1}); } ///---------------------------------------------------------------------- diff --git a/qt/scientific_interfaces/Indirect/test/ConvFitModelTest.h b/qt/scientific_interfaces/Indirect/test/ConvFitModelTest.h index 8b19d6831ddb378a99076eced5fec6f7c8dc66d2..56f1484e6a4fe66613a2ec0c40e63d0f62096134 100644 --- a/qt/scientific_interfaces/Indirect/test/ConvFitModelTest.h +++ b/qt/scientific_interfaces/Indirect/test/ConvFitModelTest.h @@ -16,6 +16,7 @@ #include "MantidAPI/FunctionFactory.h" #include "MantidAPI/IFunction.h" #include "MantidAPI/MatrixWorkspace_fwd.h" +#include "MantidAPI/MultiDomainFunction.h" #include "MantidTestHelpers/IndirectFitDataCreationHelper.h" using namespace Mantid::API; @@ -25,7 +26,8 @@ using namespace MantidQt::CustomInterfaces::IDA; namespace { std::string getFunctionString(std::string const &workspaceName) { - return "name=LinearBackground,A0=0,A1=0,ties=(A0=0.000000,A1=0.0);" + return "composite=CompositeFunction,$domains=i;name=LinearBackground,A0=0,A1=" + "0,ties=(A0=0.000000,A1=0.0);" "(composite=Convolution,FixResolution=true,NumDeriv=true;" "name=Resolution,Workspace=" + workspaceName + @@ -34,8 +36,10 @@ std::string getFunctionString(std::string const &workspaceName) { "0175)))"; } -IFunction_sptr getFunction(std::string const &functionString) { - return FunctionFactory::Instance().createInitialized(functionString); +MultiDomainFunction_sptr getFunction(std::string const &functionString) { + auto fun = FunctionFactory::Instance().createInitialized( + "composite=MultiDomainFunction;" + functionString + ";" + functionString); + return boost::dynamic_pointer_cast<MultiDomainFunction>(fun); } } // namespace @@ -64,15 +68,15 @@ public: } void test_that_the_model_is_instantiated_and_can_hold_a_workspace() { - SpectraLegacy const spectra = DiscontinuousSpectra<std::size_t>("0-1"); + Spectra const spectra = Spectra("0-1"); m_model->addWorkspace(m_workspace, spectra); - TS_ASSERT_EQUALS(m_model->numberOfWorkspaces(), 1); + TS_ASSERT_EQUALS(m_model->numberOfWorkspaces(), DatasetIndex{1}); } void test_that_addWorkspace_will_add_multiple_workspaces() { - SpectraLegacy const spectra = DiscontinuousSpectra<std::size_t>("0-1"); + Spectra const spectra = Spectra("0-1"); auto const workspace2 = createWorkspace(3, 3); auto const workspace3 = createWorkspace(3, 2); auto const workspace4 = createWorkspace(3, 6); @@ -81,12 +85,12 @@ public: addWorkspacesToModel(spectra, m_workspace, workspace2, workspace3, workspace4, workspace5); - TS_ASSERT_EQUALS(m_model->numberOfWorkspaces(), 5); + TS_ASSERT_EQUALS(m_model->numberOfWorkspaces(), DatasetIndex{5}); } void test_that_getFittingFunction_will_return_the_fitting_function_which_has_been_set() { - SpectraLegacy const spectra = DiscontinuousSpectra<std::size_t>("0-1"); + Spectra const spectra = Spectra("0-1"); addWorkspacesToModel(spectra, m_workspace); m_model->setFitFunction(getFunction(getFunctionString("Name"))); @@ -98,13 +102,13 @@ public: void test_that_getInstrumentResolution_will_return_none_if_the_index_provided_is_larger_than_the_number_of_workspaces() { - SpectraLegacy const spectra = DiscontinuousSpectra<std::size_t>("0-1"); + Spectra const spectra = Spectra("0-1"); auto const workspace2 = createWorkspace(3, 3); m_ads->addOrReplace("Name2", workspace2); addWorkspacesToModel(spectra, m_workspace, workspace2); - TS_ASSERT(!m_model->getInstrumentResolution(3)); + TS_ASSERT(!m_model->getInstrumentResolution(DatasetIndex{3})); } void @@ -112,55 +116,55 @@ public: /// A unit test for a positive response from getInstrumentResolution needs /// to be added. The workspace used in the test will need to have an /// analyser attached to its instrument - SpectraLegacy const spectra = DiscontinuousSpectra<std::size_t>("0-1"); + Spectra const spectra = Spectra("0-1"); auto const workspace2 = createWorkspace(3, 3); m_ads->addOrReplace("Name2", workspace2); addWorkspacesToModel(spectra, m_workspace, workspace2); - TS_ASSERT(!m_model->getInstrumentResolution(0)); + TS_ASSERT(!m_model->getInstrumentResolution(DatasetIndex{0})); } void test_that_getNumberHistograms_will_get_the_number_of_spectra_for_the_workspace_specified() { - SpectraLegacy const spectra = DiscontinuousSpectra<std::size_t>("0-1"); + Spectra const spectra = Spectra("0-1"); auto const workspace2 = createWorkspace(5, 3); m_ads->addOrReplace("Name2", workspace2); addWorkspacesToModel(spectra, m_workspace, workspace2); - TS_ASSERT_EQUALS(m_model->getNumberHistograms(1), 5); + TS_ASSERT_EQUALS(m_model->getNumberHistograms(DatasetIndex{1}), 5); } void test_that_getResolution_will_return_the_a_nullptr_when_the_resolution_has_not_been_set() { - SpectraLegacy const spectra = DiscontinuousSpectra<std::size_t>("0-1"); + Spectra const spectra = Spectra("0-1"); auto const resolution = createWorkspace(5, 3); addWorkspacesToModel(spectra, m_workspace); - TS_ASSERT(!m_model->getResolution(0)); + TS_ASSERT(!m_model->getResolution(DatasetIndex{0})); } void test_that_getResolution_will_return_the_workspace_which_it_was_set_at() { - SpectraLegacy const spectra = DiscontinuousSpectra<std::size_t>("0-1"); + Spectra const spectra = Spectra("0-1"); auto const resolution = createWorkspace(6, 3); addWorkspacesToModel(spectra, m_workspace); - m_model->setResolution(resolution, 0); + m_model->setResolution(resolution, DatasetIndex{0}); - TS_ASSERT_EQUALS(m_model->getResolution(0), resolution); + TS_ASSERT_EQUALS(m_model->getResolution(DatasetIndex{0}), resolution); } void test_that_getResolution_will_return_the_a_nullptr_when_the_index_provided_is_out_of_range() { - SpectraLegacy const spectra = DiscontinuousSpectra<std::size_t>("0-1"); + Spectra const spectra = Spectra("0-1"); auto const resolution = createWorkspace(6, 3); addWorkspacesToModel(spectra, m_workspace); - m_model->setResolution(resolution, 0); + m_model->setResolution(resolution, DatasetIndex{0}); - TS_ASSERT(!m_model->getResolution(2)); + TS_ASSERT(!m_model->getResolution(DatasetIndex{2})); } void test_that_getSpectrumDependentAttributes_returns_workspace_index() { @@ -174,42 +178,41 @@ public: void test_that_removeWorkspace_will_remove_the_workspace_specified_from_the_model() { - SpectraLegacy const spectra = DiscontinuousSpectra<std::size_t>("0-1"); + Spectra const spectra = Spectra("0-1"); addWorkspacesToModel(spectra, m_workspace); - m_model->removeWorkspace(0); + m_model->removeWorkspace(DatasetIndex{0}); - TS_ASSERT_EQUALS(m_model->numberOfWorkspaces(), 0); + TS_ASSERT_EQUALS(m_model->numberOfWorkspaces(), DatasetIndex{0}); } void test_that_setResolution_will_throw_when_provided_the_name_of_a_workspace_which_does_not_exist() { - TS_ASSERT_THROWS(m_model->setResolution("InvalidName", 0), + TS_ASSERT_THROWS(m_model->setResolution("InvalidName", DatasetIndex{0}), const std::runtime_error &); } void test_that_setResolution_will_set_the_resolution_when_provided_a_correct_workspace_name() { - m_model->setResolution("Name", 0); - TS_ASSERT_EQUALS(m_model->getResolution(0), m_workspace); + m_model->setResolution("Name", DatasetIndex{0}); + TS_ASSERT_EQUALS(m_model->getResolution(DatasetIndex{0}), m_workspace); } void test_that_setResolution_will_throw_when_provided_an_index_that_is_out_of_range() { - TS_ASSERT_THROWS(m_model->setResolution(m_workspace, 5), + TS_ASSERT_THROWS(m_model->setResolution(m_workspace, DatasetIndex{5}), const std::out_of_range &); } private: template <typename Workspace, typename... Workspaces> - void addWorkspacesToModel(SpectraLegacy const &spectra, - Workspace const &workspace, + void addWorkspacesToModel(Spectra const &spectra, Workspace const &workspace, Workspaces const &... workspaces) { m_model->addWorkspace(workspace, spectra); addWorkspacesToModel(spectra, workspaces...); } - void addWorkspacesToModel(SpectraLegacy const &spectra, + void addWorkspacesToModel(Spectra const &spectra, MatrixWorkspace_sptr const &workspace) { m_model->addWorkspace(workspace, spectra); } @@ -219,4 +222,4 @@ private: std::unique_ptr<ConvFitModel> m_model; }; -#endif /* MANTIDQT_CONVFITMODELTEST_H_ */ +#endif /* MANTIDQT_CONVFITMODELTEST_H_ */ \ No newline at end of file