Commit Graph

88 Commits

Author SHA1 Message Date
Mark Liversedge
1f126c98e0 DataFilter Editor Match { }
.. added matching braces as well as brackets in the
   editor since it can get pretty hairy now we
   have code blocks and named functions using braces.
2015-12-22 10:30:12 +00:00
Mark Liversedge
c6d2fef46c Merge pull request #1739 from amtriathlon/stryd
Add support for running power zones (Stryd) part 3
2015-12-21 15:51:50 +00:00
Mark Liversedge
692f5db5f9 Fix DataFilter function validation
.. it broke all the builtin functions !

.. we need to check for user functions after all the
   builtins e.g. config(cp) was marked as inerror
   when it should not have been.
2015-12-20 20:06:52 +00:00
Alejandro Martinez
078d4ac5ad Add support for running power zones (Stryd) part 3
Final part: use the zones according to sport in metrics and charts
2015-12-19 19:08:33 -03:00
Mark Liversedge
0f12872e6f User Metrics Part 3 of 4
.. User Metrics now integrated into the factory, ride cache
   and of course rides and intervals. Which means you can define
   a user metric and it will be computed and displayed like any
   of the builtin metrics.

.. lots of technical changes to support this:

   * DataFilter gets a runtime object to support multi-threading
     and uses a context for construction only - item contexts are
     used when evaluating an expression

   * RideMetric factory can now remove user metrics

   * The context in which the user modifies the user metrics will
     notify all other contexts of the change ***

*** NOTE: STRONGLY RECOMMEND THAT YOU DO NOT HAVE MULTIPLE ATHLETES
          OPEN WHEN DEVELOPING NEW METRICS SINCE IT WILL TRIGGER A
          METRIC REFRESH FOR ALL OPEN ATHLETES.
2015-12-18 13:07:56 +00:00
Mark Liversedge
09b2f4355c Tidy up context used
.. datafilter uses a context that was used to create it
   which is fine until it is used in user metrics which
   are global and shared across multiple contexts.

.. so now when evaluating a ride item we use the context
   for the rideitem being evaluated not the context of
   the data filter performing the evaluation

.. next couple of commits will need to look at the way
   we use RideItem and RideFile when computing both
   Ride and Interval metrics.
2015-12-11 19:17:53 +00:00
Mark Liversedge
d7a179907d User Metric Part 2 of 4
.. User metrics can be created, deleted and edited
   in the preferences pane.

.. A new dialog has been created to create user metrics
   and will need to be updated after step 3 of this multi
   part update completes the UserMetric code and integrates
   it into the RideMetric factory.
2015-12-11 14:03:58 +00:00
Mark Liversedge
cbf5b34ded Datafilter 'stack overflow'
.. catch problems with recursion from badly
   written datafilters by limiting function
   call stack depth to 500 calls.
2015-12-10 21:53:01 +00:00
Mark Liversedge
553ade5a9c Datafilter User Functions
We now have named functions that can be called in the datafilter.
This is primarily to support user defined metrics where we will expect
the user to optionally define a bunch of functions we will call as
part of the ridemetric methods (see design mock up).

.. Datafilters can be defimed in three forms;

   * a single line, typically as a filter
     e.g. TSS > 100

   * a block of code, typically as a formula
     e.g. { val <- TSS; val > 100; }

   * a program made up of functions, typically as a user metric
     e.g. { pass { TSS>100; } main { pass(); } }

.. This example is functionally equivalent to "TSS>250":

   {
        pass {

            # only filter rides with a high TSS
            TSS > 250;
        }

        main {

            # call our function to filter rides
            pass();
        }
    }

.. Functions can only be defined within a block

.. Functions must be defined before use

.. A "main" function must be defined as an entry point
   into the program if any functions are defined.
2015-12-09 20:49:08 +00:00
Mark Liversedge
1a85bbd70f Added RECINTSECS and NA symbols
.. NA equates to RideFile::NA when working with
   samples or averages etc and wanting to check

.. RECINTSECS is only really available when working
   with ride samples (e.g. in user metrics coming soon)
2015-12-06 10:26:46 +00:00
Mark Liversedge
6bea3d2a3a DataFilter while loops
.. added while loops to the data filter but
   bounded to 10,000 loops to stop runaway
   code.
