Merge pull request #1404 from amtriathlon/master

Fixed wrong caching when CPPlot is filtered by activity type
This commit is contained in:
Mark Liversedge
2015-06-17 17:11:22 +01:00
3 changed files with 29 additions and 8 deletions

View File

@@ -62,6 +62,7 @@ class AerobicDecoupling : public RideMetric {
const QHash<QString,RideMetric*> &,
const Context *) {
double firstHalfPower = 0.0, secondHalfPower = 0.0;
double firstHalfSpeed = 0.0, secondHalfSpeed = 0.0;
double firstHalfHR = 0.0, secondHalfHR = 0.0;
int halfway = ride->dataPoints().size() / 2;
int count = 0;
@@ -72,6 +73,7 @@ class AerobicDecoupling : public RideMetric {
if (count++ < halfway) {
if (point->hr > 0) {
firstHalfPower += point->watts;
firstHalfSpeed += point->kph;
firstHalfHR += point->hr;
++firstHalfCount;
}
@@ -79,14 +81,18 @@ class AerobicDecoupling : public RideMetric {
else {
if (point->hr > 0) {
secondHalfPower += point->watts;
secondHalfSpeed += point->kph;
secondHalfHR += point->hr;
++secondHalfCount;
}
}
}
if ((firstHalfPower > 0) && (secondHalfPower > 0)) {
if (((firstHalfPower > 0) && (secondHalfPower > 0)) ||
(ride->isRun() && (firstHalfSpeed > 0) && (secondHalfSpeed > 0))) {
firstHalfPower /= firstHalfCount;
firstHalfSpeed /= firstHalfCount;
secondHalfPower /= secondHalfCount;
secondHalfSpeed /= secondHalfCount;
firstHalfHR /= firstHalfCount;
secondHalfHR /= secondHalfCount;
@@ -97,12 +103,16 @@ class AerobicDecoupling : public RideMetric {
// should be :
double firstHalfRatio = firstHalfPower / firstHalfHR;
double secondHalfRatio = secondHalfPower / secondHalfHR;
if (ride->isRun()) {
firstHalfRatio = firstHalfSpeed / firstHalfHR;
secondHalfRatio = secondHalfSpeed / secondHalfHR;
}
percent = 100.0 * (firstHalfRatio - secondHalfRatio) / firstHalfRatio;
}
setValue(percent);
}
bool isRelevantForRide(const RideItem *ride) const { return ride->present.contains("H") && ride->present.contains("P"); }
bool isRelevantForRide(const RideItem *ride) const { return ride->present.contains("H") && (ride->present.contains("P") || (ride->isRun && ride->present.contains("S"))); }
RideMetric *clone() const { return new AerobicDecoupling(*this); }
};

View File

@@ -1533,7 +1533,7 @@ CPPlot::setRide(RideItem *rideItem)
// first make sure the bests cache is up to date as we may need it
// if plotting in percentage mode, so get data and plot it now
// delete if sport changed
if (!rangemode && (rideItem->isRun != isRun || rideItem->isSwim != isSwim)) {
if (!rangemode) {
setSport(rideItem->isRun, rideItem->isSwim);
delete bestsCache;
bestsCache = NULL;

View File

@@ -19,6 +19,7 @@
#include "RideMetric.h"
#include "RideItem.h"
#include "Zones.h"
#include "Units.h"
#include <cmath>
#include <QApplication>
@@ -252,6 +253,7 @@ class TSSPerHour : public RideMetric {
RideMetric *clone() const { return new TSSPerHour(*this); }
};
/* Running update based on: http://www.joefrielsblog.com/2014/11/the-efficiency-factor-in-running.html */
class EfficiencyFactor : public RideMetric {
Q_DECLARE_TR_FUNCTIONS(EfficiencyFactor)
double ef;
@@ -271,21 +273,29 @@ class EfficiencyFactor : public RideMetric {
setPrecision(3);
}
void compute(const RideFile *, const Zones *, int,
void compute(const RideFile *ride, const Zones *, int,
const HrZones *, int,
const QHash<QString,RideMetric*> &deps,
const Context *) {
assert(deps.contains("coggan_np"));
assert(deps.contains("xPace"));
assert(deps.contains("average_hr"));
NP *np = dynamic_cast<NP*>(deps.value("coggan_np"));
assert(np);
if (ride->isRun()) {
RideMetric *xPace = dynamic_cast<RideMetric*>(deps.value("xPace"));
assert(xPace);
ef = xPace->value(true) > 0 ? ((1000.0/METERS_PER_YARD) / xPace->value(true)) : 0.0;
} else {
NP *np = dynamic_cast<NP*>(deps.value("coggan_np"));
assert(np);
ef = np->value(true);
}
RideMetric *ah = dynamic_cast<RideMetric*>(deps.value("average_hr"));
assert(ah);
ef = np->value(true) / ah->value(true);
ef = ah->value(true) > 0 ? ef / ah->value(true) : 0.0;
setValue(ef);
}
bool isRelevantForRide(const RideItem*ride) const { return (!ride->isRun && !ride->isSwim); }
bool isRelevantForRide(const RideItem*ride) const { return ride->present.contains("H") && (ride->present.contains("P") || (ride->isRun && ride->present.contains("S"))); }
RideMetric *clone() const { return new EfficiencyFactor(*this); }
};
@@ -302,6 +312,7 @@ static bool addAllCoggan() {
RideMetricFactory::instance().addMetric(VI(), &deps);
deps.clear();
deps.append("coggan_np");
deps.append("xPace");
deps.append("average_hr");
RideMetricFactory::instance().addMetric(EfficiencyFactor(), &deps);
deps.clear();