From 1aebf24bccdab7455aa599aedfd9bf69c8125ed1 Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Thu, 13 Mar 2014 22:56:51 +0000 Subject: [PATCH] Add Power 'heat' to RideFileCache .. to indicate which power-durations are getting worked hardest .. Calculate a 'heat' score for the power duration curve. A score that counts how many rides in the aggregate have a power-duration best that is within 10% of the best value calculated. .. next step is to add it to the CP curve (when showing power) to provide some kind of shade/heat indicator for the area of the curve. --- src/CpintPlot.cpp | 4 ++++ src/RideFileCache.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++ src/RideFileCache.h | 7 +++++++ 3 files changed, 57 insertions(+) diff --git a/src/CpintPlot.cpp b/src/CpintPlot.cpp index bb334b920..3ac2e9068 100644 --- a/src/CpintPlot.cpp +++ b/src/CpintPlot.cpp @@ -772,6 +772,10 @@ CpintPlot::calculate(RideItem *rideItem) // get aggregates - incase not initialised from date change if (bests == NULL) bests = new RideFileCache(context, startDate, endDate, isFiltered, files, rangemode); + // heat ... + //! todo qDebug()<<"FTP heat="<heatMeanMaxArray()[3600]; + //! todo qDebug()<<"3min heat="<heatMeanMaxArray()[180]; + // // PLOT MODEL CURVE (DERIVED) // diff --git a/src/RideFileCache.cpp b/src/RideFileCache.cpp index f061dc666..1ce94a7c9 100644 --- a/src/RideFileCache.cpp +++ b/src/RideFileCache.cpp @@ -40,6 +40,7 @@ RideFileCache::RideFileCache(Context *context, QString fileName, RideFile *passe { // resize all the arrays to zero wattsMeanMax.resize(0); + heatMeanMax.resize(0); hrMeanMax.resize(0); cadMeanMax.resize(0); nmMeanMax.resize(0); @@ -128,6 +129,7 @@ RideFileCache::RideFileCache(RideFile *ride) : { // resize all the arrays to zero wattsMeanMax.resize(0); + heatMeanMax.resize(0); hrMeanMax.resize(0); cadMeanMax.resize(0); nmMeanMax.resize(0); @@ -1089,6 +1091,11 @@ RideFileCache::RideFileCache(Context *context, QDate start, QDate end, bool filt : start(start), end(end), context(context), rideFileName(""), ride(0) { + // remember parameters for getting heat + this->filter = filter; + this->files = files; + this->onhome = onhome; + // Oh lets get from the cache if we can -- but not if filtered if (!filter && !context->isfiltered) { @@ -1107,6 +1114,7 @@ RideFileCache::RideFileCache(Context *context, QDate start, QDate end, bool filt xPowerMeanMax.resize(0); npMeanMax.resize(0); wattsMeanMax.resize(0); + heatMeanMax.resize(0); hrMeanMax.resize(0); cadMeanMax.resize(0); nmMeanMax.resize(0); @@ -1205,6 +1213,44 @@ RideFileCache::RideFileCache(Context *context, QDate start, QDate end, bool filt } +// +// Get heat mean max -- if an aggregated curve +// +QVector &RideFileCache::heatMeanMaxArray() +{ + // not aggregated or already done it return the result + if (ride || heatMeanMax.count()) return heatMeanMax; + + // make it big enough + heatMeanMax.resize(wattsMeanMaxDouble.size()); + + // ok, we need to iterate again and compute heat based upon + // how close to the absolute best we've got + foreach (QString rideFileName, RideFileFactory::instance().listRideFiles(context->athlete->home)) { + + QDate rideDate = dateFromFileName(rideFileName); + if (((filter == true && files.contains(rideFileName)) || filter == false) && + rideDate >= start && rideDate <= end) { + + // skip globally filtered values + if (context->isfiltered && !context->filters.contains(rideFileName)) continue; + if (onhome && context->ishomefiltered && !context->homeFilters.contains(rideFileName)) continue; + + // get its cached values (will refresh if needed...) + RideFileCache rideCache(context, context->athlete->home.absolutePath() + "/" + rideFileName); + + for(int i=0; i= (0.9f * wattsMeanMaxDouble[i])) + heatMeanMax[i] = heatMeanMax[i] + 1; + } + } + } + + return heatMeanMax; +} + // // PERSISTANCE // diff --git a/src/RideFileCache.h b/src/RideFileCache.h index 01aa35aea..65750af8e 100644 --- a/src/RideFileCache.h +++ b/src/RideFileCache.h @@ -169,6 +169,8 @@ class RideFileCache QVector &wattsCPZoneArray() { return wattsCPTimeInZone; } // moderate, heavy and severe domains QVector &hrZoneArray() { return hrTimeInZone; } + QVector &heatMeanMaxArray(); // will compute if neccessary + // explain the array binning / sampling double &distBinSize(RideFile::SeriesType); // return distribution bin size double &meanMaxBinSize(RideFile::SeriesType); // return distribution bin size @@ -221,6 +223,11 @@ class RideFileCache QVector wattsKgMeanMax; // watts/kg QVector aPowerMeanMax; // RideFile::aPower + QVector heatMeanMax; // The heat of training for aggregated power data + bool filter, onhome; // saving parameters re-used when aggregating heat + QStringList files; + + QVector wattsMeanMaxDouble; // RideFile::watts QVector hrMeanMaxDouble; // RideFile::hr QVector cadMeanMaxDouble; // RideFile::cad