2015-12-06 09:57:57 +00:00
Mark Liversedge
4cb26cf27c DataFilter if/else support
.. Added if else logic but could not avoid
   needing the statement to be terminated with a
   semi-colon (;)

.. so examples are:

   if (TSS>100) TSS; else 0;

   if (TSS>100) {
      temp <- TSS;
      temp;
   } else {
      temp <- BikeScore;
      temp;
   }

.. Doesn't add much beyond the existing conditional statement
   using '?' and ':' but is a lot more readable (!)
2015-12-05 20:51:45 +00:00
Mark Liversedge
282445abc9 DataFilter { } syntax highlight
.. for errors etc.
2015-12-05 19:46:38 +00:00
Mark Liversedge
56273ea0aa DataFilter Compound Statements { ... }
.. You can now use compound statements in data filters

.. A compound statement is:
       { s1; } evaluates to s1
       { s1; s2; s3; .. sn; } evaluates to sn

.. It is possible to use the recently added user defined
   symbols to build up processing logic:

       { temp <- TSS; temp > 100 }

   is functionally equivalent to

       TSS > 100

.. At present there are no control statements outside of
   the ? and ?: operators but these will no doubt be added
   in due course.
2015-12-05 10:09:52 +00:00
Mark Liversedge
45880246f0 DataFilter User Symbols and '<-' assign
.. allow users to introduce their own symbols
   into a datafilter with:

   symbol <- expression

   Which will initialise symbol and evaluate it
   with the expression. The symbol can override
   a metric name, but that would be rather dumb!
2015-12-04 18:15:21 +00:00
Mark Liversedge
5902365456 DataFilter NOT (!) Operator
.. to negate a condition e.g. !Sport = "Run"
2015-12-04 13:50:59 +00:00
Mark Liversedge
994893c928 DataFilter add ELVIS operator
.. x ?: y

   Evaluates to x if it is non-zero, otherwise it
   evaluates to y. y is only evaluated once and only
   if x is zero. Similarly, x is only evaluated once
   and returned if it is non-zero.
2015-12-03 21:49:48 +00:00
Mark Liversedge
e7cc1f09bd Formulas config(cranklength)
.. to get the configured crank length for use in formulas
   when calculating aepf/cpv as a user data series.
2015-11-22 23:45:48 +00:00
Alejandro Martinez
c22fe3b315 Update Spanish Translation
Also set the translation context on some clases lacking it
2015-11-10 19:22:47 -03:00
Alejandro Martinez
aee176baf1 Added vdottime(VDOT, distance) to formulas
Computes the equivalent time (in seconds) for distance (in km)
at VDOT, tipically used with VDOT metric as first parameter.
2015-10-30 13:36:43 -03:00
Mark Liversedge
9e833d4a04 QStringList::contains returns QBool on QT4
.. yuk. no wonder they deprecated it in QT5. A daft idea
   that adds not value. We compare to true to avoid issues.
2015-09-05 16:33:19 +01:00
Mark Liversedge
44c0f0a9b5 Formula isset(field)
.. returns true if the user has overridden a
   metric, or a metadata tag is set.
2015-09-05 10:03:33 +01:00
Mark Liversedge
ac402756aa Formula unset(field, condition)
.. allow users to use an unset command to remove
   an override or metadata.

   e.g. unset(Old_Metadata, 1)
        unset(TSS, TSS < 0)
2015-09-05 08:20:30 +01:00
Mark Liversedge
48fe226b22 Formula set(field, value, condition)
.. allow users to use a set command to add
   an override or set metadata under certain
   conditions.

   e.g. set(Workout_Code, "HT", IF>0.9)
        set(TSS, 65, TSS <= 0 && Route = "Fave Loop")

.. we should probably add an unset() command
   to do the reverse and clear values under
   conditions too.

   USE WITH CAUTION -- TAKE A BACKUP BEFORE
   MAKING ANY RADICAL CHANGES TO YOUR DATA
2015-09-04 21:12:14 +01:00
Mark Liversedge
cddf18d58f Syntax highlight data series symbols
.. they were missed in last commit
2015-08-25 13:44:26 +01:00
Mark Liversedge
60b1562d55 Formulas support Ride Data
.. passed to eval and symbols now recongised.

