mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
CP MMP Filter improvement
.. use powerIndex to select points when t > 120s. This has resulted in a much higher hit rate at finding performance tests in MMP data (almost 99% of the time).
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include "CPPlot.h"
|
||||
#include "PowerProfile.h"
|
||||
#include "RideCache.h"
|
||||
#include "Banister.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <qwt_series_data.h>
|
||||
@@ -1384,7 +1385,7 @@ CPPlot::plotBests(RideItem *rideItem)
|
||||
// away from a linear regression
|
||||
|
||||
// the best we found is stored in here
|
||||
struct { int i; double p, t, d; } keep;
|
||||
struct { int i; double p, t, d, pix; } keep;
|
||||
|
||||
for(int i=0; i<t.count(); i++) {
|
||||
|
||||
@@ -1399,6 +1400,7 @@ CPPlot::plotBests(RideItem *rideItem)
|
||||
keep.i=i;
|
||||
keep.p=p[i];
|
||||
keep.t=t[i];
|
||||
keep.pix=powerIndex(keep.p, keep.t);
|
||||
|
||||
// but clear since we iterate beyond
|
||||
if (i>0) { // always keep pmax point
|
||||
@@ -1413,8 +1415,10 @@ CPPlot::plotBests(RideItem *rideItem)
|
||||
|
||||
// if its beloe the line multiply distance by -1
|
||||
double d = (p[x] * t[x] * 60.0f) - ((slope * t[x] * 60.00f) + intercept);
|
||||
double pix = powerIndex(p[x],t[x]);
|
||||
|
||||
if (keep.d < d) {
|
||||
// use the regression for shorter durations and 3p for longer
|
||||
if ((keep.t < 120 && keep.d < d) || (keep.t >= 120 && keep.pix < pix)) {
|
||||
keep.d = d;
|
||||
keep.i = x;
|
||||
keep.p = p[x];
|
||||
|
||||
@@ -48,6 +48,23 @@ const double typical_CP = 261,
|
||||
// and also useful to normalise TTEs for use in the Banister model as a
|
||||
// performance measurement.
|
||||
//
|
||||
|
||||
double powerIndex(double averagepower, double duration)
|
||||
{
|
||||
// so now lets work out what the 3p model says the
|
||||
// typical athlete would do for the same duration
|
||||
//
|
||||
// P(t) = W' / (t - (W'/(CP-Pmax))) + CP
|
||||
double typicalpower = (typical_WPrime / (duration - (typical_WPrime/(typical_CP-typical_Pmax)))) + typical_CP;
|
||||
|
||||
// make sure we got a sensible value
|
||||
if (typicalpower < 0 || typicalpower > 2500) return 0;
|
||||
|
||||
// we could convert to linear work time model before
|
||||
// indexing, but they cancel out so no value in doing so
|
||||
return(100.0 * averagepower/typicalpower);
|
||||
}
|
||||
|
||||
class PowerIndex : public RideMetric {
|
||||
Q_DECLARE_TR_FUNCTIONS(PowerIndex)
|
||||
public:
|
||||
@@ -100,24 +117,13 @@ class PowerIndex : public RideMetric {
|
||||
return;
|
||||
}
|
||||
|
||||
// so now lets work out what the 3p model says the
|
||||
// typical athlete would do for the same duration
|
||||
//
|
||||
// P(t) = W' / (t - (W'/(CP-Pmax))) + CP
|
||||
//
|
||||
double typicalpower = (typical_WPrime / (duration - (typical_WPrime/(typical_CP-typical_Pmax)))) + typical_CP;
|
||||
|
||||
// make sure we got a sensible value
|
||||
if (typicalpower < 0 || typicalpower > 2500) {
|
||||
setValue(RideFile::NIL);
|
||||
setCount(0);
|
||||
return;
|
||||
}
|
||||
// calculate power index, 0=out of bounds
|
||||
double pix = powerIndex(averagepower, duration);
|
||||
|
||||
// we could convert to linear work time model before
|
||||
// indexing, but they cancel out so no value in doing so
|
||||
setValue(100.0 * averagepower/typicalpower);
|
||||
setCount(1);
|
||||
setValue(pix);
|
||||
setCount(pix > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
MetricClass classification() const { return Undefined; }
|
||||
|
||||
@@ -23,4 +23,7 @@
|
||||
// using floats because they are typically used in calculations
|
||||
// that require float precision (the actual values are integers)
|
||||
extern const double typical_CP, typical_WPrime, typical_Pmax;
|
||||
|
||||
// calculate power index, used to model in cp plot too
|
||||
extern double powerIndex(double averagepower, double duration);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user