Private
Public Access
1
0

Merge branch 'feature/fastestdistance' into develop

This commit is contained in:
Sander Roosendaal
2020-11-10 08:00:14 +01:00
7 changed files with 194 additions and 10 deletions

View File

@@ -371,10 +371,10 @@ def getfastest(df,thevalue,mode='distance'):
tmax = tt.max() tmax = tt.max()
if mode == 'distance': if mode == 'distance':
if dd.max() > thevalue: if dd.max() < thevalue:
return 0 return 0
else: else:
if tt.max() > thevalue: if tt.max() < thevalue:
return 0 return 0
if tmax > 500000: if tmax > 500000:
@@ -418,10 +418,16 @@ def getfastest(df,thevalue,mode='distance'):
restime = np.array(restime) restime = np.array(restime)
distance = np.array(distance) distance = np.array(distance)
#for i in range(len(restime)):
# if restime[i]<thevalue*60*1000:
# print(i,restime[i],distance[i],60*1000*thevalue)
d2 = 0 d2 = 0
if mode == 'distance': if mode == 'distance':
d2 = griddata(distance,restime,[thevalue],method='linear',rescale=True) d2 = griddata(distance,restime,[thevalue],method='linear',rescale=True)
return d2[0]/1000.
else: else:
d2 = griddata(restime,distance,[thevalue],method='linear',rescale=True) d2 = griddata(restime,distance,[thevalue*60*1000],method='linear',rescale=True)
return d2[0]
return d2[0]/1000. return 0

View File

@@ -2131,6 +2131,8 @@ regularsessiontypechoices = (
('test','Mandatory Test'), ('test','Mandatory Test'),
('cycletarget','Total for a time period'), ('cycletarget','Total for a time period'),
('coursetest','OTW test over a course'), ('coursetest','OTW test over a course'),
('fastest_distance','Finds fastest time over a given distance'),
('fastest_time','Finds largest distance rowed over a given time'),
) )
# model for Planned Session (Workout, Challenge, Test) # model for Planned Session (Workout, Challenge, Test)
@@ -2143,6 +2145,8 @@ class PlannedSession(models.Model):
('test','Mandatory Test'), ('test','Mandatory Test'),
('cycletarget','Total for a time period'), ('cycletarget','Total for a time period'),
('coursetest','OTW test over a course'), ('coursetest','OTW test over a course'),
('fastest_distance','Finds fastest time over a given distance'),
('fastest_time','Finds largest distance rowed over a given time'),
('race','Virtual challenge'), ('race','Virtual challenge'),
('indoorrace','Indoor Virtual challenge'), ('indoorrace','Indoor Virtual challenge'),
) )
@@ -2153,6 +2157,8 @@ class PlannedSession(models.Model):
('test','Mandatory Test'), ('test','Mandatory Test'),
('cycletarget','Total for a time period'), ('cycletarget','Total for a time period'),
('coursetest','OTW test over a course'), ('coursetest','OTW test over a course'),
('fastest_distance','Finds fastest time over a given distance'),
('fastest_time','Finds largest distance rowed over a given time'),
) )
sessionmodechoices = ( sessionmodechoices = (
@@ -2274,7 +2280,7 @@ class PlannedSession(models.Model):
else: else:
self.sessionunit = 'None' self.sessionunit = 'None'
if self.sessiontype == 'test' or self.sessiontype == 'indoorrace': if self.sessiontype in ['test','indoorrace','fastest_distance','fastest_time']:
if self.sessionmode not in ['distance','time']: if self.sessionmode not in ['distance','time']:
if self.sessionvalue < 100: if self.sessionvalue < 100:
self.sessionmode = 'time' self.sessionmode = 'time'
@@ -2832,6 +2838,8 @@ class PlannedSessionFormSmall(ModelForm):
('test','Mandatory Test'), ('test','Mandatory Test'),
('cycletarget','Total for a time period'), ('cycletarget','Total for a time period'),
('coursetest','OTW test over a course'), ('coursetest','OTW test over a course'),
('fastest_distance','Finds fastest time over a given distance'),
('fastest_time','Finds largest distance rowed over a given time'),
) )
class Meta: class Meta:

View File

