Added a few new training stress metrics whilst discussing
and working on a multicomponent view of training stress.
This is all a wip falling out of discussions around stress
metrics beyond the old TSS/BikeScore models.
For now this just includes;
1. Aerobic Training Impact Scoring System on PM/PMC
2. Work (Kj) above/below CP on PM/PMC
3. Aerobic TISS on the Ride Plot
There is lots more to come; specifically around Anaerobic TISS,
looking again at polarised training and personalised training stress
based upon the individual's CP model.
.. need to think about what we're trying to achieve with this
but for assessing TT efforts we can see how far away from
a constant load the ride was.
Its just computed as average power as a percentage of max power.
.. the calculation assumed 1s recording (or was just wrong)
joules are now calculated properly, this is especially
important for SRM recordings of 0.5s samples
You can now compare seasons / date ranges across or between
athletes on the LTM charts.
This is only shown on the stack chart as we need one chart
per data series - in a similar vein to the AllPlot chart.
There are some tidy ups left to do over the next few days;
- Data table needs updating to support compare mode
- Event markers need to be shown and in the right color
- PMC curve data is slow, needs some kind of optimisation
- The tooltip is missing and needs to be put back
- Ensure the new stack frame looks correct when using a
dark plot background (or anything other than white)
- Consider how to handle zooming when there is only one
data series and hence only one chart for compare
For maximum W' capacity expended i.e. Min W'bal
expressed as a percentage of W'.
So if W' is 20 kJ and W'bal is 2kJ then 18 kJ
have been expended, which when expressed as a
percentage of W' (18/20 %) would be;
Max W' Exp of 90%
I also cleaned up a few extra instances of WPrime
being created when calculatinf metrics which was
not a big deal for the Metric refresh but would make
interval metrics painful.
.. don't rely on WPrime to compute it, its pretty simple
to compute as long as CP is set
.. add to the summary totals so always there to compare
against the total work
The final part (and one of the reasons) for the mainwindow
refactoring -- we now support tabbed athletes rather than
having a new mainwindow for each athlete opened.
Context is saved/restored and there are new functions for
opening and closing tabs and windows of tabs.
The tabbar itself is fugly -- the next few days will spend
some time looking at making it prettier on Linux/Win and
more native on Mac (see MMTabBar).
.. let the user choose metadata texts to filter
by value in the sidebar.
Note there are issues;
1. the value lists are not updated automatically when
rides are updated or imported and values are added
or removed.
2. it only works with shorttext metadata fields, we might
choose to add numeric etc later.
3. it would be nice to get an indication of how many
activities contain the value and maybe even sort
by count.
Looks at the max and min (non-zero) power values and
uses the difference between them to calculate a fatigue
index as a percentage.
i.e.
FI = (maxP - minP) / maxP * 100.00;
This is really only useful for targetted intervals as for
most riding there will always be a period of time where
the rider coasts or takes it easy.
We may look to improve it by smoothing or comparing to the
average power instead of minimum power.
Fixup crashes and major issues created by porting
to QT5. These have included;
* Fix CP plot log scale
* AllPlot axes and tooltip
* DBAccess prepare/bind bug
* LTMSettings crash
* LTMWindow zoomer/picker crash
* LTMPlot axes hack
There are still issues remaining but we can start
working through them at leisure -- the product now
builds and runs.
Added an average aPower metric.
I also and found and fixed a couple of bugs along the way;
* intervals create a ridefile and need to explicitly call
recalculateDerivedMetrics()
* the aPower calculation was using the calculated vo2max
percentage the wrong way around (!)
It TREBLES the amount of time required to refresh the
metrics, so will need to be optmised before 3.1 is released.
But it should only need to run once.
I've also added a 'RideMetric::Low' type which we could
also apply to weight.
The current TIZ metrics only allow you to chart the
absolute time in zone. Over longer periods it can be
helpful to look at the overall ratio of intensities
trained at.
There still some assert left in the code, but removed
a fair number of the examples where, its just as easy
to handle the condition gracefully, without crashing.
By 3.1 we will have eradicated assert from the code.
A bit of a mix of stuff, but basically the Athlete
class has sql stuff in it, that DBAccess used but
also referenced a session number in MainWindow.
Removed the interdependency and moved all code to do
with DB to DBAccess and out of MainWindow and Athlete.
At the same time needed to clean up a bit of memory
management and so introduced a MainWindow and Athlete
destructor.
We are now ready to do refactor part 4 to split MainWindow
into a new View class (that will be in each tab).
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.
The call to RideFile::getWeight() in RideFileCache
computation ends up with a call the read the measures
table in the DB. This is BAD since it is called from
a thread.
We now call getWeight() in the metric aggregator before
launching the ridefilecache computation -- this will cache
the weight and avoid db access.
I've also removed the duplicate code in the w/kg metric code
too and it should be marginally faster at computing metrics
now.
BIG THANKS TO ILJA BOOIJ FOR HIGHLIGHTING THIS, DESPITE MY
INITIAL SCEPTICISM. I OWE HIM A PINT (OR TWO) :)
Fixes#604
Update to the histogram plot to now plot long term metrics.
It enables you to plot distribution of say, Intensity Factor
for a season or cycle.
You can select the y-axis metric too, so rather than just
plotting duration you could plot say, TSS accumulated for
different ride intensities.
Fixes#560
1. Use the whitespace analyzer so its easier to search for
tokens that are a mix of letters and numbers e.g. workout
codes and TT route names.
2. Search as you type. Since we have very small collections
to search across (typically no more than a couple of thousand)
there is no major overhead in searching as you type.
3. Search all texts by default not just the Notes field. This is
a more appropriate default and is less likely to confuse new
users. In addition, it is most likely what most users want to
do anyway.
Last commit added a new metric but didn't increment the DBAccess
DB schema version, causing DB functions to break. This patch just
increments the version to ensure the DB is rebuilt to include
the new metric.
A few months ago I commented out the calculation of metrics
for manual ride files. This was a hack to avoid fixing the code
to handle metric calculations from overrides where there are no
data points.
This annoyingly meant that the 'rides' metric was zero for manual
ride files, and any derived metrics similarly were zero.
This patch fixes that.
This might be meaningless for actual analysis, but helps to match numbers
of devices, that exclude time with zero power from the average
calculation.
While it's controversal to be usefull, this leaves the choice to the user.