Skip to content

Commit

Permalink
Banister Data Managed in Athlete
Browse files Browse the repository at this point in the history
.. so we retrieve past ones and reuse rather than refresh
   and refit every time we plot it.
  • Loading branch information
liversedge committed Jan 11, 2019
1 parent a205e7b commit 9871d1e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 10 deletions.
11 changes: 7 additions & 4 deletions src/Charts/LTMPlot.cpp
Expand Up @@ -3549,10 +3549,13 @@ LTMPlot::createBanisterData(Context *context, LTMSettings *settings, MetricDetai
QVector<double>&x,QVector<double>&y,int&n, bool)
{
// banister model
Banister f(context, metricDetail.symbol, 0,0,0,0);
Banister *banister = context->athlete->getBanisterFor(metricDetail.symbol, 0,0);

// perform fit (date range todo)
f.fit();
// should never happen...
if (banister==NULL) {
n=0;
return;
}

int maxdays = groupForDate(settings->end.date(), settings->groupBy)
- groupForDate(settings->start.date(), settings->groupBy);
Expand All @@ -3579,7 +3582,7 @@ LTMPlot::createBanisterData(Context *context, LTMSettings *settings, MetricDetai
int currentDay = groupForDate(date, settings->groupBy);

// value for day
double value = f.value(date, metricDetail.stressType);
double value = banister->value(date, metricDetail.stressType);

if (plotData && (value || wantZero)) {
unsigned long seconds = 1;
Expand Down
22 changes: 22 additions & 0 deletions src/Core/Athlete.cpp
Expand Up @@ -36,6 +36,7 @@
#include "WithingsDownload.h"
#include "CalendarDownload.h"
#include "PMCData.h"
#include "Banister.h"
#include "ErgDB.h"
#ifdef GC_HAVE_ICAL
#include "ICalendar.h"
Expand Down Expand Up @@ -519,6 +520,27 @@ Athlete::getHeight(RideFile *ride)
return height;
}

// working with Banister data series
Banister *
Athlete::getBanisterFor(QString metricName, int t1 , int t2)
{
Banister *returning = NULL;

// if we don't already have one, create it
returning = banisterData.value(metricName, NULL); // we do
if (!returning) {

// specification is blank and passes for all
returning = new Banister(context, metricName, t1, t2); // we don't seed t1/t2 yet. (maybe never will)

// add to our collection
banisterData.insert(metricName, returning);
}

return returning;

}

// working with PMC data series
PMCData *
Athlete::getPMCFor(QString metricName, int stsdays, int ltsdays)
Expand Down
5 changes: 5 additions & 0 deletions src/Core/Athlete.h
Expand Up @@ -62,6 +62,7 @@ class Tab;
class Leaf;
class DataFilterRuntime;
class CloudServiceAutoDownload;
class Banister;

class Athlete : public QObject
{
Expand Down Expand Up @@ -111,6 +112,10 @@ class Athlete : public QObject
PMCData *getPMCFor(Leaf *expr, DataFilterRuntime *df, int stsDays = -1, int ltsDays = -1); // no Specification used!
QMap<QString, PMCData*> pmcData; // all the different PMC series

// Banister Data
Banister *getBanisterFor(QString metricName, int t1, int t2); // t1/t2 not used yet
QMap<QString, Banister*> banisterData;

// athlete measures
// note ride can override if passed
double getWeight(QDate date, RideFile *ride=NULL);
Expand Down
35 changes: 30 additions & 5 deletions src/Metrics/Banister.cpp
Expand Up @@ -101,8 +101,14 @@ const int typical_SeasonBreak = 42;
//
//
Banister::Banister(Context *context, QString symbol, double t1, double t2, double k1, double k2) :
symbol(symbol), k1(k1), k2(k2), t1(t1), t2(t2), days(0), context(context)
symbol(symbol), k1(k1), k2(k2), t1(t1), t2(t2), days(0), context(context), isstale(true)
{
// when they all change we are ready to invalidate and refresh
// don't worry about upstream events, this is what we are dependant on
connect(context, SIGNAL(estimatesRefreshed()), this, SLOT(invalidate()));
connect(context, SIGNAL(estimatesRefreshed()), this, SLOT(refresh()));

// refresh
refresh();
}

Expand All @@ -112,12 +118,15 @@ Banister::value(QDate date, int type)
{
// check in range
if (date > stop || date < start) return 0;
int index=date.toJulianDay()-start.toJulianDay();

// offset, bouinds check just in case.
long index=date.toJulianDay()-start.toJulianDay();
if (index <0 || index>=data.length()) return 0;

switch(type) {
case BANISTER_NTE: return data[index].nte;
case BANISTER_PTE: return data[index].pte;
case BANISTER_CP: return data[index].perf * typical_CP / 100;
case BANISTER_NTE: return data[index].h;
case BANISTER_PTE: return data[index].g;
case BANISTER_CP: return data[index].perf > 0 ? data[index].perf * typical_CP / 100 : 0; // avoid -ve values and divzero
default:
case BANISTER_PERFORMANCE: return data[index].perf;
}
Expand All @@ -142,9 +151,20 @@ Banister::init()
t2=15;
}

void
Banister::invalidate()
{
isstale=true;
}
void
Banister::refresh()
{
// not stale
if (!isstale) return;

// unstale
isstale=false;

// clear
init();

Expand Down Expand Up @@ -325,6 +345,11 @@ Banister::refresh()
f.tests, f.testoffset,
f.stopIndex-f.startIndex);
}

//
// EXTRACT PARAMETERS WITH A FIT
//
fit();
}


Expand Down
4 changes: 3 additions & 1 deletion src/Metrics/Banister.h
Expand Up @@ -39,7 +39,7 @@ extern const int typical_SeasonBreak;

class banisterData{
public:
banisterData() : score(0), nte(0), pte(0), perf(0), test(0) {}
banisterData() : score(0), g(0), h(0), nte(0), pte(0), perf(0), test(0) {}
double score, // TRIMP, BikeScore etc for day
g, // accumulated load with t1 decay for pte
h, // accumulated load with t2 decay for nte
Expand Down Expand Up @@ -108,11 +108,13 @@ class Banister : public QObject {
public slots:

void init(); // reset previous fits
void invalidate(); // mark as stale
void refresh(); // collect data from rides etc
void fit(); // perform fits along windows

private:
Context *context;
bool isstale;

};
#endif

0 comments on commit 9871d1e

Please sign in to comment.