diff --git a/rowers/dataroutines.py b/rowers/dataroutines.py
index 8ad8d38a..a3e06805 100644
--- a/rowers/dataroutines.py
+++ b/rowers/dataroutines.py
@@ -1554,19 +1554,22 @@ def read_data(columns, ids=[], doclean=True, workstrokesonly=True, debug=False,
_ = dataplep(rowdata.df, id=id,
bands=True, otwpower=True, barchart=True,
polars=True)
- df = pl.scan_parquet(f)
- if startenddict:
- try:
- startsecond, endsecond = startenddict[id]
- df = df.filter(pl.col("time") >= 1.0e3*startsecond,
- pl.col("time") <= 1.0e3*endsecond)
- df = df.with_columns(time = pl.col("time")-1.0e3*startsecond)
- if 'cumdist' in columns:
- df = df.collect()
- df = df.with_columns(cumdist = pl.col("cumdist")-df[0, "cumdist"]).lazy()
- except KeyError:
- pass
- data.append(df)
+ try:
+ df = pl.scan_parquet(f)
+ if startenddict:
+ try:
+ startsecond, endsecond = startenddict[id]
+ df = df.filter(pl.col("time") >= 1.0e3*startsecond,
+ pl.col("time") <= 1.0e3*endsecond)
+ df = df.with_columns(time = pl.col("time")-1.0e3*startsecond)
+ if 'cumdist' in columns:
+ df = df.collect()
+ df = df.with_columns(cumdist = pl.col("cumdist")-df[0, "cumdist"]).lazy()
+ except KeyError:
+ pass
+ data.append(df)
+ except ComputeError:
+ pass
try:
data = pl.collect_all(data)
@@ -2169,14 +2172,16 @@ def dataplep(rowdatadf, id=0, inboard=0.88, forceunit='lbs', bands=True, barchar
df = df.with_columns((pl.col(" AverageDriveForce (lbs)")/pl.col(" PeakDriveForce (lbs)")).alias("forceratio"))
else:
df = df.with_columns((pl.lit(0)).alias("forceratio"))
- f = df['TimeStamp (sec)'].diff().mean()
+ try:
+ f = df['TimeStamp (sec)'].diff().mean()
+ except TypeError:
+ f = 0
+ windowsize = 1
if f != 0 and not np.isinf(f):
try:
windowsize = 2 * (int(10. / (f))) + 1
except ValueError:
windowsize = 1
- else:
- windowsize = 1
if windowsize <= 3:
windowsize = 5
diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py
index 20989940..4ca7676b 100644
--- a/rowers/interactiveplots.py
+++ b/rowers/interactiveplots.py
@@ -22,7 +22,7 @@ import polars as pl
import pytz
from rowers.rower_rules import ispromember
-from polars.exceptions import ColumnNotFoundError
+from polars.exceptions import ColumnNotFoundError, ComputeError
from scipy.interpolate import griddata
from scipy.signal import savgol_filter
@@ -758,16 +758,28 @@ def performance_chart(user, startdate=None, enddate=None, kfitness=42, kfatigue=
df = df.filter(pl.col("date") > startdate)
- df2 = pl.DataFrame({
- "testpower" :df['testpower'],
- "testduration":df['testduration'].apply(
- lambda x: totaltime_sec_to_string(x, shorten=True)),
- "fitness":df['fitness'],
- "fatigue":df['fatigue'],
- "form":df['form'],
- "impulse":df['impulse'],
- "date": df['date'].dt.strftime('%Y-%m-%d'),
+ try:
+ df2 = pl.DataFrame({
+ "testpower" :df['testpower'],
+ "testduration":df['testduration'].apply(
+ lambda x: totaltime_sec_to_string(x, shorten=True)),
+ "fitness":df['fitness'],
+ "fatigue":df['fatigue'],
+ "form":df['form'],
+ "impulse":df['impulse'],
+ "date": df['date'].dt.strftime('%Y-%m-%d'),
})
+ except ComputeError:
+ df2 = pl.DataFrame({
+ "testpower" :df['testpower'],
+ "fitness":df['fitness'],
+ "fatigue":df['fatigue'],
+ "form":df['form'],
+ "impulse":df['impulse'],
+ "date": df['date'].dt.strftime('%Y-%m-%d'),
+ })
+ df2 = df2.with_columns((pl.lit("--")).alias("testduration"))
+
df2 = df2.fill_nan(0)
diff --git a/rowers/templates/panel_empower.html b/rowers/templates/panel_empower.html
new file mode 100644
index 00000000..2cd66d26
--- /dev/null
+++ b/rowers/templates/panel_empower.html
@@ -0,0 +1,22 @@
+{% load rowerfilters %}
+{% load tz %}
+
+ -
+
+
+ {% localtime on %}
+ | Seat Number: | {{ workout.seatnumber}} |
+ {% endlocaltime %}
+
+ | Empower side: | {{ workout.empowerside }} |
+
+ | Boat name: | {{ workout.boatname }} |
+
+ | Oar length: | {{ workout.oarlength }} |
+
+ | Oar inboard: | {{ workout.inboard }} |
+
+
+
+
+
diff --git a/rowers/tests/test_cpchart.py b/rowers/tests/test_cpchart.py
index 6f46c0cf..3c6fd404 100644
--- a/rowers/tests/test_cpchart.py
+++ b/rowers/tests/test_cpchart.py
@@ -95,6 +95,9 @@ class CPChartTest(TestCase):
'distance': 500,
'workouttype': 'rower',
'boattype': '1x',
+ 'boatname': 'CatchUp',
+ 'empowerside': 'starboard',
+ 'seatnumber': 1,
'weightcategory': 'hwt',
'adaptiveclass': 'None',
'notes': faker.text(),
diff --git a/rowers/tests/test_races.py b/rowers/tests/test_races.py
index ebf0ac06..e783db2e 100644
--- a/rowers/tests/test_races.py
+++ b/rowers/tests/test_races.py
@@ -1121,6 +1121,9 @@ class IndoorChallengesTest(TestCase):
'adaptiveclass': 'None',
'notes': faker.text(),
'rankingpiece': True,
+ 'empowerside': 'port',
+ 'boatname': 'Dolfijn',
+ 'seatnumber': 1,
'duplicate': False,
'avghr': '160',
'avgpwr': 0,
diff --git a/rowers/tests/test_settings.py b/rowers/tests/test_settings.py
index 86dc231d..504139fa 100644
--- a/rowers/tests/test_settings.py
+++ b/rowers/tests/test_settings.py
@@ -34,6 +34,9 @@ class DataTest(TestCase):
'workouttype':'water',
'rpe':1,
'boattype':'1x',
+ 'boatname': 'BOAT1',
+ 'empowerside': 'port',
+ 'seatnumber': 4,
'private':False,
}
form = WorkoutForm(data=form_data)
diff --git a/rowers/tests/test_uploads.py b/rowers/tests/test_uploads.py
index b27a198a..f93418e8 100644
--- a/rowers/tests/test_uploads.py
+++ b/rowers/tests/test_uploads.py
@@ -101,6 +101,9 @@ class ViewTest(TestCase):
'rpe':4,
'dragfactor':'112',
'raceid':0,
+ 'seatnumber': 1,
+ 'boatname': '',
+ 'empowerside': 'port',
'landingpage':'workout_edit_view',
'private':True,
'notes':'noot mies',
diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz
index e5817eac..8d223ed8 100644
Binary files a/rowers/tests/testdata/testdata.tcx.gz and b/rowers/tests/testdata/testdata.tcx.gz differ
diff --git a/rowers/utils.py b/rowers/utils.py
index 7f96a94a..49443593 100644
--- a/rowers/utils.py
+++ b/rowers/utils.py
@@ -64,6 +64,7 @@ workflowmiddlepanel = (
('panel_summary.html', 'Summary'),
('panel_map.html', 'Map'),
('panel_comments.html', 'Basic Info and Links'),
+ ('panel_empower.html', 'Empower Oarlock Info'),
('panel_notes.html', 'Workout Notes'),
('panel_shortcomment.html', 'Comment Link'),
('panel_middlesocial.html', 'Social Media Share Buttons'),
diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py
index 4151a620..8e74ee2f 100644
--- a/rowers/views/workoutviews.py
+++ b/rowers/views/workoutviews.py
@@ -680,6 +680,9 @@ def addmanual_view(request, raceid=0):
privacy = form.cleaned_data.get('privacy', 'visible')
rankingpiece = form.cleaned_data.get('rankingpiece', False)
duplicate = form.cleaned_data.get('duplicate', False)
+ seatnumber = form.cleaned_data.get('seatnumber', 1)
+ boatname = form.cleaned_data.get('boatname', '')
+ empowerside = form.cleaned_data.get('empowerside','port')
if private: # pragma: no cover
privacy = 'private'
@@ -723,6 +726,9 @@ def addmanual_view(request, raceid=0):
w.rpe = rpe
w.workouttype = workouttype
w.boattype = boattype
+ w.boatname = boatname
+ w.empowerside = empowerside
+ w.seatnumber = seatnumber
w.distance = distance
w.duration = duration
w.save()
@@ -4385,6 +4391,10 @@ def workout_edit_view(request, id=0, message="", successmessage=""):
'rankingpiece', Workout.objects.get(id=row.id).rankingpiece)
duplicate = form.cleaned_data.get(
'duplicate', Workout.objects.get(id=row.id).duplicate)
+ seatnumber = form.cleaned_data.get('seatnumber', 1)
+ boatname = form.cleaned_data.get('boatname', '')
+ empowerside = form.cleaned_data.get('empowerside','port')
+
if private:
privacy = 'private'
@@ -4438,6 +4448,9 @@ def workout_edit_view(request, id=0, message="", successmessage=""):
row.rankingpiece = rankingpiece
row.timezone = thetimezone
row.plannedsession = ps
+ row.boatname = boatname
+ row.empowerside = empowerside
+ row.seatnumber = seatnumber
dragchanged = False
if newdragfactor != row.dragfactor: # pragma: no cover