diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 982733b7..01557032 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -428,7 +428,7 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower', isbreakthrough = False if workouttype == 'water': 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 res = datautils.updatecp(delta,cpvalues,r) diff --git a/rowers/datautils.py b/rowers/datautils.py index 7c1d9136..298280d4 100644 --- a/rowers/datautils.py +++ b/rowers/datautils.py @@ -27,6 +27,7 @@ def updatecp(delta,cpvalues,r): r.p1 = p1[1] r.p2 = p1[2] r.p3 = p1[3] + r.cpratio = res[3] r.save() diff --git a/rowers/forms.py b/rowers/forms.py index 4e57a619..8b1e7622 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -131,7 +131,7 @@ class PredictedPieceForm(forms.Form): ) pieceunit = forms.ChoiceField(required=True,choices=unitchoices, initial='t',label='Unit') - value = forms.IntegerField(initial=10,label='Value') + value = forms.FloatField(initial=10,label='Value') class Meta: fields = ['value','pieceunit'] diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 7200497e..b1c7bada 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -687,7 +687,7 @@ def interactive_otwcpchart(powerdf,promember=0): script, div = components(plot) - return [script,div,p1,message] + return [script,div,p1,ratio,message] def interactive_cpchart(thedistances,thesecs,theavpower, theworkouts,promember=0): diff --git a/rowers/models.py b/rowers/models.py index 6922265f..1c305c70 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -178,6 +178,7 @@ class Rower(models.Model): p1 = models.FloatField(default=1.0,verbose_name="CP p2") p2 = models.FloatField(default=1.0,verbose_name="CP p3") 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") diff --git a/rowers/templates/otwrankings.html b/rowers/templates/otwrankings.html index a78330e4..871d79ff 100644 --- a/rowers/templates/otwrankings.html +++ b/rowers/templates/otwrankings.html @@ -164,14 +164,15 @@ Duration - Power + Power (upper) + Power {% for pred in cpredictions %} {% for key, value in pred.items %} - {% if key == "power" %} + {% if key == "power" or key == "upper" %} {{ value }} W {% endif %} {% if key == "duration" %} diff --git a/rowers/utils.py b/rowers/utils.py index 22c4680f..3fd67d94 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -76,11 +76,13 @@ def geo_distance(lat1,lon1,lat2,lon2): 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 += p1/(1+delta/p3) + pwr *= ratio + res = np.sum(cpvalues>pwr) return res>1 diff --git a/rowers/views.py b/rowers/views.py index 68781044..bef20278 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -2955,14 +2955,16 @@ def otwrankings_view(request,theuser=0, script = res[0] div = res[1] p1 = res[2] + ratio = res[3] r.p0 = p1[0] r.p1 = p1[1] r.p2 = p1[2] r.p3 = p1[3] + r.cpratio = ratio r.save() paulslope = 1 paulintercept = 1 - message = res[3] + message = res[4] else: script = '' div = '

No ranking pieces found.

' @@ -2977,18 +2979,20 @@ def otwrankings_view(request,theuser=0, clean = form.is_valid() value = form.cleaned_data['value'] hourvalue,value = divmod(value,60) + hourvalue = int(hourvalue) + minutevalue = int(value) + value = int(60*(value-minutevalue)) if hourvalue >= 24: hourvalue = 23 - rankingdurations.append(datetime.time(minute=value,hour=hourvalue)) + rankingdurations.append(datetime.time(minute=minutevalue, + hour=hourvalue, + second=value)) else: form = PredictedPieceForm() - predictions = [] cpredictions = [] - - for rankingduration in rankingdurations: t = 3600.*rankingduration.hour t += 60.*rankingduration.minute @@ -3000,13 +3004,17 @@ def otwrankings_view(request,theuser=0, pwr = p1[0]/(1+t/p1[2]) pwr += p1[1]/(1+t/p1[3]) + if pwr <= 0: pwr = 50. + if not np.isnan(pwr): + pwr2 = pwr*ratio a = { 'duration':timedeltaconv(t), - 'power':int(pwr)} + 'power':int(pwr), + 'upper':int(pwr2)} cpredictions.append(a) @@ -3017,7 +3025,6 @@ def otwrankings_view(request,theuser=0, {'rankingworkouts':theworkouts, 'interactiveplot':script, 'the_div':div, - 'predictions':predictions, 'cpredictions':cpredictions, 'avgpower':avgpower, 'form':form, diff --git a/rowsanda_107501 b/rowsanda_107501 index c733aeb4..623c0cb6 100644 Binary files a/rowsanda_107501 and b/rowsanda_107501 differ