Private
Public Access
1
0

Merge branch 'feature/additionalmetrics' into develop

This commit is contained in:
Sander Roosendaal
2017-11-29 15:43:04 +01:00
5 changed files with 161 additions and 83 deletions
+38 -18
View File
@@ -916,6 +916,16 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
w.startdatetime = timezone.now()
w.save()
if privacy == 'visible':
ts = Team.objects.filter(rower=r)
for t in ts:
w.team.add(t)
# put stroke data in database
res = dataprep(row.df, id=w.id, bands=True,
barchart=True, otwpower=True, empower=True, inboard=inboard)
isbreakthrough = False
ishard = False
if workouttype == 'water':
@@ -981,14 +991,6 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
else:
pass
if privacy == 'visible':
ts = Team.objects.filter(rower=r)
for t in ts:
w.team.add(t)
# put stroke data in database
res = dataprep(row.df, id=w.id, bands=True,
barchart=True, otwpower=True, empower=True, inboard=inboard)
return (w.id, message)
@@ -1150,14 +1152,6 @@ def new_workout_from_file(r, f2,
a = MessageAttachment(message=msg,document=f3)
a.save()
# res = myqueue(
# queuelow,
# handle_zip_file,
# r.user.email,
# title,
# f2
# )
return -1, message, f2
# Some people try to upload Concept2 logbook summaries
@@ -1547,8 +1541,27 @@ def getrowdata_db(id=0, doclean=False, convertnewtons=True):
def getsmallrowdata_db(columns, ids=[], doclean=True, workstrokesonly=True):
prepmultipledata(ids)
data = read_cols_df_sql(ids, columns)
data,extracols = read_cols_df_sql(ids, columns)
if extracols and len(ids)==1:
w = Workout.objects.get(id=ids[0])
row = rdata(w.csvfilename)
f = row.df['TimeStamp (sec)'].diff().mean()
if f != 0 and not np.isnan(f):
windowsize = 2 * (int(10. / (f))) + 1
else:
windowsize = 1
for c in extracols:
try:
cdata = row.df[c]
cdata.fillna(inplace=True,method='bfill')
# This doesn't work because sometimes data are duplicated at save
cdata2 = savgol_filter(cdata.values,windowsize,3)
print len(cdata),len(cdata2),'mies'
data[c] = cdata2
except KeyError:
data[c] = 0
# convert newtons
if doclean:
@@ -1622,10 +1635,15 @@ def read_cols_df_sql(ids, columns, convertnewtons=True):
# axx = [ax[0] for ax in axes]
axx = [f.name for f in StrokeData._meta.get_fields()]
extracols = []
for c in columns:
if not c in axx:
columns.remove(c)
extracols.append(c)
columns = list(columns) + ['distance', 'spm', 'workoutid']
columns = [x for x in columns if x != 'None']
columns = list(set(columns))
@@ -1673,7 +1691,7 @@ def read_cols_df_sql(ids, columns, convertnewtons=True):
'averageforce'] * lbstoN
engine.dispose()
return df
return df,extracols
# Read stroke data from the DB for a Workout ID. Returns a pandas dataframe
@@ -1973,6 +1991,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
)
)
if bands:
# HR bands
data['hr_ut2'] = rowdatadf.ix[:, 'hr_ut2']
@@ -2133,6 +2152,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
# write data if id given
if id != 0:
data['workoutid'] = id
engine = create_engine(database_url, echo=False)
with engine.connect() as conn, conn.begin():
data.to_sql('strokedata', engine, if_exists='append', index=False)
+39 -12
View File
@@ -2175,13 +2175,19 @@ def interactive_flex_chart2(id=0,promember=0,
except KeyError:
y1mean = 0
rowdata['xname'] = axlabels[xparam]
rowdata['yname1'] = axlabels[yparam1]
try:
rowdata['yname1'] = axlabels[yparam1]
except KeyError:
rowdata['yname1'] = yparam1
if yparam2 != 'None':
rowdata['yname2'] = axlabels[yparam2]
try:
rowdata['yname2'] = axlabels[yparam2]
except KeyError:
rowdata['yname2'] = yparam2
else:
rowdata['yname2'] = axlabels[yparam1]
rowdata['yname2'] = rowdata['yname1']
# prepare data
@@ -2281,7 +2287,12 @@ def interactive_flex_chart2(id=0,promember=0,
plot.title.text_font_size=value("1.0em")
plot.xaxis.axis_label = axlabels[xparam]
plot.yaxis.axis_label = axlabels[yparam1]
try:
yaxlabel = axlabels[yparam1]
except KeyError:
yaxlabel = yparam1
plot.yaxis.axis_label = yaxlabel
@@ -2289,7 +2300,13 @@ def interactive_flex_chart2(id=0,promember=0,
plot.y_range = yrange1
if (xparam != 'time') and (xparam != 'distance') and (xparam != 'cumdist'):
xrange1 = Range1d(start=yaxminima[xparam],end=yaxmaxima[xparam])
try:
xrange1 = Range1d(start=yaxminima[xparam],
end=yaxmaxima[xparam])
except KeyError:
xrange1 = Range1d(start=rowdata[xparam].min(),
end=rowdata[xparam].max())
plot.x_range = xrange1
if xparam == 'time':
@@ -2313,22 +2330,32 @@ def interactive_flex_chart2(id=0,promember=0,
if yparam2 != 'None':
yrange2 = Range1d(start=yaxminima[yparam2],end=yaxmaxima[yparam2])
try:
yrange2 = Range1d(start=yaxminima[yparam2],
end=yaxmaxima[yparam2])
except KeyError:
yrange2 = Range1d(start=rowdata[yparam2].min(),
end=rowdata[yparam2].max())
plot.extra_y_ranges["yax2"] = yrange2
#= {"yax2": yrange2}
try:
axlegend = axlabels[yparam2]
except KeyError:
axlegend = str(yparam2)+' '
if plottype=='line':
plot.line('x1','y2',color="red",y_range_name="yax2",
legend=axlabels[yparam2],
legend=axlegend,
source=source2)
elif plottype=='scatter':
plot.scatter('x1','y2',source=source2,legend=axlabels[yparam2]
,fill_alpha=0.4,
plot.scatter('x1','y2',source=source2,legend=axlegend,
fill_alpha=0.4,
line_color=None,color="red",y_range_name="yax2")
plot.add_layout(LinearAxis(y_range_name="yax2",
axis_label=axlabels[yparam2]),'right')
axis_label=axlegend),'right')
y2means = Span(location=y2mean,dimension='width',line_color='red',
line_dash=[6,6],line_width=2,y_range_name="yax2")
@@ -2336,7 +2363,7 @@ def interactive_flex_chart2(id=0,promember=0,
plot.add_layout(y2means)
y2label = Label(x=100,y=70,x_units='screen',y_units='screen',
text=axlabels[yparam2]+": {y2mean:6.2f}".format(y2mean=y2mean),
text=axlegend+": {y2mean:6.2f}".format(y2mean=y2mean),
background_fill_alpha=.7,
background_fill_color='white',
text_color='red',
+18 -1
View File
@@ -94,7 +94,15 @@
{% endif %}
{% endfor %}
{% endif %}
{% if promember %}
{% for key, value in extrametrics.items %}
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
{% endfor %}
{% else %}
{% for key, value in extrametrics.items %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endfor %}
{% endif %}
</div>
</div>
@@ -119,6 +127,15 @@
{% endif %}
{% endfor %}
{% endif %}
{% if promember %}
{% for key, value in extrametrics.items %}
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
{% endfor %}
{% else %}
{% for key, value in extrametrics.items %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endfor %}
{% endif %}
</div>
</div>
+5 -5
View File
@@ -363,12 +363,12 @@ urlpatterns = [
url(r'^register/thankyou/$', TemplateView.as_view(template_name='registerthankyou.html'), name='registerthankyou'),
url(r'^workout/(?P<id>\d+)/workflow$',views.workout_workflow_view,
name='workout_workflow_view'),
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<plottype>\w+)/$',views.workout_flexchart3_view),
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<plottype>\w+.*)$',views.workout_flexchart3_view),
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)$',views.workout_flexchart3_view),
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+)/$',views.workout_flexchart3_view),
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+.*)$',views.workout_flexchart3_view),
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)$',views.workout_flexchart3_view),
url(r'^workout/(?P<id>\d+)/flexchart$',views.workout_flexchart3_view),
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>\w+.*)/(?P<plottype>\w+.*)$',views.workout_comparison_view2),
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>\w+.*)/$',views.workout_comparison_view2),
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/(?P<plottype>[\w\ ]+.*)$',views.workout_comparison_view2),
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/$',views.workout_comparison_view2),
url(r'^test\_callback',views.rower_process_testcallback),
url(r'^workout/(?P<id>\d+)/test\_strokedata$',views.strokedataform),
]
+61 -47
View File
@@ -6455,7 +6455,10 @@ def instroke_view(request,id=0):
return HttpResponseRedirect(url)
rowdata = rrdata(csvfile=row.csvfilename)
instrokemetrics = rowdata.get_instroke_columns()
try:
instrokemetrics = rowdata.get_instroke_columns()
except AttributeError:
instrokemetrics = []
return render(request,
@@ -7491,7 +7494,12 @@ def workout_flexchart3_view(request,*args,**kwargs):
if yparam2 == name:
yparam2 = 'spm'
messages.info(request,'To use '+d['verbose_name']+', you have to be Pro member')
# bring back slashes
yparam1 = yparam1.replace('_slsh_','/')
yparam2 = yparam2.replace('_slsh_','/')
xparam = xparam.replace('_slsh_','/')
# create interactive plot
try:
script,div,js_resources,css_resources,workstrokesonly = interactive_flex_chart2(id,xparam=xparam,yparam1=yparam1,
@@ -7517,55 +7525,61 @@ def workout_flexchart3_view(request,*args,**kwargs):
if d['mode'] == 'erg':
axchoicespro.pop(name)
return render(request,
'flexchart3otw.html',
{'the_script':script,
'the_div':div,
'js_res': js_resources,
'css_res':css_resources,
'id':int(id),
'teams':get_my_teams(request.user),
'xparam':xparam,
'yparam1':yparam1,
'yparam2':yparam2,
'plottype':plottype,
'favoritechartnotes':favoritechartnotes,
'mayedit':mayedit,
'promember':promember,
'axchoicesbasic':axchoicesbasic,
'axchoicespro':axchoicespro,
'noylist':noylist,
'workstrokesonly': not workstrokesonly,
'favoritenr':favoritenr,
'maxfav':maxfav,
})
else:
for name,d in rowingmetrics:
if d['mode'] == 'water':
axchoicespro.pop(name)
return render(request,
'flexchart3otw.html',
{'the_script':script,
'the_div':div,
'js_res': js_resources,
'css_res':css_resources,
'teams':get_my_teams(request.user),
'id':int(id),
'xparam':xparam,
'yparam1':yparam1,
'yparam2':yparam2,
'plottype':plottype,
'axchoicesbasic':axchoicesbasic,
'axchoicespro':axchoicespro,
'favoritechartnotes':favoritechartnotes,
'noylist':noylist,
'mayedit':mayedit,
'promember':promember,
'workstrokesonly': not workstrokesonly,
'favoritenr':favoritenr,
'maxfav':maxfav,
})
rowdata = rdata(row.csvfilename)
additionalmetrics = rowdata.get_additional_metrics()
extrametrics = {m.replace('/','_slsh_'):m for m in additionalmetrics}
try:
extrametrics.pop('originalvelo')
except KeyError:
pass
try:
extrametrics.pop('cumdist')
except KeyError:
pass
try:
extrametrics.pop(' Cadence (strokes_slsh_min)')
except KeyError:
pass
try:
extrametrics.pop(' WorkPerStroke (joules)')
except KeyError:
pass
return render(request,
'flexchart3otw.html',
{'the_script':script,
'the_div':div,
'js_res': js_resources,
'css_res':css_resources,
'teams':get_my_teams(request.user),
'id':int(id),
'xparam':xparam,
'yparam1':yparam1,
'yparam2':yparam2,
'plottype':plottype,
'axchoicesbasic':axchoicesbasic,
'axchoicespro':axchoicespro,
'extrametrics':extrametrics,
'favoritechartnotes':favoritechartnotes,
'noylist':noylist,
'mayedit':mayedit,
'promember':promember,
'workstrokesonly': not workstrokesonly,
'favoritenr':favoritenr,
'maxfav':maxfav,
})
# The interactive plot with the colored Heart rate zones