Private
Public Access
1
0

Merge branch 'feature/cp2' into develop

This commit is contained in:
Sander Roosendaal
2020-10-12 18:42:52 +02:00
6 changed files with 211 additions and 39 deletions

View File

@@ -96,7 +96,7 @@ queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('default')
from rowsandall_app.settings import SITE_URL
from rowers.mytypes import otwtypes,otetypes
from rowers.mytypes import otwtypes,otetypes,rowtypes
from rowers import mytypes
from rowers.database import *
@@ -1016,6 +1016,53 @@ def fetchcperg(rower,theworkouts):
return cpdf
def fetchcp_new(rower,workouts):
data = []
for workout in workouts:
cpfile = 'media/cpdata_{id}.parquet.gz'.format(id=workout.id)
try:
df = pd.read_parquet(cpfile)
data.append(df)
except OSError:
# CP data file doesn't exist yet. has to be created
strokesdf = getsmallrowdata_db(['power','workoutid','time'],ids = [workout.id])
if not strokesdf.empty:
totaltime = strokesdf['time'].max()
try:
powermean = strokesdf['power'].mean()
except KeyError:
powermean = 0
if powermean != 0:
thesecs = totaltime
maxt = 1.05 * thesecs
if maxt > 0:
logarr = datautils.getlogarr(maxt)
dfgrouped = strokesdf.groupby(['workoutid'])
delta, cpvalues, avgpower = datautils.getcp(dfgrouped, logarr)
filename = 'media/cpdata_{id}.parquet.gz'.format(id=workout.id)
df = pd.DataFrame({
'delta':delta,
'cp':cpvalues,
'id':workout.id,
})
df.to_parquet(filename,engine='fastparquet',compression='GZIP')
data.append(df)
if len(data) == 0:
return pd.Series(),pd.Series(),0
if len(data)>1:
df = pd.concat(data,axis=0)
df = df.groupby(['delta']).max()
df = df.sort_values(['delta']).reset_index()
return df['delta'],df['cp'],0
def fetchcp(rower,theworkouts,table='cpdata'):
# get all power data from database (plus workoutid)
@@ -1434,7 +1481,7 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
isbreakthrough = False
ishard = False
if workouttype == 'water':
if workouttype in rowtypes:
df = getsmallrowdata_db(['power', 'workoutid', 'time'], ids=[w.id])
try:
powermean = df['power'].mean()
@@ -1448,15 +1495,26 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
logarr = datautils.getlogarr(maxt)
dfgrouped = df.groupby(['workoutid'])
delta, cpvalues, avgpower = datautils.getcp(dfgrouped, logarr)
filename = 'media/cpdata_{id}.parquet.gz'.format(id=w.id)
cpdf = pd.DataFrame({
'delta':delta,
'cp':cpvalues,
'id':w.id,
})
cpdf.to_parquet(filename,engine='fastparquet',compression='GZIP')
res, btvalues, res2 = utils.isbreakthrough(
delta, cpvalues, r.p0, r.p1, r.p2, r.p3, r.cpratio)
if workouttype in otwtypes:
res, btvalues, res2 = utils.isbreakthrough(
delta, cpvalues, r.p0, r.p1, r.p2, r.p3, r.cpratio)
elif workouttype in otetypes:
res, btvalues, res2 = utils.isbreakthrough(
delta, cpvalues, r.ep0, r.ep1, r.ep2, r.ep3, r.ecpratio)
else:
res = 0
res2 = 0
if res:
isbreakthrough = True
res = datautils.updatecp(delta, cpvalues, r)
res = datautils.updatecp(delta, cpvalues, r,workouttype=workouttype)
if res2 and not isbreakthrough:
ishard = True

View File

