adding manually calculated fitness and fatigue and form
This commit is contained in:
@@ -738,6 +738,13 @@ class FitnessFitForm(forms.Form):
|
|||||||
initial='rscore',
|
initial='rscore',
|
||||||
label='Workload Metric')
|
label='Workload Metric')
|
||||||
|
|
||||||
|
# temporary
|
||||||
|
k1 = forms.FloatField(required=True,initial=1.0,
|
||||||
|
label='k1')
|
||||||
|
k2 = forms.FloatField(required=True,initial=1.0,
|
||||||
|
label='k2')
|
||||||
|
p0 = forms.IntegerField(required=True,initial=100,label='Unfit Performance')
|
||||||
|
|
||||||
mode = forms.ChoiceField(required=True,
|
mode = forms.ChoiceField(required=True,
|
||||||
choices=modechoices,
|
choices=modechoices,
|
||||||
initial='rower',
|
initial='rower',
|
||||||
@@ -745,7 +752,9 @@ class FitnessFitForm(forms.Form):
|
|||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
fields = ['startdate','enddate','mode','fitnesstest','kfitness','kfatigue','metricchoice']
|
fields = ['startdate','enddate','mode','fitnesstest',
|
||||||
|
'kfitness','kfatigue','metricchoice',
|
||||||
|
'k1','k2','p0']
|
||||||
|
|
||||||
class SessionDateShiftForm(forms.Form):
|
class SessionDateShiftForm(forms.Form):
|
||||||
shiftstartdate = forms.DateField(
|
shiftstartdate = forms.DateField(
|
||||||
|
|||||||
@@ -1528,18 +1528,23 @@ def interactive_forcecurve(theworkouts,workstrokesonly=True,plottype='scatter'):
|
|||||||
return [script,div,js_resources,css_resources]
|
return [script,div,js_resources,css_resources]
|
||||||
|
|
||||||
def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None,
|
def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None,
|
||||||
enddate=None,kfitness=42,kfatigue=7,fitnesstest=20):
|
enddate=None,kfitness=42,kfatigue=7,fitnesstest=20,
|
||||||
|
metricchoice='rscore',
|
||||||
|
k1=1,k2=1,p0=100):
|
||||||
|
|
||||||
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
|
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
|
||||||
|
|
||||||
dates = []
|
dates = []
|
||||||
testpower = []
|
testpower = []
|
||||||
|
fatigues = []
|
||||||
|
fitnesses = []
|
||||||
|
|
||||||
workouts = workouts.order_by('date')
|
workouts = workouts.order_by('date')
|
||||||
data = []
|
data = []
|
||||||
|
|
||||||
fitnesstestsecs = fitnesstest*60
|
fitnesstestsecs = fitnesstest*60
|
||||||
|
|
||||||
|
# create CP data
|
||||||
for w in workouts:
|
for w in workouts:
|
||||||
cpfile = 'media/cpdata_{id}.parquet.gz'.format(id=w.id)
|
cpfile = 'media/cpdata_{id}.parquet.gz'.format(id=w.id)
|
||||||
try:
|
try:
|
||||||
@@ -1559,6 +1564,7 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None,
|
|||||||
errfunc = lambda pars,x,y: fitfunc(pars,x)-y
|
errfunc = lambda pars,x,y: fitfunc(pars,x)-y
|
||||||
|
|
||||||
for w in workouts:
|
for w in workouts:
|
||||||
|
# Create CP data point for date range
|
||||||
ids = [w.id for w in workouts.filter(date__gte=w.date-datetime.timedelta(days=kfitness),
|
ids = [w.id for w in workouts.filter(date__gte=w.date-datetime.timedelta(days=kfitness),
|
||||||
date__lte=w.date)]
|
date__lte=w.date)]
|
||||||
|
|
||||||
@@ -1590,12 +1596,32 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None,
|
|||||||
dates.append(datetime.datetime.combine(w.date,datetime.datetime.min.time()))
|
dates.append(datetime.datetime.combine(w.date,datetime.datetime.min.time()))
|
||||||
testpower.append(powertest)
|
testpower.append(powertest)
|
||||||
|
|
||||||
|
# create Fitness and Fatigue number
|
||||||
|
fatigue = 0
|
||||||
|
fitness = 0
|
||||||
|
previousworkouts = workouts.filter(date__lte=w.date)
|
||||||
|
for ww in previousworkouts:
|
||||||
|
delta = (w.date-ww.date).days
|
||||||
|
weight = getattr(ww,metricchoice)
|
||||||
|
fatigue += weight*math.exp(-delta/kfatigue)
|
||||||
|
fitness += weight*math.exp(-delta/kfitness)
|
||||||
|
|
||||||
|
fatigues.append(fatigue)
|
||||||
|
fitnesses.append(fitness)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
df = pd.DataFrame({
|
df = pd.DataFrame({
|
||||||
'date':dates,
|
'date':dates,
|
||||||
'testpower':testpower,
|
'testpower':testpower,
|
||||||
|
'fatigue':fatigues,
|
||||||
|
'fitness':fitnesses,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
df['fatigue'] = k2*df['fatigue']
|
||||||
|
df['fitness'] = p0+k1*df['fitness']
|
||||||
|
df['form'] = df['fitness']-df['fatigue']
|
||||||
|
|
||||||
|
|
||||||
df.sort_values(['date'],inplace=True)
|
df.sort_values(['date'],inplace=True)
|
||||||
|
|
||||||
@@ -1606,14 +1632,14 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
source = ColumnDataSource(
|
source = ColumnDataSource(
|
||||||
data = dict(
|
data = dict(
|
||||||
testpower = df['testpower'],
|
testpower = df['testpower'],
|
||||||
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'],
|
||||||
|
fatigue = df['fatigue'],
|
||||||
|
form = df['form'],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1654,6 +1680,13 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None,
|
|||||||
plot.circle('date','testpower',source=source,fill_color='green',size=10,
|
plot.circle('date','testpower',source=source,fill_color='green',size=10,
|
||||||
legend_label='{fitnesstest} min power'.format(fitnesstest=fitnesstest))
|
legend_label='{fitnesstest} min power'.format(fitnesstest=fitnesstest))
|
||||||
|
|
||||||
|
plot.line('date','fitness',source=source,color='yellow',
|
||||||
|
legend_label='fitness')
|
||||||
|
plot.line('date','fatigue',source=source,color='red',
|
||||||
|
legend_label='fatigue')
|
||||||
|
plot.line('date','form',source=source,color='green',
|
||||||
|
legend_label='form')
|
||||||
|
|
||||||
plot.xaxis.axis_label = 'Date'
|
plot.xaxis.axis_label = 'Date'
|
||||||
plot.yaxis.axis_label = 'Power (W)'
|
plot.yaxis.axis_label = 'Power (W)'
|
||||||
|
|
||||||
|
|||||||
@@ -1555,6 +1555,12 @@ def fitness_from_cp_view(request,userid=0,mode='rower',
|
|||||||
kfitness = 42
|
kfitness = 42
|
||||||
kfatigue = 7
|
kfatigue = 7
|
||||||
fitnesstest = 20
|
fitnesstest = 20
|
||||||
|
metricchoice = 'rscore'
|
||||||
|
|
||||||
|
# temp fit parameters
|
||||||
|
k1 = 1
|
||||||
|
k2 = 1
|
||||||
|
p0 = 100.
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = FitnessFitForm(request.POST)
|
form = FitnessFitForm(request.POST)
|
||||||
@@ -1565,6 +1571,11 @@ def fitness_from_cp_view(request,userid=0,mode='rower',
|
|||||||
kfitness = form.cleaned_data['kfitness']
|
kfitness = form.cleaned_data['kfitness']
|
||||||
kfatigue = form.cleaned_data['kfatigue']
|
kfatigue = form.cleaned_data['kfatigue']
|
||||||
fitnesstest = form.cleaned_data['fitnesstest']
|
fitnesstest = form.cleaned_data['fitnesstest']
|
||||||
|
metricchoice = form.cleaned_data['metricchoice']
|
||||||
|
# temporary manual "fit" parameters
|
||||||
|
k1 = form.cleaned_data['k1']
|
||||||
|
k2 = form.cleaned_data['k2']
|
||||||
|
p0 = form.cleaned_data['p0']
|
||||||
else:
|
else:
|
||||||
form = FitnessFitForm()
|
form = FitnessFitForm()
|
||||||
|
|
||||||
@@ -1584,6 +1595,8 @@ def fitness_from_cp_view(request,userid=0,mode='rower',
|
|||||||
kfitness=kfitness,
|
kfitness=kfitness,
|
||||||
kfatigue=kfatigue,
|
kfatigue=kfatigue,
|
||||||
fitnesstest=fitnesstest,
|
fitnesstest=fitnesstest,
|
||||||
|
metricchoice=metricchoice,
|
||||||
|
k1=k1,k2=k2,p0=p0
|
||||||
)
|
)
|
||||||
|
|
||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
|
|||||||
Reference in New Issue
Block a user