41 changes: 21 additions & 20 deletions src/Metrics/Estimator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,11 @@ Estimator::calculate()
void
Estimator::run()
{
for (int i = 0; i < 2; i++) {
bool first = true;

bool isRun = (i > 0); // two times: one for rides and other for runs
foreach (QString sport, GlobalContext::context()->rideMetadata->sports()) {

printd("%s Estimates start.\n", isRun ? "Run" : "Bike");
printd("%s Estimates start.\n", sport.toStdString().c_str());

// this needs to be done once all the other metrics
// Calculate a *weekly* estimate of CP, W' etc using
Expand All @@ -178,7 +178,7 @@ Estimator::run()
foreach(RideItem *item, rides) {

// has power and matches sport
if (item->present.contains("P") && item->isRun == isRun) {
if (item->present.contains("P") && item->sport == sport) {

// no date set
if (from == QDate()) from = item->dateTime.date();
Expand All @@ -194,7 +194,7 @@ Estimator::run()

// if we don't have 2 rides or more then skip this
if (from == to || to == QDate()) {
printd("%s Estimator ends, less than 2 rides with power data.\n", isRun ? "Run" : "Bike");
printd("%s Estimator ends, less than 2 rides with power data.\n", sport.toStdString().c_str());
continue;
}

Expand Down Expand Up @@ -231,14 +231,14 @@ Estimator::run()
QDate begin = date;
QDate end = date.addDays(6);

printd("Model progress %d/%d/%d\n", date.year(), date.month(), date.day());
printd("%s Model progress %d/%d/%d\n", sport.toStdString().c_str(), date.year(), date.month(), date.day());

// bests is a rolling 6 weeks sets of bests
QVector<float> wpk; // for getting the wpk values

// include only rides or runs .............................................................vvvvv
// include only rides or runs or ..........................................................vvvvv
QVector<QDate> weekdates;
QVector<float> week = RideFileCache::meanMaxPowerFor(context, wpk, begin, end, &weekdates, isRun);
QVector<float> week = RideFileCache::meanMaxPowerFor(context, wpk, begin, end, &weekdates, sport);

// lets extract the best performance of the week first.
// only care about performances between 3-20 minutes.
Expand All @@ -248,13 +248,13 @@ Estimator::run()
double p = double(week[t]);
if (week[t]<=0) continue;

double pix = powerIndex(p, t, isRun);
double pix = powerIndex(p, t, sport);
if (pix > bestperformance.powerIndex) {
bestperformance.duration = t;
bestperformance.power = p;
bestperformance.powerIndex = pix;
bestperformance.when = weekdates[t];
bestperformance.run = isRun;
bestperformance.sport = sport;

// for filter, saves having to convert as we go
bestperformance.x = bestperformance.when.toJulianDay();
Expand All @@ -274,7 +274,7 @@ Estimator::run()
model->setData(bests.aggregate());
model->saveParameters(add.parameters); // save the computed parms

add.run = isRun;
add.sport = sport;
add.wpk = false;
add.from = begin;
add.to = end;
Expand All @@ -288,10 +288,10 @@ Estimator::run()

// so long as the important model derived values are sensible ...
if (add.WPrime > 1000 && add.CP > 100 && add.CP < 1000) {
printd("Estimates for %s - %s (%s): CP=%.f W'=%.f\n", add.from.toString().toStdString().c_str(), add.to.toString().toStdString().c_str(), add.model.toStdString().c_str(), add.CP, add.WPrime);
printd("%s Estimates for %s - %s (%s): CP=%.f W'=%.f\n", sport.toStdString().c_str(), add.from.toString().toStdString().c_str(), add.to.toString().toStdString().c_str(), add.model.toStdString().c_str(), add.CP, add.WPrime);
est << add;
} else {
printd("Estimates for %s - %s (%s): Not available\n", add.from.toString().toStdString().c_str(), add.to.toString().toStdString().c_str(), add.model.toStdString().c_str());
printd("%s Estimates for %s - %s (%s): Not available\n", sport.toStdString().c_str(), add.from.toString().toStdString().c_str(), add.to.toString().toStdString().c_str(), add.model.toStdString().c_str());
}

// set the wpk data
Expand All @@ -313,10 +313,10 @@ Estimator::run()
(!model->hasCP() || (add.CP > 1.0f && add.CP < 10.0)) &&
(!model->hasPMax() || add.PMax > 1.0f) &&
(!model->hasFTP() || add.FTP > 1.0f)) {
printd("WPK Estimates for %s - %s (%s): CP=%.1f W'=%.1f\n", add.from.toString().toStdString().c_str(), add.to.toString().toStdString().c_str(), add.model.toStdString().c_str(), add.CP, add.WPrime);
printd("%s WPK Estimates for %s - %s (%s): CP=%.1f W'=%.1f\n", sport.toStdString().c_str(), add.from.toString().toStdString().c_str(), add.to.toString().toStdString().c_str(), add.model.toStdString().c_str(), add.CP, add.WPrime);
est << add;
} else {
printd("WPK Estimates for %s - %s (%s): Not available\n", add.from.toString().toStdString().c_str(), add.to.toString().toStdString().c_str(), add.model.toStdString().c_str(), add.CP, add.WPrime);
printd("%s WPK Estimates for %s - %s (%s): Not available\n", sport.toStdString().c_str(), add.from.toString().toStdString().c_str(), add.to.toString().toStdString().c_str(), add.model.toStdString().c_str(), add.CP, add.WPrime);
}

}
Expand All @@ -330,7 +330,8 @@ Estimator::run()

// now update them
lock.lock();
if (i == 0) {
if (first) {
first = false;
estimates = est;
performances = perfs;
} else {
Expand All @@ -341,17 +342,17 @@ Estimator::run()

// debug dump peak performances
foreach(Performance p, performances) {
printd("%s %f Peak: %f for %f secs on %s\n", p.run ? "Run" : "Bike", p.powerIndex, p.power, p.duration, p.when.toString().toStdString().c_str());
printd("%s %f Peak: %f for %f secs on %s\n", sport.toStdString().c_str(), p.powerIndex, p.power, p.duration, p.when.toString().toStdString().c_str());
}
printd("%s Estimates end.\n", isRun ? "Run" : "Bike");
printd("%s Estimates end.\n", sport.toStdString().c_str());
}
}

Performance Estimator::getPerformanceForDate(QDate date, bool wantrun)
Performance Estimator::getPerformanceForDate(QDate date, QString sport)
{
// serial search is ok as low numberish - always takes first as should be no dupes
foreach(Performance p, performances) {
if (p.when == date && p.run == wantrun) return p;
if (p.when == date && p.sport == sport) return p;
}
return Performance(QDate(),0,0,0);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Metrics/Estimator.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ class Performance {

public:
Performance(QDate wc, double power, double duration, double powerIndex) :
weekcommencing(wc), power(power), duration(duration), powerIndex(powerIndex), submaximal(false) {}
weekcommencing(wc), power(power), duration(duration), powerIndex(powerIndex), submaximal(false), sport("Bike") {}

QDate when, weekcommencing;
double power, duration, powerIndex;
bool submaximal; // set by the filter, user can choose to include.
bool run; // indicates a Running with power performance
QString sport;

double x; // different units, but basically when as a julian day
};
Expand Down Expand Up @@ -73,7 +73,7 @@ class Estimator : public QThread {
void calculate();

// get a performance for a given day
Performance getPerformanceForDate(QDate date, bool wantrun);
Performance getPerformanceForDate(QDate date, QString sport);
QList<Performance> &allPerformances() { return performances; }

protected:
Expand Down
4 changes: 2 additions & 2 deletions src/Metrics/PDModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ extern double calllmfitf(double t, const double *p);
class PDEstimate
{
public:
PDEstimate() : WPrime(0), CP(0), FTP(0), PMax(0), EI(0), wpk(false), run(false) {}
PDEstimate() : WPrime(0), CP(0), FTP(0), PMax(0), EI(0), wpk(false), sport("Bike") {}

QDate from, to;
QString model;
Expand All @@ -197,7 +197,7 @@ class PDEstimate
EI;

bool wpk;
bool run;
QString sport;

QList<double> parameters; // parameters are stored/retrieved from here
// so we can run the model using pre-computed
Expand Down