Python metrics(metric, all, filter)

A more efficient way to obtain a metric series for a large number
of activities, it can be converted to numpy array without copy:
import numpy as np
nparray = np.asarray(GC.metrics("Average_Power", True, "isRun=0 && isSwim=0")
This commit is contained in:
Alejandro Martinez
2017-12-15 11:56:55 -03:00
parent 147d3b83d9
commit ae6d00103e
6 changed files with 120 additions and 15 deletions

View File

@@ -411,6 +411,72 @@ Bindings::seasonMetrics(bool all, DateRange range, QString filter) const
return dict;
}
PythonDataSeries*
Bindings::metrics(QString metric, bool all, QString filter) const
{
Context *context = python->contexts.value(threadid());
if (context == NULL || context->athlete == NULL || context->athlete->rideCache == NULL) return NULL;
// how many rides to return if we're limiting to the
// currently selected date range ?
DateRange range = context->currentDateRange();
// apply any global filters
Specification specification;
FilterSet fs;
fs.addFilter(context->isfiltered, context->filters);
fs.addFilter(context->ishomefiltered, context->homeFilters);
// did call contain a filter?
if (filter != "") {
DataFilter dataFilter(python->chart, context);
QStringList files;
dataFilter.parseFilter(context, filter, &files);
fs.addFilter(true, files);
}
specification.setFilterSet(fs);
// we need to count rides that are in range...
int rides = 0;
foreach(RideItem *ride, context->athlete->rideCache->rides()) {
if (!specification.pass(ride)) continue;
if (all || range.pass(ride->dateTime.date())) rides++;
}
const RideMetricFactory &factory = RideMetricFactory::instance();
bool useMetricUnits = context->athlete->useMetricUnits;
for(int i=0; i<factory.metricCount();i++) {
QString symbol = factory.metricName(i);
const RideMetric *m = factory.rideMetric(symbol);
QString name = context->specialFields.internalName(factory.rideMetric(symbol)->name());
name = name.replace(" ","_");
name = name.replace("'","_");
if (name == metric) {
// found, set an array of metric values
PythonDataSeries* pds = new PythonDataSeries(name, rides);
int idx = 0;
foreach(RideItem *item, context->athlete->rideCache->rides()) {
if (!specification.pass(item)) continue;
if (all || range.pass(item->dateTime.date())) {
pds->data[idx++] = item->metrics()[i] * (useMetricUnits ? 1.0f : m->conversion()) + (useMetricUnits ? 0.0f : m->conversionSum());
}
}
// Done, return the series
return pds;
}
}
// Not found, nothing to return
return NULL;
}
int
Bindings::webpage(QString url) const
{

View File

@@ -35,6 +35,7 @@ class Bindings {
// working with metrics
PyObject* activityMetrics(bool compare=false) const;
PyObject* seasonMetrics(bool all=false, QString filter=QString(), bool compare=false) const;
PythonDataSeries *metrics(QString metric, bool all=false, QString filter=QString()) const;
// working with the web view
int webpage(QString url) const;

View File

@@ -125,6 +125,7 @@ public:
// working with metrics
PyObject* activityMetrics(bool compare=false) /TransferBack/;
PyObject* seasonMetrics(bool all=false, QString filter=QString(), bool compare=false) /TransferBack/;
PythonDataSeries *metrics(QString metric, bool all=false, QString filter=QString()) /TransferBack/;
// working with the web view
int webpage(QString url) const;

View File

@@ -35,20 +35,22 @@
#define sipName_Bindings &sipStrings_goldencheetah[118]
#define sipNameNr_webpage 127
#define sipName_webpage &sipStrings_goldencheetah[127]
#define sipNameNr_version 135
#define sipName_version &sipStrings_goldencheetah[135]
#define sipNameNr_athlete 143
#define sipName_athlete &sipStrings_goldencheetah[143]
#define sipNameNr___len__ 151
#define sipName___len__ &sipStrings_goldencheetah[151]
#define sipNameNr___str__ 159
#define sipName___str__ &sipStrings_goldencheetah[159]
#define sipNameNr_QString 167
#define sipName_QString &sipStrings_goldencheetah[167]
#define sipNameNr_series 175
#define sipName_series &sipStrings_goldencheetah[175]
#define sipNameNr_build 182
#define sipName_build &sipStrings_goldencheetah[182]
#define sipNameNr_metrics 135
#define sipName_metrics &sipStrings_goldencheetah[135]
#define sipNameNr_version 143
#define sipName_version &sipStrings_goldencheetah[143]
#define sipNameNr_athlete 151
#define sipName_athlete &sipStrings_goldencheetah[151]
#define sipNameNr___len__ 159
#define sipName___len__ &sipStrings_goldencheetah[159]
#define sipNameNr___str__ 167
#define sipName___str__ &sipStrings_goldencheetah[167]
#define sipNameNr_QString 175
#define sipName_QString &sipStrings_goldencheetah[175]
#define sipNameNr_series 183
#define sipName_series &sipStrings_goldencheetah[183]
#define sipNameNr_build 190
#define sipName_build &sipStrings_goldencheetah[190]
#define sipMalloc sipAPI_goldencheetah->api_malloc
#define sipFree sipAPI_goldencheetah->api_free

View File

@@ -278,6 +278,39 @@ static PyObject *meth_Bindings_seasonMetrics(PyObject *sipSelf, PyObject *sipArg
}
extern "C" {static PyObject *meth_Bindings_metrics(PyObject *, PyObject *);}
static PyObject *meth_Bindings_metrics(PyObject *sipSelf, PyObject *sipArgs)
{
PyObject *sipParseErr = NULL;
{
::QString* a0;
int a0State = 0;
bool a1 = 0;
::QString a2def = QString();
::QString* a2 = &a2def;
int a2State = 0;
::Bindings *sipCpp;
if (sipParseArgs(&sipParseErr, sipArgs, "BJ1|bJ1", &sipSelf, sipType_Bindings, &sipCpp, sipType_QString,&a0, &a0State, &a1, sipType_QString,&a2, &a2State))
{
::PythonDataSeries*sipRes;
sipRes = sipCpp->metrics(*a0,a1,*a2);
sipReleaseType(a0,sipType_QString,a0State);
sipReleaseType(a2,sipType_QString,a2State);
return sipConvertFromType(sipRes,sipType_PythonDataSeries,Py_None);
}
}
/* Raise an exception if the arguments couldn't be parsed. */
sipNoMethod(sipParseErr, sipName_Bindings, sipName_metrics, NULL);
return NULL;
}
extern "C" {static PyObject *meth_Bindings_webpage(PyObject *, PyObject *);}
static PyObject *meth_Bindings_webpage(PyObject *sipSelf, PyObject *sipArgs)
{
@@ -378,6 +411,7 @@ static PyMethodDef methods_Bindings[] = {
{SIP_MLNAME_CAST(sipName_activityMetrics), meth_Bindings_activityMetrics, METH_VARARGS, NULL},
{SIP_MLNAME_CAST(sipName_athlete), meth_Bindings_athlete, METH_VARARGS, NULL},
{SIP_MLNAME_CAST(sipName_build), meth_Bindings_build, METH_VARARGS, NULL},
{SIP_MLNAME_CAST(sipName_metrics), meth_Bindings_metrics, METH_VARARGS, NULL},
{SIP_MLNAME_CAST(sipName_seasonMetrics), meth_Bindings_seasonMetrics, METH_VARARGS, NULL},
{SIP_MLNAME_CAST(sipName_series), meth_Bindings_series, METH_VARARGS, NULL},
{SIP_MLNAME_CAST(sipName_seriesLast), meth_Bindings_seriesLast, METH_VARARGS, NULL},
@@ -402,7 +436,7 @@ sipClassTypeDef sipTypeDef_goldencheetah_Bindings = {
{
sipNameNr_Bindings,
{0, 0, 1},
11, methods_Bindings,
12, methods_Bindings,
0, 0,
0, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

View File

@@ -26,6 +26,7 @@ const char sipStrings_goldencheetah[] = {
't', 'h', 'r', 'e', 'a', 'd', 'i', 'd', 0,
'B', 'i', 'n', 'd', 'i', 'n', 'g', 's', 0,
'w', 'e', 'b', 'p', 'a', 'g', 'e', 0,
'm', 'e', 't', 'r', 'i', 'c', 's', 0,
'v', 'e', 'r', 's', 'i', 'o', 'n', 0,
'a', 't', 'h', 'l', 'e', 't', 'e', 0,
'_', '_', 'l', 'e', 'n', '_', '_', 0,