.. sample data is referenced using symbol names
   in all caps to make it clear you are referencing
   ride dample data.

.. the next commits will add defining formulas and plotting
   the derived data series in allplot.
2015-08-25 13:30:07 +01:00
Mark Liversedge
cb65205b42 Formula which() function
.. To select in a vector. The notation
   is a selection criteria followed by
   a list of values / vectors

   e.g. which(x>0, TSS[date:date])

   will create a vector where TSS is non
   zero for the day.

   "x" is replaced with the vector values
   and as such is a special symbol.

.. also fixed a bug with the snip cache.
2015-08-22 17:18:54 +01:00
Mark Liversedge
069342f6f5 Formula Microcache 'snips'
.. when running a formula it may use a vector
   operation to calculate e.g. an average for the
   date range.

.. these get called for every ride, but actually they
   perform the same calculation over and over

.. we cache the vector operation and result to avoid
   repeated calculations; these are only cached whilst
   a datafilter is being evaluated, so we do not need
   to worry about stale/refreshing.
2015-08-22 11:34:58 +01:00
Mark Liversedge
17bf55c40d Formula estimate function
.. estimate(model, duration) or to get the model
   parameters estimate(model, parameter) always
   for the date of the ride.

   e.g. estimate(2p, cp) gets the estimated CP
   for the date of the ride using the classic
   2 parameter model

   Models are one of;
   2p - classic monod scherrer
   3p - morton 3p
   ext - gc extended
   ws - ward-smith
   velo - veloclinic

   Parameters are one of;
   w' - W'
   cp - critical power
   ftp - functional threshold power
   pmax - max power

   For watts per kilo just add / config(weight)
   or Athlete_Weight to take into account ride
   specific weight settings / overrides.
2015-08-21 19:58:27 +01:00
Mark Liversedge
e9a7ff434d DataFilter in PMC - Part 3 of 3
.. can now use a formula in the lts, sts
   sb, rr functions.

.. e.g lts(TSS/2) evaluates to the "CTL"
   value for the ride if using TSS/2 as
   the input.

NOTE: you only get a value where a ride
exists. We may want to think about the
way we scope formulas; are they iterating
over rides or dates ?
2015-08-21 11:23:05 +01:00
Mark Liversedge
dbe92eec27 Formula Leaf Signature
.. to use when e.g. using a data filter as an input
   into the PMC functions. The data series is stored
   against a signature for the function as opposed to
   the metric symbol.

.. we need to do it for an expr not the data filter
2015-08-20 22:56:51 +01:00
Mark Liversedge
10b5f75a47 Formula Signature
.. to use when e.g. using a data filter as an input
   into the PMC functions. The data series is stored
   against a signature for the function as opposed to
   the metric symbol.
2015-08-20 18:35:45 +01:00
Mark Liversedge
a57a6e683e FilterEdit Colors
.. time to move on now, this is slightly
   embarassing.
2015-08-20 07:18:47 +01:00
Mark Liversedge
d13b396663 FilterEditor Tweak Cosmetics
.. courier font

.. syntax coloring follows common "windows IDE"
   conventions (comments green, symbols blue etc)
2015-08-20 07:14:11 +01:00
Mark Liversedge
90ac02e3c9 Add brace balancing in Filter Editor
.. for finding partner parenthesis
.. for showing unbalance parenthesis
2015-08-19 22:23:30 +01:00
Mark Liversedge
7f6991520c Fix Syntax Highlighting
.. distinct from parser now, so not susceptible
   to parsing / syntax errors in formula.

.. still need to do brace matching.
2015-08-19 21:02:08 +01:00
Mark Liversedge
bf4c37f7b2 Deprecate parser syntax highlighting
.. but do continue to highlight bad symbols etc
   with a red wavy line.

.. still need to;
   a) syntax highlight in the formula edit (just symbols
      and literals, not parsing content)

   b) add an error navigator to click on errors and have the
      text highlighted that incurred that error.
