190 lines
4.5 KiB
Python
190 lines
4.5 KiB
Python
|
|
from rowers.utils import lbstoN
|
|
import numpy as np
|
|
import yaml
|
|
import pandas as pd
|
|
from scipy import optimize
|
|
from django.utils import timezone
|
|
from polars import String, Int32, Float64
|
|
|
|
from math import log10, log2
|
|
from rowers.mytypes import otwtypes, otetypes
|
|
|
|
nometrics = [
|
|
'originalvelo',
|
|
# 'cumdist',
|
|
'strokes_slsh_min',
|
|
' WorkPerStroke (joules)',
|
|
' activityIdx',
|
|
' lapIdx',
|
|
# ' pointIdx',
|
|
' WorkoutType',
|
|
' IntervalType',
|
|
' WorkoutState',
|
|
' RowingState',
|
|
' WorkoutDurationType',
|
|
' WorkoutIntervalCount',
|
|
'ergpace',
|
|
'ref',
|
|
'id',
|
|
'deltat',
|
|
'workoutid',
|
|
'totalangle',
|
|
'hr_bottom',
|
|
'Position',
|
|
'Extensions',
|
|
'GPS Speed',
|
|
'Split (IMP)',
|
|
'Speed (IMP)',
|
|
'driveenergy',
|
|
'Distance/Stroke (IMP)',
|
|
'Distance/Stroke (GPS)',
|
|
'Distance (IMP)',
|
|
'equivergpower',
|
|
'cum_dist.1'
|
|
]
|
|
|
|
with open("rowingmetrics.yaml", "r") as file:
|
|
td = yaml.safe_load(file)
|
|
|
|
rowingmetrics = tuple(
|
|
(key, value)
|
|
for key, value in td.items()
|
|
)
|
|
|
|
|
|
|
|
metricsdicts = {}
|
|
for key, dict in rowingmetrics:
|
|
metricsdicts[key] = dict
|
|
|
|
|
|
|
|
metricsgroups = list(set([d['group'] for n, d in rowingmetrics]))
|
|
|
|
dtypes = {}
|
|
|
|
for name, d in rowingmetrics:
|
|
if d['numtype'] == 'float':
|
|
dtypes[name] = float
|
|
elif d['numtype'] == 'int': # pragma: no cover
|
|
dtypes[name] = int
|
|
|
|
axesnew = [
|
|
(name, d['verbose_name'], d['ax_min'], d['ax_max'], d['type']) for name, d in rowingmetrics
|
|
]
|
|
|
|
axes = tuple(axesnew+[('None', '<None>', 0, 1, 'basic')])
|
|
|
|
axlabels = {ax[0]: ax[1] for ax in axes}
|
|
|
|
yaxminima = {ax[0]: ax[2] for ax in axes}
|
|
|
|
yaxmaxima = {ax[0]: ax[3] for ax in axes}
|
|
|
|
|
|
def get_yaxminima(r, metric, mode):
|
|
if metric == 'pace':
|
|
if mode in otetypes:
|
|
return r.slowpaceerg
|
|
else:
|
|
return r.slowpaceotw
|
|
|
|
return yaxminima[metric]
|
|
|
|
|
|
def get_yaxmaxima(r, metric, mode):
|
|
if metric == 'pace':
|
|
if mode in otetypes:
|
|
return r.fastpaceerg
|
|
else:
|
|
return r.fastpaceotw
|
|
|
|
return yaxmaxima[metric]
|
|
|
|
|
|
defaultfavoritecharts = (
|
|
{
|
|
'yparam1': 'pace',
|
|
'yparam2': 'spm',
|
|
'xparam': 'time',
|
|
'plottype': 'line',
|
|
'workouttype': 'both',
|
|
'reststrokes': True,
|
|
'notes': """This chart shows your pace and stroke rate versus time. """,
|
|
},
|
|
{
|
|
'yparam1': 'pace',
|
|
'yparam2': 'hr',
|
|
'xparam': 'time',
|
|
'plottype': 'line',
|
|
'workouttype': 'both',
|
|
'reststrokes': True,
|
|
'notes': """This chart shows your pace and heart rate versus time.
|
|
Heart rate values will be shown only when it is in your data, i.e.
|
|
in case you recorded your heart rate during your workout""",
|
|
},
|
|
{
|
|
'yparam1': 'distanceperstroke',
|
|
'yparam2': 'hr',
|
|
'xparam': 'time',
|
|
'plottype': 'line',
|
|
'workouttype': 'otw',
|
|
'reststrokes': True,
|
|
'notes': """This chart shows the Distance covered per stroke, and your
|
|
heart rate versus time. """,
|
|
},
|
|
{
|
|
'yparam1': 'driveenergy',
|
|
'yparam2': 'hr',
|
|
'xparam': 'time',
|
|
'plottype': 'line',
|
|
'workouttype': 'ote',
|
|
'reststrokes': True,
|
|
'notes': """This chart shows the Work per Stroke and your heart rate
|
|
plotted versus time. """,
|
|
},
|
|
{
|
|
'yparam1': 'distanceperstroke',
|
|
'yparam2': 'None',
|
|
'xparam': 'spm',
|
|
'plottype': 'scatter',
|
|
'workouttype': 'otw',
|
|
'reststrokes': True,
|
|
'notes': """This chart shows the Distance per Stroke versus stroke
|
|
stroke rate. You should see a steady decline of the Distance per Stroke
|
|
as you increase stroke rate. Typical values are > 10m for steady state
|
|
dropping to 8m for race pace in the single.""",
|
|
},
|
|
{
|
|
'yparam1': 'driveenergy',
|
|
'yparam2': 'None',
|
|
'xparam': 'spm',
|
|
'plottype': 'scatter',
|
|
'workouttype': 'ote',
|
|
'reststrokes': True,
|
|
'notes': """This chart shows the Work per Stroke versus Stroke Rate.
|
|
This value should be fairly constant across all stroke rates.""",
|
|
},
|
|
)
|
|
|
|
|
|
def calc_trimp(df, sex, hrmax, hrmin, hrftp): # pragma: no cover
|
|
if sex == 'male':
|
|
f = 1.92
|
|
else:
|
|
f = 1.67
|
|
|
|
dt = df['time'].diff()/6.e4
|
|
|
|
hrr = (df['hr']-hrmin)/(hrmax-hrmin)
|
|
hrrftp = (hrftp-hrmin)/float(hrmax-hrmin)
|
|
trimp1hr = 60*hrrftp*0.64*np.exp(f*hrrftp)
|
|
|
|
trimpdata = dt*hrr*0.64*np.exp(f*hrr)
|
|
trimp = trimpdata.sum()
|
|
|
|
hrtss = 100*trimp/trimp1hr
|
|
|
|
return trimp, hrtss
|