mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
Merge pull request #1404 from amtriathlon/master
Fixed wrong caching when CPPlot is filtered by activity type
This commit is contained in:
@@ -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); }
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user