2015-08-19 12:50:38 +01:00
Mark Liversedge
4f570d8106 Fix DataFilter regression
.. the daterange() commit broke almost every builtin
   function ! (it converted them to integers due to
   and if/else logic error.

.. also tidied parser to separate literals and symbols
   whilst making builtin functions expr elements to
   look more closely at precedence
2015-08-17 22:00:15 +01:00
Mark Liversedge
e1f2c1b48b Fixup unary '-'
.. so date-9 is not treated as "date" "-9" but
   instead as "date" "-" "9"
2015-08-17 15:21:24 +01:00
Mark Liversedge
4941dacd8c Syntax highlighting from parser
.. oopsie on binary expression.

NOTE: it may be better to highlight tokens rather than
      via the parser as errors make it impossible to
      highlight the "intention" of the user
2015-08-16 22:24:49 +01:00
Mark Liversedge
2e949b13bf Formula sum, mean, max, min, count functions
Particularly useful when working with a vector
but can be used with other things.

e.g. max(xPower, BikeScore)

Or, for getting a ride's TSS expressed as a percentage
of the average TSS for the currently selected daterange.

e.g. TSS / mean(TSS[daterange(start):daterange(stop)])
2015-08-16 19:49:16 +01:00
Mark Liversedge
99845aa12a Formula Editor error highlighting
.. using red wiggly line

.. still need to find a way of providing the
   parsing errors messages and navigating to
   the part they are complaining about.
2015-08-16 18:32:32 +01:00
Mark Liversedge
a9b50af7a1 Formula Vectors
You can create a vector using the notation:

   expr [ from : to ]

   Where 'expr' will be evaluated for every activity
   between the dates from and to.

   e.g. TSS[today - 90 : today]

   will evaluate to TSS for the last 90 days

   e.g. Activities [ date:date ] > 1

   Will find all days with more than one workout.

.. when using a vector in any arithmetic expression it
   will be evaluated to a sum; this will be fixed shortly
   to enable the use of sum/mean/max/min functions.

.. If needed we can add vector operations but this will
   likely confuse many users (hell, they confuse developers)
   so we will need a good reason to add them !

Lastly, I have also added daterange(from) and daterange(to)
literals to get access to the currently selected daterange
when working in the trends view.
2015-08-16 17:23:46 +01:00
Mark Liversedge
22bc70cd1a Formula Editor Improvements 1 of 2
.. update the editor to do some basic syntax
   highlighting; literals in red, comments in
   blue and so on.

.. next commit will focus on highlighting errors
   with a wavy line and some form of error list.
2015-08-15 23:47:04 +01:00
Alejandro Martinez
06c1546a05 Minor changes for DataFilter to compile on MinGW 2015-08-15 11:46:32 -03:00
Mark Liversedge
aa3e3102f9 DataFilter Functions and "math"
.. updated the datafilter to handle general functions
   and parse them without needing them declared in the lexer

.. makes it much easier to add new functions in the future

.. did this to add core math functions;
   *  sin, cos, tan, asin, acos, atan,
   *  sinh, cosh, tanh, asinh, acosh, atanh
   *  exp, log, log10, ceil, floor, round
   *  fabs, isinf, isnan

.. we can add more later; erf/gamma spring to mind !
2015-08-15 14:17:53 +01:00
Mark Liversedge
58e2c88c9a Formula const()
.. for pi and e, we can add more later
   i.e. const(pi) and const(e) return high
   precision values for both
2015-08-15 10:33:09 +01:00
Mark Liversedge
7bc1537f30 Formula config() function and test charts
.. added config(cv) .. config(pmax) etc

.. also added some test charts including one that
   just displays configuration
2015-08-14 22:10:29 +01:00
Mark Liversedge
06a41f4583 LTM Plot Formula Part 2 of 2
.. added to LTMPlot and DataFilter methods

.. very rough and ready, but works.

.. can refine and enhance now basics are in place.
2015-08-13 12:35:17 +01:00
Mark Liversedge
53670707e6 DataFilter Conditional Expression
.. uses the C/C++ notation:

   expr ? expr2 : expr3

   Where expr is the condition e.g. X>2
   and expr2 is what to evaluate to if expr is true
   and expr3 is what to evaluate to if expr is false

   e.g.

   (Workout_Code = "1L3") ? 1 : 0

   Will evaluate as 1 for all workouts where the
   workout code is 1L3 and 0 for all other workouts.
2015-08-13 09:24:26 +01:00