Merge branch 'feature/fitnesschart' into develop
This commit is contained in:
@@ -1092,6 +1092,9 @@ def workout_goldmedalstandard(workout):
|
|||||||
return workout.goldmedalstandard,workout.goldmedalseconds
|
return workout.goldmedalstandard,workout.goldmedalseconds
|
||||||
if workout.workouttype in rowtypes:
|
if workout.workouttype in rowtypes:
|
||||||
goldmedalstandard,goldmedalseconds = calculate_goldmedalstandard(workout.user,workout)
|
goldmedalstandard,goldmedalseconds = calculate_goldmedalstandard(workout.user,workout)
|
||||||
|
if workout.workouttype in otwtypes:
|
||||||
|
factor = 100./(100.-workout.user.otwslack)
|
||||||
|
goldmedalstandard = goldmedalstandard*factor
|
||||||
workout.goldmedalstandard = goldmedalstandard
|
workout.goldmedalstandard = goldmedalstandard
|
||||||
workout.goldmedalseconds = goldmedalseconds
|
workout.goldmedalseconds = goldmedalseconds
|
||||||
workout.save()
|
workout.save()
|
||||||
|
|||||||
@@ -739,6 +739,7 @@ class PerformanceManagerForm(forms.Form):
|
|||||||
doform = forms.BooleanField(required=False,initial=False,
|
doform = forms.BooleanField(required=False,initial=False,
|
||||||
label='Freshness')
|
label='Freshness')
|
||||||
|
|
||||||
|
|
||||||
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),
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import itertools
|
|||||||
from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc
|
from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc
|
||||||
from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation, Band
|
from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation, Band
|
||||||
|
|
||||||
|
import arrow
|
||||||
|
|
||||||
from rowers.utils import myqueue, totaltime_sec_to_string
|
from rowers.utils import myqueue, totaltime_sec_to_string
|
||||||
import django_rq
|
import django_rq
|
||||||
queue = django_rq.get_queue('default')
|
queue = django_rq.get_queue('default')
|
||||||
@@ -102,46 +104,104 @@ import rowers.datautils as datautils
|
|||||||
|
|
||||||
from pandas.core.groupby.groupby import DataError
|
from pandas.core.groupby.groupby import DataError
|
||||||
|
|
||||||
|
def newtestpower(x):
|
||||||
|
try:
|
||||||
|
if abs(x['testpower'] - x['testdup']) < 1:
|
||||||
|
return np.nan
|
||||||
|
except (AttributeError,TypeError):
|
||||||
|
return np.nan
|
||||||
|
|
||||||
|
|
||||||
|
return x['testpower']
|
||||||
|
|
||||||
|
def newtestpowerid(x):
|
||||||
|
try:
|
||||||
|
if np.isnan(x['testpower']):
|
||||||
|
return np.nan
|
||||||
|
except (AttributeError,TypeError):
|
||||||
|
return np.nan
|
||||||
|
|
||||||
|
return x['id']
|
||||||
|
|
||||||
def build_goldmedalstandards(workouts,kfitness):
|
def build_goldmedalstandards(workouts,kfitness):
|
||||||
dates = []
|
dates = []
|
||||||
testpower = []
|
testpower = []
|
||||||
testduration = []
|
testduration = []
|
||||||
fatigues = []
|
fatigues = []
|
||||||
fitnesses = []
|
fitnesses = []
|
||||||
|
impulses = []
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
goldmedalstandards = []
|
goldmedalstandards = []
|
||||||
goldmedaldurations = []
|
goldmedaldurations = []
|
||||||
|
workoutdt = []
|
||||||
ids = []
|
ids = []
|
||||||
|
|
||||||
|
outids = []
|
||||||
|
|
||||||
for w in workouts:
|
for w in workouts:
|
||||||
goldmedalstandard,goldmedalseconds = dataprep.workout_goldmedalstandard(w)
|
|
||||||
ids.append(w.id)
|
ids.append(w.id)
|
||||||
|
goldmedalstandard,goldmedalseconds = dataprep.workout_goldmedalstandard(w)
|
||||||
|
if goldmedalseconds > 60:
|
||||||
goldmedalstandards.append(goldmedalstandard)
|
goldmedalstandards.append(goldmedalstandard)
|
||||||
goldmedaldurations.append(goldmedalseconds)
|
goldmedaldurations.append(goldmedalseconds)
|
||||||
|
else:
|
||||||
|
goldmedalstandards.append(0)
|
||||||
|
goldmedaldurations.append(0)
|
||||||
|
workoutdt.append(arrow.get(w.startdatetime).datetime)
|
||||||
|
|
||||||
df = pd.DataFrame({
|
df = pd.DataFrame({
|
||||||
'workout':ids,
|
'workout':ids,
|
||||||
|
'workoutdt': workoutdt,
|
||||||
'goldmedalstandard':goldmedalstandards,
|
'goldmedalstandard':goldmedalstandards,
|
||||||
'goldmedalduration':goldmedaldurations,
|
'goldmedalduration':goldmedaldurations,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
df.sort_values(['workoutdt'],inplace=True)
|
||||||
|
|
||||||
|
#for id, row in df.iterrows():
|
||||||
|
# d = row['workoutdt']
|
||||||
|
# dd = d-datetime.timedelta(days=90)
|
||||||
|
# mask = df['workoutdt']>dd
|
||||||
|
# mask2 = df['workoutdt']<=d
|
||||||
|
# df2 = df.where(mask & mask2)
|
||||||
|
# powertest = df2['goldmedalstandard'].max()
|
||||||
|
# idx = df2['goldmedalstandard'].argmax()
|
||||||
|
# durationtest = df2['goldmedalduration'].values[idx]
|
||||||
|
# dates.append(d)
|
||||||
|
# testpower.append(powertest)
|
||||||
|
# testduration.append(durationtest)
|
||||||
|
# fatigues.append(np.nan)
|
||||||
|
# fitnesses.append(np.nan)
|
||||||
|
|
||||||
for w in workouts:
|
for w in workouts:
|
||||||
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=90),
|
||||||
date__lte=w.date)]
|
date__lte=w.date)]
|
||||||
|
|
||||||
powerdf = df[df['workout'].isin(ids)]
|
powerdf = df[df['workout'].isin(ids)]
|
||||||
indexmax = powerdf['goldmedalstandard'].idxmax()
|
indexmax = powerdf['goldmedalstandard'].idxmax()
|
||||||
|
theid = powerdf.loc[indexmax,'workout']
|
||||||
powertest = powerdf['goldmedalstandard'].max()
|
powertest = powerdf['goldmedalstandard'].max()
|
||||||
durationtest = powerdf.loc[indexmax,'goldmedalduration']
|
durationtest = powerdf.loc[indexmax,'goldmedalduration']
|
||||||
|
|
||||||
dates.append(datetime.datetime.combine(w.date,datetime.datetime.min.time()))
|
|
||||||
|
dates.append(arrow.get(w.date).datetime)
|
||||||
|
if powertest > 0:
|
||||||
testpower.append(powertest)
|
testpower.append(powertest)
|
||||||
testduration.append(durationtest)
|
testduration.append(durationtest)
|
||||||
|
outids.append(theid)
|
||||||
|
else:
|
||||||
|
testpower.append(np.nan)
|
||||||
|
testduration.append(np.nan)
|
||||||
|
outids.append(np.nan)
|
||||||
|
|
||||||
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,outids
|
||||||
|
|
||||||
|
|
||||||
def get_testpower(workouts,fitnesstestsecs,kfitness):
|
def get_testpower(workouts,fitnesstestsecs,kfitness):
|
||||||
@@ -156,7 +216,7 @@ def get_testpower(workouts,fitnesstestsecs,kfitness):
|
|||||||
try:
|
try:
|
||||||
df = pd.read_parquet(cpfile)
|
df = pd.read_parquet(cpfile)
|
||||||
df['workout'] = w.id
|
df['workout'] = w.id
|
||||||
df['workoutdate'] = w.date.strftime('%d-%m-%Y')
|
df['workoutdate'] = arrow.get(w.date.strftime('%d-%m-%Y')).datetime
|
||||||
data.append(df)
|
data.append(df)
|
||||||
except:
|
except:
|
||||||
strokesdf = dataprep.getsmallrowdata_db(['power','workoutid','time'],ids=[w.id])
|
strokesdf = dataprep.getsmallrowdata_db(['power','workoutid','time'],ids=[w.id])
|
||||||
@@ -203,7 +263,7 @@ def get_testpower(workouts,fitnesstestsecs,kfitness):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
dates.append(datetime.datetime.combine(w.date,datetime.datetime.min.time()))
|
dates.append(arrow.get(w.date).datetime)
|
||||||
testpower.append(powertest)
|
testpower.append(powertest)
|
||||||
testduration.append(fitnesstestsecs)
|
testduration.append(fitnesstestsecs)
|
||||||
fatigues.append(np.nan)
|
fatigues.append(np.nan)
|
||||||
@@ -1660,6 +1720,7 @@ def interactive_forcecurve(theworkouts,workstrokesonly=True,plottype='scatter'):
|
|||||||
|
|
||||||
def getfatigues(
|
def getfatigues(
|
||||||
fatigues,fitnesses,dates,testpower,testduration,
|
fatigues,fitnesses,dates,testpower,testduration,
|
||||||
|
impulses,
|
||||||
startdate,enddate,user,metricchoice,kfatigue,kfitness):
|
startdate,enddate,user,metricchoice,kfatigue,kfitness):
|
||||||
|
|
||||||
fatigue = 0
|
fatigue = 0
|
||||||
@@ -1704,42 +1765,88 @@ def getfatigues(
|
|||||||
|
|
||||||
impulses.append(weight)
|
impulses.append(weight)
|
||||||
|
|
||||||
|
|
||||||
fatigue = (1-lambda_a)*fatigue+weight*lambda_a
|
fatigue = (1-lambda_a)*fatigue+weight*lambda_a
|
||||||
fitness = (1-lambda_c)*fitness+weight*lambda_c
|
fitness = (1-lambda_c)*fitness+weight*lambda_c
|
||||||
|
|
||||||
fatigues.append(fatigue)
|
fatigues.append(fatigue)
|
||||||
fitnesses.append(fitness)
|
fitnesses.append(fitness)
|
||||||
dates.append(datetime.datetime.combine(date,datetime.datetime.min.time()))
|
dates.append(arrow.get(date).datetime)
|
||||||
testpower.append(np.nan)
|
testpower.append(np.nan)
|
||||||
testduration.append(np.nan)
|
testduration.append(np.nan)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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'
|
||||||
|
|
||||||
|
# to avoid data mess later on
|
||||||
|
startdate = arrow.get(startdate).datetime.replace(hour=0,minute=0,second=0,microsecond=0)
|
||||||
|
enddate = enddate+datetime.timedelta(days=1)
|
||||||
|
enddate = arrow.get(enddate).datetime.replace(hour=0,minute=0,second=0,microsecond=0)
|
||||||
|
|
||||||
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 = []
|
||||||
|
impulses = []
|
||||||
|
|
||||||
|
outids = []
|
||||||
|
|
||||||
|
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, outids = build_goldmedalstandards(
|
||||||
|
workouts,kfitness
|
||||||
|
)
|
||||||
|
|
||||||
|
df = pd.DataFrame({
|
||||||
|
'id': outids,
|
||||||
|
'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)
|
||||||
|
df['id'] = df.apply(lambda x: newtestpowerid(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()
|
||||||
|
impulses = df['impulse'].tolist()
|
||||||
|
outids = df['id'].unique()
|
||||||
|
|
||||||
fatigues,fitnesses,dates,testpower,testduration,impulses = getfatigues(fatigues,
|
fatigues,fitnesses,dates,testpower,testduration,impulses = getfatigues(fatigues,
|
||||||
fitnesses,
|
fitnesses,
|
||||||
dates,
|
dates,
|
||||||
testpower,testduration,
|
testpower,testduration,
|
||||||
|
impulses,
|
||||||
startdate,enddate,
|
startdate,enddate,
|
||||||
user,metricchoice,
|
user,metricchoice,
|
||||||
kfatigue,kfitness)
|
kfatigue,kfitness)
|
||||||
@@ -1749,11 +1856,13 @@ 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,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
endfitness = fitnesses[-1]
|
endfitness = fitnesses[-1]
|
||||||
endfatigue = fatigues[-1]
|
endfatigue = fatigues[-1]
|
||||||
endform = endfitness-endfatigue
|
endform = endfitness-endfatigue
|
||||||
@@ -1771,9 +1880,14 @@ def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7,
|
|||||||
df = df.groupby(['date']).max()
|
df = df.groupby(['date']).max()
|
||||||
df['date'] = df.index.values
|
df['date'] = df.index.values
|
||||||
|
|
||||||
|
|
||||||
|
#for row in df.iterrows():
|
||||||
|
# print(row)
|
||||||
|
|
||||||
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'],
|
||||||
@@ -1836,8 +1950,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
|
||||||
@@ -1845,12 +1960,18 @@ def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7,
|
|||||||
|
|
||||||
y2rangemin = df.loc[:,['form']].min().min()
|
y2rangemin = df.loc[:,['form']].min().min()
|
||||||
y2rangemax = df.loc[:,['form']].max().max()
|
y2rangemax = df.loc[:,['form']].max().max()
|
||||||
|
#if dofatigue and showtests:
|
||||||
|
# y1rangemin = df.loc[:,['testpower','fitness','fatigue']].min().min()
|
||||||
|
# y1rangemax = df.loc[:,['testpower','fitness','fatigue']].max().max()*1.02
|
||||||
|
#elif showtests:
|
||||||
|
# y1rangemin = df.loc[:,['testpower','fitness']].min().min()
|
||||||
|
# y1rangemax = df.loc[:,['testpower','fitness']].max().max()*1.02
|
||||||
if dofatigue:
|
if dofatigue:
|
||||||
y1rangemin = df.loc[:,['fitness','fatigue']].min().min()
|
y1rangemin = df.loc[:,['fitness','fatigue']].min().min()
|
||||||
y1rangemax = df.loc[:,['fitness','fatigue']].max().max()
|
y1rangemax = df.loc[:,['fitness','fatigue']].max().max()*1.02
|
||||||
else:
|
else:
|
||||||
y1rangemin = df.loc[:,['fitness']].min().min()
|
y1rangemin = df.loc[:,['fitness']].min().min()
|
||||||
y1rangemax = df.loc[:,['fitness']].max().max()
|
y1rangemax = df.loc[:,['fitness']].max().max()*1.02
|
||||||
|
|
||||||
if doform:
|
if doform:
|
||||||
plot.extra_y_ranges["yax2"] = Range1d(start=y2rangemin,end=y2rangemax)
|
plot.extra_y_ranges["yax2"] = Range1d(start=y2rangemin,end=y2rangemax)
|
||||||
@@ -1892,6 +2013,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'),
|
||||||
@@ -1901,7 +2023,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,
|
||||||
@@ -1914,6 +2046,7 @@ def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7,
|
|||||||
plot2.y_range = Range1d(0,df['impulse'].max())
|
plot2.y_range = Range1d(0,df['impulse'].max())
|
||||||
|
|
||||||
plot2.vbar(x = df['date'], top = df['impulse'],color='gray')
|
plot2.vbar(x = df['date'], top = df['impulse'],color='gray')
|
||||||
|
plot2.vbar(x = df['date'], top = 0*df['testpower']+df['impulse'], color='red')
|
||||||
|
|
||||||
plot2.sizing_mode = 'scale_both'
|
plot2.sizing_mode = 'scale_both'
|
||||||
plot2.yaxis.axis_label = 'Impulse'
|
plot2.yaxis.axis_label = 'Impulse'
|
||||||
@@ -1935,10 +2068,10 @@ def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7,
|
|||||||
nrworkouts = workouts.count(),
|
nrworkouts = workouts.count(),
|
||||||
nrdata = len(df),
|
nrdata = len(df),
|
||||||
e = e,
|
e = e,
|
||||||
)
|
),0,0,0,[]
|
||||||
)
|
)
|
||||||
|
|
||||||
return [script,div,endfitness,endfatigue,endform]
|
return [script,div,endfitness,endfatigue,endform,outids]
|
||||||
|
|
||||||
|
|
||||||
def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None,
|
def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None,
|
||||||
@@ -1962,7 +2095,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
|
||||||
@@ -1978,8 +2111,7 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None,
|
|||||||
|
|
||||||
|
|
||||||
df['testdup'] = df['testpower'].shift(1)
|
df['testdup'] = df['testpower'].shift(1)
|
||||||
df['testpower'] = df.apply(lambda x: np.nan if abs(x['testpower'] - x['testdup']) < 1 \
|
df['testpower'] = df.apply(lambda x: newtestpower(x),axis=1)
|
||||||
else x['testpower'],axis=1)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
df['testpower'].iloc[-1] = df['testdup'].iloc[-1]
|
df['testpower'].iloc[-1] = df['testdup'].iloc[-1]
|
||||||
|
|||||||
@@ -112,6 +112,14 @@
|
|||||||
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>
|
||||||
|
The bottom chart shows the training impulse of each individual workout. A gray bar
|
||||||
|
denotes a regular workout. The red bars denote workouts that stand out in terms
|
||||||
|
of your power/time performance for that period. This is only available for workouts
|
||||||
|
where Power (Watts) is measured. How well you performed is expressed as a
|
||||||
|
Gold Medal Score, where 100 means you are as good as the world class
|
||||||
|
athletes of 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
|
||||||
@@ -143,6 +151,37 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
{% if bestworkouts %}
|
||||||
|
<h2>Marker Workouts</h2>
|
||||||
|
<li class="grid_4">
|
||||||
|
<table width="100%" class="listtable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Workout</th>
|
||||||
|
<th>Gold Medal Score</th>
|
||||||
|
<th>Duration</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for w in bestworkouts %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ w.date }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="/rowers/workout/{{ w.id|encode }}/">{{ w.name }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ w.goldmedalstandard|floatformat:"0" }} %
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ w.goldmedalseconds|secondstotimestring }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -215,7 +215,6 @@ def alertenddate(list,i):
|
|||||||
def is_coach(rower,rowers):
|
def is_coach(rower,rowers):
|
||||||
for r in rowers:
|
for r in rowers:
|
||||||
if rower not in rower_get_managers(r):
|
if rower not in rower_get_managers(r):
|
||||||
print(r,rower)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@@ -256,7 +255,6 @@ def hrmajorticks(maxval,minval):
|
|||||||
for t in ticks:
|
for t in ticks:
|
||||||
newticks.append(100+t*20)
|
newticks.append(100+t*20)
|
||||||
|
|
||||||
print(newticks)
|
|
||||||
return newticks
|
return newticks
|
||||||
|
|
||||||
def strfdeltah(tdelta):
|
def strfdeltah(tdelta):
|
||||||
@@ -272,6 +270,7 @@ def strfdeltah(tdelta):
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@register.filter
|
||||||
def secondstotimestring(tdelta):
|
def secondstotimestring(tdelta):
|
||||||
hours, rest = divmod(tdelta,3600)
|
hours, rest = divmod(tdelta,3600)
|
||||||
minutes,seconds = divmod(rest,60)
|
minutes,seconds = divmod(rest,60)
|
||||||
|
|||||||
@@ -1585,15 +1585,21 @@ def performancemanager_view(request,userid=0,mode='rower',
|
|||||||
'dofatigue':dofatigue,
|
'dofatigue':dofatigue,
|
||||||
})
|
})
|
||||||
|
|
||||||
script, thediv, endfitness, endfatigue, endform = performance_chart(
|
script, thediv, endfitness, endfatigue, endform, ids = performance_chart(
|
||||||
theuser,startdate=startdate,enddate=enddate,
|
theuser,startdate=startdate,enddate=enddate,
|
||||||
kfitness = kfitness,
|
kfitness = kfitness,
|
||||||
kfatigue = kfatigue,
|
kfatigue = kfatigue,
|
||||||
metricchoice = metricchoice,
|
metricchoice = metricchoice,
|
||||||
doform = doform,
|
doform = doform,
|
||||||
dofatigue = dofatigue,
|
dofatigue = dofatigue,
|
||||||
|
showtests = True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ids = pd.Series(ids).dropna().values
|
||||||
|
|
||||||
|
bestworkouts = Workout.objects.filter(id__in=ids).order_by('date')
|
||||||
|
|
||||||
|
|
||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
{
|
{
|
||||||
'url':'/rowers/analysis',
|
'url':'/rowers/analysis',
|
||||||
@@ -1629,6 +1635,7 @@ def performancemanager_view(request,userid=0,mode='rower',
|
|||||||
'endfitness':int(endfitness),
|
'endfitness':int(endfitness),
|
||||||
'endfatigue':int(endfatigue),
|
'endfatigue':int(endfatigue),
|
||||||
'endform':int(endform),
|
'endform':int(endform),
|
||||||
|
'bestworkouts':bestworkouts,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -1678,11 +1685,7 @@ def fitness_from_cp_view(request,userid=0,mode='rower',
|
|||||||
|
|
||||||
workouts = Workout.objects.filter(user=therower,date__gte=startdate,
|
workouts = Workout.objects.filter(user=therower,date__gte=startdate,
|
||||||
date__lte=enddate,
|
date__lte=enddate,
|
||||||
workouttype__in=mytypes.otwtypes,
|
workouttype__in=mytypes.rowtypes,
|
||||||
duplicate=False)
|
|
||||||
if mode == 'rower':
|
|
||||||
workouts = Workout.objects.filter(user=therower,date__gte=startdate,
|
|
||||||
date__lte=enddate,workouttype__in=mytypes.otetypes,
|
|
||||||
duplicate=False)
|
duplicate=False)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3502,19 +3502,19 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
|||||||
goldmedalstandard,goldmedalseconds = dataprep.workout_goldmedalstandard(w)
|
goldmedalstandard,goldmedalseconds = dataprep.workout_goldmedalstandard(w)
|
||||||
|
|
||||||
|
|
||||||
#if not np.isnan(goldmedalstandard) and goldmedalstandard > 0:
|
if not np.isnan(goldmedalstandard) and goldmedalstandard > 0:
|
||||||
# otherstats['goldmedalstandard'] = {
|
otherstats['goldmedalstandard'] = {
|
||||||
# 'verbose_name': 'Gold Medal Standard',
|
'verbose_name': 'Gold Medal Standard',
|
||||||
# 'value': int(goldmedalstandard),
|
'value': int(goldmedalstandard),
|
||||||
# 'unit': '%',
|
'unit': '%',
|
||||||
# }
|
}
|
||||||
|
|
||||||
#if not np.isnan(goldmedalseconds) and goldmedalseconds > 0:
|
if not np.isnan(goldmedalseconds) and goldmedalseconds > 0:
|
||||||
# otherstats['goldmedalseconds'] = {
|
otherstats['goldmedalseconds'] = {
|
||||||
# 'verbose_name': 'Gold Medal Standard Duration',
|
'verbose_name': 'Gold Medal Standard Duration',
|
||||||
# 'value': utils.totaltime_sec_to_string(goldmedalseconds,shorten=True),
|
'value': utils.totaltime_sec_to_string(goldmedalseconds,shorten=True),
|
||||||
# 'unit': '',
|
'unit': '',
|
||||||
# }
|
}
|
||||||
|
|
||||||
|
|
||||||
if not np.isnan(tss) and tss != 0:
|
if not np.isnan(tss) and tss != 0:
|
||||||
|
|||||||
Reference in New Issue
Block a user