@@ -27,6 +27,16 @@ import pandas as pd
from rowingdata import rowingdata as rrdata from rowingdata import rowingdata as rrdata
from rowingdata import rower as rrower from rowingdata import rower as rrower
def to_time(milliseconds):
seconds = milliseconds/1000.
hours = int(seconds / 3600)
mins = int((seconds%3600)/60)
sec = int((seconds%3600)%60)
microsec = int(1e6*(seconds % 1))
#print(seconds,hours,mins,sec,millisec)
return dt.time(hours,mins,sec,microsec)
# Wrapper around the rowingdata call to catch some exceptions # Wrapper around the rowingdata call to catch some exceptions
# Checks for CSV file, then for gzipped CSV file, and if all fails, returns 0 # Checks for CSV file, then for gzipped CSV file, and if all fails, returns 0
def rdata(file,rower=rrower()): def rdata(file,rower=rrower()):
@@ -57,6 +67,7 @@ import rowers.mytypes as mytypes
import rowers.metrics as metrics import rowers.metrics as metrics
import numpy as np import numpy as np
import rowers.dataprep as dataprep import rowers.dataprep as dataprep
import rowers.datautils as datautils
import rowers.courses as courses import rowers.courses as courses
import iso8601 import iso8601
from iso8601 import ParseError from iso8601 import ParseError
@@ -360,7 +371,7 @@ def add_workouts_plannedsession(ws,ps,r):
ids = [w.id for w in wold] + [w.id for w in ws] ids = [w.id for w in wold] + [w.id for w in ws]
ids = list(set(ids)) ids = list(set(ids))
if len(ids)>1 and ps.sessiontype in ['test','coursetest','race']: if len(ids)>1 and ps.sessiontype in ['test','coursetest','race','fastest_distance','fastest_time']:
errors.append('For tests, you can only attach one workout') errors.append('For tests, you can only attach one workout')
return result,comments,errors return result,comments,errors
@@ -383,6 +394,68 @@ def add_workouts_plannedsession(ws,ps,r):
w.id,ps.course.id,record.id, w.id,ps.course.id,record.id,
w.user.user.email,w.user.user.first_name, w.user.user.email,w.user.user.first_name,
mode='coursetest') mode='coursetest')
if ps.sessiontype == 'fastest_distance':
records = CourseTestResult.objects.filter(userid=w.user.id,plannedsession=ps)
for record in records:
record.delete()
df = dataprep.getsmallrowdata_db(['time','cumdist'],ids=[w.id])
fastest_milliseconds = datautils.getfastest(df,ps.sessionvalue,mode='distance')
if fastest_milliseconds > 0:
duration = to_time(1000.*fastest_milliseconds)
record = CourseTestResult(
userid=w.user.id,
plannedsession = ps,
duration = duration,
coursecompleted = True,
workoutid=w.id,
distance = ps.sessionvalue,
)
record.save()
else:
record = CourseTestResult(
userid = w.user.id,
workoutid=w.id,
plannedsession = ps,
duration = dt.time(0,0),
coursecompleted = True,
distance = ps.sessionvalue,
)
record.save()
if ps.sessiontype == 'fastest_time':
records = CourseTestResult.objects.filter(userid=w.user.id,plannedsession=ps)
for record in records:
record.delete()
df = dataprep.getsmallrowdata_db(['time','cumdist'],ids=[w.id])
fastest_meters = datautils.getfastest(df,ps.sessionvalue,mode='time')
if fastest_meters > 0:
duration = dt.time(0,ps.sessionvalue)
record = CourseTestResult(
userid=w.user.id,
workoutid=w.id,
plannedsession = ps,
duration = duration,
coursecompleted = True,
distance = fastest_meters,
)
record.save()
else:
record = CourseTestResult(
userid = w.user.id,
plannedsession = ps,
workoutid=w.id,
duration = dt.time(0,ps.sessionvalue),
coursecompleted = True,
distance = fastest_meters,
)
record.save()
else: else:
errors.append('Workout %i did not match session dates' % w.id) errors.append('Workout %i did not match session dates' % w.id)
@@ -636,6 +709,27 @@ def is_session_complete_ws(ws,ps):
ratio = record.distance/ps.sessionvalue ratio = record.distance/ps.sessionvalue
return ratio,'partial',completiondate return ratio,'partial',completiondate
return (0,'partial',None) return (0,'partial',None)
elif ps.sessiontype in ['fastest_time','fastest_distance']:
vs = CourseTestResult.objects.filter(plannedsession=ps,userid=ws[0].user.id)
completiondate = ws.reverse()[0].date
wids = [w.id for w in ws]
for record in vs:
if record.workoutid in wids:
if record.coursecompleted:
ratio = 1
return ratio,'on target',completiondate
else:
return 0,'partial',completiondate
if ws:
record = CourseTestResult(
userid = ws[0].user.id,
plannedsession = ps,
workoutid = ws[0].id,
duration = dt.time(0,0),
coursecompleted = False
)
record.save()
return (0,'not done',None)
elif ps.sessiontype == 'coursetest': elif ps.sessiontype == 'coursetest':
vs = CourseTestResult.objects.filter(plannedsession=ps) vs = CourseTestResult.objects.filter(plannedsession=ps)
wids = [w.id for w in ws] wids = [w.id for w in ws]

View File

