diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 46fe140e..951b287c 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -1037,7 +1037,7 @@ def fetchcp_new(rower,workouts): if len(data)>1: df = pd.concat(data,axis=0) - df = df.groupby(['delta']).max() + df = df = df[df['cp'] == df.groupby(['delta'])['cp'].transform('max')] df = df.sort_values(['delta']).reset_index() diff --git a/rowers/urls.py b/rowers/urls.py index fe50d571..236f8e4d 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -428,6 +428,8 @@ urlpatterns = [ re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/stats/$',views.workout_stats_view,name='workout_stats_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/data/$',views.workout_data_view, name='workout_data_view'), + re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/zeropower/$',views.remove_power_view, + name='remove_power_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/otwsetpower/$',views.workout_otwsetpower_view,name='workout_otwsetpower_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/interactiveotwplot/$',views.workout_otwpowerplot_view,name='workout_otwpowerplot_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/wind/$',views.workout_wind_view,name='workout_wind_view'), diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index a7625a57..31d75fdb 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -1274,6 +1274,103 @@ def workouts_join_select(request, 'teams':get_my_teams(request.user), }) +@login_required() +def remove_power_view(request,id=0): + r = getrower(request.user) + workout = get_workout_by_opaqueid(request,id) + try: + os.remove('media/cpdata{id}.parquet.gz'.format(id=workout.id)) + except OSError: + pass + + f = workout.csvfilename + powerperc = 100*np.array([r.pw_ut2, + r.pw_ut1, + r.pw_at, + r.pw_tr,r.pw_an])/r.ftp + rr = rrower(hrmax=r.max, hrut2=r.ut2, + hrut1=r.ut1, hrat=r.at, + hrtr=r.tr, hran=r.an, ftp=r.ftp, + powerperc=powerperc, powerzones=r.powerzones) + row = rdata(f,rower=rr) + row.df[' Power (watts)'] = 0 + res = dataprep.dataprep(row.df, id=workout.id) + cpdf,delta,cpvalues = dataprep.setcp(workout) + if not cpdf.empty: + if workouttype in mytypes.otwtypes: + res, btvalues, res2 = utils.isbreakthrough( + delta, cpvalues, r.p0, r.p1, r.p2, r.p3, r.cpratio) + cprange = r.cprange + firstdate = datetime.date.today()-datetime.timedelta(days=cprange) + + workouts = Workout.objects.filter( + date__gte=firstdate, + workouttype__in=otwtypes, + user = w.user, + ) + + dd,cpcp,avgpower,workoutnames = dataprep.fetchcp_new(r,workouts) + + powerdf = pd.DataFrame({ + 'Delta':dd, + 'CP':cpcp, + }) + + + 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) + + res2 = datautils.cpfit(powerdf) + if len(powerdf) != 0: + p1 = res2[0] + r.p0 = p1[0] + r.p1 = p1[1] + r.p2 = p1[2] + r.p3 = p1[3] + r.cpratio = res2[3] + r.save() + + elif workouttype in mytypes.otetypes: + res, btvalues, res2 = utils.isbreakthrough( + delta, cpvalues, r.ep0, r.ep1, r.ep2, r.ep3, r.ecpratio) + cprange = r.cprange + firstdate = datetime.date.today()-datetime.timedelta(days=cprange) + workouts = Workout.objects.filter( + date__gte=firstdate, + workouttype__in=otetypes, + user = w.user, + ) + dd,cpcp,avgpower,workoutnames = fetchcp_new(r,workouts) + powerdf = pd.DataFrame({ + 'Delta':dd, + 'CP':cpcp, + }) + + + 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) + res2 = datautils.cpfit(powerdf) + if len(powerdf) != 0: + res = datautils.cpfit(powerdf) + p1 = res2[0] + r.ep0 = p1[0] + r.ep1 = p1[1] + r.ep2 = p1[2] + r.ep3 = p1[3] + r.ecpratio = res2[3] + r.save() + + url = reverse(r.defaultlandingpage, + kwargs = { + 'id':id, + } + ) + return HttpResponseRedirect(url) + # Team comparison @user_passes_test(ispromember,login_url='/rowers/paidplans/', message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality. If you are already a Pro user, please log in to access this functionality",