scidavis  2.3.0
About: SciDAVis is a free application for Scientific Data Analysis and Visualization (a fork off of QtiPlot).
  Fossies Dox: scidavis-2.3.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

Filter.cpp
Go to the documentation of this file.
1 
11 
29 #include "Filter.h"
30 #include "Legend.h"
31 #include "ColorButton.h"
32 #include "Table.h"
33 #include "FunctionCurve.h"
34 #include "PlotCurve.h"
35 #include "core/column/Column.h"
36 
37 #include <QApplication>
38 #include <QMessageBox>
39 #include <QLocale>
40 
41 #include <gsl/gsl_sort.h>
42 
43 #include <algorithm>
44 using namespace std;
45 
47  : QObject(parent)
48 {
49  QObject::setObjectName(name);
50  init();
51  d_graph = g;
52 }
53 
55  : QObject(parent)
56 {
57  QObject::setObjectName(name);
58  init();
59  d_table = t;
60 }
61 
63 {
64  d_n = 0;
66  d_tolerance = 1e-4;
67  d_points = 100;
68  d_max_iterations = 1000;
69  d_curve = 0;
70  d_prec = ((ApplicationWindow *)parent())->fit_output_precision;
71  d_init_err = false;
72  d_sort_data = false;
73  d_min_points = 2;
74  d_explanation = objectName();
75  d_graph = 0;
76  d_table = 0;
77 }
78 
79 void Filter::setInterval(double from, double to)
80 {
81  if (!d_curve)
82  {
83  QMessageBox::critical((ApplicationWindow *)parent(), tr("SciDAVis") + " - " + tr("Error"),
84  tr("Please assign a curve first!"));
85  return;
86  }
87  setDataFromCurve (d_curve->title().text(), from, to);
88 }
89 
90 void Filter::setDataCurve(int curve, double start, double end)
91 {
92  if (start > end) qSwap(start, end);
93 
94  if (d_n > 0)
95  {//delete previousely allocated memory
96  delete[] d_x;
97  delete[] d_y;
98  }
99 
100  d_init_err = false;
101  d_curve = d_graph->curve(curve);
102  if (d_sort_data)
103  d_n = sortedCurveData(d_curve, start, end, &d_x, &d_y);
104  else
105  d_n = curveData(d_curve, start, end, &d_x, &d_y);
106 
107  if (!isDataAcceptable()) {
108  d_init_err = true;
109  return;
110  }
111 
112  // ensure range is within data range
113  if (d_n>0)
114  {
115  d_from = max(start, *min_element(d_x,d_x+d_n));
116  d_to = min(end, *max_element(d_x,d_x+d_n));
117  }
118 }
119 
121  if (d_n < unsigned(d_min_points)) {
122  QMessageBox::critical((ApplicationWindow *)parent(), tr("SciDAVis") + " - " + tr("Error"),
123  tr("You need at least %1 points in order to perform this operation!").arg(d_min_points));
124  return false;
125  }
126  return true;
127 }
128 
129 int Filter::curveIndex(const QString& curveTitle, Graph *g)
130 {
131  if (curveTitle.isEmpty())
132  {
133  QMessageBox::critical((ApplicationWindow *)parent(), tr("Filter Error"),
134  tr("Please enter a valid curve name!"));
135  d_init_err = true;
136  return -1;
137  }
138 
139  if (g)
140  d_graph = g;
141 
142  if (!d_graph)
143  {
144  d_init_err = true;
145  return -1;
146  }
147 
148  return d_graph->curveIndex(curveTitle);
149 }
150 
151 bool Filter::setDataFromCurve(const QString& curveTitle, Graph *g)
152 {
153  int index = curveIndex(curveTitle, g);
154  if (index < 0)
155  {
156  d_init_err = true;
157  return false;
158  }
159 
160  d_graph->range(index, &d_from, &d_to);
161  setDataCurve(index, d_from, d_to);
162  return true;
163 }
164 
165 bool Filter::setDataFromCurve(const QString& curveTitle, double from, double to, Graph *g)
166 {
167  int index = curveIndex(curveTitle, g);
168  if (index < 0)
169  {
170  d_init_err = true;
171  return false;
172  }
173 
174  setDataCurve(index, from, to);
175  return true;
176 }
177 
178 void Filter::setColor(const QString& colorName)
179 {
180  QColor c = QColor(COLORVALUE(colorName));
181  if (colorName == "green")
182  c = QColor(Qt::green);
183  else if (colorName == "darkYellow")
184  c = QColor(Qt::darkYellow);
186  {
187  QMessageBox::critical((ApplicationWindow *)parent(), tr("Color Name Error"),
188  tr("The color name '%1' is not valid, a default color (red) will be used instead!").arg(colorName));
190  return;
191  }
192 
193  d_curveColor = c;
194 }
195 
197 {
198  Legend* mrk = d_graph->newLegend(legendInfo());
199  if (d_graph->hasLegend())
200  {
201  Legend* legend = d_graph->legend();
202  QPoint p = legend->rect().bottomLeft();
203  mrk->setOrigin(QPoint(p.x(), p.y()+20));
204  }
205  d_graph->replot();
206 }
207 
209 {
210  if (d_init_err)
211  return false;
212 
213 // if (d_n < 0)
214 // {
215 // QMessageBox::critical((ApplicationWindow *)parent(), tr("SciDAVis") + " - " + tr("Error"),
216 // tr("You didn't specify a valid data set for this operation!"));
217 // return false;
218 // }
219 
220  QApplication::setOverrideCursor(Qt::WaitCursor);
221 
222  output();//data analysis and output
223  ((ApplicationWindow *)parent())->updateLog(logInfo());
224 
225  QApplication::restoreOverrideCursor();
226  return true;
227 }
228 
230 {
231  vector<double> X(d_points);
232  vector<double> Y(d_points);
233 
234  //do the data analysis
235  calculateOutputData(&X[0], &Y[0]);
236 
237  addResultCurve(&X[0], &Y[0]);
238 }
239 
240 int Filter::sortedCurveData(QwtPlotCurve *c, double start, double end, double **x, double **y)
241 {
242  if (!c || c->rtti() != QwtPlotItem::Rtti_PlotCurve)
243  return 0;
244 
245  // start/end finding only works on nondecreasing data, so sort first
246  int datasize = c->dataSize();
247  vector<double> xtemp;
248  for (int i = 0; i < datasize; i++) {
249  xtemp.push_back(c->x(i));
250  }
251  vector<size_t> p(datasize);
252  gsl_sort_index(&p[0], &xtemp[0], 1, datasize);
253 
254  // find indices that, when permuted by the sort result, give start and end
255  int i_start, i_end;
256  for (i_start = 0; i_start < datasize; i_start++)
257  if (c->x(p[i_start]) >= start)
258  break;
259  for (i_end = datasize-1; i_end >= 0; i_end--)
260  if (c->x(p[i_end]) <= end)
261  break;
262 
263  // make result arrays
264  int n = i_end - i_start + 1;
265  // TODO refactor caller code to make this mroe RAII.
266  (*x) = new double[n];
267  (*y) = new double[n];
268  for (int j = 0, i = i_start; i <= i_end; i++, j++) {
269  (*x)[j] = c->x(p[i]);
270  (*y)[j] = c->y(p[i]);
271  }
272  return n;
273 }
274 
275 int Filter::curveData(QwtPlotCurve *c, double start, double end, double **x, double **y)
276 {
277  if (!c || c->rtti() != QwtPlotItem::Rtti_PlotCurve)
278  return 0;
279 
280  int datasize = c->dataSize();
281  int i_start = 0, i_end = c->dataSize();
282  for (i_start = 0; i_start < datasize; i_start++)
283  if (c->x(i_start) >= start)
284  break;
285  for (i_end = datasize-1; i_end >= 0; i_end--)
286  if (c->x(i_end) <= end)
287  break;
288 
289  int n = i_end - i_start + 1;
290  // TODO refactor caller code to make this mroe RAII.
291  (*x) = new double[n];
292  (*y) = new double[n];
293 
294  for (int j = 0, i = i_start; i <= i_end; i++, j++) {
295  (*x)[j] = c->x(i);
296  (*y)[j] = c->y(i);
297  }
298  return n;
299 }
300 
301 QwtPlotCurve* Filter::addResultCurve(double *x, double *y)
302 {
303  ApplicationWindow *app = (ApplicationWindow *)parent();
304  const QString tableName = app->generateUniqueName(this->objectName());
305  Column *xCol = new Column(tr("1", "filter table x column name"), SciDAVis::Numeric);
306  Column *yCol = new Column(tr("2", "filter table y column name"), SciDAVis::Numeric);
309  for (int i=0; i<d_points; i++)
310  {
311  xCol->setValueAt(i, x[i]);
312  yCol->setValueAt(i, y[i]);
313  }
314  // first set the values, then add the columns to the table, otherwise, we generate too many undo commands
315  Table *t = app->newHiddenTable(tableName, d_explanation + " " + tr("of") + " " + d_curve->title().text(),
316  QList<Column *>() << xCol << yCol);
317 
318  DataCurve *c = new DataCurve(t, tableName + "_" + xCol->name(), tableName + "_" + yCol->name());
319  c->setData(x, y, d_points);
320  c->setPen(QPen(d_curveColor, 1));
322  d_graph->updatePlot();
323 
324  return (QwtPlotCurve*)c;
325 }
326 
328 {
329  if (d_n > 0)
330  {//delete the memory allocated for the data
331  delete[] d_x;
332  delete[] d_y;
333  }
334 }
Filter::isDataAcceptable
virtual bool isDataAcceptable()
Definition: Filter.cpp:120
Filter::d_max_iterations
int d_max_iterations
Maximum number of iterations per fit.
Definition: Filter.h:145
Filter::d_points
int d_points
Number of result points to de calculated and displayed in the output curve.
Definition: Filter.h:139
Filter::setColor
void setColor(QColor colorId)
Sets the color of the output fit curve.
Definition: Filter.h:64
Filter::sortedCurveData
int sortedCurveData(QwtPlotCurve *c, double start, double end, double **x, double **y)
Same as curveData, but sorts the points by their x value.
Definition: Filter.cpp:240
FunctionCurve.h
Graph::insertPlotItem
void insertPlotItem(QwtPlotItem *i, int type)
Definition: Graph.cpp:3281
Column.h
Filter::d_x
double * d_x
x data set to be analysed
Definition: Filter.h:130
SciDAVis::Y
@ Y
y values
Definition: globals.h:58
Filter::d_sort_data
bool d_sort_data
Specifies if the filter needs sorted data as input.
Definition: Filter.h:160
Filter::d_to
double d_to
Definition: Filter.h:157
Filter::d_prec
int d_prec
Precision (number of significant digits) used for the results output.
Definition: Filter.h:151
Filter::d_curve
QwtPlotCurve * d_curve
The curve to be analysed.
Definition: Filter.h:148
Column
Aspect that manages a column.
Definition: Column.h:59
Filter::~Filter
~Filter()
Definition: Filter.cpp:327
ColorButton.h
Filter::d_tolerance
double d_tolerance
GSL Tolerance, if ever needed...
Definition: Filter.h:136
Table
MDI window providing a spreadsheet table with column logic.
Definition: Table.h:51
Filter::setInterval
void setInterval(double from, double to)
Changes the data range if the source curve was already assigned. Provided for convenience.
Definition: Filter.cpp:79
ColorButton::color
QColor color() const
Get the color of the display part.
Definition: ColorButton.cpp:140
Column::setPlotDesignation
void setPlotDesignation(SciDAVis::PlotDesignation pd)
Set the column plot designation.
Definition: Column.cpp:136
Filter::curveIndex
int curveIndex(const QString &curveTitle, Graph *g)
Performs checks and returns the index of the source data curve if OK, -1 otherwise.
Definition: Filter.cpp:129
Filter::legendInfo
virtual QString legendInfo()
Output string added to the plot as a new legend.
Definition: Filter.h:82
Filter::curveData
int curveData(QwtPlotCurve *c, double start, double end, double **x, double **y)
Sets x and y to the curve points between start and end.
Definition: Filter.cpp:275
Graph::newLegend
Legend * newLegend()
Definition: Graph.cpp:2485
Graph::replot
void replot()
Definition: Graph.h:249
ApplicationWindow::newHiddenTable
Table * newHiddenTable(const QString &name, const QString &label, QList< Column * > columns)
Create a Table which is initially hidden; used to return the result of an analysis operation.
Definition: ApplicationWindow.cpp:2565
AbstractAspect::name
QString name() const
Definition: AbstractAspect.cpp:229
PlotCurve.h
ApplicationWindow
SciDAVis's main window.
Definition: ApplicationWindow.h:122
Filter::d_table
Table * d_table
A table source of data.
Definition: Filter.h:124
Filter::d_min_points
int d_min_points
Minimum number of data points necessary to perform the operation.
Definition: Filter.h:163
Filter::output
virtual void output()
Performs the data analysis and takes care of the output.
Definition: Filter.cpp:229
Graph::Line
@ Line
Definition: Graph.h:129
Filter::d_explanation
QString d_explanation
String explaining the operation in the comment of the result table and in the project explorer.
Definition: Filter.h:166
Legend.h
Graph::hasLegend
bool hasLegend()
Definition: Graph.h:364
Legend::rect
QRect rect() const
Bounding rectangle in paint coordinates.
Definition: Legend.cpp:106
Filter::d_graph
Graph * d_graph
The graph where the result curve should be displayed.
Definition: Filter.h:118
Graph::legend
Legend * legend()
Definition: Graph.cpp:1796
Filter::d_curveColor
QColor d_curveColor
Color index of the result curve.
Definition: Filter.h:142
Legend::setOrigin
void setOrigin(const QPoint &p)
Definition: Legend.cpp:142
name
char * name()
Definition: exp_saturation.c:45
Filter::setDataCurve
virtual void setDataCurve(int curve, double start, double end)
Definition: Filter.cpp:90
Filter::d_from
double d_from
Data interval.
Definition: Filter.h:157
COLORVALUE
static QString COLORVALUE(QString s)
Definition: ColorButton.h:43
Filter::showLegend
virtual void showLegend()
Adds a new legend to the plot. Calls virtual legendInfo()
Definition: Filter.cpp:196
DataCurve
Definition: PlotCurve.h:52
ColorButton::isValidColor
static bool isValidColor(const QColor &color)
Returns TRUE if the color is included in the color box, otherwise returns FALSE.
Definition: ColorButton.cpp:168
Filter::logInfo
virtual QString logInfo()
Output string added to the log pannel of the application.
Definition: Filter.h:112
Filter::d_n
unsigned d_n
Size of the data arrays.
Definition: Filter.h:127
Filter::run
virtual bool run()
Actually does the job. Should be reimplemented in derived classes.
Definition: Filter.cpp:208
Graph
A 2D-plotting widget.
Definition: Graph.h:119
SciDAVis::X
@ X
x values
Definition: globals.h:57
Filter::calculateOutputData
virtual void calculateOutputData(double *X, double *Y)
Calculates the data for the output curve and store it in the X an Y vectors.
Definition: Filter.h:118
SciDAVis::Numeric
@ Numeric
column contains doubles
Definition: globals.h:67
Filter::setDataFromCurve
bool setDataFromCurve(const QString &curveTitle, Graph *g=0)
Definition: Filter.cpp:151
Filter::Filter
Filter(ApplicationWindow *parent, Table *t=0, QString name=QString())
Definition: Filter.cpp:54
Filter::d_init_err
bool d_init_err
Error flag telling if something went wrong during the initialization phase.
Definition: Filter.h:154
Filter::addResultCurve
QwtPlotCurve * addResultCurve(double *x, double *y)
Adds the result curve to the target output plot window. Creates a hidden table and frees the input da...
Definition: Filter.cpp:301
Graph::updatePlot
void updatePlot()
Definition: Graph.cpp:3474
Filter::init
void init()
Definition: Filter.cpp:62
Filter::d_y
double * d_y
y data set to be analysed
Definition: Filter.h:133
Table.h
Graph::curve
QwtPlotCurve * curve(int index) const
get curve by index
Definition: Graph.cpp:2821
ApplicationWindow::generateUniqueName
QString generateUniqueName(const QString &name, bool increment=true)
Definition: ApplicationWindow.cpp:13503
Graph::curveIndex
int curveIndex(long key) const
Definition: Graph.h:199
Legend
A piece of text to be drawn on a Plot.
Definition: Legend.h:56
Column::setValueAt
void setValueAt(int row, double new_value)
Set the content of row 'row'.
Definition: Column.cpp:229
Filter.h
Graph::range
int range(int index, double *start, double *end)
Definition: Graph.cpp:2834