Commit d2821fdf authored by Robert Applin's avatar Robert Applin
Browse files

Refs #28842. Implement estimation code.

parent 4652ece0
......@@ -23,6 +23,9 @@ public:
virtual IFunction_sptr doFit(const std::string &wsName,
const std::pair<double, double> &range,
const IFunction_sptr func);
virtual IFunction_sptr
calculateEstimate(const std::string &workspaceName,
const std::pair<double, double> &range);
};
} // namespace MantidWidgets
......
......@@ -34,7 +34,7 @@ public:
virtual void addFitSpectrum(const std::string &wsName) = 0;
virtual void addFunction(Mantid::API::IFunction_sptr func) = 0;
virtual void updateFunction(const Mantid::API::IFunction_sptr func) = 0;
virtual void fitWarning(const std::string &message) = 0;
virtual void displayWarning(const std::string &message) = 0;
virtual QWidget *getQWidget() = 0;
virtual void setupPlotFitSplitter(const double &start, const double &end) = 0;
virtual QWidget *createFitPane(const double &start, const double &end) = 0;
......@@ -63,7 +63,7 @@ public:
void addFitSpectrum(const std::string &wsName) override;
void addFunction(Mantid::API::IFunction_sptr func) override;
void updateFunction(const Mantid::API::IFunction_sptr func) override;
void fitWarning(const std::string &message) override;
void displayWarning(const std::string &message) override;
QWidget *getQWidget() override { return static_cast<QWidget *>(this); };
public slots:
......
......@@ -7,8 +7,88 @@
#include "MantidQtWidgets/InstrumentView/PlotFitAnalysisPaneModel.h"
#include "MantidAPI/Algorithm.h"
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/CompositeFunction.h"
#include "MantidAPI/FunctionFactory.h"
#include "MantidAPI/MatrixWorkspace.h"
#include <algorithm>
#include <numeric>
namespace {
MatrixWorkspace_sptr cropWorkspace(const MatrixWorkspace_sptr &workspace,
double startX, double endX) {
auto cropper = AlgorithmManager::Instance().create("CropWorkspace");
cropper->setAlwaysStoreInADS(false);
cropper->setProperty("InputWorkspace", workspace);
cropper->setProperty("OutputWorkspace", "__cropped");
cropper->setProperty("XMin", startX);
cropper->setProperty("XMax", endX);
cropper->execute();
return cropper->getProperty("OutputWorkspace");
}
MatrixWorkspace_sptr convertToPointData(const MatrixWorkspace_sptr &workspace) {
auto converter = AlgorithmManager::Instance().create("ConvertToPointData");
converter->setAlwaysStoreInADS(false);
converter->setProperty("InputWorkspace", workspace);
converter->setProperty("OutputWorkspace", "__pointData");
converter->execute();
return converter->getProperty("OutputWorkspace");
}
IFunction_sptr createFlatBackground(double height = 0.0) {
auto flatBackground =
FunctionFactory::Instance().createFunction("FlatBackground");
flatBackground->setParameter("A0", height);
return flatBackground;
}
IFunction_sptr createGaussian(double height = 0.0, double peakCentre = 0.0,
double sigma = 0.0) {
auto gaussian = FunctionFactory::Instance().createFunction("Gaussian");
gaussian->setParameter("Height", height);
gaussian->setParameter("PeakCentre", peakCentre);
gaussian->setParameter("Sigma", sigma);
return gaussian;
}
IFunction_sptr createGaussian(const Mantid::MantidVec &xData,
const Mantid::MantidVec &yData,
double backgroundHeight) {
const auto maxValue = *std::max_element(yData.begin(), yData.end());
auto sigma(0.0);
auto centre(0.0);
auto isMaximum(false);
for (auto i = 0u; i < yData.size(); ++i) {
if (yData[i] == maxValue && !isMaximum) {
isMaximum = true;
centre = xData[i];
}
if (isMaximum && yData[i] < maxValue / 2.0) {
isMaximum = false;
sigma = xData[i] - centre;
}
}
return createGaussian(maxValue - backgroundHeight, centre, sigma);
}
CompositeFunction_sptr
createCompositeFunction(const IFunction_sptr &flatBackground,
const IFunction_sptr &gaussian) {
auto composite = std::make_shared<CompositeFunction>();
composite->addFunction(flatBackground);
composite->addFunction(gaussian);
return composite;
}
} // namespace
using namespace Mantid::API;
namespace MantidQt {
namespace MantidWidgets {
......@@ -28,5 +108,26 @@ PlotFitAnalysisPaneModel::doFit(const std::string &wsName,
return alg->getProperty("Function");
}
IFunction_sptr PlotFitAnalysisPaneModel::calculateEstimate(
const std::string &workspaceName, const std::pair<double, double> &range) {
auto &ads = AnalysisDataService::Instance();
if (ads.doesExist(workspaceName)) {
auto workspace = ads.retrieveWS<MatrixWorkspace>(workspaceName);
workspace = cropWorkspace(workspace, range.first, range.second);
workspace = convertToPointData(workspace);
const auto xData = workspace->readX(0);
const auto yData = workspace->readY(0);
const auto background = std::accumulate(yData.begin(), yData.end(), 0.0) /
static_cast<double>(yData.size());
return createCompositeFunction(createFlatBackground(background),
createGaussian(xData, yData, background));
}
return createCompositeFunction(createFlatBackground(), createGaussian());
}
} // namespace MantidWidgets
} // namespace MantidQt
......@@ -41,16 +41,23 @@ void PlotFitAnalysisPanePresenter::doFit() {
func = m_model->doFit(m_currentName, m_view->getRange(), func);
m_view->updateFunction(func);
} catch (...) {
m_view->fitWarning("Fit failed");
m_view->displayWarning("Fit failed");
}
m_view->addFitSpectrum(m_currentName + "_fits_Workspace");
} else {
m_view->fitWarning(
m_view->displayWarning(
"Need to have extracted a data and selected a function to fit");
}
}
void PlotFitAnalysisPanePresenter::updateEstimate() {}
void PlotFitAnalysisPanePresenter::updateEstimate() {
if (!m_currentName.empty())
m_view->updateFunction(
m_model->calculateEstimate(m_currentName, m_view->getRange()));
else
m_view->displayWarning(
"Could not update estimate: data has not been extracted.");
}
void PlotFitAnalysisPanePresenter::addFunction(
Mantid::API::IFunction_sptr func) {
......
......@@ -124,8 +124,8 @@ void PlotFitAnalysisPaneView::addFunction(Mantid::API::IFunction_sptr func) {
m_fitBrowser->setFunction(std::move(func));
}
void PlotFitAnalysisPaneView::fitWarning(const std::string &message) {
QMessageBox::warning(this, "Fit error", message.c_str());
void PlotFitAnalysisPaneView::displayWarning(const std::string &message) {
QMessageBox::warning(this, "Warning!", message.c_str());
}
} // namespace MantidWidgets
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment