From 380dc47ac772df6fdac5feb98c67f64941dee572 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Date: Tue, 25 May 2021 15:18:25 -0300 Subject: [PATCH] Generalize HrZones for any sport All sports defined as values for Sport metadata field can have specifics HR Zones and default to Bike zones otherwise. Similar to current HR zones for Run. Part 2 of #3280 --- src/Charts/CriticalPowerWindow.cpp | 3 +- src/Charts/HistogramWindow.cpp | 2 +- src/Charts/LTMPlot.cpp | 6 ++-- src/Charts/OverviewItems.cpp | 18 +++++------ src/Charts/PowerHist.cpp | 28 ++++++++-------- src/Charts/PowerHist.h | 4 +-- src/Charts/RideEditor.cpp | 2 +- src/Charts/RideSummaryWindow.cpp | 44 ++++++++++++++----------- src/Core/Athlete.cpp | 12 ++++--- src/Core/Athlete.h | 4 +-- src/Core/DataFilter.cpp | 12 +++---- src/Core/RideCache.cpp | 7 +++- src/Core/RideCache.h | 2 +- src/Core/RideItem.cpp | 6 ++-- src/FileIO/RideFile.cpp | 16 +++++++-- src/FileIO/RideFile.h | 2 ++ src/FileIO/RideFileCache.cpp | 8 ++--- src/Gui/AthletePages.cpp | 27 +++++++++------- src/Gui/AthletePages.h | 12 +++---- src/Metrics/HrTimeInZone.cpp | 18 +++++------ src/Metrics/HrZones.cpp | 6 ++-- src/Metrics/HrZones.h | 6 ++-- src/Metrics/PeakHr.cpp | 2 +- src/Metrics/RideMetadata.cpp | 18 +++++++++++ src/Metrics/RideMetadata.h | 2 ++ src/Metrics/TRIMPPoints.cpp | 20 ++++++------ src/Python/SIP/Bindings.cpp | 52 +++++++++++++++--------------- src/R/RTool.cpp | 52 +++++++++++++++--------------- 28 files changed, 220 insertions(+), 171 deletions(-) diff --git a/src/Charts/CriticalPowerWindow.cpp b/src/Charts/CriticalPowerWindow.cpp index aed7b77a1..574a6bb1f 100644 --- a/src/Charts/CriticalPowerWindow.cpp +++ b/src/Charts/CriticalPowerWindow.cpp @@ -1751,9 +1751,10 @@ CriticalPowerWindow::dateRangeChanged(DateRange dateRange) fs.addFilter(context->isfiltered, context->filters); fs.addFilter(context->ishomefiltered, context->homeFilters); int nActivities, nRides, nRuns, nSwims; + QString sport; context->athlete->rideCache->getRideTypeCounts( Specification(dateRange, fs), - nActivities, nRides, nRuns, nSwims); + nActivities, nRides, nRuns, nSwims, sport); // lets work out the average CP configure value if (series() != veloclinicplot && context->athlete->zones(nActivities == nRuns)) { diff --git a/src/Charts/HistogramWindow.cpp b/src/Charts/HistogramWindow.cpp index 194ad2904..d6c8e57b4 100644 --- a/src/Charts/HistogramWindow.cpp +++ b/src/Charts/HistogramWindow.cpp @@ -771,7 +771,7 @@ HistogramWindow::rideSelected() if (rangemode) { // get range that applies to this ride powerRange = context->athlete->zones(ride->isRun)->whichRange(ride->dateTime.date()); - hrRange = context->athlete->hrZones(ride->isRun)->whichRange(ride->dateTime.date()); + hrRange = context->athlete->hrZones(ride->sport)->whichRange(ride->dateTime.date()); } // update diff --git a/src/Charts/LTMPlot.cpp b/src/Charts/LTMPlot.cpp index 083f8c38d..092197e0f 100644 --- a/src/Charts/LTMPlot.cpp +++ b/src/Charts/LTMPlot.cpp @@ -3060,7 +3060,8 @@ LTMPlot::createEstimateData(Context *context, LTMSettings *settings, MetricDetai if (!SearchFilterBox::isNull(metricDetail.datafilter)) spec.addMatches(SearchFilterBox::matches(context, metricDetail.datafilter)); int nActivities, nRides, nRuns, nSwims; - context->athlete->rideCache->getRideTypeCounts(spec, nActivities, nRides, nRuns, nSwims); + QString sport; + context->athlete->rideCache->getRideTypeCounts(spec, nActivities, nRides, nRuns, nSwims, sport); metricDetail.run = (nRuns > 0 && nActivities == nRuns); // resize the curve array to maximum possible size (even if we don't need it) @@ -3755,7 +3756,8 @@ LTMPlot::createPerformanceData(Context *context, LTMSettings *settings, MetricDe if (!SearchFilterBox::isNull(metricDetail.datafilter)) spec.addMatches(SearchFilterBox::matches(context, metricDetail.datafilter)); int nActivities, nRides, nRuns, nSwims; - context->athlete->rideCache->getRideTypeCounts(spec, nActivities, nRides, nRuns, nSwims); + QString sport; + context->athlete->rideCache->getRideTypeCounts(spec, nActivities, nRides, nRuns, nSwims, sport); metricDetail.run = (nRuns > 0 && nActivities == nRuns); int maxdays = groupForDate(settings->end.date(), settings->groupBy) diff --git a/src/Charts/OverviewItems.cpp b/src/Charts/OverviewItems.cpp index 460e2b6a6..bdb7cf634 100644 --- a/src/Charts/OverviewItems.cpp +++ b/src/Charts/OverviewItems.cpp @@ -232,11 +232,11 @@ ZoneOverviewItem::ZoneOverviewItem(ChartSpace *parent, QString name, RideFile::s // // HEARTRATE // - if (!polarized && series == RideFile::hr && parent->context->athlete->hrZones(false)) { + if (!polarized && series == RideFile::hr && parent->context->athlete->hrZones("Bike")) { // set the zero values - for(int i=0; icontext->athlete->hrZones(false)->getScheme().nzones_default; i++) { + for(int i=0; icontext->athlete->hrZones("Bike")->getScheme().nzones_default; i++) { *barset << 0; - categories << parent->context->athlete->hrZones(false)->getScheme().zone_default_name[i]; + categories << parent->context->athlete->hrZones("Bike")->getScheme().zone_default_name[i]; } } @@ -1206,14 +1206,14 @@ ZoneOverviewItem::setDateRange(DateRange dr) for(int i=0; i<3; i++) { vals[i] += item->getForSymbol(timeInZonesHRPolarized[i]); } - } else if (parent->context->athlete->hrZones(item->isRun)) { + } else if (parent->context->athlete->hrZones(item->sport)) { int numhrzones; - int hrrange = parent->context->athlete->hrZones(item->isRun)->whichRange(item->dateTime.date()); + int hrrange = parent->context->athlete->hrZones(item->sport)->whichRange(item->dateTime.date()); if (hrrange > -1) { - numhrzones = parent->context->athlete->hrZones(item->isRun)->numZones(hrrange); + numhrzones = parent->context->athlete->hrZones(item->sport)->numZones(hrrange); for(int i=0; igetForSymbol(timeInZonesHR[i]); } @@ -1323,15 +1323,15 @@ ZoneOverviewItem::setData(RideItem *item) if (time > 0 && sum > 0) barset->replace(i, round((time/sum) * 100)); else barset->replace(i, 0); } - } else if (parent->context->athlete->hrZones(item->isRun)) { + } else if (parent->context->athlete->hrZones(item->sport)) { int numhrzones; - int hrrange = parent->context->athlete->hrZones(item->isRun)->whichRange(item->dateTime.date()); + int hrrange = parent->context->athlete->hrZones(item->sport)->whichRange(item->dateTime.date()); if (hrrange > -1) { double sum=0; - numhrzones = parent->context->athlete->hrZones(item->isRun)->numZones(hrrange); + numhrzones = parent->context->athlete->hrZones(item->sport)->numZones(hrrange); for(int i=0; igetForSymbol(timeInZonesHR[i]); } diff --git a/src/Charts/PowerHist.cpp b/src/Charts/PowerHist.cpp index 6c3777e08..cf5817d87 100644 --- a/src/Charts/PowerHist.cpp +++ b/src/Charts/PowerHist.cpp @@ -330,7 +330,7 @@ PowerHist::refreshHRZoneLabels() if (!rideItem) return; if (series == RideFile::hr) { - const HrZones *zones = context->athlete->hrZones(rideItem->isRun); + const HrZones *zones = context->athlete->hrZones(rideItem->sport); int zone_range = zones->whichRange(rideItem->dateTime.date()); // generate labels for existing zones @@ -707,7 +707,7 @@ PowerHist::recalcCompare() // if (!cpzoned) { - const HrZones *hrzones = context->athlete->hrZones(false); + const HrZones *hrzones = context->athlete->hrZones("Bike"); int hrzone_range = -1; if (hrzones) { @@ -928,16 +928,16 @@ PowerHist::recalc(bool force) // hr scale draw int hrRange; - if (series == RideFile::hr && zoned && rideItem && context->athlete->hrZones(rideItem->isRun) && - (hrRange=context->athlete->hrZones(rideItem->isRun)->whichRange(rideItem->dateTime.date())) != -1) { + if (series == RideFile::hr && zoned && rideItem && context->athlete->hrZones(rideItem->sport) && + (hrRange=context->athlete->hrZones(rideItem->sport)->whichRange(rideItem->dateTime.date())) != -1) { if (cpzoned) { setAxisScaleDraw(QwtPlot::xBottom, new PolarisedZoneScaleDraw()); setAxisScale(QwtPlot::xBottom, -0.99, 3, 1); } else { - setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(context->athlete->hrZones(rideItem->isRun), hrRange)); + setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(context->athlete->hrZones(rideItem->sport), hrRange)); if (hrRange >= 0) - setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->hrZones(rideItem->isRun)->numZones(hrRange), 1); + setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->hrZones(rideItem->sport)->numZones(hrRange), 1); else setAxisScale(QwtPlot::xBottom, -0.99, 0, 1); } @@ -975,14 +975,14 @@ PowerHist::recalc(bool force) } // hr zoned for a time range - if (source == Cache && zoned && series == RideFile::hr && context->athlete->hrZones(false)) { + if (source == Cache && zoned && series == RideFile::hr && context->athlete->hrZones("Bike")) { if (cpzoned) { setAxisScaleDraw(QwtPlot::xBottom, new PolarisedZoneScaleDraw()); setAxisScale(QwtPlot::xBottom, -0.99, 3, 1); } else { - setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(context->athlete->hrZones(false), 0)); - if (context->athlete->hrZones(false)->getRangeSize()) - setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->hrZones(false)->numZones(0), 1); // use zones from first defined range + setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(context->athlete->hrZones("Bike"), 0)); + if (context->athlete->hrZones("Bike")->getRangeSize()) + setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->hrZones("Bike")->numZones(0), 1); // use zones from first defined range } } @@ -1943,9 +1943,9 @@ PowerHist::setArraysFromRide(RideFile *ride, HistData &standard, const Zones *zo int AeTP = zoneRange != -1 ? zones->getAeT(zoneRange) : 0; double WPRIME = zoneRange != -1 ? zones->getWprime(zoneRange) : 22000; - int hrZoneRange = context->athlete->hrZones(ride->isRun()) ? context->athlete->hrZones(ride->isRun())->whichRange(ride->startTime().date()) : -1; - int LTHR = hrZoneRange != -1 ? context->athlete->hrZones(ride->isRun())->getLT(hrZoneRange) : 0; - int AeTHR = hrZoneRange != -1 ? context->athlete->hrZones(ride->isRun())->getAeT(hrZoneRange) : 0; + int hrZoneRange = context->athlete->hrZones(ride->sport()) ? context->athlete->hrZones(ride->sport())->whichRange(ride->startTime().date()) : -1; + int LTHR = hrZoneRange != -1 ? context->athlete->hrZones(ride->sport())->getLT(hrZoneRange) : 0; + int AeTHR = hrZoneRange != -1 ? context->athlete->hrZones(ride->sport())->getAeT(hrZoneRange) : 0; int paceZoneRange = context->athlete->paceZones(ride->isSwim()) ? context->athlete->paceZones(ride->isSwim())->whichRange(ride->startTime().date()) : -1; double CV = (paceZoneRange != -1) ? context->athlete->paceZones(ride->isSwim())->getCV(paceZoneRange) : 0.0; @@ -2146,7 +2146,7 @@ PowerHist::setArraysFromRide(RideFile *ride, HistData &standard, const Zones *zo standard.hrCPZoneArray[2] ++; } - hrIndex = context->athlete->hrZones(ride->isRun())->whichZone(hrZoneRange, p1->hr); + hrIndex = context->athlete->hrZones(ride->sport())->whichZone(hrZoneRange, p1->hr); if (hrIndex >= 0 && hrIndex < maxSize) { if (hrIndex >= standard.hrZoneArray.size()) diff --git a/src/Charts/PowerHist.h b/src/Charts/PowerHist.h index f0e62c8d7..7a0b94b0c 100644 --- a/src/Charts/PowerHist.h +++ b/src/Charts/PowerHist.h @@ -473,7 +473,7 @@ public: if (! rideItem) return; - const HrZones *zones = parent->context->athlete->hrZones(rideItem->isRun); + const HrZones *zones = parent->context->athlete->hrZones(rideItem->sport); int zone_range = -1; if (zones) zone_range = zones->whichRange(rideItem->dateTime.date()); @@ -524,7 +524,7 @@ public: if (! rideItem) return; - const HrZones *zones = parent->context->athlete->hrZones(rideItem->isRun); + const HrZones *zones = parent->context->athlete->hrZones(rideItem->sport); int zone_range = -1; if (zones) zone_range = zones->whichRange(rideItem->dateTime.date()); diff --git a/src/Charts/RideEditor.cpp b/src/Charts/RideEditor.cpp index d1c20aab8..b1e9b3058 100644 --- a/src/Charts/RideEditor.cpp +++ b/src/Charts/RideEditor.cpp @@ -505,7 +505,7 @@ AnomalyDialog::check() anomalyList->horizontalHeader()->hide(); // use MaxHR if available for suspicious, otherwise 200 - const HrZones *hrZones = rideEditor->context->athlete->hrZones(rideEditor->ride->isRun); + const HrZones *hrZones = rideEditor->context->athlete->hrZones(rideEditor->ride->sport); int hrZR = hrZones ? hrZones->whichRange(rideEditor->ride->dateTime.date()) : -1; int maxHR = hrZR > 0 ? hrZones->getMaxHr(hrZR) : 200; diff --git a/src/Charts/RideSummaryWindow.cpp b/src/Charts/RideSummaryWindow.cpp index 4bd2c1e56..05d866f3a 100644 --- a/src/Charts/RideSummaryWindow.cpp +++ b/src/Charts/RideSummaryWindow.cpp @@ -433,7 +433,8 @@ RideSummaryWindow::htmlSummary() // activities counts by sport to select training zones int nActivities, nRides, nRuns, nSwims; - context->athlete->rideCache->getRideTypeCounts(specification, nActivities, nRides, nRuns, nSwims); + QString sport; + context->athlete->rideCache->getRideTypeCounts(specification, nActivities, nRides, nRuns, nSwims, sport); // set those colors summary = GCColor::css(ridesummary); @@ -1012,24 +1013,24 @@ RideSummaryWindow::htmlSummary() // or summarising date range with homogeneous activities // if ((ridesummary && rideItem && rideItem->present.contains("H")) || - (!ridesummary && ((nActivities==nRides) || (nActivities==nRuns)))) { + (!ridesummary && !sport.isEmpty())) { int numhrzones = 0; int hrrange = -1; // get zones to use via ride for ridesummary - if (ridesummary && rideItem && context->athlete->hrZones(rideItem->isRun)) { + if (ridesummary && rideItem && context->athlete->hrZones(rideItem->sport)) { // get zones to use via ride for ridesummary - hrrange = context->athlete->hrZones(rideItem->isRun)->whichRange(rideItem->dateTime.date()); - if (hrrange > -1) numhrzones = context->athlete->hrZones(rideItem->isRun)->numZones(hrrange); + hrrange = context->athlete->hrZones(rideItem->sport)->whichRange(rideItem->dateTime.date()); + if (hrrange > -1) numhrzones = context->athlete->hrZones(rideItem->sport)->numZones(hrrange); // or for end of daterange plotted for daterange summary - } else if (context->athlete->hrZones(nActivities==nRuns)) { + } else if (context->athlete->hrZones(sport)) { // get from end if period - hrrange = context->athlete->hrZones(nActivities==nRuns)->whichRange(myDateRange.to); - if (hrrange > -1) numhrzones = context->athlete->hrZones(nActivities==nRuns)->numZones(hrrange); + hrrange = context->athlete->hrZones(sport)->whichRange(myDateRange.to); + if (hrrange > -1) numhrzones = context->athlete->hrZones(sport)->numZones(hrrange); } @@ -1043,8 +1044,8 @@ RideSummaryWindow::htmlSummary() } summary += tr("

Heart Rate Zones

"); - if (ridesummary) summary += context->athlete->hrZones(rideItem->isRun)->summarize(hrrange, time_in_zone, altColor); //aggregating - else summary += context->athlete->hrZones(nActivities==nRuns)->summarize(hrrange, time_in_zone, altColor); //aggregating + if (ridesummary) summary += context->athlete->hrZones(rideItem->sport)->summarize(hrrange, time_in_zone, altColor); //aggregating + else summary += context->athlete->hrZones(sport)->summarize(hrrange, time_in_zone, altColor); //aggregating } } @@ -1964,7 +1965,10 @@ RideSummaryWindow::htmlCompareSummary() const // Counts of activity types to select Power and Pace Zones int nActivities=0, nRides=0, nRuns=0, nSwims=0; + QString sport; foreach (RideItem *metrics, intervalMetrics) { + if (nActivities == 0) sport = metrics->sport; + else if (sport != metrics->sport) sport = ""; nActivities++; if (metrics->isRun) nRuns++; else if (metrics->isSwim) nSwims++; @@ -2047,15 +2051,14 @@ RideSummaryWindow::htmlCompareSummary() const // TIME IN HR ZONES when all rides or all runs, // use zones accordingly - if (((nActivities==nRides) || (nActivities==nRuns)) && - context->athlete->zones(nActivities==nRuns)) { + if (!sport.isEmpty() && context->athlete->hrZones(sport)) { // get from end if period - int rangeidx = context->athlete->hrZones(nActivities==nRuns)->whichRange(QDate::currentDate()); // use current zone names et al + int rangeidx = context->athlete->hrZones(sport)->whichRange(QDate::currentDate()); // use current zone names et al if (rangeidx > -1) { // get the list of zones - HrZoneRange range = const_cast(context->athlete->hrZones(nActivities==nRuns))->getHrZoneRange(rangeidx); + HrZoneRange range = const_cast(context->athlete->hrZones(sport))->getHrZoneRange(rangeidx); QList zones = range.zones; // we've got a range and a count of zones so all is well @@ -2326,9 +2329,13 @@ RideSummaryWindow::htmlCompareSummary() const // Counts of activity types to select Power and Pace Zones int nActivities=0, nRides=0, nRuns=0, nSwims=0; + QString sport; foreach (CompareDateRange dr, context->compareDateRanges) { int a, b, r, s; - dr.context->athlete->rideCache->getRideTypeCounts(dr.specification, a, b, r, s); + QString sp; + dr.context->athlete->rideCache->getRideTypeCounts(dr.specification, a, b, r, s, sp); + if (nActivities == 0) sport = sp; + else if (sport != sp) sport = ""; nActivities += a; nRides += b; nRuns += r; @@ -2479,15 +2486,14 @@ RideSummaryWindow::htmlCompareSummary() const // TIME IN HR ZONES when all rides or all runs, // use zones accordingly - if (((nActivities==nRides) || (nActivities==nRuns)) && - context->athlete->zones(nActivities==nRuns)) { + if (!sport.isEmpty() && context->athlete->hrZones(sport)) { // get from end if period - int rangeidx = context->athlete->hrZones(nActivities==nRuns)->whichRange(QDate::currentDate()); // use current zone names et al + int rangeidx = context->athlete->hrZones(sport)->whichRange(QDate::currentDate()); // use current zone names et al if (rangeidx > -1) { // get the list of zones - HrZoneRange range = const_cast(context->athlete->hrZones(nActivities==nRuns))->getHrZoneRange(rangeidx); + HrZoneRange range = const_cast(context->athlete->hrZones(sport))->getHrZoneRange(rangeidx); QList zones = range.zones; // we've got a range and a count of zones so all is well diff --git a/src/Core/Athlete.cpp b/src/Core/Athlete.cpp index 110b6289e..68352744b 100644 --- a/src/Core/Athlete.cpp +++ b/src/Core/Athlete.cpp @@ -111,8 +111,10 @@ Athlete::Athlete(Context *context, const QDir &homeDir) } // Heartrate Zones for Bike & Run - for (int i=0; i < 2; i++) { - hrzones_[i] = new HrZones(i>0); + QString defaultHrZoneFN = HrZones().fileName(); + foreach (QString sport, GlobalContext::context()->rideMetadata->sports()) { + QString i = RideFile::sportTag(sport); + hrzones_[i] = new HrZones(i); QFile hrzonesFile(home->config().canonicalPath() + "/" + hrzones_[i]->fileName()); if (hrzonesFile.exists()) { if (!hrzones_[i]->read(hrzonesFile)) { @@ -121,9 +123,9 @@ Athlete::Athlete(Context *context, const QDir &homeDir) QMessageBox::warning(context->mainWindow, tr("Reading HR Zones File %1").arg(hrzones_[i]->fileName()), hrzones_[i]->warningString()); } } - if (i == 1 && hrzones_[i]->getRangeSize() == 0) { // No running HR zones + if (i != "Bike" && hrzones_[i]->getRangeSize() == 0) { // No HR zones // Start with Cycling HR zones for backward compatibilty - QFile hrzonesFile(home->config().canonicalPath() + "/" + hrzones_[0]->fileName()); + QFile hrzonesFile(home->config().canonicalPath() + "/" + HrZones().fileName()); // Load without error/warning report to avoid repetition if (hrzonesFile.exists()) hrzones_[i]->read(hrzonesFile); } @@ -252,7 +254,7 @@ Athlete::~Athlete() delete measures; for (int i=0; i<2; i++) delete zones_[i]; - for (int i=0; i<2; i++) delete hrzones_[i]; + foreach (HrZones* hrzones, hrzones_) delete hrzones; for (int i=0; i<2; i++) delete pacezones_[i]; delete autoImportConfig; delete autoImport; diff --git a/src/Core/Athlete.h b/src/Core/Athlete.h index cb9402c5a..b7904661e 100644 --- a/src/Core/Athlete.h +++ b/src/Core/Athlete.h @@ -82,10 +82,10 @@ class Athlete : public QObject // zones const Zones *zones(bool isRun) const { return zones_[isRun]; } - const HrZones *hrZones(bool isRun) const { return hrzones_[isRun]; } + const HrZones *hrZones(QString sport) const { return hrzones_.value(sport); } const PaceZones *paceZones(bool isSwim) const { return pacezones_[isSwim]; } Zones *zones_[2]; - HrZones *hrzones_[2]; + QHash hrzones_; PaceZones *pacezones_[2]; void setCriticalPower(int cp); diff --git a/src/Core/DataFilter.cpp b/src/Core/DataFilter.cpp index 573d779b4..6fea44220 100644 --- a/src/Core/DataFilter.cpp +++ b/src/Core/DataFilter.cpp @@ -3289,14 +3289,14 @@ Result Leaf::eval(DataFilterRuntime *df, Leaf *leaf, Result x, long it, RideItem // // LTHR, AeTHR, MaxHR, RHR // - int hrZoneRange = m->context->athlete->hrZones(m->isRun) ? - m->context->athlete->hrZones(m->isRun)->whichRange(m->dateTime.date()) + int hrZoneRange = m->context->athlete->hrZones(m->sport) ? + m->context->athlete->hrZones(m->sport)->whichRange(m->dateTime.date()) : -1; - int LTHR = hrZoneRange != -1 ? m->context->athlete->hrZones(m->isRun)->getLT(hrZoneRange) : 0; - int AeTHR = hrZoneRange != -1 ? m->context->athlete->hrZones(m->isRun)->getAeT(hrZoneRange) : 0; - int RHR = hrZoneRange != -1 ? m->context->athlete->hrZones(m->isRun)->getRestHr(hrZoneRange) : 0; - int MaxHR = hrZoneRange != -1 ? m->context->athlete->hrZones(m->isRun)->getMaxHr(hrZoneRange) : 0; + int LTHR = hrZoneRange != -1 ? m->context->athlete->hrZones(m->sport)->getLT(hrZoneRange) : 0; + int AeTHR = hrZoneRange != -1 ? m->context->athlete->hrZones(m->sport)->getAeT(hrZoneRange) : 0; + int RHR = hrZoneRange != -1 ? m->context->athlete->hrZones(m->sport)->getRestHr(hrZoneRange) : 0; + int MaxHR = hrZoneRange != -1 ? m->context->athlete->hrZones(m->sport)->getMaxHr(hrZoneRange) : 0; // // CV diff --git a/src/Core/RideCache.cpp b/src/Core/RideCache.cpp index 35b876abc..12e710a69 100644 --- a/src/Core/RideCache.cpp +++ b/src/Core/RideCache.cpp @@ -784,9 +784,10 @@ RideCache::getDistinctValues(QString field) void RideCache::getRideTypeCounts(Specification specification, int& nActivities, - int& nRides, int& nRuns, int& nSwims) + int& nRides, int& nRuns, int& nSwims, QString& sport) { nActivities = nRides = nRuns = nSwims = 0; + sport = ""; // loop through and aggregate foreach (RideItem *ride, rides_) { @@ -794,6 +795,10 @@ RideCache::getRideTypeCounts(Specification specification, int& nActivities, // skip filtered rides if (!specification.pass(ride)) continue; + // sport is not empty only when all activities are from the same sport + if (nActivities == 0) sport = ride->sport; + else if (sport != ride-> sport) sport = ""; + nActivities++; if (ride->isSwim) nSwims++; else if (ride->isRun) nRuns++; diff --git a/src/Core/RideCache.h b/src/Core/RideCache.h index 5908de5ca..da28d1c0b 100644 --- a/src/Core/RideCache.h +++ b/src/Core/RideCache.h @@ -72,7 +72,7 @@ class RideCache : public QObject // Count of activities matching specification void getRideTypeCounts(Specification specification, int& nActivities, - int& nRides, int& nRuns, int& nSwims); + int& nRides, int& nRuns, int& nSwims, QString& sport); // Check if metric is relevant for some activity matching specification enum SportRestriction { AnySport, OnlyRides, OnlyRuns, OnlySwims, OnlyXtrains }; bool isMetricRelevantForRides(Specification specification, diff --git a/src/Core/RideItem.cpp b/src/Core/RideItem.cpp index 339a4680b..31200dd3e 100644 --- a/src/Core/RideItem.cpp +++ b/src/Core/RideItem.cpp @@ -501,7 +501,7 @@ RideItem::checkStale() unsigned long rfingerprint = static_cast(context->athlete->zones(isRun)->getFingerprint(dateTime.date())) + (appsettings->cvalue(context->athlete->cyclist, context->athlete->zones(isRun)->useCPforFTPSetting(), 0).toInt() ? 1 : 0) + static_cast(context->athlete->paceZones(isSwim)->getFingerprint(dateTime.date())) - + static_cast(context->athlete->hrZones(isRun)->getFingerprint(dateTime.date())) + + static_cast(context->athlete->hrZones(sport)->getFingerprint(dateTime.date())) + static_cast(context->athlete->routes->getFingerprint()) + static_cast(getHrvFingerprint()) + appsettings->cvalue(context->athlete->cyclist, GC_DISCOVERY, 57).toInt(); // 57 does not include search for PEAKS @@ -604,7 +604,7 @@ RideItem::refresh() if (context->athlete->zones(isRun)) zoneRange = context->athlete->zones(isRun)->whichRange(dateTime.date()); else zoneRange = -1; - if (context->athlete->hrZones(isRun)) hrZoneRange = context->athlete->hrZones(isRun)->whichRange(dateTime.date()); + if (context->athlete->hrZones(sport)) hrZoneRange = context->athlete->hrZones(sport)->whichRange(dateTime.date()); else hrZoneRange = -1; if (context->athlete->paceZones(isSwim)) paceZoneRange = context->athlete->paceZones(isSwim)->whichRange(dateTime.date()); @@ -653,7 +653,7 @@ RideItem::refresh() fingerprint = static_cast(context->athlete->zones(isRun)->getFingerprint(dateTime.date())) + (appsettings->cvalue(context->athlete->cyclist, context->athlete->zones(isRun)->useCPforFTPSetting(), 0).toInt() ? 1 : 0) + static_cast(context->athlete->paceZones(isSwim)->getFingerprint(dateTime.date())) - + static_cast(context->athlete->hrZones(isRun)->getFingerprint(dateTime.date())) + + static_cast(context->athlete->hrZones(sport)->getFingerprint(dateTime.date())) + static_cast(context->athlete->routes->getFingerprint()) + + static_cast(getHrvFingerprint()) + appsettings->cvalue(context->athlete->cyclist, GC_DISCOVERY, 57).toInt(); // 57 does not include search for PEAKS diff --git a/src/FileIO/RideFile.cpp b/src/FileIO/RideFile.cpp index 54c4142e5..9a76f87e4 100644 --- a/src/FileIO/RideFile.cpp +++ b/src/FileIO/RideFile.cpp @@ -212,6 +212,16 @@ RideFile::wprimeData() return wprime_; } +QString +RideFile::sportTag(QString sport) +{ + // Run, Bike and Swim are standarized, all others are up to the user + if (sport == "Bike" || sport == tr("Bike")) return "Bike"; + if (sport == "Run" || sport == tr("Run")) return "Run"; + if (sport == "Swim" || sport == tr("Swim")) return "Swim"; + return sport; +} + QString RideFile::sport() const { @@ -227,7 +237,7 @@ RideFile::isBike() const { // for now we just look at Sport and default to Bike when Sport is not // set and isRun and isSwim are false - return (getTag("Sport", "") == "Bike" || getTag("Sport", "") == tr("Bike")) || + return (sportTag(getTag("Sport", "")) == "Bike") || (getTag("Sport","") == "" && !isRun() && !isSwim()); } @@ -236,7 +246,7 @@ RideFile::isRun() const { // for now we just look at Sport and if there are any // running specific data series in the data when Sport is not set - return (getTag("Sport", "") == "Run" || getTag("Sport", "") == tr("Run")) || + return (sportTag(getTag("Sport", "")) == "Run") || (getTag("Sport","") == "" && (areDataPresent()->rvert || areDataPresent()->rcad || areDataPresent()->rcontact)); } @@ -244,7 +254,7 @@ bool RideFile::isSwim() const { // for now we just look at Sport or presence of length data for lap swims - return (getTag("Sport", "") == "Swim" || getTag("Sport", "") == tr("Swim")) || + return (sportTag(getTag("Sport", "")) == "Swim") || (getTag("Sport","") == "" && xdata_.value("SWIM", NULL) != NULL); } diff --git a/src/FileIO/RideFile.h b/src/FileIO/RideFile.h index 97ce4c997..fc4ddcbd7 100644 --- a/src/FileIO/RideFile.h +++ b/src/FileIO/RideFile.h @@ -242,6 +242,8 @@ class RideFile : public QObject // QObject to emit signals static double minimumFor(SeriesType series); static QColor colorFor(SeriesType series); static bool parseRideFileName(const QString &name, QDateTime *dt); + + static QString sportTag(QString sport); QString sport() const; bool isBike() const; bool isRun() const; diff --git a/src/FileIO/RideFileCache.cpp b/src/FileIO/RideFileCache.cpp index 04f3d6150..62ef85204 100644 --- a/src/FileIO/RideFileCache.cpp +++ b/src/FileIO/RideFileCache.cpp @@ -1564,7 +1564,7 @@ RideFileCache::computeDistribution(QVector &array, RideFile::SeriesType s // get zones that apply, if any int zoneRange = context->athlete->zones(ride->isRun()) ? context->athlete->zones(ride->isRun())->whichRange(ride->startTime().date()) : -1; - int hrZoneRange = context->athlete->hrZones(ride->isRun()) ? context->athlete->hrZones(ride->isRun())->whichRange(ride->startTime().date()) : -1; + int hrZoneRange = context->athlete->hrZones(ride->sport()) ? context->athlete->hrZones(ride->sport())->whichRange(ride->startTime().date()) : -1; int paceZoneRange = context->athlete->paceZones(ride->isSwim()) ? context->athlete->paceZones(ride->isSwim())->whichRange(ride->startTime().date()) : -1; CP=0; @@ -1580,8 +1580,8 @@ RideFileCache::computeDistribution(QVector &array, RideFile::SeriesType s LTHR=0; int AeTHR=0; if (hrZoneRange != -1) { - LTHR=context->athlete->hrZones(ride->isRun())->getLT(hrZoneRange); - AeTHR=context->athlete->hrZones(ride->isRun())->getAeT(hrZoneRange); + LTHR=context->athlete->hrZones(ride->sport())->getLT(hrZoneRange); + AeTHR=context->athlete->hrZones(ride->sport())->getAeT(hrZoneRange); } CV=0; @@ -1659,7 +1659,7 @@ RideFileCache::computeDistribution(QVector &array, RideFile::SeriesType s // hr time in zone if (series == RideFile::hr && hrZoneRange != -1) { - int index = context->athlete->hrZones(ride->isRun())->whichZone(hrZoneRange, dp->value(series)); + int index = context->athlete->hrZones(ride->sport())->whichZone(hrZoneRange, dp->value(series)); if (index >= 0) hrTimeInZone[index] += ride->recIntSecs(); } diff --git a/src/Gui/AthletePages.cpp b/src/Gui/AthletePages.cpp index 5a454949c..68482e75f 100644 --- a/src/Gui/AthletePages.cpp +++ b/src/Gui/AthletePages.cpp @@ -1719,22 +1719,23 @@ HrZonePage::HrZonePage(Context *context) : context(context) sportLabel = new QLabel(tr("Sport")); sportCombo = new QComboBox(); - sportCombo->addItem(tr("Bike")); - sportCombo->addItem(tr("Run")); - sportCombo->setCurrentIndex(0); hlayout->addStretch(); hlayout->addWidget(sportLabel); hlayout->addWidget(sportCombo); hlayout->addStretch(); layout->addLayout(hlayout); - connect(sportCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changeSport(int))); + connect(sportCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changeSport())); tabs = new QTabWidget(this); layout->addWidget(tabs); - for (int i=0; i < nSports; i++) { - hrZones[i] = new HrZones(i > 0); + foreach (QString sport, GlobalContext::context()->rideMetadata->sports()) { + QString i = RideFile::sportTag(sport); + + // Add sport to combo + sportCombo->addItem(sport, i); // get current config by reading it in (leave mainwindow zones alone) + hrZones[i] = new HrZones(i); QFile zonesFile(context->athlete->home->config().canonicalPath() + "/" + hrZones[i]->fileName()); if (zonesFile.exists()) { hrZones[i]->read(zonesFile); @@ -1746,20 +1747,22 @@ HrZonePage::HrZonePage(Context *context) : context(context) schemePage[i] = new HrSchemePage(hrZones[i]); ltPage[i] = new LTPage(context, hrZones[i], schemePage[i]); } + sportCombo->setCurrentIndex(0); // finish setup for the default sport - changeSport(sportCombo->currentIndex()); + changeSport(); } HrZonePage::~HrZonePage() { - for (int i=0; icurrentData().toString(); tabs->clear(); tabs->addTab(ltPage[i], tr("Lactate Threshold")); tabs->addTab(schemePage[i], tr("Default")); @@ -1771,16 +1774,16 @@ HrZonePage::saveClicked() qint32 changed = 0; // write - for (int i=0; i < nSports; i++) { + foreach (QString i, hrZones.keys()) { hrZones[i]->setScheme(schemePage[i]->getScheme()); hrZones[i]->write(context->athlete->home->config()); // reread HR zones QFile hrzonesFile(context->athlete->home->config().canonicalPath() + "/" + context->athlete->hrzones_[i]->fileName()); context->athlete->hrzones_[i]->read(hrzonesFile); - if (i == 1 && context->athlete->hrzones_[i]->getRangeSize() == 0) { // No running HR zones + if (context->athlete->hrzones_[i]->getRangeSize() == 0) { // No HR zones // Start with Cycling HR zones for backward compatibilty - QFile hrzonesFile(context->athlete->home->config().canonicalPath() + "/" + context->athlete->hrzones_[0]->fileName()); + QFile hrzonesFile(context->athlete->home->config().canonicalPath() + "/" + HrZones().fileName()); if (hrzonesFile.exists()) context->athlete->hrzones_[i]->read(hrzonesFile); } diff --git a/src/Gui/AthletePages.h b/src/Gui/AthletePages.h index 1a6ce1430..dd55e1916 100644 --- a/src/Gui/AthletePages.h +++ b/src/Gui/AthletePages.h @@ -414,19 +414,17 @@ class HrZonePage : public QWidget private: - static const int nSports = 2; - QLabel *sportLabel; QComboBox *sportCombo; - HrZones *hrZones[nSports]; - quint16 b4Fingerprint[nSports]; // how did it start ? - HrSchemePage *schemePage[nSports]; - LTPage *ltPage[nSports]; + QHash hrZones; + QHash b4Fingerprint; // how did it start ? + QHash schemePage; + QHash ltPage; private slots: - void changeSport(int i); + void changeSport(); }; diff --git a/src/Metrics/HrTimeInZone.cpp b/src/Metrics/HrTimeInZone.cpp index 037575cd2..3a224608a 100644 --- a/src/Metrics/HrTimeInZone.cpp +++ b/src/Metrics/HrTimeInZone.cpp @@ -60,13 +60,13 @@ public: seconds = 0; // get zone ranges - if (item->context->athlete->hrZones(item->isRun) && item->hrZoneRange >= 0 && item->ride()->areDataPresent()->hr) { + if (item->context->athlete->hrZones(item->sport) && item->hrZoneRange >= 0 && item->ride()->areDataPresent()->hr) { // iterate and compute RideFileIterator it(item->ride(), spec); while (it.hasNext()) { struct RideFilePoint *point = it.next(); totalSecs += item->ride()->recIntSecs(); - if (item->context->athlete->hrZones(item->isRun)->whichZone(item->hrZoneRange, point->hr) == level) + if (item->context->athlete->hrZones(item->sport)->whichZone(item->hrZoneRange, point->hr) == level) seconds += item->ride()->recIntSecs(); } } @@ -780,9 +780,9 @@ public: seconds = 0; // get zone ranges - if (item->context->athlete->hrZones(item->isRun) && item->hrZoneRange >= 0 && item->ride()->areDataPresent()->hr) { + if (item->context->athlete->hrZones(item->sport) && item->hrZoneRange >= 0 && item->ride()->areDataPresent()->hr) { - int AeT = item->context->athlete->hrZones(item->isRun)->getAeT(item->hrZoneRange); + int AeT = item->context->athlete->hrZones(item->sport)->getAeT(item->hrZoneRange); // iterate and compute RideFileIterator it(item->ride(), spec); @@ -844,10 +844,10 @@ public: seconds = 0; // get zone ranges - if (item->context->athlete->hrZones(item->isRun) && item->hrZoneRange >= 0 && item->ride()->areDataPresent()->hr) { + if (item->context->athlete->hrZones(item->sport) && item->hrZoneRange >= 0 && item->ride()->areDataPresent()->hr) { - int AeT = item->context->athlete->hrZones(item->isRun)->getAeT(item->hrZoneRange); - int LT = item->context->athlete->hrZones(item->isRun)->getLT(item->hrZoneRange); + int AeT = item->context->athlete->hrZones(item->sport)->getAeT(item->hrZoneRange); + int LT = item->context->athlete->hrZones(item->sport)->getLT(item->hrZoneRange); // iterate and compute RideFileIterator it(item->ride(), spec); @@ -909,9 +909,9 @@ public: seconds = 0; // get zone ranges - if (item->context->athlete->hrZones(item->isRun) && item->hrZoneRange >= 0 && item->ride()->areDataPresent()->hr) { + if (item->context->athlete->hrZones(item->sport) && item->hrZoneRange >= 0 && item->ride()->areDataPresent()->hr) { - int LT = item->context->athlete->hrZones(item->isRun)->getLT(item->hrZoneRange); + int LT = item->context->athlete->hrZones(item->sport)->getLT(item->hrZoneRange); // iterate and compute RideFileIterator it(item->ride(), spec); diff --git a/src/Metrics/HrZones.cpp b/src/Metrics/HrZones.cpp index fc34d5c3e..d6ed5e9e5 100644 --- a/src/Metrics/HrZones.cpp +++ b/src/Metrics/HrZones.cpp @@ -53,10 +53,10 @@ void HrZones::initializeZoneParameters() sizeof(initial_zone_default) / sizeof(initial_zone_default[0]); - if (run) { - fileName_ = "run-hr.zones"; - } else { + if (sport_.isEmpty() || sport_ == "Bike") { fileName_ = "hr.zones"; + } else { + fileName_ = sport_.toLower() + "-hr.zones"; } scheme.zone_default.clear(); diff --git a/src/Metrics/HrZones.h b/src/Metrics/HrZones.h index 09b3b80a6..15dd96524 100644 --- a/src/Metrics/HrZones.h +++ b/src/Metrics/HrZones.h @@ -90,7 +90,7 @@ class HrZones : public QObject private: // Sport - bool run; + QString sport_; // Scheme bool defaults_from_user; @@ -105,7 +105,7 @@ class HrZones : public QObject public: - HrZones(bool run=false) : run(run), defaults_from_user(false) { + HrZones(QString sport="Bike") : sport_(sport), defaults_from_user(false) { initializeZoneParameters(); } @@ -124,7 +124,7 @@ class HrZones : public QObject void initializeZoneParameters(); // Sport - bool isRun() { return run; } + const QString& sport() const { return sport_; } // // Zone history - Ranges diff --git a/src/Metrics/PeakHr.cpp b/src/Metrics/PeakHr.cpp index 35a7b3bdb..b406e2187 100644 --- a/src/Metrics/PeakHr.cpp +++ b/src/Metrics/PeakHr.cpp @@ -57,7 +57,7 @@ class HrZone : public RideMetric { void compute(RideItem *item, Specification, const QHash &deps) { // no zones - const HrZones* zones = item->context->athlete->hrZones(item->isRun); + const HrZones* zones = item->context->athlete->hrZones(item->sport); if (!zones || !item->ride()->areDataPresent()->hr) { setValue(RideFile::NIL); setCount(0); diff --git a/src/Metrics/RideMetadata.cpp b/src/Metrics/RideMetadata.cpp index ed3004bf1..6b8e95ea1 100644 --- a/src/Metrics/RideMetadata.cpp +++ b/src/Metrics/RideMetadata.cpp @@ -477,6 +477,24 @@ RideMetadata::calendarText(RideItem *rideItem) return calendarText; } +// Sports, as displayed to users +QStringList +RideMetadata::sports() +{ + QStringList sportList; + foreach (FieldDefinition field, getFields()) { + if (field.name == "Sport") { + sportList = field.values; + break; + } + } + + // Ensure default sport + if (sportList.isEmpty()) sportList << "Bike"; + + return sportList; +} + /*---------------------------------------------------------------------- * Forms (one per tab) *--------------------------------------------------------------------*/ diff --git a/src/Metrics/RideMetadata.h b/src/Metrics/RideMetadata.h index ef1ba1e8c..4a54b8c7c 100644 --- a/src/Metrics/RideMetadata.h +++ b/src/Metrics/RideMetadata.h @@ -162,6 +162,8 @@ class RideMetadata : public QWidget bool hasCalendarText(); QString calendarText(RideItem *rideItem); + QStringList sports(); + QString getColorField() const { return colorfield; } void setColorField(QString x) { colorfield = x; } diff --git a/src/Metrics/TRIMPPoints.cpp b/src/Metrics/TRIMPPoints.cpp index 4252d9c05..f0769c981 100644 --- a/src/Metrics/TRIMPPoints.cpp +++ b/src/Metrics/TRIMPPoints.cpp @@ -60,15 +60,15 @@ class TRIMPPoints : public RideMetric { void compute(RideItem *item, Specification, const QHash &deps) { - if (!item->context->athlete->hrZones(item->isRun) || item->hrZoneRange < 0) { + if (!item->context->athlete->hrZones(item->sport) || item->hrZoneRange < 0) { setValue(RideFile::NIL); return; } // use resting HR from zones, but allow it to be // overriden in ride metadata - double maxHr = item->context->athlete->hrZones(item->isRun)->getMaxHr(item->hrZoneRange); - double restHr = item->context->athlete->hrZones(item->isRun)->getRestHr(item->hrZoneRange); + double maxHr = item->context->athlete->hrZones(item->sport)->getMaxHr(item->hrZoneRange); + double restHr = item->context->athlete->hrZones(item->sport)->getRestHr(item->hrZoneRange); restHr = item->getText("Rest HR", QString("%1").arg(restHr)).toDouble(); assert(deps.contains("time_riding")); @@ -129,16 +129,16 @@ public: void compute(RideItem *item, Specification, const QHash &deps) { - if (!item->context->athlete->hrZones(item->isRun) || item->hrZoneRange < 0) { + if (!item->context->athlete->hrZones(item->sport) || item->hrZoneRange < 0) { setValue(RideFile::NIL); return; } // use resting HR from zones, but allow it to be // overriden in ride metadata - double maxHr = item->context->athlete->hrZones(item->isRun)->getMaxHr(item->hrZoneRange); - double restHr = item->context->athlete->hrZones(item->isRun)->getRestHr(item->hrZoneRange); - double ltHr = item->context->athlete->hrZones(item->isRun)->getLT(item->hrZoneRange); + double maxHr = item->context->athlete->hrZones(item->sport)->getMaxHr(item->hrZoneRange); + double restHr = item->context->athlete->hrZones(item->sport)->getRestHr(item->hrZoneRange); + double ltHr = item->context->athlete->hrZones(item->sport)->getLT(item->hrZoneRange); restHr = item->getText("Rest HR", QString("%1").arg(restHr)).toDouble(); @@ -194,7 +194,7 @@ public: void compute(RideItem *item, Specification, const QHash &deps) { - if (!item->context->athlete->hrZones(item->isRun) || item->hrZoneRange < 0) { + if (!item->context->athlete->hrZones(item->sport) || item->hrZoneRange < 0) { setValue(RideFile::NIL); return; } @@ -204,7 +204,7 @@ public: assert(averageHrMetric); double hr = averageHrMetric->value(true); - QList trimpk = item->context->athlete->hrZones(item->isRun)->getZoneTrimps(item->hrZoneRange); + QList trimpk = item->context->athlete->hrZones(item->sport)->getZoneTrimps(item->hrZoneRange); double value = 0; if (trimpk.size()>0) { @@ -292,7 +292,7 @@ public: double secs = timeRidingMetric->value(true) ? timeRidingMetric->value(true) : durationMetric->value(true); - int nZone = item->context->athlete->hrZones(item->isRun)->whichZone(item->hrZoneRange, hr); + int nZone = item->context->athlete->hrZones(item->sport)->whichZone(item->hrZoneRange, hr); if (nZone >= 0 && nZone < trimpk.size()) value += trimpk[nZone] * secs; } diff --git a/src/Python/SIP/Bindings.cpp b/src/Python/SIP/Bindings.cpp index cb6b63257..a6c326841 100644 --- a/src/Python/SIP/Bindings.cpp +++ b/src/Python/SIP/Bindings.cpp @@ -241,30 +241,30 @@ Bindings::athleteZones(PyObject* date, QString sport) const } // BIKE HR - if (context->athlete->hrZones(false)) { + if (context->athlete->hrZones("Bike")) { - int range=context->athlete->hrZones(false)->whichRange(forDate); + int range=context->athlete->hrZones("Bike")->whichRange(forDate); if (range >= 0) { bike.date = forDate; - bike.lthr = context->athlete->hrZones(false)->getLT(range); - bike.aethr = context->athlete->hrZones(false)->getAeT(range); - bike.rhr = context->athlete->hrZones(false)->getRestHr(range); - bike.hrmax = context->athlete->hrZones(false)->getMaxHr(range); + bike.lthr = context->athlete->hrZones("Bike")->getLT(range); + bike.aethr = context->athlete->hrZones("Bike")->getAeT(range); + bike.rhr = context->athlete->hrZones("Bike")->getRestHr(range); + bike.hrmax = context->athlete->hrZones("Bike")->getMaxHr(range); } } // RUN HR - if (context->athlete->hrZones(true)) { + if (context->athlete->hrZones("Run")) { - int range=context->athlete->hrZones(true)->whichRange(forDate); + int range=context->athlete->hrZones("Run")->whichRange(forDate); if (range >= 0) { run.date = forDate; - run.lthr = context->athlete->hrZones(true)->getLT(range); - run.aethr = context->athlete->hrZones(true)->getAeT(range); - run.rhr = context->athlete->hrZones(true)->getRestHr(range); - run.hrmax = context->athlete->hrZones(true)->getMaxHr(range); + run.lthr = context->athlete->hrZones("Run")->getLT(range); + run.aethr = context->athlete->hrZones("Run")->getAeT(range); + run.rhr = context->athlete->hrZones("Run")->getRestHr(range); + run.hrmax = context->athlete->hrZones("Run")->getMaxHr(range); } } @@ -340,32 +340,32 @@ Bindings::athleteZones(PyObject* date, QString sport) const } // BIKE HR - if (context->athlete->hrZones(false)) { + if (context->athlete->hrZones("Bike")) { - for (int range=0; range < context->athlete->hrZones(false)->getRangeSize(); range++) { + for (int range=0; range < context->athlete->hrZones("Bike")->getRangeSize(); range++) { gcZoneConfig c("bike"); - c.date = context->athlete->hrZones(false)->getStartDate(range); - c.lthr = context->athlete->hrZones(false)->getLT(range); - c.aethr = context->athlete->hrZones(false)->getAeT(range); - c.rhr = context->athlete->hrZones(false)->getRestHr(range); - c.hrmax = context->athlete->hrZones(false)->getMaxHr(range); + c.date = context->athlete->hrZones("Bike")->getStartDate(range); + c.lthr = context->athlete->hrZones("Bike")->getLT(range); + c.aethr = context->athlete->hrZones("Bike")->getAeT(range); + c.rhr = context->athlete->hrZones("Bike")->getRestHr(range); + c.hrmax = context->athlete->hrZones("Bike")->getMaxHr(range); config << c; } } // RUN HR - if (context->athlete->hrZones(true)) { + if (context->athlete->hrZones("Run")) { - for (int range=0; range < context->athlete->hrZones(true)->getRangeSize(); range++) { + for (int range=0; range < context->athlete->hrZones("Run")->getRangeSize(); range++) { gcZoneConfig c("run"); - c.date = context->athlete->hrZones(true)->getStartDate(range); - c.lthr = context->athlete->hrZones(true)->getLT(range); - c.aethr = context->athlete->hrZones(true)->getAeT(range); - c.rhr = context->athlete->hrZones(true)->getRestHr(range); - c.hrmax = context->athlete->hrZones(true)->getMaxHr(range); + c.date = context->athlete->hrZones("Run")->getStartDate(range); + c.lthr = context->athlete->hrZones("Run")->getLT(range); + c.aethr = context->athlete->hrZones("Run")->getAeT(range); + c.rhr = context->athlete->hrZones("Run")->getRestHr(range); + c.hrmax = context->athlete->hrZones("Run")->getMaxHr(range); config << c; } diff --git a/src/R/RTool.cpp b/src/R/RTool.cpp index 420242acb..e03eec3e6 100644 --- a/src/R/RTool.cpp +++ b/src/R/RTool.cpp @@ -554,30 +554,30 @@ RTool::zones(SEXP pDate, SEXP pSport) } // BIKE HR - if (rtool->context->athlete->hrZones(false)) { + if (rtool->context->athlete->hrZones("Bike")) { - int range=rtool->context->athlete->hrZones(false)->whichRange(forDate); + int range=rtool->context->athlete->hrZones("Bike")->whichRange(forDate); if (range >= 0) { bike.date = forDate; - bike.lthr = rtool->context->athlete->hrZones(false)->getLT(range); - bike.aethr = rtool->context->athlete->hrZones(false)->getAeT(range); - bike.rhr = rtool->context->athlete->hrZones(false)->getRestHr(range); - bike.hrmax = rtool->context->athlete->hrZones(false)->getMaxHr(range); + bike.lthr = rtool->context->athlete->hrZones("Bike")->getLT(range); + bike.aethr = rtool->context->athlete->hrZones("Bike")->getAeT(range); + bike.rhr = rtool->context->athlete->hrZones("Bike")->getRestHr(range); + bike.hrmax = rtool->context->athlete->hrZones("Bike")->getMaxHr(range); } } // RUN HR - if (rtool->context->athlete->hrZones(true)) { + if (rtool->context->athlete->hrZones("Run")) { - int range=rtool->context->athlete->hrZones(true)->whichRange(forDate); + int range=rtool->context->athlete->hrZones("Run")->whichRange(forDate); if (range >= 0) { run.date = forDate; - run.lthr = rtool->context->athlete->hrZones(true)->getLT(range); - run.aethr = rtool->context->athlete->hrZones(true)->getAeT(range); - run.rhr = rtool->context->athlete->hrZones(true)->getRestHr(range); - run.hrmax = rtool->context->athlete->hrZones(true)->getMaxHr(range); + run.lthr = rtool->context->athlete->hrZones("Run")->getLT(range); + run.aethr = rtool->context->athlete->hrZones("Run")->getAeT(range); + run.rhr = rtool->context->athlete->hrZones("Run")->getRestHr(range); + run.hrmax = rtool->context->athlete->hrZones("Run")->getMaxHr(range); } } @@ -653,32 +653,32 @@ RTool::zones(SEXP pDate, SEXP pSport) } // BIKE HR - if (rtool->context->athlete->hrZones(false)) { + if (rtool->context->athlete->hrZones("Bike")) { - for (int range=0; range < rtool->context->athlete->hrZones(false)->getRangeSize(); range++) { + for (int range=0; range < rtool->context->athlete->hrZones("Bike")->getRangeSize(); range++) { gcZoneConfig c("bike"); - c.date = rtool->context->athlete->hrZones(false)->getStartDate(range); - c.lthr = rtool->context->athlete->hrZones(false)->getLT(range); - c.aethr = rtool->context->athlete->hrZones(false)->getAeT(range); - c.rhr = rtool->context->athlete->hrZones(false)->getRestHr(range); - c.hrmax = rtool->context->athlete->hrZones(false)->getMaxHr(range); + c.date = rtool->context->athlete->hrZones("Bike")->getStartDate(range); + c.lthr = rtool->context->athlete->hrZones("Bike")->getLT(range); + c.aethr = rtool->context->athlete->hrZones("Bike")->getAeT(range); + c.rhr = rtool->context->athlete->hrZones("Bike")->getRestHr(range); + c.hrmax = rtool->context->athlete->hrZones("Bike")->getMaxHr(range); config << c; } } // RUN HR - if (rtool->context->athlete->hrZones(true)) { + if (rtool->context->athlete->hrZones("Run")) { - for (int range=0; range < rtool->context->athlete->hrZones(true)->getRangeSize(); range++) { + for (int range=0; range < rtool->context->athlete->hrZones("Run")->getRangeSize(); range++) { gcZoneConfig c("run"); - c.date = rtool->context->athlete->hrZones(true)->getStartDate(range); - c.lthr = rtool->context->athlete->hrZones(true)->getLT(range); - c.aethr = rtool->context->athlete->hrZones(true)->getAeT(range); - c.rhr = rtool->context->athlete->hrZones(true)->getRestHr(range); - c.hrmax = rtool->context->athlete->hrZones(true)->getMaxHr(range); + c.date = rtool->context->athlete->hrZones("Run")->getStartDate(range); + c.lthr = rtool->context->athlete->hrZones("Run")->getLT(range); + c.aethr = rtool->context->athlete->hrZones("Run")->getAeT(range); + c.rhr = rtool->context->athlete->hrZones("Run")->getRestHr(range); + c.hrmax = rtool->context->athlete->hrZones("Run")->getMaxHr(range); config << c; }