@@ -205,6 +205,20 @@
if (this.value == 'cycletarget') { if (this.value == 'cycletarget') {
$("td #id_criterium").prop("value","none"); $("td #id_criterium").prop("value","none");
$('#id_guidance').html("<p>For Cycle Targets, the default criterium is 'Approximately'</p>"); $('#id_guidance').html("<p>For Cycle Targets, the default criterium is 'Approximately'</p>");
}
if (this.value == 'fastest_distance') {
$("td #id_criterium").prop("value","exact");
$("td #id_sessionunit").prop("value","m");
$("td #id_sessionmode").prop("value","distance")
$('#id_guidance').html("<p>For Fastest Distance, set an exact number of meters</p>");
}
if (this.value == 'fastest_time') {
$("td #id_criterium").prop("value","exact");
$("td #id_sessionunit").prop("value","min");
$("td #id_sessionmode").prop("value","time")
$('#id_guidance').html("<p>For Fastest Time, set an exact number of minutes</p>");
} }
} }

View File

@@ -41,7 +41,7 @@
</table> </table>
</li> </li>
<li class="grid_2"> <li class="grid_2">
{% if plannedsession.sessiontype == 'test' or plannedsession.sessiontype == 'coursetest' %} {% if plannedsession.sessiontype == 'test' or plannedsession.sessiontype == 'coursetest' or plannedsession.sessiontype == 'fastest_distance' or plannedsession.sessiontype == 'fastest_time' %}
<h2>Ranking</h2> <h2>Ranking</h2>
<table id="rankingtable" class="listtable shortpadded tablesorter" width="80%"> <table id="rankingtable" class="listtable shortpadded tablesorter" width="80%">
<thead> <thead>

View File

@@ -558,7 +558,7 @@ def cpdata(workouts, options):
res = interactive_otwcpchart(powerdf,promember=True,rowername=rowername,r=r, res = interactive_otwcpchart(powerdf,promember=True,rowername=rowername,r=r,
cpfit=cpfit,title=title,type=wtype) cpfit=cpfit,title=title,type=wtype)
print('noot')
script = res[0] script = res[0]
div = res[1] div = res[1]
p1 = res[2] p1 = res[2]

View File

@@ -1876,10 +1876,12 @@ def plannedsession_detach_view(request,id=0,psid=0):
@permission_required('plannedsession.view_session',fn=get_session_by_pk,raise_exception=True) @permission_required('plannedsession.view_session',fn=get_session_by_pk,raise_exception=True)
def plannedsession_view(request,id=0,userid=0): def plannedsession_view(request,id=0,userid=0):
r = getrequestplanrower(request,userid=userid) r = getrequestplanrower(request,userid=userid)
ps = get_object_or_404(PlannedSession,pk=id) ps = get_object_or_404(PlannedSession,pk=id)
if ps.sessiontype in ['race','indoorrace']: if ps.sessiontype in ['race','indoorrace']:
url = reverse('virtualevent_view', url = reverse('virtualevent_view',
kwargs={'id':ps.id} kwargs={'id':ps.id}
@@ -1974,12 +1976,72 @@ def plannedsession_view(request,id=0,userid=0):
) )
wdict['distance'] = ps.course.distance wdict['distance'] = ps.course.distance
wdict['coursecompleted'] = False wdict['coursecompleted'] = False
ranking.append(wdict) ranking.append(wdict)
if ps.sessiontype == 'coursetest': if ps.sessiontype == 'coursetest':
ranking = sorted(ranking, key=lambda k: k['time']) ranking = sorted(ranking, key=lambda k: k['time'])
if ps.sessiontype == 'fastest_distance':
vs = CourseTestResult.objects.filter(plannedsession=ps)
if vs:
for record in vs:
userid = record.userid
uu = User.objects.get(id=userid)
w = Workout.objects.get(id=record.workoutid)
wdict = {
'name': uu.first_name+' '+uu.last_name,
'date': w.date,
'distance': record.distance,
'type': w.workouttype,
'coursecompleted':True,
}
coursecompleted = record.coursecompleted
t = record.duration
wdict['time'] = datetime.timedelta(
hours=t.hour,
seconds=t.second,
minutes=t.minute,
microseconds=t.microsecond
)
wdict['coursecompleted'] = coursecompleted
ranking.append(wdict)
ranking = sorted(ranking, key=lambda k: k['time'])
if ps.sessiontype == 'fastest_time':
vs = CourseTestResult.objects.filter(plannedsession=ps)
if vs:
for record in vs:
userid = record.userid
uu = User.objects.get(id=userid)
w = Workout.objects.get(id=record.workoutid)
wdict = {
'name': uu.first_name+' '+uu.last_name,
'date': w.date,
'distance': record.distance,
'type': w.workouttype,
'coursecompleted':True,
}
coursecompleted = record.coursecompleted
t = record.duration
wdict['time'] = datetime.timedelta(
hours=t.hour,
seconds=t.second,
minutes=t.minute,
microseconds=t.microsecond
)
wdict['coursecompleted'] = coursecompleted
ranking.append(wdict)
ranking = sorted(ranking, key=lambda k: -k['distance'])
# if coursetest, need to reorder the ranking # if coursetest, need to reorder the ranking
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)