From 017024e06a5e81ede0b47acab98e8eb27a685c50 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 19 Jan 2023 09:31:07 +0100 Subject: [PATCH] faster perf chart --- rowers/interactiveplots.py | 90 ++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 27 deletions(-) diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 69020a45..3d9246a4 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -1498,8 +1498,27 @@ def interactive_forcecurve(theworkouts, workstrokesonly=True, plottype='scatter' return [script, div, js_resources, css_resources] +def weightfromrecord(row,metricchoice): + vv = row[metricchoice] + if vv > 0: + return vv + if vv == 0: + if metricchoice == 'rscore' and row['hrtss'] > 0: # pragma: no cover + return row['hrtss'] + if vv < 0: + w = Workout.objects.get(id=row['id']) + trimp, hrtss = dataprep.workout_trimp(w) + rscore, normp = dataprep.workout_rscore(w) + if row['rpe'] and row['rpe'] > 0: # pragma: no cover + dd = 3600*row['duration'].hour+60*row['duration'].minute+row['duration'].second + dd = dd/3600 + return rpetotss[row['rpe']]*dd + + return 0 + def getfatigues( + df, fatigues, fitnesses, dates, testpower, testduration, impulses, startdate, enddate, user, metricchoice, kfatigue, kfitness): @@ -1517,24 +1536,20 @@ def getfatigues( for i in range(nrdays+1): date = startdate+datetime.timedelta(days=i) - ws = Workout.objects.filter( - user=user.rower, date=date, duplicate=False) + datekey = date.strftime('%Y-%m-%d') weight = 0 - for w in ws: - if getattr(w, metricchoice) > 0: - weight += getattr(w, metricchoice) - if getattr(w, metricchoice) == 0: - if metricchoice == 'rscore' and w.hrtss > 0: # pragma: no cover - weight += w.hrtss - if getattr(w, metricchoice) < 0: - trimp, hrtss = dataprep.workout_trimp(w) - rscore, normp = dataprep.workout_rscore(w) - if w.rpe and w.rpe > 0: # pragma: no cover - dd = 3600*w.duration.hour+60*w.duration.minute+w.duration.second - dd = dd/3600 - weight += rpetotss[w.rpe]*dd - + try: + df2 = df.loc[date.date()] + + if type(df2) == pd.Series: + weight += weightfromrecord(df2,metricchoice) + else: + for index, row in df2.iterrows(): + weight += weightfromrecord(row,metricchoice) + except KeyError: + pass + impulses.append(weight) fatigue = (1-lambda_a)*fatigue+weight*lambda_a @@ -1760,6 +1775,25 @@ def performance_chart(user, startdate=None, enddate=None, kfitness=42, kfatigue= workouttype__in=mytypes.rowtypes, duplicate=False).order_by('date') + # make fast dict for dates / workouts + records = [] + for w in workouts: + dd = { + 'date':w.date, + 'trimp':w.trimp, + 'rscore':w.rscore, + 'hrtss':w.hrtss, + 'duration':w.duration, + 'id':w.id, + 'rpe':w.rpe, + } + records.append(dd) + + df = pd.DataFrame.from_records(records) + if df.empty: + return ['', 'No Data', 0, 0, 0, outids] + df.set_index('date', inplace=True) + markerworkouts = workouts.filter(rankingpiece=True) outids = [w.id for w in markerworkouts] dates = [arrow.get(w.date).datetime for w in workouts] @@ -1771,17 +1805,18 @@ def performance_chart(user, startdate=None, enddate=None, kfitness=42, kfatigue= fitnesses = [np.nan for w in workouts] fatigues = [np.nan for w in workouts] - fatigues, fitnesses, dates, testpower, testduration, impulses = getfatigues(fatigues, - fitnesses, - dates, - testpower, testduration, - impulses, - startdate - - datetime.timedelta( - days=90), - enddate, - user, metricchoice, - kfatigue, kfitness) + fatigues, fitnesses, dates, testpower, testduration, impulses = getfatigues( + df, + fatigues, + fitnesses, + dates, + testpower, testduration, + impulses, + startdate -datetime.timedelta(days=90), + enddate, + user, metricchoice, + kfatigue, kfitness + ) df = pd.DataFrame({ 'date': dates, @@ -1792,6 +1827,7 @@ def performance_chart(user, startdate=None, enddate=None, kfitness=42, kfatigue= 'impulse': impulses, }) + endfitness = fitnesses[-2] endfatigue = fatigues[-2] endform = endfitness-endfatigue