Private
Public Access
1
0

Merge branch 'release/v12.87'

This commit is contained in:
Sander Roosendaal
2020-06-10 08:24:19 +02:00
6 changed files with 127 additions and 72 deletions
+31 -25
View File
@@ -26,7 +26,7 @@ def updatecp(delta,cpvalues,r):
powerdf.dropna(axis=0,inplace=True) powerdf.dropna(axis=0,inplace=True)
powerdf.sort_values(['Delta','CP'],ascending=[1,0],inplace=True) powerdf.sort_values(['Delta','CP'],ascending=[1,0],inplace=True)
powerdf.drop_duplicates(subset='Delta',keep='first',inplace=True) powerdf.drop_duplicates(subset='Delta',keep='first',inplace=True)
res = cpfit(powerdf) res = cpfit(powerdf)
p1 = res[0] p1 = res[0]
@@ -45,7 +45,7 @@ def cpfit(powerdf):
# Fit the data to thee parameter CP model # Fit the data to thee parameter CP model
fitfunc = lambda pars,x: abs(pars[0])/(1+(x/abs(pars[2]))) + abs(pars[1])/(1+(x/abs(pars[3]))) fitfunc = lambda pars,x: abs(pars[0])/(1+(x/abs(pars[2]))) + abs(pars[1])/(1+(x/abs(pars[3])))
errfunc = lambda pars,x,y: fitfunc(pars,x)-y errfunc = lambda pars,x,y: fitfunc(pars,x)-y
p1 = p0 p1 = p0
@@ -58,7 +58,7 @@ def cpfit(powerdf):
except: except:
factor = fitfunc(p0,thesecs.mean())/theavpower.mean() factor = fitfunc(p0,thesecs.mean())/theavpower.mean()
p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]] p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]]
else: else:
factor = fitfunc(p0,thesecs.mean())/theavpower.mean() factor = fitfunc(p0,thesecs.mean())/theavpower.mean()
p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]] p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]]
@@ -82,7 +82,7 @@ def cpfit(powerdf):
dd = fitpoints-theavpower dd = fitpoints-theavpower
ddmin = dd.min() ddmin = dd.min()
frac = abs(ddmin)/fitpoints.mean() frac = abs(ddmin)/fitpoints.mean()
ratio = fitpoints.mean()/fitpoints0.mean() ratio = fitpoints.mean()/fitpoints0.mean()
return p1,fitt,fitpower,ratio return p1,fitt,fitpower,ratio
@@ -90,8 +90,15 @@ def cpfit(powerdf):
def getlogarr(maxt): def getlogarr(maxt):
maxlog10 = np.log10(maxt-5) maxlog10 = np.log10(maxt-5)
logarr = np.arange(50)*maxlog10/50. logarr = np.arange(50)*maxlog10/50.
logarr = [5+int(10.**(la)) for la in logarr] res = []
logarr = pd.Series(logarr) for la in logarr:
try:
v = 5+int(10.**(la))
except ValueError:
v = 0
res.append(v)
logarr = pd.Series(res)
logarr.drop_duplicates(keep='first',inplace=True) logarr.drop_duplicates(keep='first',inplace=True)
logarr = logarr.values logarr = logarr.values
@@ -111,9 +118,9 @@ def getsinglecp(df):
'time':1000*(df['TimeStamp (sec)']-df.loc[:,'TimeStamp (sec)'].iloc[0]), 'time':1000*(df['TimeStamp (sec)']-df.loc[:,'TimeStamp (sec)'].iloc[0]),
'power':df[' Power (watts)'] 'power':df[' Power (watts)']
}) })
dfnew['workoutid'] = 0 dfnew['workoutid'] = 0
dfgrouped = dfnew.groupby(['workoutid']) dfgrouped = dfnew.groupby(['workoutid'])
delta,cpvalue,avgpower = getcp(dfgrouped,logarr) delta,cpvalue,avgpower = getcp(dfgrouped,logarr)
@@ -124,7 +131,7 @@ def getcp_new(dfgrouped,logarr):
cpvalue = [] cpvalue = []
avgpower = {} avgpower = {}
for id, group in dfgrouped: for id, group in dfgrouped:
tt = group['time'].copy() tt = group['time'].copy()
@@ -149,7 +156,7 @@ def getcp_new(dfgrouped,logarr):
ww.values, ww.values,
newt,method='linear', newt,method='linear',
rescale=True) rescale=True)
tt = pd.Series(newt) tt = pd.Series(newt)
ww = pd.Series(ww) ww = pd.Series(ww)
@@ -178,7 +185,7 @@ def getcp_new(dfgrouped,logarr):
restime = [] restime = []
power = [] power = []
for i in np.arange(0,len(tt)+1,1): for i in np.arange(0,len(tt)+1,1):
restime.append(deltat*i) restime.append(deltat*i)
cp = np.diag(F,i).max() cp = np.diag(F,i).max()
@@ -189,19 +196,19 @@ def getcp_new(dfgrouped,logarr):
restime = np.array(restime) restime = np.array(restime)
power = np.array(power) power = np.array(power)
#power[0] = power[1] #power[0] = power[1]
cpvalues = griddata(restime,power, cpvalues = griddata(restime,power,
logarr,method='linear', fill_value=0) logarr,method='linear', fill_value=0)
for cpv in cpvalues: for cpv in cpvalues:
cpvalue.append(cpv) cpvalue.append(cpv)
for d in logarr: for d in logarr:
delta.append(d) delta.append(d)
df = pd.DataFrame({ df = pd.DataFrame({
'delta':delta, 'delta':delta,
'cpvalue':cpvalue 'cpvalue':cpvalue
@@ -215,8 +222,8 @@ def getcp_new(dfgrouped,logarr):
cpvalue = df['cpvalue'] cpvalue = df['cpvalue']
return delta,cpvalue,avgpower return delta,cpvalue,avgpower
def getcp(dfgrouped,logarr): def getcp(dfgrouped,logarr):
delta = [] delta = []
cpvalue = [] cpvalue = []
@@ -228,7 +235,7 @@ def getcp(dfgrouped,logarr):
ww = group['power'].copy() ww = group['power'].copy()
# Remove data where PM is repeating final power value # Remove data where PM is repeating final power value
# of an interval during the rest # of an interval during the rest
rolling_std = ww.rolling(window=4).std() rolling_std = ww.rolling(window=4).std()
deltas = tt.diff() deltas = tt.diff()
@@ -240,7 +247,7 @@ def getcp(dfgrouped,logarr):
tmax = tt.max() tmax = tt.max()
if tmax > 500000: if tmax > 500000:
newlen = int(tmax/2000.) newlen = int(tmax/2000.)
else: else:
@@ -255,7 +262,7 @@ def getcp(dfgrouped,logarr):
tt = pd.Series(newt) tt = pd.Series(newt)
ww = pd.Series(ww) ww = pd.Series(ww)
try: try:
avgpower[id] = int(ww.mean()) avgpower[id] = int(ww.mean())
except ValueError: except ValueError:
@@ -272,7 +279,7 @@ def getcp(dfgrouped,logarr):
cpw.append(wmax) cpw.append(wmax)
dt = pd.Series(dt) dt = pd.Series(dt)
cpw = pd.Series(cpw) cpw = pd.Series(cpw)
if len(dt)>2: if len(dt)>2:
@@ -286,12 +293,12 @@ def getcp(dfgrouped,logarr):
for d in logarr: for d in logarr:
delta.append(d) delta.append(d)
delta = pd.Series(delta,name='Delta') delta = pd.Series(delta,name='Delta')
cpvalue = pd.Series(cpvalue,name='CP') cpvalue = pd.Series(cpvalue,name='CP')
cpdf = pd.DataFrame({ cpdf = pd.DataFrame({
'delta':delta, 'delta':delta,
'cpvalue':cpvalue 'cpvalue':cpvalue
@@ -332,4 +339,3 @@ def getmaxwattinterval(tt,ww,i):
deltat = 0 deltat = 0
return deltat,wmax return deltat,wmax
+13 -1
View File
@@ -261,6 +261,18 @@ def pretty_timedelta(secs):
return '{}:{:02}:{:02}'.format(int(hours),int(minutes),int(seconds)) return '{}:{:02}:{:02}'.format(int(hours),int(minutes),int(seconds))
def mapcolors(x):
try:
return mytypes.color_map[x]
except KeyError:
return mytypes.colors[-1]
def maptypes(x):
try:
return mytypes.workouttypes_ordered[x]
except KeyError:
return 'Other'
def interactive_workouttype_piechart(workouts): def interactive_workouttype_piechart(workouts):
if len(workouts) == 0: if len(workouts) == 0:
return "","Not enough workouts to make a chart" return "","Not enough workouts to make a chart"
@@ -286,7 +298,7 @@ def interactive_workouttype_piechart(workouts):
data = pd.DataFrame(data) data = pd.DataFrame(data)
data['color'] = data['type'].apply(lambda x:mytypes.color_map[x]) data['color'] = data['type'].apply(lambda x:mapcolors(x))
data['totaltime'] = data['value'].apply(lambda x:pretty_timedelta(x)) data['totaltime'] = data['value'].apply(lambda x:pretty_timedelta(x))
data['type'] = data['type'].apply(lambda x:mytypes.workouttypes_ordered[x]) data['type'] = data['type'].apply(lambda x:mytypes.workouttypes_ordered[x])
+2 -1
View File
@@ -273,7 +273,8 @@ checktypes = [i[0] for i in workouttypes]
from bokeh.palettes import Category10,Category20, Category20c from bokeh.palettes import Category10,Category20, Category20c
colors = Category10[9]+Category20[19]+Category20c[19] #colors = Category10[9]
colors = Category10[9]+list(set(Category20[19]+Category20c[19]))
color_map = {checktypes[i]:colors[i] for i in range(len(checktypes))} color_map = {checktypes[i]:colors[i] for i in range(len(checktypes))}
workoutsources = ( workoutsources = (
+7 -2
View File
@@ -30,6 +30,7 @@ import datetime
import pytz import pytz
import iso8601 import iso8601
from json.decoder import JSONDecodeError
from matplotlib.backends.backend_agg import FigureCanvas from matplotlib.backends.backend_agg import FigureCanvas
#from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas #from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas
@@ -380,8 +381,9 @@ def handle_check_race_course(self,
except IOError: except IOError:
return 0 return 0
row.calc_dist_from_gps()
rowdata = row.df rowdata = row.df
rowdata['cum_dist'] = rowdata['gps_dist_calculated']
try: try:
s = rowdata[' latitude'] s = rowdata[' latitude']
@@ -2028,7 +2030,10 @@ def handle_makeplot(f1, f2, t, hrdata, plotnr, imagename,
elif (plotnr == 2): elif (plotnr == 2):
fig1 = row.get_metersplot_erg(t,pacerange=oterange,**kwargs) fig1 = row.get_metersplot_erg(t,pacerange=oterange,**kwargs)
elif (plotnr == 3): elif (plotnr == 3):
t += ' - Heart Rate Distribution' try:
t += ' - Heart Rate Distribution'
except TypeError:
t = 'Heart Rate Distribution'
fig1 = row.get_piechart(t,**kwargs) fig1 = row.get_piechart(t,**kwargs)
elif (plotnr == 4): elif (plotnr == 4):
if haspower: if haspower:
+46 -36
View File
@@ -1640,18 +1640,22 @@ def virtualevent_addboat_view(request,id=0):
race = race).exclude(userid = r.id) race = race).exclude(userid = r.id)
for otherrecord in otherrecords: for otherrecord in otherrecords:
otheruser = Rower.objects.get(id=otherrecord.userid) try:
othername = otheruser.user.first_name+' '+otheruser.user.last_name otheruser = Rower.objects.get(id=otherrecord.userid)
registeredname = r.user.first_name+' '+r.user.last_name othername = otheruser.user.first_name+' '+otheruser.user.last_name
if otherrecord.emailnotifications: registeredname = r.user.first_name+' '+r.user.last_name
job = myqueue( if otherrecord.emailnotifications:
queue, job = myqueue(
handle_sendemail_raceregistration, queue,
otheruser.user.email, othername, handle_sendemail_raceregistration,
registeredname, otheruser.user.email, othername,
race.name, registeredname,
race.id race.name,
) race.id
)
except Rower.DoesNotExist:
pass
followers = VirtualRaceFollower.objects.filter(race = race) followers = VirtualRaceFollower.objects.filter(race = race)
@@ -1868,18 +1872,21 @@ def virtualevent_register_view(request,id=0):
race = race).exclude(userid = r.id) race = race).exclude(userid = r.id)
for otherrecord in otherrecords: for otherrecord in otherrecords:
otheruser = Rower.objects.get(id=otherrecord.userid) try:
othername = otheruser.user.first_name+' '+otheruser.user.last_name otheruser = Rower.objects.get(id=otherrecord.userid)
registeredname = r.user.first_name+' '+r.user.last_name othername = otheruser.user.first_name+' '+otheruser.user.last_name
if otherrecord.emailnotifications: registeredname = r.user.first_name+' '+r.user.last_name
job = myqueue( if otherrecord.emailnotifications:
queue, job = myqueue(
handle_sendemail_raceregistration, queue,
otheruser.user.email, othername, handle_sendemail_raceregistration,
registeredname, otheruser.user.email, othername,
race.name, registeredname,
race.id race.name,
) race.id
)
except Rower.DoesNotExist:
pass
followers = VirtualRaceFollower.objects.filter(race = race) followers = VirtualRaceFollower.objects.filter(race = race)
@@ -2136,18 +2143,21 @@ def indoorvirtualevent_register_view(request,id=0):
race = race).exclude(userid = r.id) race = race).exclude(userid = r.id)
for otherrecord in otherrecords: for otherrecord in otherrecords:
otheruser = Rower.objects.get(id=otherrecord.userid) try:
othername = otheruser.user.first_name+' '+otheruser.user.last_name otheruser = Rower.objects.get(id=otherrecord.userid)
registeredname = r.user.first_name+' '+r.user.last_name othername = otheruser.user.first_name+' '+otheruser.user.last_name
if otherrecord.emailnotifications: registeredname = r.user.first_name+' '+r.user.last_name
job = myqueue( if otherrecord.emailnotifications:
queue, job = myqueue(
handle_sendemail_raceregistration, queue,
otheruser.user.email, othername, handle_sendemail_raceregistration,
registeredname, otheruser.user.email, othername,
race.name, registeredname,
race.id race.name,
) race.id
)
except Rower.DoesNotExist:
pass
followers = VirtualRaceFollower.objects.filter(race = race) followers = VirtualRaceFollower.objects.filter(race = race)
+28 -7
View File
@@ -5913,13 +5913,34 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
# we are saving the results obtained from the split by power/pace interpreter # we are saving the results obtained from the split by power/pace interpreter
elif request.method == 'POST' and "savepowerpaceform" in request.POST: elif request.method == 'POST' and "savepowerpaceform" in request.POST:
powerorpace = request.POST['powerorpace'] try:
value_pace = request.POST['value_pace'] powerorpace = request.POST['powerorpace']
value_power = request.POST['value_power'] except:
value_work = request.POST['value_work'] powerorpace = 'pace'
value_spm = request.POST['value_spm'] try:
activeminutesmin = request.POST['activeminutesmin'] value_pace = request.POST['value_pace']
activeminutesmax = request.POST['activeminutesmax'] except:
value_pace = avpace
try:
value_power = request.POST['value_power']
except:
value_power = int(normp)
try:
value_work = request.POST['value_work']
except:
value_work = int(normw)
try:
value_spm = request.POST['value_spm']
except:
value_spm = int(normspm)
try:
activeminutesmin = request.POST['activeminutesmin']
except:
activeminutesmin = 0
try:
activeminutesmax = request.POST['activeminutesmax']
except:
pass
try: try:
activesecondsmin = 60.*float(activeminutesmin) activesecondsmin = 60.*float(activeminutesmin)
activesecondsmax = 60.*float(activeminutesmax) activesecondsmax = 60.*float(activeminutesmax)