diff --git a/src/BikeScore.cpp b/src/BikeScore.cpp index a896a7690..70fda17a3 100644 --- a/src/BikeScore.cpp +++ b/src/BikeScore.cpp @@ -143,25 +143,23 @@ class BikeScore : public RideMetric { QString name() const { return "skiba_bike_score"; } QString units(bool) const { return ""; } double value(bool) const { return score; } - void compute(const RideFile *ride, const Zones *zones, int zoneRange, + void compute(const RideFile *, const Zones *zones, int zoneRange, const QHash &deps) { if (!zones || zoneRange < 0) return; - if (ride->deviceType() == QString("Manual CSV")) { - // manual entry, use BS from dataPoints - score = ride->dataPoints().first()->bs; - } - else { - assert(deps.contains("skiba_xpower")); - assert(deps.contains("skiba_relative_intensity")); - XPower *xp = dynamic_cast(deps.value("skiba_xpower")); - RideMetric *ri = deps.value("skiba_relative_intensity"); - assert(ri); - double normWork = xp->xpower * xp->secs; - double rawBikeScore = normWork * ri->value(true); - double workInAnHourAtCP = zones->getCP(zoneRange) * 3600; - score = rawBikeScore / workInAnHourAtCP * 100.0; - } + assert(deps.contains("skiba_xpower")); + assert(deps.contains("skiba_relative_intensity")); + XPower *xp = dynamic_cast(deps.value("skiba_xpower")); + RideMetric *ri = deps.value("skiba_relative_intensity"); + assert(ri); + double normWork = xp->xpower * xp->secs; + double rawBikeScore = normWork * ri->value(true); + double workInAnHourAtCP = zones->getCP(zoneRange) * 3600; + score = rawBikeScore / workInAnHourAtCP * 100.0; + } + void override(const QMap &map) { + if (map.contains("value")) + score = map.value("value").toDouble(); } RideMetric *clone() const { return new BikeScore(*this); } bool canAggregate() const { return true; } diff --git a/src/DanielsPoints.cpp b/src/DanielsPoints.cpp index d58f3233e..d82cbb546 100644 --- a/src/DanielsPoints.cpp +++ b/src/DanielsPoints.cpp @@ -52,7 +52,14 @@ class DanielsPoints : public RideMetric { // Manual entry: use BS from dataPoints with a scaling factor // that works about right for long, steady rides. double scaling_factor = 0.55; - score = ride->dataPoints().first()->bs * scaling_factor; + if (ride->metricOverrides.contains("skiba_bike_score")) { + const QMap bsm = + ride->metricOverrides.value("skiba_bike_score"); + if (bsm.contains("value")) { + double bs = bsm.value("value").toDouble(); + score = bs * scaling_factor; + } + } return; } diff --git a/src/ManualRideFile.cpp b/src/ManualRideFile.cpp index 54f78d080..04a439e6a 100644 --- a/src/ManualRideFile.cpp +++ b/src/ManualRideFile.cpp @@ -109,8 +109,11 @@ RideFile *ManualFileReader::openRideFile(QFile &file, QStringList &errors) const cad = nm = 0.0; interval = 0; - rideFile->appendPoint(minutes * 60.0, cad, hr, km, - kph, nm, watts, alt, 0.0, 0.0, interval, bs); + rideFile->appendPoint(minutes * 60.0, cad, hr, km, + kph, nm, watts, alt, 0.0, 0.0, interval); + QMap bsm; + bsm.insert("value", QString("%1").arg(bs)); + rideFile->metricOverrides.insert("skiba_bike_score", bsm); rideSec = minutes * 60.0; } diff --git a/src/RideFile.cpp b/src/RideFile.cpp index 1e4e1ac27..f2bde604a 100644 --- a/src/RideFile.cpp +++ b/src/RideFile.cpp @@ -123,10 +123,6 @@ void RideFile::writeAsCsv(QFile &file, bool bIsMetric) const out << point->interval; out << ","; out << point->alt; - if (point->bs > 0.0) { - out << ","; - out << point->bs; - } out << "\n"; } @@ -200,10 +196,10 @@ QStringList RideFileFactory::listRideFiles(const QDir &dir) const void RideFile::appendPoint(double secs, double cad, double hr, double km, double kph, double nm, double watts, double alt, - double lon, double lat, int interval, double bs) + double lon, double lat, int interval) { dataPoints_.append(new RideFilePoint(secs, cad, hr, km, kph, - nm, watts, alt, lon, lat, interval,bs)); + nm, watts, alt, lon, lat, interval)); dataPresent.secs |= (secs != 0); dataPresent.cad |= (cad != 0); dataPresent.hr |= (hr != 0); diff --git a/src/RideFile.h b/src/RideFile.h index e1242a585..14294acfd 100644 --- a/src/RideFile.h +++ b/src/RideFile.h @@ -45,13 +45,12 @@ struct RideFilePoint { double secs, cad, hr, km, kph, nm, watts, alt, lon, lat;; int interval; - double bs; // to init in order RideFilePoint() : secs(0.0), cad(0.0), hr(0.0), km(0.0), kph(0.0), - nm(0.0), watts(0.0), alt(0.0), lon(0.0), lat(0.0), interval(0), bs(0.0) {} + nm(0.0), watts(0.0), alt(0.0), lon(0.0), lat(0.0), interval(0) {} RideFilePoint(double secs, double cad, double hr, double km, double kph, - double nm, double watts, double alt, double lon, double lat, int interval, double bs) : + double nm, double watts, double alt, double lon, double lat, int interval) : secs(secs), cad(cad), hr(hr), km(km), kph(kph), nm(nm), - watts(watts), alt(alt), lon(lon), lat(lat), interval(interval), bs(bs) {} + watts(watts), alt(alt), lon(lon), lat(lat), interval(interval) {} }; struct RideFileDataPresent @@ -107,7 +106,7 @@ class RideFile void appendPoint(double secs, double cad, double hr, double km, double kph, double nm, double watts, double alt, - double lon, double lat, int interval, double bs=0.0); + double lon, double lat, int interval); const QList &intervals() const { return intervals_; } void addInterval(double start, double stop, const QString &name) { @@ -122,6 +121,8 @@ class RideFile void resetDataPresent(); double timeToDistance(double) const; // get distance in km at time in secs + + QMap > metricOverrides; }; struct RideFileReader { diff --git a/src/RideItem.cpp b/src/RideItem.cpp index c1d8f867c..3f9a17f85 100644 --- a/src/RideItem.cpp +++ b/src/RideItem.cpp @@ -171,7 +171,10 @@ RideItem::computeMetrics() if (!metrics.contains(deps[j])) goto later; RideMetric *metric = factory.newMetric(name); - metric->compute(ride(), zones, zone_range, metrics); + if (ride()->metricOverrides.contains(name)) + metric->override(ride()->metricOverrides.value(name)); + else + metric->compute(ride(), zones, zone_range, metrics); metrics.insert(name, metric); i.remove(); } diff --git a/src/RideMetric.h b/src/RideMetric.h index 335f0f184..a597be595 100644 --- a/src/RideMetric.h +++ b/src/RideMetric.h @@ -37,6 +37,9 @@ struct RideMetric { const Zones *zones, int zoneRange, const QHash &deps) = 0; + virtual void override(const QMap &) { + assert(false); + } virtual bool canAggregate() const { return false; } virtual void aggregateWith(RideMetric *other) { (void) other;