hr pie v1
This commit is contained in:
@@ -1382,398 +1382,6 @@ def ajax_agegrouprecords(request,
|
||||
)
|
||||
|
||||
|
||||
# Show ranking distances including predicted paces
|
||||
@login_required()
|
||||
@permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True)
|
||||
def rankings_view2(request, userid=0,
|
||||
startdate=timezone.now()-datetime.timedelta(days=365),
|
||||
enddate=timezone.now(),
|
||||
deltadays=-1,
|
||||
startdatestring="",
|
||||
enddatestring=""):
|
||||
|
||||
if deltadays > 0: # pragma: no cover
|
||||
startdate = enddate-datetime.timedelta(days=int(deltadays))
|
||||
|
||||
if startdatestring != "": # pragma: no cover
|
||||
startdate = iso8601.parse_date(startdatestring)
|
||||
|
||||
if enddatestring != "": # pragma: no cover
|
||||
enddate = iso8601.parse_date(enddatestring)
|
||||
|
||||
if enddate < startdate: # pragma: no cover
|
||||
s = enddate
|
||||
enddate = startdate
|
||||
startdate = s
|
||||
|
||||
if userid == 0:
|
||||
userid = request.user.id
|
||||
else:
|
||||
lastupdated = "1900-01-01"
|
||||
|
||||
promember = 0
|
||||
r = getrequestrower(request, userid=userid)
|
||||
theuser = r.user
|
||||
|
||||
wcdurations = []
|
||||
wcpower = []
|
||||
|
||||
lastupdated = "1900-01-01"
|
||||
userid = 0
|
||||
if 'options' in request.session:
|
||||
options = request.session['options']
|
||||
try:
|
||||
wcdurations = options['wcdurations']
|
||||
wcpower = options['wcpower']
|
||||
lastupdated = options['lastupdated']
|
||||
except KeyError: # pragma: no cover
|
||||
pass
|
||||
try:
|
||||
userid = options['userid']
|
||||
except KeyError: # pragma: no cover
|
||||
userid = 0
|
||||
else:
|
||||
options = {}
|
||||
|
||||
lastupdatedtime = arrow.get(lastupdated).timestamp()
|
||||
current_time = arrow.utcnow().timestamp()
|
||||
|
||||
deltatime_seconds = current_time - lastupdatedtime
|
||||
recalc = False
|
||||
if str(userid) != str(theuser) or deltatime_seconds > 3600:
|
||||
recalc = True
|
||||
options['lastupdated'] = arrow.utcnow().isoformat()
|
||||
else: # pragma: no cover
|
||||
recalc = False
|
||||
|
||||
options['userid'] = theuser.id
|
||||
|
||||
if r.birthdate:
|
||||
age = calculate_age(r.birthdate)
|
||||
else:
|
||||
age = 0
|
||||
|
||||
agerecords = CalcAgePerformance.objects.filter(
|
||||
age=age,
|
||||
sex=r.sex,
|
||||
weightcategory=r.weightcategory)
|
||||
|
||||
if len(agerecords) == 0:
|
||||
recalc = True
|
||||
wcpower = []
|
||||
wcdurations = []
|
||||
else:
|
||||
wcdurations = []
|
||||
wcpower = []
|
||||
for record in agerecords:
|
||||
wcdurations.append(record.duration)
|
||||
wcpower.append(record.power)
|
||||
|
||||
options['wcpower'] = wcpower
|
||||
options['wcdurations'] = wcdurations
|
||||
if theuser:
|
||||
options['userid'] = theuser.id
|
||||
|
||||
request.session['options'] = options
|
||||
|
||||
result = request.user.is_authenticated and ispromember(request.user)
|
||||
if result:
|
||||
promember = 1
|
||||
|
||||
# get all indoor rows in date range
|
||||
|
||||
# process form
|
||||
if request.method == 'POST' and "daterange" in request.POST:
|
||||
dateform = DateRangeForm(request.POST)
|
||||
deltaform = DeltaDaysForm(request.POST)
|
||||
if dateform.is_valid():
|
||||
startdate = dateform.cleaned_data['startdate']
|
||||
enddate = dateform.cleaned_data['enddate']
|
||||
if startdate > enddate: # pragma: no cover
|
||||
s = enddate
|
||||
enddate = startdate
|
||||
startdate = s
|
||||
elif request.method == 'POST' and "datedelta" in request.POST: # pragma: no cover
|
||||
deltaform = DeltaDaysForm(request.POST)
|
||||
if deltaform.is_valid():
|
||||
deltadays = deltaform.cleaned_data['deltadays']
|
||||
if deltadays:
|
||||
enddate = timezone.now()
|
||||
startdate = enddate-datetime.timedelta(days=deltadays)
|
||||
if startdate > enddate:
|
||||
s = enddate
|
||||
enddate = startdate
|
||||
startdate = s
|
||||
dateform = DateRangeForm(initial={
|
||||
'startdate': startdate,
|
||||
'enddate': enddate,
|
||||
})
|
||||
else:
|
||||
dateform = DateRangeForm()
|
||||
deltaform = DeltaDaysForm()
|
||||
|
||||
else:
|
||||
dateform = DateRangeForm(initial={
|
||||
'startdate': startdate,
|
||||
'enddate': enddate,
|
||||
})
|
||||
deltaform = DeltaDaysForm()
|
||||
|
||||
# get all 2k (if any) - this rower, in date range
|
||||
try:
|
||||
r = getrower(theuser)
|
||||
except Rower.DoesNotExist: # pragma: no cover
|
||||
r = 0
|
||||
|
||||
uu = theuser
|
||||
|
||||
# test to fix bug
|
||||
startdate = datetime.datetime.combine(startdate, datetime.time())
|
||||
enddate = datetime.datetime.combine(enddate, datetime.time(23, 59, 59))
|
||||
startdate = arrow.get(startdate).datetime
|
||||
enddate = arrow.get(enddate).datetime
|
||||
|
||||
thedistances = []
|
||||
theworkouts = []
|
||||
thesecs = []
|
||||
|
||||
rankingdistances.sort()
|
||||
rankingdurations.sort()
|
||||
|
||||
for rankingdistance in rankingdistances:
|
||||
|
||||
workouts = Workout.objects.filter(
|
||||
user=r, distance=rankingdistance,
|
||||
workouttype__in=['rower', 'dynamic', 'slides'],
|
||||
rankingpiece=True,
|
||||
startdatetime__gte=startdate,
|
||||
startdatetime__lte=enddate).order_by('duration')
|
||||
if workouts:
|
||||
thedistances.append(rankingdistance)
|
||||
theworkouts.append(workouts[0])
|
||||
|
||||
timesecs = 3600*workouts[0].duration.hour
|
||||
timesecs += 60*workouts[0].duration.minute
|
||||
timesecs += workouts[0].duration.second
|
||||
timesecs += 1.e-6*workouts[0].duration.microsecond
|
||||
|
||||
thesecs.append(timesecs)
|
||||
|
||||
for rankingduration in rankingdurations:
|
||||
|
||||
workouts = Workout.objects.filter(
|
||||
user=r, duration=rankingduration,
|
||||
workouttype='rower',
|
||||
rankingpiece=True,
|
||||
startdatetime__gte=startdate,
|
||||
startdatetime__lte=enddate).order_by('-distance')
|
||||
if workouts:
|
||||
thedistances.append(workouts[0].distance)
|
||||
theworkouts.append(workouts[0])
|
||||
|
||||
timesecs = 3600*workouts[0].duration.hour
|
||||
timesecs += 60*workouts[0].duration.minute
|
||||
timesecs += workouts[0].duration.second
|
||||
timesecs += 1.e-5*workouts[0].duration.microsecond
|
||||
|
||||
thesecs.append(timesecs)
|
||||
|
||||
thedistances = np.array(thedistances)
|
||||
thesecs = np.array(thesecs)
|
||||
|
||||
thevelos = thedistances/thesecs
|
||||
theavpower = 2.8*(thevelos**3)
|
||||
|
||||
# create interactive plot
|
||||
if len(thedistances) != 0:
|
||||
res = interactive_cpchart(
|
||||
r, thedistances, thesecs, theavpower,
|
||||
theworkouts, promember=promember,
|
||||
wcdurations=wcdurations, wcpower=wcpower
|
||||
)
|
||||
script = res[0]
|
||||
div = res[1]
|
||||
paulslope = res[2]
|
||||
paulintercept = res[3]
|
||||
p1 = res[4]
|
||||
message = res[5]
|
||||
else:
|
||||
script = ''
|
||||
div = '<p>No ranking pieces found.</p>'
|
||||
paulslope = 1
|
||||
paulintercept = 1
|
||||
p1 = [1, 1, 1, 1]
|
||||
message = ""
|
||||
|
||||
if request.method == 'POST' and "piece" in request.POST: # pragma: no cover
|
||||
form = PredictedPieceForm(request.POST)
|
||||
if form.is_valid():
|
||||
value = form.cleaned_data['value']
|
||||
hourvalue, value = divmod(value, 60)
|
||||
if hourvalue >= 24:
|
||||
hourvalue = 23
|
||||
pieceunit = form.cleaned_data['pieceunit']
|
||||
if pieceunit == 'd':
|
||||
rankingdistances.append(value)
|
||||
else:
|
||||
rankingdurations.append(datetime.time(
|
||||
minute=int(value), hour=int(hourvalue)))
|
||||
else:
|
||||
form = PredictedPieceForm()
|
||||
|
||||
rankingdistances.sort()
|
||||
rankingdurations.sort()
|
||||
|
||||
predictions = []
|
||||
cpredictions = []
|
||||
|
||||
for rankingdistance in rankingdistances:
|
||||
# Paul's model
|
||||
p = paulslope*np.log10(rankingdistance)+paulintercept
|
||||
velo = 500./p
|
||||
t = rankingdistance/velo
|
||||
pwr = 2.8*(velo**3)
|
||||
try:
|
||||
pwr = int(pwr)
|
||||
except (ValueError, AttributeError): # pragma: no cover
|
||||
pwr = 0
|
||||
|
||||
a = {'distance': rankingdistance,
|
||||
'duration': timedeltaconv(t),
|
||||
'pace': timedeltaconv(p),
|
||||
'power': int(pwr)}
|
||||
predictions.append(a)
|
||||
|
||||
# CP model -
|
||||
pwr2 = p1[0]/(1+t/p1[2])
|
||||
pwr2 += p1[1]/(1+t/p1[3])
|
||||
|
||||
if pwr2 <= 0: # pragma: no cover
|
||||
pwr2 = 50.
|
||||
|
||||
velo2 = (pwr2/2.8)**(1./3.)
|
||||
|
||||
if np.isnan(velo2) or velo2 <= 0: # pragma: no cover
|
||||
velo2 = 1.0
|
||||
|
||||
t2 = rankingdistance/velo2
|
||||
|
||||
pwr3 = p1[0]/(1+t2/p1[2])
|
||||
pwr3 += p1[1]/(1+t2/p1[3])
|
||||
|
||||
if pwr3 <= 0: # pragma: no cover
|
||||
pwr3 = 50.
|
||||
|
||||
velo3 = (pwr3/2.8)**(1./3.)
|
||||
if np.isnan(velo3) or velo3 <= 0: # pragma: no cover
|
||||
velo3 = 1.0
|
||||
|
||||
t3 = rankingdistance/velo3
|
||||
p3 = 500./velo3
|
||||
|
||||
a = {'distance': rankingdistance,
|
||||
'duration': timedeltaconv(t3),
|
||||
'pace': timedeltaconv(p3),
|
||||
'power': int(pwr3)}
|
||||
cpredictions.append(a)
|
||||
|
||||
for rankingduration in rankingdurations:
|
||||
t = 3600.*rankingduration.hour
|
||||
t += 60.*rankingduration.minute
|
||||
t += rankingduration.second
|
||||
t += rankingduration.microsecond/1.e6
|
||||
|
||||
# Paul's model
|
||||
ratio = paulintercept/paulslope
|
||||
|
||||
u = ((2**(2+ratio))*(5.**(3+ratio))*t*np.log(10))/paulslope
|
||||
|
||||
d = 500*t*np.log(10.)
|
||||
d = d/(paulslope*lambertw(u))
|
||||
d = d.real
|
||||
|
||||
velo = d/t
|
||||
p = 500./velo
|
||||
pwr = 2.8*(velo**3)
|
||||
try:
|
||||
a = {'distance': int(d),
|
||||
'duration': timedeltaconv(t),
|
||||
'pace': timedeltaconv(p),
|
||||
'power': int(pwr)}
|
||||
predictions.append(a)
|
||||
except: # pragma: no cover
|
||||
pass
|
||||
|
||||
# CP model
|
||||
pwr = p1[0] / (1 + t / p1[2])
|
||||
pwr += p1[1] / (1 + t / p1[3])
|
||||
|
||||
if pwr <= 0: # pragma: no cover
|
||||
pwr = 50.
|
||||
|
||||
velo = (pwr / 2.8)**(1. / 3.)
|
||||
|
||||
if np.isnan(velo) or velo <= 0: # pragma: no cover
|
||||
velo = 1.0
|
||||
|
||||
d = t * velo
|
||||
p = 500. / velo
|
||||
a = {'distance': int(d),
|
||||
'duration': timedeltaconv(t),
|
||||
'pace': timedeltaconv(p),
|
||||
'power': int(pwr)}
|
||||
cpredictions.append(a)
|
||||
|
||||
if recalc:
|
||||
wcdurations = []
|
||||
wcpower = []
|
||||
durations = [1, 4, 30, 60]
|
||||
distances = [100, 500, 1000, 2000, 5000, 6000, 10000, 21097, 42195]
|
||||
|
||||
df = pd.DataFrame(
|
||||
list(
|
||||
C2WorldClassAgePerformance.objects.filter(
|
||||
sex=r.sex,
|
||||
weightcategory=r.weightcategory
|
||||
).values()
|
||||
)
|
||||
)
|
||||
|
||||
jsondf = df.to_json()
|
||||
|
||||
job = myqueue(queue,
|
||||
handle_getagegrouprecords,
|
||||
jsondf, distances, durations, age, r.sex, r.weightcategory)
|
||||
try:
|
||||
request.session['async_tasks'] += [(job.id, 'agegrouprecords')]
|
||||
except KeyError:
|
||||
request.session['async_tasks'] = [(job.id, 'agegrouprecords')]
|
||||
|
||||
messages.error(request, message)
|
||||
return render(request, 'rankings.html',
|
||||
{'rankingworkouts': theworkouts,
|
||||
'interactiveplot': script,
|
||||
'the_div': div,
|
||||
'predictions': predictions,
|
||||
'cpredictions': cpredictions,
|
||||
'nrdata': len(thedistances),
|
||||
'form': form,
|
||||
'dateform': dateform,
|
||||
'deltaform': deltaform,
|
||||
'id': theuser,
|
||||
'theuser': uu,
|
||||
'rower': r,
|
||||
'active': 'nav-analysis',
|
||||
'age': age,
|
||||
'sex': r.sex,
|
||||
'recalc': recalc,
|
||||
'weightcategory': r.weightcategory,
|
||||
'startdate': startdate,
|
||||
'enddate': enddate,
|
||||
'teams': get_my_teams(request.user),
|
||||
})
|
||||
|
||||
|
||||
@login_required()
|
||||
def otecp_toadmin_view(request, theuser=0,
|
||||
startdate=timezone.now() - datetime.timedelta(days=365),
|
||||
|
||||
@@ -630,50 +630,6 @@ def otw_use_gps(request, id=0):
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
# Show Stroke power histogram for a workout
|
||||
@login_required()
|
||||
@permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True)
|
||||
def workout_histo_view(request, id=0):
|
||||
w = get_workoutuser(id, request)
|
||||
r = getrequestrower(request)
|
||||
|
||||
mayedit = 0
|
||||
if w.user == r:
|
||||
mayedit = 1
|
||||
|
||||
res = interactive_histoall([w], 'power', False)
|
||||
script = res[0]
|
||||
div = res[1]
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url': '/rowers/list-workouts/',
|
||||
'name': 'Workouts'
|
||||
},
|
||||
{
|
||||
'url': get_workout_default_page(request, id),
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url': reverse('workout_histo_view', kwargs={'id': id}),
|
||||
'name': 'Histogram'
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
return render(request,
|
||||
'histo_single.html',
|
||||
{'interactiveplot': script,
|
||||
'breadcrumbs': breadcrumbs,
|
||||
'active': 'nav-workouts',
|
||||
'workout': w,
|
||||
'rower': r,
|
||||
'the_div': div,
|
||||
'id': id,
|
||||
'mayedit': mayedit,
|
||||
'teams': get_my_teams(request.user),
|
||||
})
|
||||
|
||||
|
||||
# add a workout manually
|
||||
@login_required()
|
||||
|
||||
Reference in New Issue
Block a user