Merge branch 'feature/otwcp3' into develop
This commit is contained in:
@@ -430,6 +430,7 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
|
||||
delta,cpvalues,avgpower = datautils.getsinglecp(row.df)
|
||||
if utils.isbreakthrough(delta,cpvalues,r.p0,r.p1,r.p2,r.p3):
|
||||
isbreakthrough = True
|
||||
res = datautils.updatecp(delta,cpvalues,r)
|
||||
|
||||
dtavg = row.df['TimeStamp (sec)'].diff().mean()
|
||||
|
||||
|
||||
@@ -1,6 +1,88 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from scipy.interpolate import griddata
|
||||
from scipy import optimize
|
||||
|
||||
def updatecp(delta,cpvalues,r):
|
||||
cp2 = r.p0/(1+delta/r.p2)
|
||||
cp2 += r.p1/(1+delta/r.p3)
|
||||
|
||||
delta = delta.append(delta)
|
||||
cp = cpvalues.append(cp2)
|
||||
|
||||
powerdf = pd.DataFrame({
|
||||
'Delta':delta,
|
||||
'CP':cp,
|
||||
})
|
||||
|
||||
powerdf.dropna(axis=0,inplace=True)
|
||||
powerdf.sort_values(['Delta','CP'],ascending=[1,0],inplace=True)
|
||||
powerdf.drop_duplicates(subset='Delta',keep='first',inplace=True)
|
||||
|
||||
|
||||
res = cpfit(powerdf)
|
||||
p1 = res[0]
|
||||
|
||||
r.p0 = p1[0]
|
||||
r.p1 = p1[1]
|
||||
r.p2 = p1[2]
|
||||
r.p3 = p1[3]
|
||||
|
||||
r.save()
|
||||
|
||||
return 1
|
||||
|
||||
def cpfit(powerdf):
|
||||
# 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])))
|
||||
errfunc = lambda pars,x,y: fitfunc(pars,x)-y
|
||||
|
||||
p0 = [500,350,10,8000]
|
||||
|
||||
p1 = p0
|
||||
|
||||
thesecs = powerdf['Delta']
|
||||
theavpower = powerdf['CP']
|
||||
|
||||
if len(thesecs)>=4:
|
||||
p1, success = optimize.leastsq(errfunc, p0[:], args = (thesecs,theavpower))
|
||||
else:
|
||||
factor = fitfunc(p0,thesecs.mean())/theavpower.mean()
|
||||
p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]]
|
||||
|
||||
|
||||
p1 = [abs(p) for p in p1]
|
||||
fitt = pd.Series(10**(4*np.arange(100)/100.))
|
||||
|
||||
fitpower = fitfunc(p1,fitt)
|
||||
|
||||
fitpoints = fitfunc(p1,thesecs)
|
||||
fitpoints0 = fitpoints.copy()
|
||||
dd = fitpoints-theavpower
|
||||
|
||||
ddmin = dd.min()
|
||||
|
||||
frac = abs(ddmin)/fitpoints.mean()
|
||||
|
||||
while frac>0.0001:
|
||||
fitpoints = fitpoints*(fitpoints.mean()-ddmin)/(fitpoints.mean())
|
||||
dd = fitpoints-theavpower
|
||||
ddmin = dd.min()
|
||||
frac = abs(ddmin)/fitpoints.mean()
|
||||
|
||||
ratio = fitpoints.mean()/fitpoints0.mean()
|
||||
|
||||
return p1,fitt,fitpower,ratio
|
||||
|
||||
def getlogarr(maxt):
|
||||
maxlog10 = np.log10(maxt-5)
|
||||
logarr = np.log10(5.)+np.arange(50)*maxlog10/50.
|
||||
logarr = [int(10.**(la)) for la in logarr]
|
||||
logarr = pd.Series(logarr)
|
||||
logarr.drop_duplicates(keep='first',inplace=True)
|
||||
|
||||
logarr = logarr.values
|
||||
return logarr
|
||||
|
||||
def getsinglecp(df):
|
||||
thesecs = df['TimeStamp (sec)'].max()-df['TimeStamp (sec)'].min()
|
||||
@@ -9,13 +91,7 @@ def getsinglecp(df):
|
||||
else:
|
||||
maxt = 1000.
|
||||
|
||||
maxlog10 = np.log10(maxt)
|
||||
logarr = np.arange(50)*maxlog10/50.
|
||||
logarr = [int(10.**(la)) for la in logarr]
|
||||
logarr = pd.Series(logarr)
|
||||
logarr.drop_duplicates(keep='first',inplace=True)
|
||||
|
||||
logarr = logarr.values
|
||||
logarr = getlogarr(maxt)
|
||||
|
||||
|
||||
dfnew = pd.DataFrame({
|
||||
@@ -42,7 +118,7 @@ def getcp(dfgrouped,logarr):
|
||||
|
||||
tmax = tt.max()
|
||||
if tmax > 500000:
|
||||
newlen = int(tmax/5000.)
|
||||
newlen = int(tmax/2000.)
|
||||
else:
|
||||
newlen = len(tt)
|
||||
if newlen < len(tt):
|
||||
|
||||
@@ -55,6 +55,7 @@ import rowers.dataprep as dataprep
|
||||
from rowers.metrics import axes,axlabels,yaxminima,yaxmaxima
|
||||
|
||||
from utils import lbstoN
|
||||
import datautils
|
||||
|
||||
watermarkurl = "/static/img/logo7.png"
|
||||
watermarksource = ColumnDataSource(dict(
|
||||
@@ -618,28 +619,10 @@ def interactive_otwcpchart(powerdf,promember=0):
|
||||
|
||||
# there is no Paul's law for OTW
|
||||
|
||||
# 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])))
|
||||
errfunc = lambda pars,x,y: fitfunc(pars,x)-y
|
||||
|
||||
p0 = [500,350,10,8000]
|
||||
|
||||
p1 = p0
|
||||
|
||||
thesecs = powerdf['Delta']
|
||||
theavpower = powerdf['CP']
|
||||
|
||||
if len(thesecs)>=4:
|
||||
p1, success = optimize.leastsq(errfunc, p0[:], args = (thesecs,theavpower))
|
||||
else:
|
||||
factor = fitfunc(p0,thesecs.mean())/theavpower.mean()
|
||||
p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]]
|
||||
|
||||
|
||||
p1 = [abs(p) for p in p1]
|
||||
fitt = pd.Series(10**(4*np.arange(100)/100.))
|
||||
|
||||
fitpower = fitfunc(p1,fitt)
|
||||
p1,fitt,fitpower,ratio = datautils.cpfit(powerdf)
|
||||
|
||||
message = ""
|
||||
#if len(fitpower[fitpower<0]) > 0:
|
||||
@@ -652,6 +635,7 @@ def interactive_otwcpchart(powerdf,promember=0):
|
||||
sourcecomplex = ColumnDataSource(
|
||||
data = dict(
|
||||
CP = fitpower,
|
||||
CPmax = ratio*fitpower,
|
||||
duration = fitt,
|
||||
ftime = ftime
|
||||
)
|
||||
@@ -690,6 +674,7 @@ def interactive_otwcpchart(powerdf,promember=0):
|
||||
hover.tooltips = OrderedDict([
|
||||
('Duration ','@ftime'),
|
||||
('Power (W)','@CP{int}'),
|
||||
('Power (W) upper','@CPmax{int}'),
|
||||
])
|
||||
|
||||
hover.mode = 'mouse'
|
||||
@@ -697,6 +682,9 @@ def interactive_otwcpchart(powerdf,promember=0):
|
||||
plot.line('duration','CP',source=sourcecomplex,legend="CP Model",
|
||||
color='green')
|
||||
|
||||
plot.line('duration','CPmax',source=sourcecomplex,legend="CP Model",
|
||||
color='red')
|
||||
|
||||
script, div = components(plot)
|
||||
|
||||
return [script,div,p1,message]
|
||||
|
||||
@@ -232,7 +232,7 @@ class Rower(models.Model):
|
||||
('hidden','Hidden'),
|
||||
)
|
||||
|
||||
getemailnotifications = models.BooleanField(default=True,
|
||||
getemailnotifications = models.BooleanField(default=False,
|
||||
verbose_name='Receive email notifications')
|
||||
|
||||
rowerplan = models.CharField(default='basic',max_length=30,
|
||||
|
||||
@@ -2931,15 +2931,7 @@ def otwrankings_view(request,theuser=0,
|
||||
maxt = 1000.
|
||||
|
||||
|
||||
maxlog10 = np.log10(maxt)
|
||||
logarr = np.arange(50)*maxlog10/50.
|
||||
logarr = [int(10.**(la)) for la in logarr]
|
||||
logarr = pd.Series(logarr)
|
||||
logarr.drop_duplicates(keep='first',inplace=True)
|
||||
|
||||
logarr = logarr.values
|
||||
|
||||
|
||||
logarr = datautils.getlogarr(maxt)
|
||||
|
||||
dfgrouped = df.groupby(['workoutid'])
|
||||
delta,cpvalue,avgpower = datautils.getcp(dfgrouped,logarr)
|
||||
@@ -8101,8 +8093,10 @@ def team_view(request,id=0):
|
||||
if inviteid:
|
||||
teams.send_invite_email(inviteid)
|
||||
successmessage = text
|
||||
messages.info(request,successmessage)
|
||||
else:
|
||||
message = text
|
||||
messages.error(request,message)
|
||||
|
||||
elif request.user == t.manager:
|
||||
inviteform = TeamInviteForm()
|
||||
|
||||
Reference in New Issue
Block a user