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.
This commit is contained in:
Mark Liversedge
2014-03-13 22:56:51 +00:00
parent f5e2d277c7
commit 1aebf24bcc
3 changed files with 57 additions and 0 deletions

View File

@@ -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="<<bests->heatMeanMaxArray()[3600];
//! todo qDebug()<<"3min heat="<<bests->heatMeanMaxArray()[180];
//
// PLOT MODEL CURVE (DERIVED)
//

View File

@@ -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<float> &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<rideCache.wattsMeanMaxDouble.count() && i<wattsMeanMaxDouble.count(); i++) {
// is it within 10% of the best we have ?
if (rideCache.wattsMeanMaxDouble[i] >= (0.9f * wattsMeanMaxDouble[i]))
heatMeanMax[i] = heatMeanMax[i] + 1;
}
}
}
return heatMeanMax;
}
//
// PERSISTANCE
//

View File

@@ -169,6 +169,8 @@ class RideFileCache
QVector<float> &wattsCPZoneArray() { return wattsCPTimeInZone; } // moderate, heavy and severe domains
QVector<float> &hrZoneArray() { return hrTimeInZone; }
QVector<float> &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<float> wattsKgMeanMax; // watts/kg
QVector<float> aPowerMeanMax; // RideFile::aPower
QVector<float> heatMeanMax; // The heat of training for aggregated power data
bool filter, onhome; // saving parameters re-used when aggregating heat
QStringList files;
QVector<double> wattsMeanMaxDouble; // RideFile::watts
QVector<double> hrMeanMaxDouble; // RideFile::hr
QVector<double> cadMeanMaxDouble; // RideFile::cad