Private
Public Access
1
0

Adding gold medal standard to performance chart (optional)

This commit is contained in:
Sander Roosendaal
2021-01-01 16:51:00 +01:00
parent 0e9944044d
commit 87b6684465
5 changed files with 74 additions and 13 deletions

View File

@@ -739,6 +739,9 @@ class PerformanceManagerForm(forms.Form):
doform = forms.BooleanField(required=False,initial=False, doform = forms.BooleanField(required=False,initial=False,
label='Freshness') label='Freshness')
showtests = forms.BooleanField(required=False,initial=False,
label='Show my best workouts')
class FitnessFitForm(forms.Form): class FitnessFitForm(forms.Form):
startdate = forms.DateField( startdate = forms.DateField(
initial=timezone.now()-datetime.timedelta(days=365), initial=timezone.now()-datetime.timedelta(days=365),

View File

@@ -120,6 +120,7 @@ def build_goldmedalstandards(workouts,kfitness):
testduration = [] testduration = []
fatigues = [] fatigues = []
fitnesses = [] fitnesses = []
impulses = []
data = [] data = []
goldmedalstandards = [] goldmedalstandards = []
@@ -185,8 +186,9 @@ def build_goldmedalstandards(workouts,kfitness):
fatigues.append(np.nan) fatigues.append(np.nan)
fitnesses.append(np.nan) fitnesses.append(np.nan)
impulses.append(np.nan)
return dates, testpower, testduration, fatigues, fitnesses return dates, testpower, testduration, fatigues, fitnesses,impulses
def get_testpower(workouts,fitnesstestsecs,kfitness): def get_testpower(workouts,fitnesstestsecs,kfitness):
@@ -1762,24 +1764,55 @@ def getfatigues(
return fatigues,fitnesses,dates,testpower,testduration,impulses return fatigues,fitnesses,dates,testpower,testduration,impulses
def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7, def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7,
metricchoice='trimp',doform=False,dofatigue=False): metricchoice='trimp',doform=False,dofatigue=False,
showtests=False):
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
TOOLS2 = 'box_zoom,hover' TOOLS2 = 'box_zoom,hover'
fatigues = []
fitnesses = []
dates = []
testpower = []
testduration = []
modelchoice = 'coggan' modelchoice = 'coggan'
p0 = 0 p0 = 0
k1 = 1 k1 = 1
k2 = 1 k2 = 1
dates = []
testpower = []
fatigues = []
fitnesses = []
testduration = []
if showtests:
workouts = Workout.objects.filter(user=user.rower,date__gte=startdate,
date__lte=enddate,
workouttype__in=mytypes.rowtypes,
duplicate=False)
dates,testpower,testduration,fatigues,fitnesses,impulses = build_goldmedalstandards(
workouts,kfitness
)
df = pd.DataFrame({
'date':dates,
'testpower':testpower,
'testduration':testduration,
'fatigue':fatigues,
'fitness':fitnesses,
'impulse':impulses,
})
df.sort_values(['date'],inplace=True)
df['testdup'] = df['testpower'].shift(1)
df['testpower'] = df.apply(lambda x: newtestpower(x),axis=1)
try:
df['testpower'].iloc[-1] = df['testdup'].iloc[-1]
except IndexError:
pass
dates = [d for d in df['date']]
testpower = df['testpower'].values.tolist()
fatigues = df['fatigue'].values.tolist()
fitnesses = df['fitness'].values.tolist()
testduration = df['testduration'].values.tolist()
fatigues,fitnesses,dates,testpower,testduration,impulses = getfatigues(fatigues, fatigues,fitnesses,dates,testpower,testduration,impulses = getfatigues(fatigues,
fitnesses, fitnesses,
@@ -1794,6 +1827,7 @@ def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7,
df = pd.DataFrame({ df = pd.DataFrame({
'date':dates, 'date':dates,
'testpower':testpower, 'testpower':testpower,
'testduration': testduration,
'fatigue':fatigues, 'fatigue':fatigues,
'fitness':fitnesses, 'fitness':fitnesses,
'impulse':impulses, 'impulse':impulses,
@@ -1819,6 +1853,7 @@ def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7,
source = ColumnDataSource( source = ColumnDataSource(
data = dict( data = dict(
testpower = df['testpower'], testpower = df['testpower'],
testduration = df['testduration'].apply(lambda x:totaltime_sec_to_string(x,shorten=True)),
date = df['date'], date = df['date'],
fdate = df['date'].map(lambda x: x.strftime('%d-%m-%Y')), fdate = df['date'].map(lambda x: x.strftime('%d-%m-%Y')),
fitness = df['fitness'], fitness = df['fitness'],
@@ -1881,8 +1916,9 @@ def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7,
yaxlabel = 'Fitness' yaxlabel = 'Fitness'
#plot.circle('date','testpower',source=source,fill_color='green',size=10, if showtests:
# legend_label=legend_label.format(fitnesstest=fitnesstest)) plot.circle('date','testpower',source=source,fill_color='green',size=10,
legend_label='Your best workouts')
plot.xaxis.axis_label = None plot.xaxis.axis_label = None
plot.yaxis.axis_label = yaxlabel plot.yaxis.axis_label = yaxlabel
@@ -1937,6 +1973,7 @@ def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7,
linked_crosshair = CrosshairTool(dimensions='height') linked_crosshair = CrosshairTool(dimensions='height')
hover.tooltips = OrderedDict([ hover.tooltips = OrderedDict([
#(legend_label,'@testpower'), #(legend_label,'@testpower'),
('Date','@fdate'), ('Date','@fdate'),
@@ -1946,7 +1983,17 @@ def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7,
('Impulse','@impulse{int}') ('Impulse','@impulse{int}')
]) ])
if showtests:
hover.tooltips = OrderedDict([
#(legend_label,'@testpower'),
('Date','@fdate'),
(fitlabel,'@fitness{int}'),
(fatiguelabel,'@fatigue{int}'),
(formlabel,'@form{int}'),
('Impulse','@impulse{int}'),
('Gold Medal Score','@testpower{int}'),
('Test', '@testduration'),
])
plot2 = Figure(tools=TOOLS2,x_axis_type='datetime', plot2 = Figure(tools=TOOLS2,x_axis_type='datetime',
plot_width=900,plot_height=150, plot_width=900,plot_height=150,
@@ -2007,7 +2054,7 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None,
workouts,fitnesstestsecs,kfitness workouts,fitnesstestsecs,kfitness
) )
else: else:
dates,testpower, testduration,fatigues,fitnesses = build_goldmedalstandards( dates,testpower, testduration,fatigues,fitnesses,impulses = build_goldmedalstandards(
workouts,kfitness workouts,kfitness
) )
# create CP data # create CP data

View File

@@ -891,6 +891,7 @@ class Rower(models.Model):
kfatigue = models.IntegerField(default=7,verbose_name='Fatigue Time Decay Constant (days)') kfatigue = models.IntegerField(default=7,verbose_name='Fatigue Time Decay Constant (days)')
showfit = models.BooleanField(default=False) showfit = models.BooleanField(default=False)
showfresh = models.BooleanField(default=False) showfresh = models.BooleanField(default=False)
showtests = models.BooleanField(default=False)
pw_ut2 = models.IntegerField(default=124,verbose_name="UT2 Power") pw_ut2 = models.IntegerField(default=124,verbose_name="UT2 Power")
pw_ut1 = models.IntegerField(default=171,verbose_name="UT1 Power") pw_ut1 = models.IntegerField(default=171,verbose_name="UT1 Power")

View File

@@ -112,6 +112,11 @@
on the left. The model balances out after a few weeks of regular training, so don't on the left. The model balances out after a few weeks of regular training, so don't
make this chart shorter than a few months. make this chart shorter than a few months.
</p> </p>
<p>
Optionally, the chart shows you workouts that represent your best performance for that period.
We automatically detect hard workout segments and tests and compare them to world class
("Gold Medal") standards for your gender, weight and age category.
</p>
<p> <p>
For this chart to reflect your fitness and freshness, it is important to have all workouts on For this chart to reflect your fitness and freshness, it is important to have all workouts on
Rowsandall.com. You can automatically import workouts from other fitness platforms. Change Rowsandall.com. You can automatically import workouts from other fitness platforms. Change

View File

@@ -1567,6 +1567,7 @@ def performancemanager_view(request,userid=0,mode='rower',
usegoldmedalstandard = False usegoldmedalstandard = False
doform = therower.showfresh doform = therower.showfresh
dofatigue = therower.showfit dofatigue = therower.showfit
showtests = therower.showtests
if request.method == 'POST': if request.method == 'POST':
form = PerformanceManagerForm(request.POST) form = PerformanceManagerForm(request.POST)
@@ -1576,13 +1577,16 @@ def performancemanager_view(request,userid=0,mode='rower',
metricchoice = form.cleaned_data['metricchoice'] metricchoice = form.cleaned_data['metricchoice']
dofatigue = form.cleaned_data['dofatigue'] dofatigue = form.cleaned_data['dofatigue']
doform = form.cleaned_data['doform'] doform = form.cleaned_data['doform']
showtests = form.cleaned_data['showtests']
therower.showfresh = doform therower.showfresh = doform
therower.showfatigue = dofatigue therower.showfatigue = dofatigue
therower.showtests = showtests
therower.save() therower.save()
else: else:
form = PerformanceManagerForm(initial={ form = PerformanceManagerForm(initial={
'doform':doform, 'doform':doform,
'dofatigue':dofatigue, 'dofatigue':dofatigue,
'showtests':showtests,
}) })
script, thediv, endfitness, endfatigue, endform = performance_chart( script, thediv, endfitness, endfatigue, endform = performance_chart(
@@ -1592,6 +1596,7 @@ def performancemanager_view(request,userid=0,mode='rower',
metricchoice = metricchoice, metricchoice = metricchoice,
doform = doform, doform = doform,
dofatigue = dofatigue, dofatigue = dofatigue,
showtests = showtests,
) )
breadcrumbs = [ breadcrumbs = [
@@ -1680,7 +1685,7 @@ def fitness_from_cp_view(request,userid=0,mode='rower',
date__lte=enddate, date__lte=enddate,
workouttype__in=mytypes.rowtypes, workouttype__in=mytypes.rowtypes,
duplicate=False) duplicate=False)
script,thediv = fitnessfit_chart( script,thediv = fitnessfit_chart(