/* * Copyright (c) 2011 Damien Grauser * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "GoldenCheetah.h" #include "HrPwWindow.h" #include "MainWindow.h" #include "LTMWindow.h" #include "HrPwPlot.h" #include "SmallPlot.h" #include "RideItem.h" #include #include #include #include // tooltip HrPwWindow::HrPwWindow(MainWindow *mainWindow) : GcWindow(mainWindow), mainWindow(mainWindow), current(NULL) { setControls(NULL); setInstanceName("HrPw"); QVBoxLayout *vlayout = new QVBoxLayout; setLayout(vlayout); // just the hr and power as a plot smallPlot = new SmallPlot(this); smallPlot->setMaximumHeight(200); smallPlot->setMinimumHeight(100); vlayout->addWidget(smallPlot); vlayout->setStretch(0, 20); // main plot hrPwPlot = new HrPwPlot(mainWindow, this); // tooltip on hover over point hrPwPlot->tooltip = new LTMToolTip(QwtPlot::xBottom, QwtPlot::yLeft, QwtPicker::VLineRubberBand, QwtPicker::AlwaysOn, hrPwPlot->canvas(), ""); hrPwPlot->tooltip->setRubberBand(QwtPicker::VLineRubberBand); hrPwPlot->tooltip->setMousePattern(QwtEventPattern::MouseSelect1, Qt::LeftButton, Qt::ShiftModifier); hrPwPlot->tooltip->setTrackerPen(QColor(Qt::black)); hrPwPlot->_canvasPicker = new LTMCanvasPicker(hrPwPlot); // setup the plot QColor inv(Qt::white); inv.setAlpha(0); hrPwPlot->tooltip->setRubberBandPen(inv); hrPwPlot->tooltip->setEnabled(true); vlayout->addWidget(hrPwPlot); vlayout->setStretch(1, 100); // the controls QWidget *c = new QWidget(this); setControls(c); QFormLayout *cl = new QFormLayout(c); QLabel *delayLabel = new QLabel(tr("HR delay"), this); delayEdit = new QLineEdit(this); delayEdit->setFixedWidth(30); cl->addRow(delayLabel, delayEdit); delaySlider = new QSlider(Qt::Horizontal); delaySlider->setTickPosition(QSlider::TicksBelow); delaySlider->setTickInterval(1); delaySlider->setMinimum(1); delaySlider->setMaximum(100); delayEdit->setValidator(new QIntValidator(delaySlider->minimum(), delaySlider->maximum(), delayEdit)); cl->addRow(delaySlider); smooth = 240; QLabel *smoothLabel = new QLabel(tr("Smooth"), this); smoothEdit = new QLineEdit(this); smoothEdit->setFixedWidth(30); smoothEdit->setText(QString("%1").arg(smooth)); cl->addRow(smoothLabel, smoothEdit); smoothSlider = new QSlider(Qt::Horizontal); smoothSlider->setTickPosition(QSlider::TicksBelow); smoothSlider->setTickInterval(10); smoothSlider->setMinimum(0); smoothSlider->setMaximum(500); smoothSlider->setValue(smooth); smoothEdit->setValidator(new QIntValidator(smoothSlider->minimum(), smoothSlider->maximum(), smoothEdit)); cl->addRow(smoothSlider); joinlineCheckBox = new QCheckBox(this);; joinlineCheckBox->setText(tr("Join points")); joinlineCheckBox->setCheckState(Qt::Unchecked); setJoinLineFromCheckBox(); cl->addRow(joinlineCheckBox); shadeZones = new QCheckBox(this);; shadeZones->setText(tr("Shade Zones")); shadeZones->setCheckState(Qt::Checked); setShadeZones(); cl->addRow(shadeZones); // connect them all up now initialised connect(hrPwPlot->_canvasPicker, SIGNAL(pointHover(QwtPlotCurve*, int)), hrPwPlot, SLOT(pointHover(QwtPlotCurve*, int))); connect(joinlineCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setJoinLineFromCheckBox())); connect(shadeZones, SIGNAL(stateChanged(int)), this, SLOT(setShadeZones())); connect(smoothEdit, SIGNAL(editingFinished()), this, SLOT(setSmoothingFromLineEdit())); connect(smoothSlider, SIGNAL(valueChanged(int)), this, SLOT(setSmoothingFromSlider())); connect(delayEdit, SIGNAL(editingFinished()), this, SLOT(setDelayFromLineEdit())); connect(delaySlider, SIGNAL(valueChanged(int)), this, SLOT(setDelayFromSlider())); //connect(mainWindow, SIGNAL(configChanged()), this, SLOT(configChanged())); connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected())); } void HrPwWindow::rideSelected() { if (!amVisible()) return; RideItem *ride = myRideItem; if (!ride || !ride->ride()) return; setData(ride); } void HrPwWindow::setData(RideItem *ride) { setSmooth(240); hrPwPlot->setDataFromRide(ride); smallPlot->setData(ride); } void HrPwWindow::setJoinLineFromCheckBox() { if (hrPwPlot->joinLine != joinlineCheckBox->isChecked()) { hrPwPlot->setJoinLine(joinlineCheckBox->isChecked()); hrPwPlot->replot(); } } void HrPwWindow::setShadeZones() { if (hrPwPlot->shadeZones != shadeZones->isChecked()) { hrPwPlot->setShadeZones(shadeZones->isChecked()); hrPwPlot->replot(); } } void HrPwWindow::setSmooth(int _smooth) { smooth = _smooth; smoothSlider->setValue(_smooth); smoothEdit->setText(QString("%1").arg(_smooth)); hrPwPlot->recalc(); } void HrPwWindow::setSmoothingFromLineEdit() { int _smooth = smoothEdit->text().toInt(); setSmooth(_smooth); } void HrPwWindow::setSmoothingFromSlider() { setSmooth(smoothSlider->value()); } void HrPwWindow::setDelayFromLineEdit() { int delay = delayEdit->text().toInt(); if (hrPwPlot->delay != delay) { delaySlider->setValue(delay); hrPwPlot->delay = delaySlider->value(); hrPwPlot->recalc(); } } void HrPwWindow::setDelayFromSlider() { if (hrPwPlot->delay != delaySlider->value()) { delayEdit->setText(QString("%1").arg(delaySlider->value())); hrPwPlot->delay = delaySlider->value(); hrPwPlot->recalc(); } } int HrPwWindow::findDelay(QVector &wattsArray, QVector &hrArray, int rideTimeSecs) { int delay = 0; double maxr = 0; for (int a = 10; a <=60; ++a) { QVector delayHr(rideTimeSecs); for (int j = a; jmaxr) { maxr = r; delay = a; } } delayEdit->setText(QString("%1").arg(delay)); delaySlider->setValue(delay); return delay; } /**************************************/ /* Fichier CPP de la librairie reglin */ /* Réalisé par GONNELLA Stéphane */ /**************************************/ /* Déclaratin globale des variables */ /*********************/ /* Fonctions de test */ /*********************/ /* Fonction de test de présence d'un zéro */ int HrPwWindow::test_zero(QVector &tab,int n) { for(int i=0;i &tab,int n) { for(int i=0;i &r) { double temp=0; int ajust=0; for(int i=0;i<5;i++) { if(r[i]>temp) { temp=r[i]; ajust = i+1; } } return ajust; } /**********************/ /* Fonctions de somme */ /**********************/ /* Fonction de somme d'éléments d'un tableau d'entier */ int HrPwWindow::somme(QVector &tab,int n) { int somme=0; for (int i=0;i &tab,int n) { double somme=0; for (int i=0;i &tab,int n) { double moyenne = double(somme(tab,n))/n; return (moyenne); } /* Fonction de calcul de moyenne d'éléments d'un tableau de réel */ double HrPwWindow::moyenne(QVector &tab,int n) { double moyenne = somme(tab,n)/n; return (moyenne); } /* Fonction de calcul de moyenne d'elements d'un tableau de réel(2) */ double HrPwWindow::moyenne2(double somme,int n) { double moyenne = somme/n; return (moyenne); } /***********************/ /* Fonction de produit */ /***********************/ /* Fonction de calcul du produit d'éléments de deux tableau ligne par ligne */ void HrPwWindow::produittab(QVector &tab1,QVector &tab2,int n) { tab_temp.resize(n); //Réservation de l'espace mémoire for (int i=0;i &tab,QVector &tabTemp,int n) { tab_temp.resize(n); //Réservation de l'espace mémoire for (int i=0;i &tab,QVector &tabTemp,int n) { tab_temp.resize(n); //Réservation de l'espace mémoire for (int i=0;i &tab,QVector &tabTemp,int n) { tab_temp.resize(n); //Réservation de l'espace mémoire for (int i=0;i &tab,double Moyenne,int n) { tab_temp.resize(n); //Réservation de l'espace mémoire for (int i=0;i &Xi, QVector &Yi,int n) { double cov; produittab(Xi,Yi,n); cov = moyenne(tab_temp,n) - ( moyenne(Xi,n) * moyenne(Yi,n) ); return (cov); } /* Fonction de calcul de la somme des carrés des écarts a la moyenne */ double HrPwWindow::variance(QVector &val,int n) { double sce; produittab(val,val,n); sce = moyenne(tab_temp,n) - ( moyenne(val,n) * moyenne(val,n)); return (sce); } /* Fonction de calcul de l'écart-type */ double HrPwWindow::ecarttype(QVector &val,int n) { double ect= sqrt(variance(val,n)); return (ect); } /******************************************************/ /* Fonctions pour le calcul de la régression linéaire */ /* par la méthode des moindres carré */ /******************************************************/ /* Fonction de clacul de la pente (a) */ double HrPwWindow::pente(QVector &Xi,QVector &Yi,int n) { double a = covariance(Xi,Yi,n)/variance(Xi,n); return (a); } /* Fonction de clacul de l'ordonnée a l'origine (b) */ double HrPwWindow::ordonnee(QVector &Xi,QVector &Yi,int n) { double b = moyenne(Yi,n) - ( pente(Xi,Yi,n) * moyenne(Xi,n) ); return (b); } /* Fonction de calcul du coef de corrélation (r) */ double HrPwWindow::corr(QVector &Xi, QVector &Yi,int n) { double r = covariance(Xi,Yi,n)/(ecarttype(Xi,n)*ecarttype(Yi,n)); //double r=pente(Xi,Yi,n)*pente(Xi,Yi,n)*(variance(Xi,n)/variance(Yi,n)); return (r); } /* Fonction de détermination du meilleur ajustement */ int HrPwWindow::ajustement(QVector &Xi,QVector &Yi,int n) { QVector r(5),lnXi(100),lnYi(100),logXi(100),logYi(100),invXi(100); //corrélation pour linéaire r[0]=val_abs(corr(Xi,Yi,n)); //corrélation pour exponetielle lntab(Yi,lnYi,n); r[1]=val_abs(corr(Xi,lnYi,n)); //corrélation pour puissance logtab(Xi,logXi,n); logtab(Yi,logYi,n); r[2]=val_abs(corr(logXi,logYi,n)); //corrélation pour inverse invtab(Xi,invXi,n); r[3]=val_abs(corr(invXi,Yi,n)); //corrélation pour logarithmique lntab(Xi,lnXi,n); r[4]=val_abs(corr(lnXi,Yi,n)); //Test du meilleur ajustement return rmax(r); } /*****************************/ /* Fin du fichier reglin.cpp */ /*****************************/