Private
Public Access
1
0

using upper limit for OTW breakthrough detection

This commit is contained in:
Sander Roosendaal
2017-06-27 04:10:53 +02:00
parent a8b8083b0f
commit 0f71ee9481
9 changed files with 25 additions and 13 deletions

View File

@@ -428,7 +428,7 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
isbreakthrough = False isbreakthrough = False
if workouttype == 'water': if workouttype == 'water':
delta,cpvalues,avgpower = datautils.getsinglecp(row.df) delta,cpvalues,avgpower = datautils.getsinglecp(row.df)
if utils.isbreakthrough(delta,cpvalues,r.p0,r.p1,r.p2,r.p3): if utils.isbreakthrough(delta,cpvalues,r.p0,r.p1,r.p2,r.p3,r.cpratio):
isbreakthrough = True isbreakthrough = True
res = datautils.updatecp(delta,cpvalues,r) res = datautils.updatecp(delta,cpvalues,r)

View File

@@ -27,6 +27,7 @@ def updatecp(delta,cpvalues,r):
r.p1 = p1[1] r.p1 = p1[1]
r.p2 = p1[2] r.p2 = p1[2]
r.p3 = p1[3] r.p3 = p1[3]
r.cpratio = res[3]
r.save() r.save()

View File

@@ -131,7 +131,7 @@ class PredictedPieceForm(forms.Form):
) )
pieceunit = forms.ChoiceField(required=True,choices=unitchoices, pieceunit = forms.ChoiceField(required=True,choices=unitchoices,
initial='t',label='Unit') initial='t',label='Unit')
value = forms.IntegerField(initial=10,label='Value') value = forms.FloatField(initial=10,label='Value')
class Meta: class Meta:
fields = ['value','pieceunit'] fields = ['value','pieceunit']

View File

@@ -687,7 +687,7 @@ def interactive_otwcpchart(powerdf,promember=0):
script, div = components(plot) script, div = components(plot)
return [script,div,p1,message] return [script,div,p1,ratio,message]
def interactive_cpchart(thedistances,thesecs,theavpower, def interactive_cpchart(thedistances,thesecs,theavpower,
theworkouts,promember=0): theworkouts,promember=0):

View File

@@ -178,6 +178,7 @@ class Rower(models.Model):
p1 = models.FloatField(default=1.0,verbose_name="CP p2") p1 = models.FloatField(default=1.0,verbose_name="CP p2")
p2 = models.FloatField(default=1.0,verbose_name="CP p3") p2 = models.FloatField(default=1.0,verbose_name="CP p3")
p3 = models.FloatField(default=1.0,verbose_name="CP p4") p3 = models.FloatField(default=1.0,verbose_name="CP p4")
cpratio = models.FloatField(default=1.0,verbose_name="CP fit ratio")
otwslack = models.IntegerField(default=0,verbose_name="OTW Power slack") otwslack = models.IntegerField(default=0,verbose_name="OTW Power slack")

View File

@@ -164,14 +164,15 @@
<thead> <thead>
<tr> <tr>
<th> Duration</th> <th> Duration</th>
<th> Power </th> <th> Power (upper)</th>
<th> Power</th>
<tr> <tr>
</thead> </thead>
<tbody> <tbody>
{% for pred in cpredictions %} {% for pred in cpredictions %}
<tr> <tr>
{% for key, value in pred.items %} {% for key, value in pred.items %}
{% if key == "power" %} {% if key == "power" or key == "upper" %}
<td> {{ value }} W </td> <td> {{ value }} W </td>
{% endif %} {% endif %}
{% if key == "duration" %} {% if key == "duration" %}

View File

@@ -76,11 +76,13 @@ def geo_distance(lat1,lon1,lat2,lon2):
return [distance,bearing] return [distance,bearing]
def isbreakthrough(delta,cpvalues,p0,p1,p2,p3): def isbreakthrough(delta,cpvalues,p0,p1,p2,p3,ratio):
pwr = p0/(1+delta/p2) pwr = p0/(1+delta/p2)
pwr += p1/(1+delta/p3) pwr += p1/(1+delta/p3)
pwr *= ratio
res = np.sum(cpvalues>pwr) res = np.sum(cpvalues>pwr)
return res>1 return res>1

View File

@@ -2955,14 +2955,16 @@ def otwrankings_view(request,theuser=0,
script = res[0] script = res[0]
div = res[1] div = res[1]
p1 = res[2] p1 = res[2]
ratio = res[3]
r.p0 = p1[0] r.p0 = p1[0]
r.p1 = p1[1] r.p1 = p1[1]
r.p2 = p1[2] r.p2 = p1[2]
r.p3 = p1[3] r.p3 = p1[3]
r.cpratio = ratio
r.save() r.save()
paulslope = 1 paulslope = 1
paulintercept = 1 paulintercept = 1
message = res[3] message = res[4]
else: else:
script = '' script = ''
div = '<p>No ranking pieces found.</p>' div = '<p>No ranking pieces found.</p>'
@@ -2977,18 +2979,20 @@ def otwrankings_view(request,theuser=0,
clean = form.is_valid() clean = form.is_valid()
value = form.cleaned_data['value'] value = form.cleaned_data['value']
hourvalue,value = divmod(value,60) hourvalue,value = divmod(value,60)
hourvalue = int(hourvalue)
minutevalue = int(value)
value = int(60*(value-minutevalue))
if hourvalue >= 24: if hourvalue >= 24:
hourvalue = 23 hourvalue = 23
rankingdurations.append(datetime.time(minute=value,hour=hourvalue)) rankingdurations.append(datetime.time(minute=minutevalue,
hour=hourvalue,
second=value))
else: else:
form = PredictedPieceForm() form = PredictedPieceForm()
predictions = []
cpredictions = [] cpredictions = []
for rankingduration in rankingdurations: for rankingduration in rankingdurations:
t = 3600.*rankingduration.hour t = 3600.*rankingduration.hour
t += 60.*rankingduration.minute t += 60.*rankingduration.minute
@@ -3000,13 +3004,17 @@ def otwrankings_view(request,theuser=0,
pwr = p1[0]/(1+t/p1[2]) pwr = p1[0]/(1+t/p1[2])
pwr += p1[1]/(1+t/p1[3]) pwr += p1[1]/(1+t/p1[3])
if pwr <= 0: if pwr <= 0:
pwr = 50. pwr = 50.
if not np.isnan(pwr): if not np.isnan(pwr):
pwr2 = pwr*ratio
a = { a = {
'duration':timedeltaconv(t), 'duration':timedeltaconv(t),
'power':int(pwr)} 'power':int(pwr),
'upper':int(pwr2)}
cpredictions.append(a) cpredictions.append(a)
@@ -3017,7 +3025,6 @@ def otwrankings_view(request,theuser=0,
{'rankingworkouts':theworkouts, {'rankingworkouts':theworkouts,
'interactiveplot':script, 'interactiveplot':script,
'the_div':div, 'the_div':div,
'predictions':predictions,
'cpredictions':cpredictions, 'cpredictions':cpredictions,
'avgpower':avgpower, 'avgpower':avgpower,
'form':form, 'form':form,

Binary file not shown.