.. 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.
.. 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.
.. 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
.. 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
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)])
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.
.. 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.
.. 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 !
.. 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.
.. get rid of terrible cut and paste code, duplicating
eval for particular leafs
.. eval returns a Result() object which can be numeric
or textual (date strings are parsed to numeric)
.. can now add formulas to LTM as well as adding more
functions that may be useful (conditionals, maths
spring to mind first).
.. will rerun as ride selection changes.
.. but will never stop until cleared so use at your
own risk, as will run EVERY time you select a
different ride.
.. introduce concept of configChanged(what) to
pass details of what config has been changed
.. fixed zones changes to re-read after write
to correct the save twice to get changes to
zones bug.
.. next parts need to spot changes (part 2) and
then action appropriately (part 3)
.. to enable queries such as;
Date > "2014/02/28"
for rides since 28th February 2014
.. might be useful to allow localised dates
but using this makes it easier to document !
.. a query like today > "1900/01/01" will pass
on all rides, but user being an idiot.
.. use "Date" and "Today" which evaluate to the number
of days since 1st Jan 1900.
.. so a filter for the last 90 days would be:
(Today - Date) < 30
.. will add date strings next.
lts(metric), sts(metric), sb(metric) all return the PMC
value for the metric in question for the date of the ride
and therefore allow you to select rides based upon PMC data.
e.g. sb(TSS) > -5
could be considered a way of looking for rides when you were
in a well tapered state, or at least, when you should be able
to perform well.
or, e.g. lts(TSS) > 100
could be a way of looking for rides at peak form (if 100 is
a peak CTL for you).
.. used to create a 'specification' against which we match
a rideitem when plotting etc.
.. so rather than passing an array/vector/list of data when
calling a plot, we pass the 'specification' to use instead.
.. the plots themselves should now iterate across the shared
ride cache only plotting the items that pass the specification.
.. this should reduce memory usage and increase performance.
.. no longer uses metricDB but traverses in memory cache
and should be a lot faster.
NOTE: the line endings for DataFilter.{cpp,h} have been
changed from dos to unix format which has resulted in
the entire file being changed, apologies but needed to
clean that up anyway.
.. isRun is a bool, so isRun = 0 or isRun = 1
will filter for runs.
.. note isRun does more than just look at sport
it also checks if there are running data series
in the file and may extend to more over time
... have the same consistent handling for (TM) at all visible places
... do not allow Translation of BikeScore (since it's a TM and might
cause unexpected behavior)
... Have (TM) sign everwhere visible - only in Searches just use
"BikeScore" as Symbol
... allow/use only internal field names (delivered by Column Chooser) in
Data Filter expressions
... multipe tr()
(cherry picked from commit bc4164adab74dd82c0a0307d7d0fbb736f95ef0d)
Porting the codebase to QT 5 (5.2) to get the
latest bug fixes, performance and improved platform
support.
This first part is to fixup the codebase to compile
on Qt 5, but some aspects have been broken (video).
The second part is to migrate from Qwt 6.0.1 to the
latest Qwt for multiaxis support.
The third part will be to fixup any platform specific
issues or issues identified at runtime.
Peak aPower durations now computed and cached;
* updated RideFileCache to work with aPower
* CP curve now allows you to plot aPower
* LTM plot allows you to plot aPower peaks
* DataFilter allows 'best(apower, duration)' function
Added static functions to ridefilecache
to get best and tiz values for series and duration
or zones and glued them in to the datafilter code
recently added.
It uses seek (via QDataStream::skipRawData) and is
quite fast on my Linux development PC.
We now need to update the LTM settings dialogs to
the new mockups so we can plot custom durations for
peak power / NP etc too.
NOTE: Not tried on Windows / Mac, so may not be quite
so fast there, will need to check.
To try this out, in the search filter box type:
best(power, 3600) > 250
to filter only those rides where the best hour
power is greater than 250 watts. It should
return almost instantly.
Fixes the crash but the eval code is a bit of a
fuck up. It was evaluating children instead of
using recursion, and now we have lots more types
and expressions its all a bit of a mess.
Will need to rewrite to use recursion and it will
be a lot simpler!
Will now allow users to specify a formula using
the * / + - ^ operators. This can be used to specify
values (e.g. TSS > 100*2) or to calculate a totally
new user metric (e.g. Average_Heart_Rate / RPE).
Also added two functions as well;
1. best (series, duration) which returns the best value
for the series of the given
duration in seconds.
Where series is one of; power,
hr, cadence, speed, torque,
xpower, np.
2. tiz (series, zone) which returns the time spent
in the given series and zone
Where series is either power
or hr and zone is 1-10.
NOTE:
We know need to add the functions for retrieving the best and
tiz values from the ridefilecache without having to read the
entire file (ie. read the header and use lseek).
Decoupled classes from MainWindow to reference Context
and Athlete (and introduced a couple of new headers).
We no longer pass around a MainWindow pointer to children
but pass a context instead.
There are still a few pieces left in MainWindow that need
to move to a better place;
* Setting/clearing filter selection
* Working with Intervals
* Adding/Deleting Rides
* Save on Exit
As mentioned previously there are lots of other parts to
this refactor left to do;
* break MainWindow Gui elements into Toolbar and Views
* migrate from RideItem and Ridelist to ActivityCollection
and Activity classes that are not tied into gui elements.
* introduce Application Context and AthleteCollection
Breaking the MainWindow 'god object' into
separate classes for Athlete and Context.
Further updates will need to;
- break MainWindow Gui elements into Toolbar and Views
- migrate from RideItem and Ridelist to ActivityCollection
and Activity classes that are not tied into gui elements.
- introduce Application Context and AthleteCollection
Once these are done we will be in a position to decouple
most classes from mainwindow and also introduce tabbed
athletes.