@@ -8,12 +8,24 @@ import numpy as np
from scipy.interpolate import griddata
from scipy import optimize
from rowers.mytypes import otwtypes,otetypes,rowtypes
#p0 = [500,350,10,8000]
p0 = [190,200,33,16000]
def updatecp(delta,cpvalues,r):
cp2 = r.p0/(1+delta/r.p2)
cp2 += r.p1/(1+delta/r.p3)
def updatecp(delta,cpvalues,r,workouttype='water'):
if workouttype in otwtypes:
p0 = r.p0
p1 = r.p1
p2 = r.p2
p3 = r.p3
else:
p0 = r.ep0
p1 = r.ep1
p2 = r.ep2
p3 = r.ep3
cp2 = p0/(1+delta/p2)
cp2 += p1/(1+delta/p3)
delta = delta.append(delta)
cp = cpvalues.append(cp2)
@@ -31,11 +43,18 @@ def updatecp(delta,cpvalues,r):
res = cpfit(powerdf)
p1 = res[0]
r.p0 = p1[0]
r.p1 = p1[1]
r.p2 = p1[2]
r.p3 = p1[3]
r.cpratio = res[3]
if workouttype in otwtypes:
r.p0 = p1[0]
r.p1 = p1[1]
r.p2 = p1[2]
r.p3 = p1[3]
r.cpratio = res[3]
else:
r.ep0 = p1[0]
r.ep1 = p1[1]
r.ep2 = p1[2]
r.ep3 = p1[3]
r.ecpratio = res[3]
r.save()
@@ -89,7 +108,10 @@ def cpfit(powerdf):
def getlogarr(maxt):
maxlog10 = np.log10(maxt-5)
logarr = np.arange(50)*maxlog10/50.
#print(maxlog10,round(maxlog10))
aantal = 10*round(maxlog10)
logarr = np.arange(aantal+1)/10.
res = []
for la in logarr:
try:

View File

@@ -1036,7 +1036,7 @@ analysischoices = (
('flexall','Cumulative Flex Chart'),
('stats','Statistics'),
('compare','Compare'),
('cp','CP Chart')
('cp','CP chart'),
)

View File

@@ -2985,6 +2985,13 @@ def auto_delete_file_on_delete(sender, instance, **kwargs):
except FileNotFoundError:
pass
# remove parquet file
try:
dirname = 'media/cpdata_{id}.parquet.gz'.format(id=instance.id)
os.remove(dirname)
except FileNotFoundError:
pass
@receiver(models.signals.post_delete,sender=Workout)
def update_duplicates_on_delete(sender, instance, **kwargs):
if instance.id:

View File

