20#include <QApplication>
24#include <QItemSelectionModel>
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"));
52 createWidgets (mainWindow);
61void 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]));
104 m_labelY->setText (
"");
105 m_model->setRowCount (0);
106 m_lblMeanSquareError->setText (
"");
107 m_lblRootMeanSquare->setText (
"");
108 m_lblRSquared->setText (
"");
118void 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;
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);
143 m_model =
new FittingModel;
144 m_model->setColumnCount (2);
146 m_view =
new WindowTable (*m_model);
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);
182 QString text = m_model->selectionAsText (m_modelExport.delimiter());
184 if (!text.isEmpty ()) {
187 QApplication::clipboard ()->setText (text);
192void FittingWindow::initializeOrder ()
194 const int SECOND_ORDER = 2;
196 int index = m_cmbOrder->findData (QVariant (SECOND_ORDER));
197 m_cmbOrder->setCurrentIndex (index);
200int FittingWindow::maxOrder ()
const
202 return m_cmbOrder->currentData().toInt();
205void FittingWindow::refreshTable ()
207 int order = m_cmbOrder->currentData().toInt();
212 calculateCurveFitAndStatistics ();
215void FittingWindow::resizeTable (
int order)
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);
250void FittingWindow::slotCmbOrder(
int )
257 const QString &curveSelected,
263 m_curveSelected = curveSelected;
271 m_pointsConvenient.clear ();
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);
#define ENGAUGE_CHECK_PTR(ptr)
Drop in replacement for Q_CHECK_PTR.
const int COLUMN_POLYNOMIAL_TERMS
const int MAX_POLYNOMIAL_ORDER
const int COLUMN_COEFFICIENTS
log4cpp::Category * mainCat
Container for one set of digitized Points.
const Points points() const
Return a shallow copy of the Points.
int numPoints() const
Number of points.
DocumentModelExportFormat modelExport() const
Get method for DocumentModelExportFormat.
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.
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.
virtual void clear()
Clear stale information.
virtual void doCopy()
Copy the current selection to the clipboard.
FittingWindow(MainWindow *mainWindow)
Single constructor. Parent is needed or else this widget cannot be redocked after being undocked.
virtual void update(const CmdMediator &cmdMediator, const MainWindowModel &modelMainWindow, const QString &curveSelected, const Transformation &transformation)
Populate the table with the specified Curve.
virtual void closeEvent(QCloseEvent *event)
Catch close event so corresponding menu item in MainWindow can be updated accordingly.
void signalCurveFit(FittingCurveCoefficients, double, double, bool, bool)
Signal containing coefficients from curve fit.
virtual QTableView * view() const
QTableView-based class used by child class.
void signalFittingWindowClosed()
Signal that this QDockWidget was just closed.
Model for DlgSettingsMainWindow.
bool dragDropExport() const
Get method for drag and drop export.
int significantDigits() const
Get method for significant digits.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
QPointF posScreen() const
Accessor for screen position.
WindowAbstractBase(QWidget *parent)
Single constructor. Parent is needed or else this widget cannot be redocked after being undocked.
#define LOG4CPP_INFO_S(logger)