Commit 01198875 authored by Alexander Semke's avatar Alexander Semke
Browse files

Finished the implementation of fitting initiated via spreadsheet's context menu.

BUG: 379104
FIXED-IN: 2.5
parent 0590a94b
......@@ -53,6 +53,7 @@
#include "backend/lib/commandtemplates.h"
#include "backend/lib/macros.h"
#include "backend/lib/trace.h"
#include "kdefrontend/spreadsheet/PlotDataDialog.h" //for PlotDataDialog::AnalysisAction. TODO: find a better place for this enum.
#include "kdefrontend/ThemeHandler.h"
#include "kdefrontend/widgets/ThemesWidget.h"
......@@ -405,17 +406,51 @@ void CartesianPlot::initActions() {
addInterpolationAction = new QAction(i18n("Interpolate"), this);
addSmoothAction = new QAction(i18n("Smooth"), this);
addFitAction.append(new QAction(i18n("Linear"), this));
addFitAction.append(new QAction(i18n("Power"), this));
addFitAction.append(new QAction(i18n("Exponential (degree 1)"), this));
addFitAction.append(new QAction(i18n("Exponential (degree 2)"), this));
addFitAction.append(new QAction(i18n("Inverse exponential"), this));
addFitAction.append(new QAction(i18n("Gauss"), this));
addFitAction.append(new QAction(i18n("Cauchy-Lorentz"), this));
addFitAction.append(new QAction(i18n("Arc Tangent"), this));
addFitAction.append(new QAction(i18n("Hyperbolic tangent"), this));
addFitAction.append(new QAction(i18n("Error function"), this));
addFitAction.append(new QAction(i18n("Custom"), this));
QAction* fitAction = new QAction(i18n("Linear"), this);
fitAction->setData(PlotDataDialog::FitLinear);
addFitAction.append(fitAction);
fitAction = new QAction(i18n("Power"), this);
fitAction->setData(PlotDataDialog::FitPower);
addFitAction.append(fitAction);
fitAction = new QAction(i18n("Exponential (degree 1)"), this);
fitAction->setData(PlotDataDialog::FitExp1);
addFitAction.append(fitAction);
fitAction = new QAction(i18n("Exponential (degree 2)"), this);
fitAction->setData(PlotDataDialog::FitExp2);
addFitAction.append(fitAction);
fitAction = new QAction(i18n("Inverse exponential"), this);
fitAction->setData(PlotDataDialog::FitInvExp);
addFitAction.append(fitAction);
fitAction = new QAction(i18n("Gauss"), this);
fitAction->setData(PlotDataDialog::FitGauss);
addFitAction.append(fitAction);
fitAction = new QAction(i18n("Cauchy-Lorentz"), this);
fitAction->setData(PlotDataDialog::FitCauchyLorentz);
addFitAction.append(fitAction);
fitAction = new QAction(i18n("Arc Tangent"), this);
fitAction->setData(PlotDataDialog::FitTan);
addFitAction.append(fitAction);
fitAction = new QAction(i18n("Hyperbolic tangent"), this);
fitAction->setData(PlotDataDialog::FitTanh);
addFitAction.append(fitAction);
fitAction = new QAction(i18n("Error function"), this);
fitAction->setData(PlotDataDialog::FitErrFunc);
addFitAction.append(fitAction);
fitAction = new QAction(i18n("Custom"), this);
fitAction->setData(PlotDataDialog::FitCustom);
addFitAction.append(fitAction);
addFourierFilterAction = new QAction(i18n("Fourier filter"), this);
......@@ -1057,7 +1092,8 @@ XYFitCurve* CartesianPlot::addFitCurve() {
//set the fit model category and type
const QAction* action = qobject_cast<const QAction*>(QObject::sender());
curve->initFitData(action, addFitAction);
PlotDataDialog::AnalysisAction type = (PlotDataDialog::AnalysisAction)action->data().toInt();
curve->initFitData(type);
this->addChild(curve);
curve->recalculate();
......
......@@ -89,74 +89,74 @@ void XYFitCurve::recalculate() {
d->recalculate();
}
void XYFitCurve::initFitData(const QAction *action, QVector<QAction*> actionList) {
void XYFitCurve::initFitData(PlotDataDialog::AnalysisAction action) {
if (!action)
return;
Q_D(XYFitCurve);
XYFitCurve::FitData fitData = d->fitData;
if (action == actionList.at(0)) {
if (action == PlotDataDialog::FitLinear) {
//Linear
fitData.modelCategory = nsl_fit_model_basic;
fitData.modelType = nsl_fit_model_polynomial;
fitData.model = nsl_fit_model_basic_equation[fitData.modelType];
fitData.paramNames << "c0" << "c1";
} else if (action == actionList.at(1)) {
} else if (action == PlotDataDialog::FitPower) {
//Power
fitData.modelCategory = nsl_fit_model_basic;
fitData.modelType = nsl_fit_model_power;
fitData.model = nsl_fit_model_basic_equation[fitData.modelType];
fitData.paramNames << "a" << "b";
} else if (action == actionList.at(2)) {
} else if (action == PlotDataDialog::FitExp1) {
//Exponential (degree 1)
fitData.modelCategory = nsl_fit_model_basic;
fitData.modelType = nsl_fit_model_exponential;
fitData.model = nsl_fit_model_basic_equation[fitData.modelType];
fitData.paramNames << "a" << "b";
} else if (action == actionList.at(3)) {
} else if (action == PlotDataDialog::FitExp2) {
//Exponential (degree 2)
fitData.modelCategory = nsl_fit_model_basic;
fitData.modelType = nsl_fit_model_exponential;
fitData.degree = 2;
fitData.model = "a1*exp(b1*x) + a2*exp(b2*x)";
fitData.paramNames << "a1" << "b1" << "a2" << "b2";
} else if (action == actionList.at(4)) {
} else if (action == PlotDataDialog::FitInvExp) {
//Inverse exponential
fitData.modelCategory = nsl_fit_model_basic;
fitData.modelType = nsl_fit_model_inverse_exponential;
fitData.model = nsl_fit_model_basic_equation[fitData.modelType];
fitData.paramNames << "a" << "b" << "c";
} else if (action == actionList.at(5)) {
} else if (action == PlotDataDialog::FitGauss) {
//Gauss
fitData.modelCategory = nsl_fit_model_peak;
fitData.model = nsl_fit_model_peak_equation[fitData.modelType];
fitData.modelType = nsl_fit_model_gaussian;
fitData.paramNames << "s" << "mu" << "a";
} else if (action == actionList.at(6)) {
} else if (action == PlotDataDialog::FitCauchyLorentz) {
//Cauchy-Lorentz
fitData.modelCategory = nsl_fit_model_peak;
fitData.modelType = nsl_fit_model_lorentz;
fitData.model = nsl_fit_model_peak_equation[fitData.modelType];
fitData.paramNames << "g" << "mu" << "a";
} else if (action == actionList.at(7)) {
} else if (action == PlotDataDialog::FitTan) {
//Arc tangent
fitData.modelCategory = nsl_fit_model_growth;
fitData.modelType = nsl_fit_model_atan;
fitData.model = nsl_fit_model_growth_equation[fitData.modelType];
fitData.paramNames << "s" << "mu" << "a";
} else if (action == actionList.at(8)) {
} else if (action == PlotDataDialog::FitTanh) {
//Hyperbolic tangent
fitData.modelCategory = nsl_fit_model_growth;
fitData.modelType = nsl_fit_model_tanh;
fitData.model = nsl_fit_model_growth_equation[fitData.modelType];
fitData.paramNames << "s" << "mu" << "a";
} else if (action == actionList.at(9)) {
} else if (action == PlotDataDialog::FitErrFunc) {
//Error function
fitData.modelCategory = nsl_fit_model_growth;
fitData.modelType = nsl_fit_model_erf;
fitData.model = nsl_fit_model_growth_equation[fitData.modelType];
fitData.paramNames << "s" << "mu" << "a";
} else if (action == actionList.at(10)) {
} else {
//Custom
fitData.modelCategory = nsl_fit_model_custom;
fitData.modelType = nsl_fit_model_custom;
......
......@@ -31,6 +31,8 @@
#define XYFITCURVE_H
#include "backend/worksheet/plots/cartesian/XYCurve.h"
#include "kdefrontend/spreadsheet/PlotDataDialog.h" //for PlotDataDialog::AnalysisAction. TODO: find a better place for this enum.
extern "C" {
#include "backend/nsl/nsl_fit.h"
}
......@@ -104,7 +106,7 @@ public:
virtual ~XYFitCurve();
void recalculate();
void initFitData(const QAction*, QVector<QAction*>); // init fit data for selected action from available list of actions
void initFitData(PlotDataDialog::AnalysisAction);
virtual QIcon icon() const override;
virtual void save(QXmlStreamWriter*) const override;
virtual bool load(XmlStreamReader*, bool preview) override;
......
......@@ -276,8 +276,8 @@ void PlotDataDialog::plot() {
}
}
addCurvesToPlot(plot);
worksheet->addChild(plot);
addCurvesToPlot(plot);
} else {
//one plot per curve
addCurvesToPlots(worksheet);
......@@ -288,6 +288,7 @@ void PlotDataDialog::plot() {
Project* project = m_spreadsheet->project();
project->beginMacro( i18n("Plot data from %1", m_spreadsheet->name()) );
Worksheet* worksheet = new Worksheet(0, i18n("Plot data from %1", m_spreadsheet->name()));
project->addChild(worksheet);
if (ui.rbCurvePlacement1->isChecked()) {
//all curves in one plot
......@@ -310,7 +311,6 @@ void PlotDataDialog::plot() {
addCurvesToPlots(worksheet);
}
project->addChild(worksheet);
project->endMacro();
}
RESET_CURSOR;
......@@ -363,8 +363,8 @@ void PlotDataDialog::addCurvesToPlots(Worksheet* worksheet) const {
}
}
addCurve(name, xColumn, yColumn, plot);
worksheet->addChild(plot);
addCurve(name, xColumn, yColumn, plot);
plot->scaleAuto();
}
......@@ -445,7 +445,7 @@ void PlotDataDialog::addCurve(const QString& name, Column* xColumn, Column* yCol
XYFitCurve* analysisCurve = new XYFitCurve(i18n("Fit to '%1'", name));
analysisCurve->setXDataColumn(xColumn);
analysisCurve->setYDataColumn(yColumn);
//TODO: initFitModel();
analysisCurve->initFitData(m_analysisAction);
plot->addChild(analysisCurve);
analysisCurve->recalculate();
break;
......@@ -454,8 +454,8 @@ void PlotDataDialog::addCurve(const QString& name, Column* xColumn, Column* yCol
XYFourierFilterCurve* analysisCurve = new XYFourierFilterCurve(i18n("Fourier Filter of '%1'", name));
analysisCurve->setXDataColumn(xColumn);
analysisCurve->setYDataColumn(yColumn);
analysisCurve->recalculate();
plot->addChild(analysisCurve);
analysisCurve->recalculate();
break;
}
}
......
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