diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 5ce1a5d6..c1e4684e 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -210,6 +210,12 @@ def clean_df_stats(datadf,workstrokesonly=True,ignorehr=True, datadf.loc[mask,'pace'] = np.nan except KeyError: pass + + try: + mask = datadf['efficiency'] < 0. + datadf.loc[mask,'efficiency'] = np.nan + except KeyError: + pass try: mask = datadf['pace']/1000. < 60. @@ -454,7 +460,8 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower', if consistencychecks: a_messages.error(r.user,'Failed consistency check: '+key+', autocorrected') 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: pass @@ -994,6 +1001,9 @@ def getrowdata_db(id=0,doclean=False): else: row = Workout.objects.get(id=id) + if data['efficiency'].mean() == 0 and data['power'].mean() != 0: + data = add_efficiency(id=id) + if doclean: data = clean_df_stats(data,ignorehr=True) @@ -1080,6 +1090,7 @@ def read_cols_df_sql(ids,columns): # drop columns that are not in offical list # axx = [ax[0] for ax in axes] axx = [f.name for f in StrokeData._meta.get_fields()] + for c in columns: if not c in axx: columns.remove(c) @@ -1108,10 +1119,12 @@ def read_cols_df_sql(ids,columns): ids = tuple(ids), )) + connection = engine.raw_connection() df = pd.read_sql_query(query,engine) - df = df.fillna(value=0) + df = df.fillna(value=0) + try: df['peakforce'] = df['peakforce']*lbstoN except KeyError: @@ -1253,6 +1266,27 @@ def datafusion(id1,id2,columns,offset): 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. # it reindexes, sorts, filters, and smooths the data, then # saves it to the stroke_data table in the database @@ -1394,7 +1428,7 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True, try: driveenergy = rowdatadf.ix[:,'driveenergy'] except KeyError: - driveenergy = 0*power + driveenergy = power*60/spm else: driveenergy = data['driveenergy'] @@ -1423,6 +1457,14 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True, 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['catch'] = catch data['slip'] = slip @@ -1432,6 +1474,7 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True, data['drivelength'] = drivelength data['totalangle'] = totalangle data['effectiveangle'] = effectiveangle + data['efficiency'] = efficiency if otwpower: try: diff --git a/rowers/dataprepnodjango.py b/rowers/dataprepnodjango.py index 27cb5db7..e985de1c 100644 --- a/rowers/dataprepnodjango.py +++ b/rowers/dataprepnodjango.py @@ -15,15 +15,32 @@ from sqlalchemy import create_engine import sqlalchemy as sa from rowsandall_app.settings import DATABASES +#from rowsandall_app.settings_dev import DATABASES from utils import lbstoN -user = DATABASES['default']['USER'] -password = DATABASES['default']['PASSWORD'] -database_name = DATABASES['default']['NAME'] -host = DATABASES['default']['HOST'] -port = DATABASES['default']['PORT'] +try: + user = DATABASES['default']['USER'] +except KeyError: + user = '' +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( user=user, @@ -563,6 +580,10 @@ def smalldataprep(therows,xparam,yparam1,yparam2): def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True, empower=True,debug=True): + + if rowdatadf.empty: + return 0 + rowdatadf.set_index([range(len(rowdatadf))],inplace=True) t = rowdatadf.ix[:,'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'] power = rowdatadf.ix[:,' Power (watts)'] - averageforce = rowdatadf.ix[:,' AverageDriveForce (lbs)'] drivelength = rowdatadf.ix[:,' DriveLength (meters)'] try: @@ -590,7 +610,10 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True, forceratio = forceratio.fillna(value=0) f = rowdatadf['TimeStamp (sec)'].diff().mean() - windowsize = 2*(int(10./(f)))+1 + if f != 0: + windowsize = 2*(int(10./(f)))+1 + else: + windowsize = 1 if windowsize <= 3: windowsize = 5 @@ -660,31 +683,76 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True, if empower: try: wash = rowdatadf.ix[:,'wash'] - catch = rowdatadf.ix[:,'catch'] - finish = rowdatadf.ix[:,'finish'] - peakforceangle = rowdatadf.ix[:,'peakforceangle'] - driveenergy = rowdatadf.ix[:,'driveenergy'] - drivelength = driveenergy/(averageforce*4.44822) - slip = rowdatadf.ix[:,'slip'] - if windowsize > 3: - wash = savgol_filter(wash,windowsize,3) - slip = savgol_filter(slip,windowsize,3) - catch = savgol_filter(catch,windowsize,3) - finish = savgol_filter(finish,windowsize,3) - peakforceangle = savgol_filter(peakforceangle,windowsize,3) - driveenergy = savgol_filter(driveenergy,windowsize,3) - drivelength = savgol_filter(drivelength,windowsize,3) - data['wash'] = wash - data['catch'] = catch - data['slip'] = slip - data['finish'] = finish - data['peakforceangle'] = peakforceangle - data['driveenergy'] = driveenergy - data['drivelength'] = drivelength - data['peakforce'] = peakforce - data['averageforce'] = averageforce except KeyError: - pass + wash = 0*power + + try: + catch = rowdatadf.ix[:,'catch'] + except KeyError: + catch = 0*power + + try: + finish = rowdatadf.ix[:,'finish'] + except KeyError: + finish = 0*power + + try: + peakforceangle = rowdatadf.ix[:,'peakforceangle'] + except KeyError: + peakforceangle = 0*power + + + if data['driveenergy'].mean() == 0: + try: + 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) + + try: + slip = rowdatadf.ix[:,'slip'] + except KeyError: + slip = 0*power + + totalangle = finish-catch + effectiveangle = finish-wash-catch-slip + if windowsize > 3 and windowsize