diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 0f5e03ab..fb2bb691 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -49,7 +49,8 @@ import itertools import math from tasks import ( handle_sendemail_unrecognized, handle_sendemail_breakthrough, - handle_sendemail_hard, handle_updatecp,handle_updateergcp + handle_sendemail_hard, handle_updatecp,handle_updateergcp, + handle_calctrimp, ) from django.conf import settings @@ -1017,6 +1018,8 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', res = dataprep(row.df, id=w.id, bands=True, barchart=True, otwpower=True, empower=True, inboard=inboard) + rscore,normp = workout_rscore(w) + isbreakthrough = False ishard = False if workouttype == 'water': @@ -2255,82 +2258,93 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True, return data -def workout_trimp(workout): - r = workout.user +def workout_trimp(w): + r = w.user + + if w.trimp > 0: + return w.trimp,w.hrtss + + r = w.user + ftp = float(r.ftp) + if w.workouttype in otwtypes: + ftp = ftp*(100.-r.otwslack)/100. + if r.hrftp == 0: hrftp = (r.an+r.tr)/2. r.hrftp = int(hrftp) r.save() - - df,row = getrowdata_db(id=workout.id) - df = clean_df_stats(df,workstrokesonly=False) - if df.empty: - df,row = getrowdata_db(id=workout.id) - df = clean_df_stats(df,workstrokesonly=False) - trimp,hrtss = calc_trimp(df,r.sex,r.max,r.rest,r.hrftp) - if not np.isnan(trimp): - trimp = int(trimp) - else: - trimp = 0 - if not np.isnan(hrtss): - hrtss = int(hrtss) - else: - hrtss = 0 - return trimp,hrtss + + + job = myqueue( + queuehigh, + handle_calctrimp, + w.id, + w.csvfilename, + ftp, + r.sex, + r.hrftp, + r.max, + r.rest) + + return 0,0 def workout_rscore(w): + if w.rscore > 0: + return w.rscore,w.normp + r = w.user - df,row = getrowdata_db(id=w.id) - df = clean_df_stats(df,workstrokesonly=False) - if df.empty: - df,row = getrowdata_db(id=w.id) - df = clean_df_stats(df,workstrokesonly=False) + ftp = float(r.ftp) + if w.workouttype in otwtypes: + ftp = ftp*(100.-r.otwslack)/100. - df['deltat'] = df['time'].diff() - duration = df['time'].max()-df['time'].min() - duration /= 1.0e3 - df['pwr4'] = df['power']**(4.0) - pwr4mean = wavg(df,'pwr4','deltat') - pwrmean = wavg(df,'power','deltat') - normp = (pwr4mean)**(0.25) - if not np.isnan(normp): - ftp = float(r.ftp) - if w.workouttype in otwtypes: - ftp = ftp*(100.-r.otwslack)/100. + if r.hrftp == 0: + hrftp = (r.an+r.tr)/2. + r.hrftp = int(hrftp) + r.save() - intensityfactor = pwrmean/float(ftp) - intensityfactor = normp/float(ftp) - tss = 100.*((duration*normp*intensityfactor)/(3600.*ftp)) - else: - tss = 0 + - return tss,normp + job = myqueue( + queuehigh, + handle_calctrimp, + w.id, + w.csvfilename, + ftp, + r.sex, + r.hrftp, + r.max, + r.rest) + + return 0,0 def workout_normv(w,pp=4.0): - df,row = getrowdata_db(id=w.id) - df = clean_df_stats(df,workstrokesonly=False) - if df.empty: - df,row = getrowdata_db(id=w.id) - df = clean_df_stats(df,workstrokesonly=False) + if w.normv > 0: + return w.normv,w.normw - df['deltat'] = df['time'].diff() - duration = df['time'].max()-df['time'].min() - duration /= 1.0e3 - df['v4'] = df['velo']**(pp) - v4mean = wavg(df,'v4','deltat') - normv = v4mean**(1./pp) + r = w.user + ftp = float(r.ftp) + if w.workouttype in otwtypes: + ftp = ftp*(100.-r.otwslack)/100. + + if r.hrftp == 0: + hrftp = (r.an+r.tr)/2. + r.hrftp = int(hrftp) + r.save() + + + + job = myqueue( + queuehigh, + handle_calctrimp, + w.id, + w.csvfilename, + ftp, + r.sex, + r.hrftp, + r.max, + r.rest) + + return 0,0 - df['w4'] = df['driveenergy']**(pp) - w4mean = wavg(df,'w4','deltat') - normw = w4mean**(1./pp) - - - if np.isnan(normv): - normv = 500./120. - - if np.isnan(normw): - normw = 0 - - return normv,normw diff --git a/rowers/dataprepnodjango.py b/rowers/dataprepnodjango.py index 745723ba..9ef61a54 100644 --- a/rowers/dataprepnodjango.py +++ b/rowers/dataprepnodjango.py @@ -693,6 +693,7 @@ def testdata(time,distance,pace,spm): return t1 and t2 and t3 and t4 + def getsmallrowdata_db(columns,ids=[],debug=False): data = read_cols_df_sql(ids,columns,debug=debug) diff --git a/rowers/models.py b/rowers/models.py index 5519af85..4e877fd3 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -1496,6 +1496,12 @@ class Workout(models.Model): max_length=100) distance = models.IntegerField(default=0,blank=True) duration = models.TimeField(default=1,blank=True) + trimp = models.IntegerField(default=-1,blank=True) + rscore = models.IntegerField(default=-1,blank=True) + hrtss = models.IntegerField(default=-1,blank=True) + normp = models.IntegerField(default=-1,blank=True) + normv = models.FloatField(default=-1,blank=True) + normw = models.FloatField(default=-1,blank=True) weightcategory = models.CharField( default="hwt", max_length=10, diff --git a/rowers/tasks.py b/rowers/tasks.py index 85b9278a..7b43f34f 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -39,7 +39,7 @@ from django_rq import job from django.utils import timezone from django.utils.html import strip_tags -from utils import deserialize_list,ewmovingaverage +from utils import deserialize_list,ewmovingaverage,wavg from rowers.dataprepnodjango import ( update_strokedata, new_workout_from_file, @@ -545,6 +545,101 @@ We have updated Power and Work per Stroke data according to the instructions by res = email.send() return 1 +@app.task +def handle_calctrimp(id, + csvfilename, + ftp, + sex, + hrftp, + hrmax, + hrmin, + debug=False, **kwargs): + if debug: + engine = create_engine(database_url_debug, echo=False) + else: + engine = create_engine(database_url, echo=False) + + try: + rowdata = rdata(csvfilename) + except IOError: + try: + rowdata = rdata(csvfilename + '.csv') + except IOError: + try: + rowdata = rdata(csvfilename + '.gz') + except IOError: + return 0 + + df = rowdata.df + + df['deltat'] = df[' ElapsedTime (sec)'].diff().abs() + duration = df['TimeStamp (sec)'].max()-df['TimeStamp (sec)'].min() + + df[' Power (watts)'] = df[' Power (watts)'].abs() + + df['pwr4'] = df[' Power (watts)']**(4.0) + pwr4mean = wavg(df,'pwr4','deltat') + pwrmean = wavg(df,' Power (watts)','deltat') + if pwr4mean > 0: + normp = (pwr4mean)**(0.25) + else: + normp = pwrmean + + intensityfactor = pwrmean/float(ftp) + intensityfactor = normp/float(ftp) + tss = 100.*((duration*normp*intensityfactor)/(3600.*ftp)) + + if sex == 'male': + f = 1.92 + else: + f = 1.67 + + dt = df['TimeStamp (sec)'].diff()/6.e4 + + hrr = (df[' HRCur (bpm)']-hrmin)/(hrmax-hrmin) + hrrftp = (hrftp-hrmin)/float(hrmax-hrmin) + trimp1hr = 60*hrrftp*0.64*np.exp(f*hrrftp) + + trimpdata = dt*hrr*0.64*np.exp(f*hrr) + trimp = trimpdata.sum() + + hrtss = 100*trimp/trimp1hr + + pp = 8.0 + + df['v4'] = df[' AverageBoatSpeed (m/s)']**(pp) + v4mean = wavg(df,'v4','deltat') + normv = v4mean**(1./pp) + + df['w4'] = df['driveenergy']**(pp) + w4mean = wavg(df,'w4','deltat') + normw = w4mean**(1./pp) + + + if np.isnan(normv): + normv = 500./120. + + if np.isnan(normw): + normw = 0 + + query = 'UPDATE rowers_workout SET rscore = {tss}, normp = {normp}, trimp={trimp}, hrtss={hrtss}, normv={normv}, normw={normw} WHERE id={id}'.format( + tss = int(tss), + normp = int(normp), + trimp = int(trimp), + hrtss = int(hrtss), + normv=normv, + normw=normw, + id = id, + ) + + with engine.connect() as conn, conn.begin(): + result = conn.execute(query) + conn.close() + engine.dispose() + + return 1 + + @app.task def handle_updatedps(useremail, workoutids, debug=False,**kwargs): for wid, f1 in workoutids: