Private
Public Access
1
0

Merge branch 'release/v3.51'

This commit is contained in:
Sander Roosendaal
2017-08-08 13:28:37 +02:00
9 changed files with 307 additions and 45 deletions
+54 -2
View File
@@ -211,6 +211,12 @@ def clean_df_stats(datadf,workstrokesonly=True,ignorehr=True,
except KeyError: except KeyError:
pass pass
try:
mask = datadf['efficiency'] < 0.
datadf.loc[mask,'efficiency'] = np.nan
except KeyError:
pass
try: try:
mask = datadf['pace']/1000. < 60. mask = datadf['pace']/1000. < 60.
datadf.loc[mask,'pace'] = np.nan datadf.loc[mask,'pace'] = np.nan
@@ -403,6 +409,15 @@ def timedeltaconv(x):
return dt return dt
def paceformatsecs(values):
out = []
for v in values:
td = timedeltaconv(v)
formattedv = strfdelta(td)
out.append(formattedv)
return out
# Processes painsled CSV file to database # Processes painsled CSV file to database
def save_workout_database(f2,r,dosmooth=True,workouttype='rower', def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
dosummary=True,title='Workout', dosummary=True,title='Workout',
@@ -445,7 +460,8 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
if consistencychecks: if consistencychecks:
a_messages.error(r.user,'Failed consistency check: '+key+', autocorrected') a_messages.error(r.user,'Failed consistency check: '+key+', autocorrected')
else: else:
a_messages.error(r.user,'Failed consistency check: '+key+', not corrected') pass
# a_messages.error(r.user,'Failed consistency check: '+key+', not corrected')
except ZeroDivisionError: except ZeroDivisionError:
pass pass
@@ -985,6 +1001,9 @@ def getrowdata_db(id=0,doclean=False):
else: else:
row = Workout.objects.get(id=id) row = Workout.objects.get(id=id)
if data['efficiency'].mean() == 0 and data['power'].mean() != 0:
data = add_efficiency(id=id)
if doclean: if doclean:
data = clean_df_stats(data,ignorehr=True) data = clean_df_stats(data,ignorehr=True)
@@ -1071,6 +1090,7 @@ def read_cols_df_sql(ids,columns):
# drop columns that are not in offical list # drop columns that are not in offical list
# axx = [ax[0] for ax in axes] # axx = [ax[0] for ax in axes]
axx = [f.name for f in StrokeData._meta.get_fields()] axx = [f.name for f in StrokeData._meta.get_fields()]
for c in columns: for c in columns:
if not c in axx: if not c in axx:
columns.remove(c) columns.remove(c)
@@ -1099,8 +1119,10 @@ def read_cols_df_sql(ids,columns):
ids = tuple(ids), ids = tuple(ids),
)) ))
connection = engine.raw_connection() connection = engine.raw_connection()
df = pd.read_sql_query(query,engine) df = pd.read_sql_query(query,engine)
df = df.fillna(value=0) df = df.fillna(value=0)
try: try:
@@ -1244,6 +1266,27 @@ def datafusion(id1,id2,columns,offset):
return df return df
def add_efficiency(id=0):
rowdata,row = getrowdata_db(id=id,doclean=False)
power = rowdata['power']
pace = rowdata['pace']/1.0e3
velo = 500./pace
ergpw = 2.8*velo**3
efficiency = 100.*ergpw/power
efficiency = efficiency.replace([-np.inf,np.inf],np.nan)
efficiency.fillna(method='ffill')
rowdata['efficiency'] = efficiency
delete_strokedata(id)
if id != 0:
rowdata['workoutid'] = id
engine = create_engine(database_url, echo=False)
with engine.connect() as conn, conn.begin():
rowdata.to_sql('strokedata',engine,if_exists='append',index=False)
conn.close()
engine.dispose()
return rowdata
# This is the main routine. # This is the main routine.
# it reindexes, sorts, filters, and smooths the data, then # it reindexes, sorts, filters, and smooths the data, then
# saves it to the stroke_data table in the database # saves it to the stroke_data table in the database
@@ -1385,7 +1428,7 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
try: try:
driveenergy = rowdatadf.ix[:,'driveenergy'] driveenergy = rowdatadf.ix[:,'driveenergy']
except KeyError: except KeyError:
driveenergy = 0*power driveenergy = power*60/spm
else: else:
driveenergy = data['driveenergy'] driveenergy = data['driveenergy']
@@ -1414,6 +1457,14 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
totalangle = savgol_filter(totalangle,windowsize,3) totalangle = savgol_filter(totalangle,windowsize,3)
effectiveangle = savgol_filter(effectiveangle,windowsize,3) effectiveangle = savgol_filter(effectiveangle,windowsize,3)
velo = 500./p
ergpw = 2.8*velo**3
efficiency = 100.*ergpw/power
efficiency = efficiency.replace([-np.inf,np.inf],np.nan)
efficiency.fillna(method='ffill')
data['wash'] = wash data['wash'] = wash
data['catch'] = catch data['catch'] = catch
data['slip'] = slip data['slip'] = slip
@@ -1423,6 +1474,7 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
data['drivelength'] = drivelength data['drivelength'] = drivelength
data['totalangle'] = totalangle data['totalangle'] = totalangle
data['effectiveangle'] = effectiveangle data['effectiveangle'] = effectiveangle
data['efficiency'] = efficiency
if otwpower: if otwpower:
try: try:
+84 -11
View File
@@ -15,15 +15,32 @@ from sqlalchemy import create_engine
import sqlalchemy as sa import sqlalchemy as sa
from rowsandall_app.settings import DATABASES from rowsandall_app.settings import DATABASES
#from rowsandall_app.settings_dev import DATABASES
from utils import lbstoN from utils import lbstoN
user = DATABASES['default']['USER'] try:
password = DATABASES['default']['PASSWORD'] user = DATABASES['default']['USER']
database_name = DATABASES['default']['NAME'] except KeyError:
host = DATABASES['default']['HOST'] user = ''
port = DATABASES['default']['PORT'] try:
password = DATABASES['default']['PASSWORD']
except KeyError:
password = ''
try:
database_name = DATABASES['default']['NAME']
except KeyError:
database_name = ''
try:
host = DATABASES['default']['HOST']
except KeyError:
host = ''
try:
port = DATABASES['default']['PORT']
except KeyError:
port = ''
database_url = 'mysql://{user}:{password}@{host}:{port}/{database_name}'.format( database_url = 'mysql://{user}:{password}@{host}:{port}/{database_name}'.format(
user=user, user=user,
@@ -563,6 +580,10 @@ def smalldataprep(therows,xparam,yparam1,yparam2):
def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True, def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
empower=True,debug=True): empower=True,debug=True):
if rowdatadf.empty:
return 0
rowdatadf.set_index([range(len(rowdatadf))],inplace=True) rowdatadf.set_index([range(len(rowdatadf))],inplace=True)
t = rowdatadf.ix[:,'TimeStamp (sec)'] t = rowdatadf.ix[:,'TimeStamp (sec)']
t = pd.Series(t-rowdatadf.ix[0,'TimeStamp (sec)']) t = pd.Series(t-rowdatadf.ix[0,'TimeStamp (sec)'])
@@ -576,7 +597,6 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
cumdist = rowdatadf.ix[:,'cum_dist'] cumdist = rowdatadf.ix[:,'cum_dist']
power = rowdatadf.ix[:,' Power (watts)'] power = rowdatadf.ix[:,' Power (watts)']
averageforce = rowdatadf.ix[:,' AverageDriveForce (lbs)'] averageforce = rowdatadf.ix[:,' AverageDriveForce (lbs)']
drivelength = rowdatadf.ix[:,' DriveLength (meters)'] drivelength = rowdatadf.ix[:,' DriveLength (meters)']
try: try:
@@ -590,7 +610,10 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
forceratio = forceratio.fillna(value=0) forceratio = forceratio.fillna(value=0)
f = rowdatadf['TimeStamp (sec)'].diff().mean() f = rowdatadf['TimeStamp (sec)'].diff().mean()
if f != 0:
windowsize = 2*(int(10./(f)))+1 windowsize = 2*(int(10./(f)))+1
else:
windowsize = 1
if windowsize <= 3: if windowsize <= 3:
windowsize = 5 windowsize = 5
@@ -660,13 +683,48 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
if empower: if empower:
try: try:
wash = rowdatadf.ix[:,'wash'] wash = rowdatadf.ix[:,'wash']
except KeyError:
wash = 0*power
try:
catch = rowdatadf.ix[:,'catch'] catch = rowdatadf.ix[:,'catch']
except KeyError:
catch = 0*power
try:
finish = rowdatadf.ix[:,'finish'] finish = rowdatadf.ix[:,'finish']
except KeyError:
finish = 0*power
try:
peakforceangle = rowdatadf.ix[:,'peakforceangle'] peakforceangle = rowdatadf.ix[:,'peakforceangle']
except KeyError:
peakforceangle = 0*power
if data['driveenergy'].mean() == 0:
try:
driveenergy = rowdatadf.ix[:,'driveenergy'] driveenergy = rowdatadf.ix[:,'driveenergy']
except KeyError:
driveenergy = power*60/spm
else:
driveenergy = data['driveenergy']
arclength = (inboard-0.05)*(np.radians(finish)-np.radians(catch))
if arclength.mean()>0:
drivelength = arclength
elif drivelength.mean() == 0:
drivelength = driveenergy/(averageforce*4.44822) drivelength = driveenergy/(averageforce*4.44822)
try:
slip = rowdatadf.ix[:,'slip'] slip = rowdatadf.ix[:,'slip']
if windowsize > 3: except KeyError:
slip = 0*power
totalangle = finish-catch
effectiveangle = finish-wash-catch-slip
if windowsize > 3 and windowsize<len(slip):
wash = savgol_filter(wash,windowsize,3) wash = savgol_filter(wash,windowsize,3)
slip = savgol_filter(slip,windowsize,3) slip = savgol_filter(slip,windowsize,3)
catch = savgol_filter(catch,windowsize,3) catch = savgol_filter(catch,windowsize,3)
@@ -674,6 +732,17 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
peakforceangle = savgol_filter(peakforceangle,windowsize,3) peakforceangle = savgol_filter(peakforceangle,windowsize,3)
driveenergy = savgol_filter(driveenergy,windowsize,3) driveenergy = savgol_filter(driveenergy,windowsize,3)
drivelength = savgol_filter(drivelength,windowsize,3) drivelength = savgol_filter(drivelength,windowsize,3)
totalangle = savgol_filter(totalangle,windowsize,3)
effectiveangle = savgol_filter(effectiveangle,windowsize,3)
velo = 500./p
ergpw = 2.8*velo**3
efficiency = 100.*ergpw/power
efficiency = efficiency.replace([-np.inf,np.inf],np.nan)
efficiency.fillna(method='ffill')
data['wash'] = wash data['wash'] = wash
data['catch'] = catch data['catch'] = catch
data['slip'] = slip data['slip'] = slip
@@ -681,10 +750,9 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
data['peakforceangle'] = peakforceangle data['peakforceangle'] = peakforceangle
data['driveenergy'] = driveenergy data['driveenergy'] = driveenergy
data['drivelength'] = drivelength data['drivelength'] = drivelength
data['peakforce'] = peakforce data['totalangle'] = totalangle
data['averageforce'] = averageforce data['effectiveangle'] = effectiveangle
except KeyError: data['efficiency'] = efficiency
pass
if otwpower: if otwpower:
try: try:
@@ -703,11 +771,16 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
ergpace[ergpace == np.inf] = 240. ergpace[ergpace == np.inf] = 240.
ergpace2 = ergpace.apply(lambda x: timedeltaconv(x)) ergpace2 = ergpace.apply(lambda x: timedeltaconv(x))
efficiency = efficiency.replace([-np.inf,np.inf],np.nan)
efficiency.fillna(method='ffill')
data['ergpace'] = ergpace*1e3 data['ergpace'] = ergpace*1e3
data['nowindpace'] = nowindpace*1e3 data['nowindpace'] = nowindpace*1e3
data['equivergpower'] = equivergpower data['equivergpower'] = equivergpower
data['fergpace'] = nicepaceformat(ergpace2) data['fergpace'] = nicepaceformat(ergpace2)
data['fnowindpace'] = nicepaceformat(nowindpace2) data['fnowindpace'] = nicepaceformat(nowindpace2)
data['efficiency'] = efficiency
data = data.replace([-np.inf,np.inf],np.nan) data = data.replace([-np.inf,np.inf],np.nan)
data = data.fillna(method='ffill') data = data.fillna(method='ffill')
+14
View File
@@ -275,10 +275,24 @@ class IntervalUpdateForm(forms.Form):
self.fields['type_%s' % i].widget.attrs['style'] = 'width:156px; height: 22px;' self.fields['type_%s' % i].widget.attrs['style'] = 'width:156px; height: 22px;'
self.fields['intervald_%s' % i].widget = forms.TimeInput(format='%H:%M:%S.%f') self.fields['intervald_%s' % i].widget = forms.TimeInput(format='%H:%M:%S.%f')
boattypes = (
('1x', '1x (single)'),
('2x', '2x (double)'),
('2-', '2- (pair)'),
('4x', '4x (quad)'),
('4-', '4- (four)'),
('8+', '8+ (eight)'),
)
# This form sets options for the summary stats page # This form sets options for the summary stats page
class StatsOptionsForm(forms.Form): class StatsOptionsForm(forms.Form):
includereststrokes = forms.BooleanField(initial=False,label='Include Rest Strokes',required=False) includereststrokes = forms.BooleanField(initial=False,label='Include Rest Strokes',required=False)
water = forms.BooleanField(initial=False,required=False) water = forms.BooleanField(initial=False,required=False)
waterboattype = forms.MultipleChoiceField(choices=boattypes,
label='Water Boat Type',
widget=forms.CheckboxSelectMultiple(),
initial = ['1x','2x','2-','4x','4-','8+'])
rower = forms.BooleanField(initial=True,required=False) rower = forms.BooleanField(initial=True,required=False)
dynamic = forms.BooleanField(initial=True,required=False) dynamic = forms.BooleanField(initial=True,required=False)
slides = forms.BooleanField(initial=True,required=False) slides = forms.BooleanField(initial=True,required=False)
+5
View File
@@ -1331,11 +1331,16 @@ def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='',
hover = HoverTool(names=['data'], hover = HoverTool(names=['data'],
tooltips = [ tooltips = [
(groupby,'@groupval{1.1}'), (groupby,'@groupval{1.1}'),
(xparamname,'@x{1.1}'),
(yparamname,'@y')
]) ])
else: else:
hover = HoverTool(names=['data'], hover = HoverTool(names=['data'],
tooltips = [ tooltips = [
(groupby,'@groupval'), (groupby,'@groupval'),
(xparamname,'@x{1.1}'),
(yparamname,'@y')
,
]) ])
hover.mode = 'mouse' hover.mode = 'mouse'
+1
View File
@@ -22,6 +22,7 @@ axes = (
('totalangle', 'Drive Length (deg)',40,140,'pro'), ('totalangle', 'Drive Length (deg)',40,140,'pro'),
('effectiveangle', 'Effective Drive Length (deg)',40,140,'pro'), ('effectiveangle', 'Effective Drive Length (deg)',40,140,'pro'),
('rhythm', 'Stroke Rhythm (%)',20,55,'pro'), ('rhythm', 'Stroke Rhythm (%)',20,55,'pro'),
('efficiency', 'OTW efficiency (%)',0,110,'pro'),
('None', 'None',0,1,'basic'), ('None', 'None',0,1,'basic'),
) )
+1
View File
@@ -536,6 +536,7 @@ class StrokeData(models.Model):
rhythm = models.FloatField(default=1.0,null=True,verbose_name='Rhythm') rhythm = models.FloatField(default=1.0,null=True,verbose_name='Rhythm')
totalangle = models.FloatField(default=0.0,null=True,verbose_name='Total Stroke Length (deg)') totalangle = models.FloatField(default=0.0,null=True,verbose_name='Total Stroke Length (deg)')
effectiveangle = models.FloatField(default=0.0,null=True,verbose_name='Effective Stroke Length (deg)') effectiveangle = models.FloatField(default=0.0,null=True,verbose_name='Effective Stroke Length (deg)')
efficiency = models.FloatField(default=-1,null=True,verbose_name='OTW Efficiency')
# A wrapper around the png files # A wrapper around the png files
class GraphImage(models.Model): class GraphImage(models.Model):
+49
View File
@@ -9,6 +9,55 @@
{{ js_res | safe }} {{ js_res | safe }}
{{ css_res| safe }} {{ css_res| safe }}
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$(function() {
// Get the form fields and hidden div
var checkbox = $("#id_water");
var hidden = $("#id_waterboattype");
// Hide the fields.
// Use JS to do this in case the user doesn't have JS
// enabled.
hidden.hide();
// Setup an event listener for when the state of the
// checkbox changes.
checkbox.change(function() {
// Check to see if the checkbox is checked.
// If it is, show the fields and populate the input.
// If not, hide the fields.
if (checkbox.is(':checked')) {
// Show the hidden fields.
hidden.show();
} else {
// 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
// unticks the checkbox.
//
// This would do the job:
//
// $("#hidden_field").val("");
}
});
});
</script>
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
+49 -5
View File
@@ -6,14 +6,58 @@
{% block content %} {% block content %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script async="true" type="text/javascript"> <script>
$(function() {
// Get the form fields and hidden div
var checkbox = $("#id_water");
var hidden = $("#id_waterboattype");
// Hide the fields.
// Use JS to do this in case the user doesn't have JS
// enabled.
hidden.hide();
// Setup an event listener for when the state of the
// checkbox changes.
checkbox.change(function() {
// Check to see if the checkbox is checked.
// If it is, show the fields and populate the input.
// If not, hide the fields.
if (checkbox.is(':checked')) {
// Show the hidden fields.
hidden.show();
} else {
// 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
// unticks the checkbox.
//
// This would do the job:
//
// $("#hidden_field").val("");
}
});
});
</script>
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
{{ plotscript |safe }} {{ plotscript |safe }}
<script> <script>
// Set things up to resize the plot on a window resize. You can play with // Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior. // the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () { var plot_resize_setup = function () {
+27 -4
View File
@@ -2097,7 +2097,8 @@ def cum_flex(request,theuser=0,
enddatestring="", enddatestring="",
options={ options={
'includereststrokes':False, 'includereststrokes':False,
'workouttypes':['rower','dynamic','slides'] 'workouttypes':['rower','dynamic','slides'],
'waterboattype':['1x','2x','2-','4x','4-','8+']
}): }):
if 'options' in request.session: if 'options' in request.session:
@@ -2108,6 +2109,7 @@ def cum_flex(request,theuser=0,
workstrokesonly = not includereststrokes workstrokesonly = not includereststrokes
checktypes = ['water','rower','dynamic','slides','skierg', checktypes = ['water','rower','dynamic','slides','skierg',
'paddle','snow','coastal','other'] 'paddle','snow','coastal','other']
waterboattype = ['1x','2x','2-','4x','4-','8+']
if deltadays>0: if deltadays>0:
startdate = enddate-datetime.timedelta(days=int(deltadays)) startdate = enddate-datetime.timedelta(days=int(deltadays))
@@ -2174,6 +2176,7 @@ def cum_flex(request,theuser=0,
if optionsform.is_valid(): if optionsform.is_valid():
includereststrokes = optionsform.cleaned_data['includereststrokes'] includereststrokes = optionsform.cleaned_data['includereststrokes']
workstrokesonly = not includereststrokes workstrokesonly = not includereststrokes
waterboattype = optionsform.cleaned_data['waterboattype']
workouttypes = [] workouttypes = []
for type in checktypes: for type in checktypes:
if optionsform.cleaned_data[type]: if optionsform.cleaned_data[type]:
@@ -2182,6 +2185,7 @@ def cum_flex(request,theuser=0,
options = { options = {
'includereststrokes':includereststrokes, 'includereststrokes':includereststrokes,
'workouttypes':workouttypes, 'workouttypes':workouttypes,
'waterboattype':waterboattype,
} }
form = DateRangeForm(initial={ form = DateRangeForm(initial={
'startdate': startdate, 'startdate': startdate,
@@ -2205,6 +2209,7 @@ def cum_flex(request,theuser=0,
r2 = getrower(theuser) r2 = getrower(theuser)
allworkouts = Workout.objects.filter(user=r2, allworkouts = Workout.objects.filter(user=r2,
workouttype__in=workouttypes, workouttype__in=workouttypes,
boattype__in=waterboattype,
startdatetime__gte=startdate, startdatetime__gte=startdate,
startdatetime__lte=enddate) startdatetime__lte=enddate)
@@ -2242,6 +2247,8 @@ def cum_flex(request,theuser=0,
initial = {} initial = {}
initial['includereststrokes'] = includereststrokes initial['includereststrokes'] = includereststrokes
initial['waterboattype'] = waterboattype
for wtype in checktypes: for wtype in checktypes:
if wtype in workouttypes: if wtype in workouttypes:
initial[wtype] = True initial[wtype] = True
@@ -3565,18 +3572,24 @@ def multiflex_view(request,userid=0,
# prepare data frame # prepare data frame
datadf = dataprep.read_cols_df_sql(ids,fieldlist) datadf = dataprep.read_cols_df_sql(ids,fieldlist)
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
datadf = dataprep.filter_df(datadf,'spm',spmmin, datadf = dataprep.filter_df(datadf,'spm',spmmin,
largerthan=True) largerthan=True)
datadf = dataprep.filter_df(datadf,'spm',spmmax, datadf = dataprep.filter_df(datadf,'spm',spmmax,
largerthan=False) largerthan=False)
datadf = dataprep.filter_df(datadf,'driveenergy',workmin, datadf = dataprep.filter_df(datadf,'driveenergy',workmin,
largerthan=True) largerthan=True)
datadf = dataprep.filter_df(datadf,'driveneergy',workmax, datadf = dataprep.filter_df(datadf,'driveneergy',workmax,
largerthan=False) largerthan=False)
datadf.dropna(axis=0,how='any',inplace=True) datadf.dropna(axis=0,how='any',inplace=True)
datemapping = { datemapping = {
w.id:w.date for w in workouts w.id:w.date for w in workouts
} }
@@ -3631,11 +3644,16 @@ def multiflex_view(request,userid=0,
df = pd.DataFrame({ df = pd.DataFrame({
xparam:xvalues, xparam:xvalues,
yparam:yvalues, yparam:yvalues,
'x':xvalues,
'y':yvalues,
'xerror':xerror, 'xerror':xerror,
'yerror':yerror, 'yerror':yerror,
'groupsize':groupsize, 'groupsize':groupsize,
}) })
if yparam == 'pace':
df['y'] = dataprep.paceformatsecs(df['y']/1.0e3)
aantal = len(df) aantal = len(df)
if groupby != 'date': if groupby != 'date':
@@ -4026,7 +4044,6 @@ def workouts_view(request,message='',successmessage='',
else: else:
activity_enddate = enddate activity_enddate = enddate
print "aap",activity_enddate
if teamid: if teamid:
try: try:
@@ -4929,7 +4946,8 @@ def cumstats(request,theuser=0,
plotfield='spm', plotfield='spm',
options={ options={
'includereststrokes':False, 'includereststrokes':False,
'workouttypes':['rower','dynamic','slides'] 'workouttypes':['rower','dynamic','slides'],
'waterboattype':['1x','2x','2-','4x','4-','8+']
}): }):
if 'options' in request.session: if 'options' in request.session:
@@ -4940,6 +4958,7 @@ def cumstats(request,theuser=0,
workstrokesonly = not includereststrokes workstrokesonly = not includereststrokes
checktypes = ['water','rower','dynamic','slides','skierg', checktypes = ['water','rower','dynamic','slides','skierg',
'paddle','snow','other','coastal'] 'paddle','snow','other','coastal']
waterboattype = ['1x','2x','2-','4x','4-','8+']
if deltadays>0: if deltadays>0:
startdate = enddate-datetime.timedelta(days=int(deltadays)) startdate = enddate-datetime.timedelta(days=int(deltadays))
@@ -5006,6 +5025,7 @@ def cumstats(request,theuser=0,
includereststrokes = optionsform.cleaned_data['includereststrokes'] includereststrokes = optionsform.cleaned_data['includereststrokes']
workstrokesonly = not includereststrokes workstrokesonly = not includereststrokes
workouttypes = [] workouttypes = []
waterboattype = optionsform.cleaned_data['waterboattype']
for type in checktypes: for type in checktypes:
if optionsform.cleaned_data[type]: if optionsform.cleaned_data[type]:
workouttypes.append(type) workouttypes.append(type)
@@ -5013,6 +5033,7 @@ def cumstats(request,theuser=0,
options = { options = {
'includereststrokes':includereststrokes, 'includereststrokes':includereststrokes,
'workouttypes':workouttypes, 'workouttypes':workouttypes,
'waterboattype':waterboattype,
} }
form = DateRangeForm() form = DateRangeForm()
deltaform = DeltaDaysForm() deltaform = DeltaDaysForm()
@@ -5031,6 +5052,7 @@ def cumstats(request,theuser=0,
r2 = getrower(theuser) r2 = getrower(theuser)
allergworkouts = Workout.objects.filter(user=r2, allergworkouts = Workout.objects.filter(user=r2,
workouttype__in=workouttypes, workouttype__in=workouttypes,
boattype__in=waterboattype,
startdatetime__gte=startdate, startdatetime__gte=startdate,
startdatetime__lte=enddate) startdatetime__lte=enddate)
@@ -5132,6 +5154,7 @@ def cumstats(request,theuser=0,
# set options form correctly # set options form correctly
initial = {} initial = {}
initial['includereststrokes'] = includereststrokes initial['includereststrokes'] = includereststrokes
initial['waterboattype'] = waterboattype
for wtype in checktypes: for wtype in checktypes:
if wtype in workouttypes: if wtype in workouttypes:
@@ -5613,7 +5636,7 @@ def workout_flexchart3_view(request,*args,**kwargs):
axchoicespro.pop('totalangle') axchoicespro.pop('totalangle')
axchoicespro.pop('effectiveangle') axchoicespro.pop('effectiveangle')
axchoicespro.pop('peakforceangle') axchoicespro.pop('peakforceangle')
axchoicespro.pop('efficiency')
return render(request, return render(request,
'flexchart3otw.html', 'flexchart3otw.html',