From 344da00a9d9cecf8097e437020031f9d8a7aefbb Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Wed, 4 May 2016 11:39:14 +0100 Subject: [PATCH] R GC.activity.meanmax() .. returns a data.frame with meanmax arrays for the series that are present --- src/FileIO/RideFileCache.cpp | 18 +++ src/FileIO/RideFileCache.h | 1 + src/R/RTool.cpp | 207 +++++++++++++++++++++++++++++++++++ src/R/RTool.h | 4 +- 4 files changed, 229 insertions(+), 1 deletion(-) diff --git a/src/FileIO/RideFileCache.cpp b/src/FileIO/RideFileCache.cpp index 89a810285..38d554e59 100644 --- a/src/FileIO/RideFileCache.cpp +++ b/src/FileIO/RideFileCache.cpp @@ -661,6 +661,24 @@ RideFileCache::meanMaxDates(RideFile::SeriesType series) } } +QList RideFileCache::meanMaxList() +{ + QList list; + list << RideFile::watts + << RideFile::wattsKg + << RideFile::nm + << RideFile::hr + << RideFile::cad + << RideFile::kph + << RideFile::vam + << RideFile::NP + << RideFile::aPower + << RideFile::xPower + ; + + return list; +} + QVector & RideFileCache::meanMaxArray(RideFile::SeriesType series) { diff --git a/src/FileIO/RideFileCache.h b/src/FileIO/RideFileCache.h index da007b9ac..2231fbdf9 100644 --- a/src/FileIO/RideFileCache.h +++ b/src/FileIO/RideFileCache.h @@ -201,6 +201,7 @@ class RideFileCache static RideFileCache *createCacheFor(RideFile*); // get data + static QList meanMaxList(); // list of types available as meanmax arrays QVector &meanMaxArray(RideFile::SeriesType); // return meanmax array for the given series QVector &meanMaxDates(RideFile::SeriesType series); // the dates of the bests QVector &distributionArray(RideFile::SeriesType); // return distribution array for the given series diff --git a/src/R/RTool.cpp b/src/R/RTool.cpp index ddc2f2a7a..26125cf62 100644 --- a/src/R/RTool.cpp +++ b/src/R/RTool.cpp @@ -23,6 +23,7 @@ #include "RideCache.h" #include "RideItem.h" #include "RideFile.h" +#include "RideFileCache.h" #include "Colors.h" #include "RideMetric.h" #include "RideMetadata.h" @@ -83,6 +84,7 @@ RTool::RTool() { "GC.athlete.home", (DL_FUNC) &RTool::athleteHome, 0 ,0, 0 }, { "GC.activities", (DL_FUNC) &RTool::activities, 0 ,0, 0 }, { "GC.activity", (DL_FUNC) &RTool::activity, 0 ,0, 0 }, + { "GC.activity.meanmax", (DL_FUNC) &RTool::activityMeanmax, 0 ,0, 0 }, { "GC.metrics", (DL_FUNC) &RTool::metrics, 0 ,0, 0 }, { "GC.pmc", (DL_FUNC) &RTool::pmc, 0 ,0, 0 }, { NULL, NULL, 0, 0, 0 } @@ -97,6 +99,7 @@ RTool::RTool() // currently in the compare pane if compare is enabled or // just a 1 item list with the current ride { "GC.activity", (DL_FUNC) &RTool::activity, 1 }, + { "GC.activity.meanmax", (DL_FUNC) &RTool::activityMeanmax, 1 }, // metrics is passed a Rboolean for "all": // TRUE -> return all metrics, FALSE -> apply date range selection @@ -124,6 +127,7 @@ RTool::RTool() "GC.athlete.home <- function() { .Call(\"GC.athlete.home\") }\n" "GC.activities <- function() { .Call(\"GC.activities\") }\n" "GC.activity <- function(compare=FALSE) { .Call(\"GC.activity\", compare) }\n" + "GC.activity.meanmax <- function(compare=FALSE) { .Call(\"GC.activity.meanmax\", compare) }\n" "GC.metrics <- function(all=FALSE, compare=FALSE) { .Call(\"GC.metrics\", all, compare) }\n" "GC.pmc <- function(all=FALSE, metric=\"TSS\") { .Call(\"GC.pmc\", all, metric) }\n" "GC.version <- function() { return(\"%1\") }\n" @@ -821,6 +825,209 @@ RTool::activity(SEXP pCompare) return Rf_allocVector(INTSXP, 0); } +SEXP +RTool::dfForActivityMeanmax(const RideItem *i) +{ + // how many series and how big are they? + unsigned int seriescount=0, size=0; + + // get the meanmax array + RideFileCache *cache = const_cast(i)->fileCache(); + if (cache != NULL) { + // how many points in the ridefilecache and how many series to return + foreach(RideFile::SeriesType series, cache->meanMaxList()) { + QVector values = cache->meanMaxArray(series); + if (values.count()) { + size = values.count(); + seriescount++; + } + } + } + + // we return a list of series vectors + SEXP ans; + PROTECT(ans = Rf_allocList(seriescount)); + + // we collect the names as we go + SEXP names; + PROTECT(names = Rf_allocVector(STRSXP, seriescount)); // names attribute (column names) + int next=0; + SEXP nextS = ans; + + // + // Now we need to add vectors to the ans list... + // + + foreach(RideFile::SeriesType series, cache->meanMaxList()) { + + QVector values = cache->meanMaxArray(series); + + // don't add empty ones + if (values.count()==0) continue; + + + // set a vector + SEXP vector; + PROTECT(vector=Rf_allocVector(REALSXP, size)); + + for(unsigned int j=0; jcontext) { + + + if (rtool->context->isCompareIntervals) { + + // how many to return? + int count=0; + foreach(CompareInterval p, rtool->context->compareIntervals) if (p.isChecked()) count++; + + // cool we can return a list of intervals to compare + SEXP list; + PROTECT(list=Rf_allocVector(LISTSXP, count)); + + // start at the front + SEXP nextS = list; + + // a named list with data.frame 'activity' and color 'color' + SEXP namedlist; + + // names + SEXP names; + PROTECT(names=Rf_allocVector(STRSXP, 2)); + SET_STRING_ELT(names, 0, Rf_mkChar("meanmax")); + SET_STRING_ELT(names, 1, Rf_mkChar("color")); + + // create a data.frame for each and add to list + foreach(CompareInterval p, rtool->context->compareIntervals) { + if (p.isChecked()) { + + // create a named list + PROTECT(namedlist=Rf_allocVector(LISTSXP, 2)); + SEXP offset = namedlist; + + // add the ride + SEXP df = rtool->dfForActivityMeanmax(p.rideItem); + SETCAR(offset, df); + offset=CDR(offset); + + // add the color + SEXP color; + PROTECT(color=Rf_allocVector(STRSXP, 1)); + SET_STRING_ELT(color, 0, Rf_mkChar(p.color.name().toLatin1().constData())); + SETCAR(offset, color); + + // name them + Rf_namesgets(namedlist, names); + + // add to back and move on + SETCAR(nextS, namedlist); + nextS=CDR(nextS); + + UNPROTECT(2); + } + } + UNPROTECT(2); // list and names + + return list; + + } else if(rtool->context->currentRideItem() && const_cast(rtool->context->currentRideItem())->ride()) { + + // just return a list of one ride + // cool we can return a list of intervals to compare + SEXP list; + PROTECT(list=Rf_allocVector(LISTSXP, 1)); + + // names + SEXP names; + PROTECT(names=Rf_allocVector(STRSXP, 2)); + SET_STRING_ELT(names, 0, Rf_mkChar("meanmax")); + SET_STRING_ELT(names, 1, Rf_mkChar("color")); + + // named list of activity and color + SEXP namedlist; + PROTECT(namedlist=Rf_allocVector(LISTSXP, 2)); + SEXP offset = namedlist; + + // add the ride + SEXP df = rtool->dfForActivityMeanmax(rtool->context->currentRideItem()); + SETCAR(offset, df); + offset=CDR(offset); + + // add the color + SEXP color; + PROTECT(color=Rf_allocVector(STRSXP, 1)); + SET_STRING_ELT(color, 0, Rf_mkChar("#FF00FF")); + SETCAR(offset, color); + + // name them + Rf_namesgets(namedlist, names); + + // add to back and move on + SETCAR(list, namedlist); + UNPROTECT(4); + + return list; + } + + } else if (!compare) { // not compare, so just return a dataframe + + // access via global as this is a static function + if(rtool->context && rtool->context->currentRideItem() && const_cast(rtool->context->currentRideItem())->ride()) { + + // get as a data frame + ans = rtool->dfForActivityMeanmax(rtool->context->currentRideItem()); + return ans; + } + } + + // nothing to return + return Rf_allocVector(INTSXP, 0); +} + SEXP RTool::pmc(SEXP pAll, SEXP pMetric) { diff --git a/src/R/RTool.h b/src/R/RTool.h index 2d4a9cada..16d79272b 100644 --- a/src/R/RTool.h +++ b/src/R/RTool.h @@ -45,9 +45,10 @@ class RTool { static SEXP athlete(); static SEXP athleteHome(); static SEXP activities(); - static SEXP activity(SEXP all); + static SEXP activity(SEXP compare); static SEXP metrics(SEXP all, SEXP compare); static SEXP pmc(SEXP all, SEXP metric); + static SEXP activityMeanmax(SEXP compare); bool starting; bool failed; @@ -74,6 +75,7 @@ class RTool { // return a dataframe for the ride passed SEXP dfForActivity(RideFile *f); + SEXP dfForActivityMeanmax(const RideItem *i); SEXP dfForDateRange(bool all, DateRange range); };