7 #include "CmdMediator.h"
9 #include "CurveConnectAs.h"
10 #include "CurveStyle.h"
11 #include "EngaugeAssert.h"
12 #include "FittingCurveCoefficients.h"
13 #include "FittingModel.h"
14 #include "FittingStatistics.h"
15 #include "FittingWindow.h"
16 #include "GeometryModel.h"
18 #include "MainWindow.h"
19 #include "MainWindowModel.h"
20 #include <QApplication>
23 #include <QGridLayout>
24 #include <QItemSelectionModel>
28 #include "Transformation.h"
29 #include "WindowTable.h"
31 const int COLUMN_COEFFICIENTS = 0;
32 const int COLUMN_POLYNOMIAL_TERMS = 1;
36 m_isLogXTheta (false),
37 m_isLogYRadius (false),
38 m_significantDigits (mainWindow->modelMainWindow().significantDigits ())
41 setAllowedAreas (Qt::AllDockWidgetAreas);
42 setWindowTitle (tr (
"Curve Fitting Window"));
43 setStatusTip (tr (
"Curve Fitting Window"));
44 setWhatsThis (tr (
"Curve Fitting Window\n\n"
45 "This window applies a curve fit to the currently selected curve.\n\n"
46 "If drag-and-drop is disabled, a rectangular set of cells may be selected by clicking and dragging. Otherwise, if "
47 "drag-and-drop is enabled, a rectangular set of cells may be selected using Click then Shift+Click, since click and drag "
48 "starts the dragging operation. Drag-and-drop mode is set in the Main Window settings"));
50 m_coefficients.resize (MAX_POLYNOMIAL_ORDER + 1);
52 createWidgets (mainWindow);
57 FittingWindow::~FittingWindow()
61 void FittingWindow::calculateCurveFitAndStatistics ()
65 double mse = 0, rms = 0, rSquared = 0;
72 qFloor (m_significantDigits));
74 m_lblMeanSquareError->setText (QString::number (mse));
75 m_lblRootMeanSquare->setText (QString::number (rms));
76 m_lblRSquared->setText (QString::number (rSquared));
79 if (m_pointsConvenient.size () > 0) {
80 int last = m_pointsConvenient.size () - 1;
82 m_pointsConvenient [0].x(),
83 m_pointsConvenient [last].x (),
95 for (
int row = 0, order = m_model->rowCount () - 1; row < m_model->rowCount (); row++, order--) {
97 QStandardItem *item =
new QStandardItem (QString::number (m_coefficients [order]));
98 m_model->setItem (row, COLUMN_COEFFICIENTS, item);
104 m_labelY->setText (
"");
105 m_model->setRowCount (0);
106 m_lblMeanSquareError->setText (
"");
107 m_lblRootMeanSquare->setText (
"");
108 m_lblRSquared->setText (
"");
113 LOG4CPP_INFO_S ((*mainCat)) <<
"FittingWindow::closeEvent";
118 void FittingWindow::createWidgets (
MainWindow *mainWindow)
120 QWidget *widget =
new QWidget;
123 QGridLayout *layout =
new QGridLayout;
124 widget->setLayout (layout);
128 QLabel *labelOrder =
new QLabel (QString (
"%1:").arg (tr (
"Order")));
129 layout->addWidget (labelOrder, row, 0, 1, 1);
131 m_cmbOrder =
new QComboBox;
132 for (
int order = 0; order <= MAX_POLYNOMIAL_ORDER; order++) {
133 m_cmbOrder->addItem (QString::number (order), QVariant (order));
135 connect (m_cmbOrder, SIGNAL (currentIndexChanged (
int)),
this, SLOT (slotCmbOrder (
int)));
136 layout->addWidget (m_cmbOrder, row++, 1, 1, 1);
139 m_labelY =
new QLabel;
140 layout->addWidget (m_labelY, row++, 0, 1, 1);
144 m_model->setColumnCount (2);
147 connect (m_view, SIGNAL (signalTableStatusChange ()),
148 mainWindow, SLOT (slotTableStatusChange ()));
150 layout->addWidget (m_view, row++, 0, 1, 2);
153 QLabel *lblMeanSquareError =
new QLabel (QString (
"%1:").arg (tr (
"Mean square error")));
154 layout->addWidget (lblMeanSquareError, row, 0, 1, 1);
156 m_lblMeanSquareError =
new QLineEdit;
157 m_lblMeanSquareError->setReadOnly (
true);
158 m_lblMeanSquareError->setWhatsThis (tr (
"Calculated mean square error statistic"));
159 layout->addWidget (m_lblMeanSquareError, row++, 1, 1, 1);
161 QLabel *lblRootMeanSquare =
new QLabel (QString (
"%1:").arg (tr (
"Root mean square")));
162 layout->addWidget (lblRootMeanSquare, row, 0, 1, 1);
164 m_lblRootMeanSquare =
new QLineEdit;
165 m_lblRootMeanSquare->setReadOnly (
true);
166 m_lblRootMeanSquare->setWhatsThis (tr (
"Calculated root mean square statistic. This is calculated as the square root of the mean square error"));
167 layout->addWidget (m_lblRootMeanSquare, row++, 1, 1, 1);
169 QLabel *lblRSquared =
new QLabel (QString (
"%1:").arg (tr (
"R squared")));
170 layout->addWidget (lblRSquared, row, 0, 1, 1);
172 m_lblRSquared =
new QLineEdit;
173 m_lblRSquared->setReadOnly (
true);
174 m_lblRSquared->setWhatsThis (tr (
"Calculated R squared statistic"));
175 layout->addWidget (m_lblRSquared, row++, 1, 1, 1);
180 LOG4CPP_INFO_S ((*mainCat)) <<
"FittingWindow::doCopy";
184 if (!text.isEmpty ()) {
187 QApplication::clipboard ()->setText (text);
192 void FittingWindow::initializeOrder ()
194 const int SECOND_ORDER = 2;
196 int index = m_cmbOrder->findData (QVariant (SECOND_ORDER));
197 m_cmbOrder->setCurrentIndex (index);
200 int FittingWindow::maxOrder ()
const
202 return m_cmbOrder->currentData().toInt();
205 void FittingWindow::refreshTable ()
207 int order = m_cmbOrder->currentData().toInt();
212 calculateCurveFitAndStatistics ();
215 void FittingWindow::resizeTable (
int order)
217 LOG4CPP_INFO_S ((*mainCat)) <<
"FittingWindow::resizeTable";
219 m_model->setRowCount (order + 1);
222 QString yTerm = QString (
"%1%2%3")
223 .arg (m_curveSelected)
224 .arg (m_curveSelected.isEmpty () ?
227 .arg (m_isLogYRadius ?
230 m_labelY->setText (yTerm);
233 QString xString = (m_isLogXTheta ?
236 for (
int row = 0, term = order; term >= 0; row++, term--) {
239 QString termString = QString (
"%1%2%3%4")
240 .arg ((term > 0) ? xString :
"")
241 .arg ((term > 1) ?
"^" :
"")
242 .arg ((term > 1) ? QString::number (term) :
"")
243 .arg ((term > 0) ?
"+" :
"");
245 QStandardItem *item =
new QStandardItem (termString);
246 m_model->setItem (row, COLUMN_POLYNOMIAL_TERMS, item);
250 void FittingWindow::slotCmbOrder(
int )
257 const QString &curveSelected,
260 LOG4CPP_INFO_S ((*mainCat)) <<
"FittingWindow::update";
263 m_curveSelected = curveSelected;
271 m_pointsConvenient.clear ();
278 ENGAUGE_CHECK_PTR (curve);
283 const Points points = curve->
points();
284 Points::const_iterator itr;
285 for (itr = points.begin (); itr != points.end (); itr++) {
287 const Point &point = *itr;
295 double x = qLn (posGraph.x()) / qLn (10.0);
298 if (m_isLogYRadius) {
299 double y = qLn (posGraph.y()) / qLn (10.0);
303 m_pointsConvenient.append (posGraph);
313 return dynamic_cast<QTableView*
> (m_view);
const Points points() const
Return a shallow copy of the Points.
Dockable widget abstract base class.
void calculateCurveFitAndStatistics(unsigned int order, const FittingPointsConvenient &pointsConvenient, FittingCurveCoefficients &coefficients, double &mse, double &rms, double &rSquared, int significantDigits)
Compute the curve fit and the statistics for that curve fit.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
int numPoints() const
Number of points.
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
virtual void update(const CmdMediator &cmdMediator, const MainWindowModel &modelMainWindow, const QString &curveSelected, const Transformation &transformation)
Populate the table with the specified Curve.
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
QPointF posScreen() const
Accessor for screen position.
bool dragDropExport() const
Get method for drag and drop export.
FittingWindow(MainWindow *mainWindow)
Single constructor. Parent is needed or else this widget cannot be redocked after being undocked...
QString selectionAsText(ExportDelimiter delimiter) const
Convert the selection into exportable text which is good for text editors.
int significantDigits() const
Get method for significant digits.
virtual QTableView * view() const
QTableView-based class used by child class.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
void setDelimiter(ExportDelimiter delimiter)
Save output delimiter.
Model for DlgSettingsMainWindow.
void signalFittingWindowClosed()
Signal that this QDockWidget was just closed.
void signalCurveFit(FittingCurveCoefficients, double, double, bool, bool)
Signal containing coefficients from curve fit.
Table view class with support for both drag-and-drop and copy-and-paste.
Container for one set of digitized Points.
const Curve * curveForCurveName(const QString &curveName) const
See CurvesGraphs::curveForCurveNames, although this also works for AXIS_CURVE_NAME.
This class does the math to compute statistics for FittingWindow.
virtual void closeEvent(QCloseEvent *event)
Catch close event so corresponding menu item in MainWindow can be updated accordingly.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
DocumentModelExportFormat modelExport() const
Get method for DocumentModelExportFormat.
virtual void clear()
Clear stale information.
virtual void doCopy()
Copy the current selection to the clipboard.