@@ -2,7 +2,7 @@
{% load staticfiles %}
{% load rowerfilters %}
{% block title %}Workouts{% endblock %}
{% block title %}Analysis{% endblock %}
{% block main %}
<script>
@@ -16,14 +16,14 @@
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$(function() {
// Get the form fields and hidden div
var modality = $("#id_modality");
var hidden = $("#id_waterboattype");
// Hide the fields.
// Use JS to do this in case the user doesn't have JS
// Use JS to do this in case the user doesn't have JS
// enabled.
hidden.hide();
@@ -32,8 +32,8 @@
hidden.show();
}
// Setup an event listener for when the state of the
// Setup an event listener for when the state of the
// checkbox changes.
modality.change(function() {
// Check to see if the checkbox is checked.
@@ -48,10 +48,10 @@
// Make sure that the hidden fields are indeed
// hidden.
hidden.hide();
// You may also want to clear the value of the
// hidden fields here. Just in case somebody
// shows the fields, enters data to them and then
// You may also want to clear the value of the
// hidden fields here. Just in case somebody
// shows the fields, enters data to them and then
// unticks the checkbox.
//
// This would do the job:
@@ -67,7 +67,7 @@
<script>
// script for chart options form
$(function() {
// Get the form fields and hidden div
var functionfield = $("#id_function");
var plotfield = $("#id_plotfield").parent().parent();
@@ -82,14 +82,16 @@
var spmmax = $("#id_spmmax").parent().parent();
var workmin = $("#id_workmin").parent().parent();
var workmax = $("#id_workmax").parent().parent();
var xaxis = $("#id_xaxis").parent().parent();
var yaxis1 = $("#id_yaxis1").parent().parent();
var yaxis2 = $("#id_yaxis2").parent().parent();
var plottype = $("#id_plottype").parent().parent();
var xaxis = $("#id_xaxis").parent().parent();
var yaxis1 = $("#id_yaxis1").parent().parent();
var yaxis2 = $("#id_yaxis2").parent().parent();
var plottype = $("#id_plottype").parent().parent();
var reststrokes = $("#id_includereststrokes").parent().parent();
// Hide the fields.
// Use JS to do this in case the user doesn't have JS
// Use JS to do this in case the user doesn't have JS
// enabled.
plotfield.hide();
x_param.hide();
@@ -102,6 +104,11 @@
yaxis1.hide();
yaxis2.hide();
plottype.hide();
reststrokes.hide();
workmin.hide();
workmax.hide();
spmmin.hide();
spmmax.hide();
if (functionfield.val() == 'boxplot') {
plotfield.show();
@@ -136,8 +143,8 @@
plottype.show();
}
// Setup an event listener for when the state of the
// Setup an event listener for when the state of the
// checkbox changes.
functionfield.change(function() {
// Check to see if the checkbox is checked.
@@ -161,6 +168,7 @@
yaxis1.hide();
yaxis2.hide();
plottype.hide();
reststrokes.show();
}
else if (Value=='histo') {
plotfield.show();
@@ -178,6 +186,7 @@
yaxis1.hide();
yaxis2.hide();
plottype.hide();
reststrokes.show();
}
else if (Value=='trendflex') {
@@ -196,6 +205,7 @@
yaxis1.hide();
yaxis2.hide();
plottype.hide();
reststrokes.show();
}
else if (Value=='flexall') {
@@ -214,6 +224,7 @@
binsize.hide();
plottype.hide();
errorbars.hide();
reststrokes.show();
}
else if (Value=='stats') {
xaxis.hide();
@@ -227,6 +238,7 @@
binsize.hide();
errorbars.hide();
plottype.hide();
reststrokes.show();
}
else if (Value=='compare') {
xaxis.show();
@@ -244,10 +256,29 @@
binsize.hide();
plottype.show();
errorbars.hide();
reststrokes.show();
}
else if (Value=='cp') {
plotfield.hide();
spmmin.hide();
spmmax.hide();
workmin.hide();
workmax.hide();
x_param.hide();
y_param.hide();
groupby.hide();
palette.hide();
binsize.hide();
errorbars.hide();
xaxis.hide();
yaxis1.hide();
yaxis2.hide();
plottype.hide();
reststrokes.hide();
}
});
});
});
</script>
<div id="id_css_res">
@@ -285,9 +316,9 @@
<input type="submit" value="GO"></input>
</form>
<form enctype="multipart/form-data" action="" method="post">
{% if workouts %}
<input type="checkbox" onClick="toggle(this)" /> Toggle All<br/>
<table width="100%" class="listtable">
{{ form.as_table }}

View File

@@ -500,6 +500,60 @@ def histodata(workouts, options):
return(script,div)
def cpdata(workouts, options):
userid = options['userid']
u = User.objects.get(id=userid)
r = u.rower
ids = [w.id for w in workouts]
delta, cpvalue, avgpower = dataprep.fetchcp_new(r,workouts)
powerdf = pd.DataFrame({
'Delta':delta,
'CP':cpvalue,
})
if powerdf.empty:
return('','<p>No valid data found</p>')
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)
rowername = r.user.first_name+" "+r.user.last_name
if len(powerdf) !=0 :
res = interactive_otwcpchart(powerdf,promember=True,rowername=rowername)
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[4]
else:
script = ''
div = '<p>No ranking pieces found.</p>'
paulslope = 1
paulintercept = 1
p1 = [1,1,1,1]
message = ""
scripta = script.split('\n')[2:-1]
script = ''.join(scripta)
return (script,div)
def statsdata(workouts, options):
includereststrokes = options['includereststrokes']
spmmin = options['spmmin']
@@ -726,7 +780,7 @@ def analysis_view_data(request,userid=0):
elif function == 'compare':
script,div = comparisondata(workouts,options)
elif function == 'cp':
script, div = cpdata(workouts,options)
script, div = cpdata(workouts, options)
else:
script = ''
div = 'Unknown analysis functions'