1
/***************************************************************************
4
--------------------------------------------------------------------
5
Copyright : (C) 2007 by Ion Vasilief
6
Email (use @ for *) : ion_vasilief*yahoo.fr
7
Description : Abstract base class for data analysis operations
9
***************************************************************************/
11
/***************************************************************************
13
* This program is free software; you can redistribute it and/or modify *
14
* it under the terms of the GNU General Public License as published by *
15
* the Free Software Foundation; either version 2 of the License, or *
16
* (at your option) any later version. *
18
* This program is distributed in the hope that it will be useful, *
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21
* GNU General Public License for more details. *
23
* You should have received a copy of the GNU General Public License *
24
* along with this program; if not, write to the Free Software *
25
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
26
* Boston, MA 02110-1301 USA *
28
***************************************************************************/
33
#include "FunctionCurve.h"
34
#include "PlotCurve.h"
35
#include "core/column/Column.h"
37
#include <QApplication>
38
#include <QMessageBox>
41
#include <gsl/gsl_sort.h>
43
Filter::Filter( ApplicationWindow *parent, Graph *g, const char * name)
44
: QObject( parent, name)
50
Filter::Filter( ApplicationWindow *parent, Table *t, const char * name)
51
: QObject( parent, name)
60
d_curveColorIndex = 1;
63
d_max_iterations = 1000;
65
d_prec = ((ApplicationWindow *)parent())->fit_output_precision;
69
d_explanation = QString(name());
74
void Filter::setInterval(double from, double to)
78
QMessageBox::critical((ApplicationWindow *)parent(), tr("SciDAVis") + " - " + tr("Error"),
79
tr("Please assign a curve first!"));
82
setDataFromCurve (d_curve->title().text(), from, to);
85
void Filter::setDataCurve(int curve, double start, double end)
88
{//delete previousely allocated memory
94
d_curve = d_graph->curve(curve);
96
d_n = sortedCurveData(d_curve, start, end, &d_x, &d_y);
98
d_n = curveData(d_curve, start, end, &d_x, &d_y);
102
QMessageBox::critical((ApplicationWindow *)parent(), tr("SciDAVis") + " - " + tr("Error"),
103
tr("Several data points have the same x value causing divisions by zero, operation aborted!"));
107
else if (d_n < d_min_points)
109
QMessageBox::critical((ApplicationWindow *)parent(), tr("SciDAVis") + " - " + tr("Error"),
110
tr("You need at least %1 points in order to perform this operation!").arg(d_min_points));
119
int Filter::curveIndex(const QString& curveTitle, Graph *g)
121
if (curveTitle.isEmpty())
123
QMessageBox::critical((ApplicationWindow *)parent(), tr("Filter Error"),
124
tr("Please enter a valid curve name!"));
138
return d_graph->curveIndex(curveTitle);
141
bool Filter::setDataFromCurve(const QString& curveTitle, Graph *g)
143
int index = curveIndex(curveTitle, g);
150
d_graph->range(index, &d_from, &d_to);
151
setDataCurve(index, d_from, d_to);
155
bool Filter::setDataFromCurve(const QString& curveTitle, double from, double to, Graph *g)
157
int index = curveIndex(curveTitle, g);
164
setDataCurve(index, from, to);
168
void Filter::setColor(const QString& colorName)
170
QColor c = QColor(colorName);
171
if (colorName == "green")
172
c = QColor(Qt::green);
173
else if (colorName == "darkYellow")
174
c = QColor(Qt::darkYellow);
175
if (!ColorBox::isValidColor(c))
177
QMessageBox::critical((ApplicationWindow *)parent(), tr("Color Name Error"),
178
tr("The color name '%1' is not valid, a default color (red) will be used instead!").arg(colorName));
179
d_curveColorIndex = 1;
183
d_curveColorIndex = ColorBox::colorIndex(c);
186
void Filter::showLegend()
188
Legend* mrk = d_graph->newLegend(legendInfo());
189
if (d_graph->hasLegend())
191
Legend* legend = d_graph->legend();
192
QPoint p = legend->rect().bottomLeft();
193
mrk->setOrigin(QPoint(p.x(), p.y()+20));
205
QMessageBox::critical((ApplicationWindow *)parent(), tr("SciDAVis") + " - " + tr("Error"),
206
tr("You didn't specify a valid data set for this operation!"));
210
QApplication::setOverrideCursor(Qt::WaitCursor);
212
output();//data analysis and output
213
((ApplicationWindow *)parent())->updateLog(logInfo());
215
QApplication::restoreOverrideCursor();
219
void Filter::output()
221
double *X = new double[d_points];
222
double *Y = new double[d_points];
224
//do the data analysis
225
calculateOutputData(X, Y);
227
addResultCurve(X, Y);
230
int Filter::sortedCurveData(QwtPlotCurve *c, double start, double end, double **x, double **y)
235
int i_start = 0, i_end = c->dataSize();
236
for (int i = 0; i < i_end; i++)
237
if (c->x(i) >= start)
242
for (int i = i_end-1; i >= 0; i--)
248
int n = i_end - i_start + 1;
249
(*x) = new double[n];
250
(*y) = new double[n];
251
double *xtemp = new double[n];
252
double *ytemp = new double[n];
255
for (int i = i_start; i <= i_end; i++)
258
ytemp[j++] = c->y(i);
260
size_t *p = new size_t[n];
261
gsl_sort_index(p, xtemp, 1, n);
262
for (int i=0; i<n; i++)
264
(*x)[i] = xtemp[p[i]];
265
(*y)[i] = ytemp[p[i]];
273
int Filter::curveData(QwtPlotCurve *c, double start, double end, double **x, double **y)
278
int i_start = 0, i_end = c->dataSize();
279
for (int i = 0; i < i_end; i++)
280
if (c->x(i) >= start)
285
for (int i = i_end-1; i >= 0; i--)
291
int n = i_end - i_start + 1;
292
(*x) = new double[n];
293
(*y) = new double[n];
296
for (int i = i_start; i <= i_end; i++)
304
QwtPlotCurve* Filter::addResultCurve(double *x, double *y)
306
ApplicationWindow *app = (ApplicationWindow *)parent();
307
const QString tableName = app->generateUniqueName(QString(this->name()));
308
Column *xCol = new Column(tr("1", "filter table x column name"), SciDAVis::Numeric);
309
Column *yCol = new Column(tr("2", "filter table y column name"), SciDAVis::Numeric);
310
xCol->setPlotDesignation(SciDAVis::X);
311
yCol->setPlotDesignation(SciDAVis::Y);
312
for (int i=0; i<d_points; i++)
314
xCol->setValueAt(i, x[i]);
315
yCol->setValueAt(i, y[i]);
317
// first set the values, then add the columns to the table, otherwise, we generate too many undo commands
318
Table *t = app->newHiddenTable(tableName, d_explanation + " " + tr("of") + " " + d_curve->title().text(),
319
QList<Column *>() << xCol << yCol);
321
DataCurve *c = new DataCurve(t, tableName + "_" + xCol->name(), tableName + "_" + yCol->name());
322
c->setData(x, y, d_points);
323
c->setPen(QPen(ColorBox::color(d_curveColorIndex), 1));
324
d_graph->insertPlotItem(c, Graph::Line);
325
d_graph->updatePlot();
329
return (QwtPlotCurve*)c;
335
{//delete the memory allocated for the data