Formula config() function and test charts

.. added config(cv) .. config(pmax) etc

.. also added some test charts including one that
   just displays configuration
This commit is contained in:
Mark Liversedge
2015-08-14 22:10:29 +01:00
parent b7dabef8ea
commit b5ce92a045
8 changed files with 150 additions and 6 deletions

View File

@@ -25,6 +25,10 @@
#include "PMCData.h"
#include <QDebug>
#include "Zones.h"
#include "PaceZones.h"
#include "HrZones.h"
#include "DataFilter_yacc.h"
// LEXER VARIABLES WE INTERACT WITH
@@ -113,7 +117,7 @@ void Leaf::print(Leaf *leaf, int level)
leaf->print(leaf->lvalue.l, level+1);
leaf->print(leaf->rvalue.l, level+1);
break;
case Leaf::Function : qDebug()<<"function"<<leaf->function<<"series="<<*(leaf->series->lvalue.n);
case Leaf::Function : qDebug()<<"function"<<leaf->function<<"parm="<<*(leaf->series->lvalue.n);
if (leaf->lvalue.l) leaf->print(leaf->lvalue.l, level+1);
break;
case Leaf::Conditional : qDebug()<<"cond";
@@ -238,7 +242,8 @@ void Leaf::validateFilter(DataFilter *df, Leaf *leaf)
// is the symbol valid?
QRegExp bestValidSymbols("^(apower|power|hr|cadence|speed|torque|vam|xpower|np|wpk)$", Qt::CaseInsensitive);
QRegExp tizValidSymbols("^(power|hr)$", Qt::CaseInsensitive);
QString symbol = *(leaf->series->lvalue.n);
QRegExp configValidSymbols("^(cp|w\\'|pmax|cv|d\\'|scv|sd\\'|height|weight|lthr|maxhr|rhr|units)$", Qt::CaseInsensitive);
QString symbol = leaf->series->lvalue.n->toLower();
if (leaf->function == "sts" || leaf->function == "lts" || leaf->function == "sb" || leaf->function == "rr") {
@@ -254,10 +259,15 @@ void Leaf::validateFilter(DataFilter *df, Leaf *leaf)
if (leaf->function == "tiz" && !tizValidSymbols.exactMatch(symbol))
DataFiltererrors << QString(QObject::tr("invalid data series for tiz(): %1")).arg(symbol);
// now set the series type
leaf->seriesType = nameToSeries(symbol);
}
if (leaf->function == "config" && !configValidSymbols.exactMatch(symbol))
DataFiltererrors << QString(QObject::tr("invalid data series for config(): %1")).arg(symbol);
if (leaf->function == "best" || leaf->function == "tiz") {
// now set the series type used as parameter 1 to best/tiz
leaf->seriesType = nameToSeries(symbol);
}
}
}
break;
@@ -521,7 +531,111 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, RideItem *m)
if (leaf->function == "rr") return Result(pmcData->rr(m->dateTime.date()));
}
if (leaf->function == "config") {
//
// Get CP and W' estimates for date of ride
//
double CP = 0;
double WPRIME = 0;
double PMAX = 0;
int zoneRange;
if (context->athlete->zones()) {
// if range is -1 we need to fall back to a default value
zoneRange = context->athlete->zones()->whichRange(m->dateTime.date());
CP = zoneRange >= 0 ? context->athlete->zones()->getCP(zoneRange) : 0;
WPRIME = zoneRange >= 0 ? context->athlete->zones()->getWprime(zoneRange) : 0;
PMAX = zoneRange >= 0 ? context->athlete->zones()->getPmax(zoneRange) : 0;
// did we override CP in metadata ?
int oCP = m->getText("CP","0").toInt();
int oW = m->getText("W'","0").toInt();
int oPMAX = m->getText("Pmax","0").toInt();
if (oCP) CP=oCP;
if (oW) WPRIME=oW;
if (oPMAX) PMAX=oPMAX;
}
//
// LTHR, MaxHR, RHR
//
int hrZoneRange = context->athlete->hrZones() ?
context->athlete->hrZones()->whichRange(m->dateTime.date())
: -1;
int LTHR = hrZoneRange != -1 ? context->athlete->hrZones()->getLT(hrZoneRange) : 0;
int RHR = hrZoneRange != -1 ? context->athlete->hrZones()->getRestHr(hrZoneRange) : 0;
int MaxHR = hrZoneRange != -1 ? context->athlete->hrZones()->getMaxHr(hrZoneRange) : 0;
//
// CV' D'
//
int paceZoneRange = context->athlete->paceZones(false) ?
context->athlete->paceZones(false)->whichRange(m->dateTime.date()) :
-1;
double CV = (paceZoneRange != -1) ? context->athlete->paceZones(false)->getCV(paceZoneRange) : 0.0;
double DPRIME = 0; //XXX(paceZoneRange != -1) ? context->athlete->paceZones(false)->getDPrime(paceZoneRange) : 0.0;
int spaceZoneRange = context->athlete->paceZones(true) ?
context->athlete->paceZones(true)->whichRange(m->dateTime.date()) :
-1;
double SCV = (spaceZoneRange != -1) ? context->athlete->paceZones(true)->getCV(spaceZoneRange) : 0.0;
double SDPRIME = 0; //XXX (spaceZoneRange != -1) ? context->athlete->paceZones(true)->getDPrime(spaceZoneRange) : 0.0;
//
// HEIGHT and WEIGHT
//
double HEIGHT = m->getText("Height","0").toDouble();
if (HEIGHT == 0) HEIGHT = context->athlete->getHeight(NULL);
double WEIGHT = m->getWeight();
QString symbol = leaf->series->lvalue.n->toLower();
if (symbol == "cp") {
return Result(CP);
}
if (symbol == "w'") {
return Result(WPRIME);
}
if (symbol == "pmax") {
return Result(PMAX);
}
if (symbol == "scv") {
return Result(SCV);
}
if (symbol == "sd'") {
return Result(SDPRIME);
}
if (symbol == "cv") {
return Result(CV);
}
if (symbol == "d'") {
return Result(DPRIME);
}
if (symbol == "lthr") {
return Result(LTHR);
}
if (symbol == "rhr") {
return Result(RHR);
}
if (symbol == "maxhr") {
return Result(MaxHR);
}
if (symbol == "weight") {
return Result(WEIGHT);
}
if (symbol == "height") {
return Result(HEIGHT);
}
if (symbol == "units") {
return Result(context->athlete->useMetricUnits ? 1 : 0);
}
}
// get here for tiz and best
switch (leaf->lvalue.l->type) {
default:

View File

@@ -73,6 +73,7 @@ class Leaf {
int op;
QString function;
Leaf *series; // is a symbol
bool dynamic;
RideFile::SeriesType seriesType; // for ridefilecache

View File

@@ -52,6 +52,7 @@
[Ss][Tt][Ss] strcpy(DataFilterlval.function, "sts"); return STS;
[Ss][Bb] strcpy(DataFilterlval.function, "sb"); return SB;
[Rr][Rr] strcpy(DataFilterlval.function, "rr"); return RR;
[Cc][Oo][Nn][Ff][Ii][Gg] strcpy(DataFilterlval.function, "config"); return CONFIG;
"&&" DataFilterlval.op = AND; return AND;
[Aa][nN][Dd] DataFilterlval.op = AND; return AND;
@@ -72,6 +73,9 @@
"Max_W'_Expended" return SYMBOL; /* special case */
"W'_Work" return SYMBOL; /* special case */
"W'bal_TAU" return SYMBOL; /* special case */
[Ww]\' return SYMBOL; /* special case */
[Dd]\' return SYMBOL; /* special case */
[Ss][Dd]\' return SYMBOL; /* special case */
[a-zA-Z0-9][a-zA-Z0-9_%™]+ return SYMBOL; /* symbols can start with 0-9 */

View File

@@ -54,7 +54,7 @@ extern Leaf *root; // root node for parsed statement
// Constants can be a string or a number
%token <leaf> DF_STRING DF_INTEGER DF_FLOAT
%token <function> BEST TIZ STS LTS SB RR
%token <function> BEST TIZ STS LTS SB RR CONFIG
// comparative operators
%token <op> Q COL
@@ -205,6 +205,11 @@ value : symbol { $$ = $1; }
$$->series = $3;
$$->lvalue.l = NULL;
}
| CONFIG '(' symbol ')' { $$ = new Leaf(); $$->type = Leaf::Function;
$$->function = QString($1);
$$->series = $3;
$$->lvalue.l = NULL;
}
;
%%

View File

@@ -1737,6 +1737,17 @@ EditMetricDetailDialog::EditMetricDetailDialog(Context *context, LTMTool *ltmToo
QStringList names = context->tab->rideNavigator()->logicalHeadings;
// add functions ...
list << "config(cp)";
list << "config(w')";
list << "config(pmax)";
list << "config(cv)";
list << "config(scv)";
list << "config(height)";
list << "config(weight)";
list << "config(lthr)";
list << "config(maxhr)";
list << "config(rhr)";
list << "config(units)";
list << "ctl";
list << "tsb";
list << "atl";

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
<charts version="16">
<chart name="Configuration">"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OgAAAAgA/////wAAAAAAAAAEAEMAUAAAAAoAVwBhAHQAdABzAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAABAAAAAAAAAAD//////////8B////////f38AAAAAAAA/8AAAAAAAAAAAAAAB//8AAAAAAAAAAAAAAAAAAAAD5wAADhD/////AAAACgAAAAAAAAAAAAAAAAwAMgAgAFAAYQByAG0AAAAAAAAAAAAADhABAAAAAP////8AAAAWAGMAbwBuAGYAaQBnACgAQwBQACkACgAAAAIAAAAOAHMAZQBhAHIAYwBoADoAAAAIAP////8AAAAAAAAABABXACcAAAAMAEoAbwB1AGwAZQBzAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAABAAAAAAAAAAD//////////8B//9VVaqqAAAAAAAAAAA/8AAAAAAAAAAAAAAB//8AAAAAAAAAAAAAAAAAAAAD5wAADhD/////AAAACgAAAAAAAAAAAAAAAAwAMgAgAFAAYQByAG0AAAAAAAAAAAAADhABAAAAAP////8AAAAWAGMAbwBuAGYAaQBnACgAdwAnACkACgAAAAIAAAAOAHMAZQBhAHIAYwBoADoAAAAIAP////8AAAAAAAAACABQAE0AYQB4AAAACgBXAGEAdAB0AHMAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAEAAAAAAAAAAP//////////wH//1VV//9/fwAAAAAAAD/wAAAAAAAAAAAAAAH//wAAAAAAAAAAAAAAAAAAAAAAAAAOEP////8AAAAKAAAAAAAAAAAAAAAADAAyACAAUABhAHIAbQAAAAAAAAAAAAAOEAAAAAAA/////wAAABoAYwBvAG4AZgBpAGcAKABQAG0AYQB4ACkACgAAAAIAAAAOAHMAZQBhAHIAYwBoADoAAAAAAAM="</chart>
</charts>

View File

@@ -0,0 +1,3 @@
<charts version="16">
<chart name="Sport Mix">"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"</chart>
</charts>