From dd48d66c3aa73dc337ce42ee76cab43df2a92931 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 16 Jan 2018 17:04:30 +0100 Subject: [PATCH] first attempt --- rowers/datautils.py | 3 +- rowers/models.py | 4 ++- rowers/urls.py | 2 ++ rowers/views.py | 80 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/rowers/datautils.py b/rowers/datautils.py index 5aba0141..1358e0d6 100644 --- a/rowers/datautils.py +++ b/rowers/datautils.py @@ -300,7 +300,8 @@ def getmaxwattinterval(tt,ww,i): wmax = 0 deltat = 0 except KeyError: - pass + wmax = 0 + deltat = 0 else: wmax = 0 deltat = 0 diff --git a/rowers/models.py b/rowers/models.py index db2fb086..f96ff624 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -248,13 +248,15 @@ class PowerTimeFitnessMetric(models.Model): ('water','On the water') ) - data = models.DateField(default=timezone.now) + date = models.DateField(default=timezone.now) user = models.ForeignKey(User) PowerFourMin = models.FloatField(default=0) PowerTwoK = models.FloatField(default=0) PowerOneHour = models.FloatField(default=0) workoutmode = models.CharField(default='rower',choices=modechoices, max_length=40) + class Meta: + db_table = 'powertimefitnessmetric' class C2WorldClassAgePerformance(models.Model): weightcategories = ( diff --git a/rowers/urls.py b/rowers/urls.py index 7d345028..b43cc09d 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -125,6 +125,8 @@ urlpatterns = [ url(r'^agegroupcp/(?P\d+)/(?P\d+)$',views.agegroupcpview), url(r'^ajax_agegroup/(?P\d+)/(?P\w+.*)/(?P\w+.*)/(?P\d+)$', views.ajax_agegrouprecords), + url(r'^updatefitness/(?P\w+.*)/(?P\d+)$',views.fitness_metric_view), + url(r'^updatefitness$',views.fitness_metric_view), url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/(?P\d+)m$', views.agegrouprecordview), url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/(?P\d+)min$', diff --git a/rowers/views.py b/rowers/views.py index 09571a41..61aa9644 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -238,6 +238,7 @@ from io import BytesIO from scipy.special import lambertw from dataprep import timedeltaconv +from dataprep import getsmallrowdata_db from scipy.interpolate import griddata @@ -3206,6 +3207,85 @@ def addmanual_view(request): {'form':form, }) +@login_required() +def fitness_metric_view(request,mode='rower',days=42): + r = getrower(request.user) + startdate = timezone.now()-datetime.timedelta(days=days) + if mode == 'rower': + workouts = Workout.objects.filter( + user=r, + workouttype__in=['rower','dynamic','slides'], + startdatetime__gte=startdate) + else: + workouts = Workout.objects.filter( + user=r, + workouttype__in=['water','coastal'], + startdatetime__gte=startdate) + + theids = [int(w.id) for w in workouts] + columns = ['power','workoutid','time'] + df = getsmallrowdata_db(columns,ids=theids) + df.dropna(inplace=True,axis=0) + + if df.empty: + # change this + return 'aap' + + # df is not empty. We continue + dfgrouped = df.groupby(['workoutid']) + maxt = 1.05*df['time'].max()/1000. + + logarr = datautils.getlogarr(maxt) + + delta,cpvalue,avgpower = datautils.getcp(dfgrouped,logarr) + + powerdf = pd.DataFrame({ + 'Delta':delta, + 'CP':cpvalue, + }) + + powerdf = powerdf[powerdf['CP']>0] + 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) + + p1,fitt,fitpower,ratio = datautils.cpfit(powerdf) + # This is code duplication from datautils -- correct asap + fitfunc = lambda pars,x: abs(pars[0])/(1+(x/abs(pars[2]))) + abs(pars[1])/(1+(x/abs(pars[3]))) + + powerfourmin = fitfunc(p1,240.) + powerhour = fitfunc(p1,3600.) + + # 2k power + velofourmin = (powerfourmin/2.8)**(1./3.) + dfourmin = 240.*velofourmin + dratio = 2000./dfourmin + pacefourmin = 500./velofourmin + + # assume 5 sec per doubling drop + pace2k = pacefourmin + 5.*np.log10(dratio)/np.log10(2.) + velo2k = 500./pace2k + t2k = 2000./velo2k + pwr2k = fitfunc(p1,t2k) + velo2 = (pwr2k/2.8)**(1./3.) + if np.isnan(velo2) or velo2 <= 0: + velo2 = 1.0 + + t2 = 2000./velo2 + + pwr2k = fitfunc(p1,t2) + + velo3 = (pwr2k/2.8)**(1./3.) + + t3 = 2000./velo3 + + power2k = fitfunc(p1,t3) + + print powerfourmin,power2k,powerhour + + return HttpResponse("success") + + # Show ranking distances including predicted paces @login_required() def rankings_view(request,theuser=0,