adding critical stroke rate chart
This commit is contained in:
@@ -553,7 +553,10 @@ def setcp(workout, background=False, recurrance=True):
|
||||
# check dts
|
||||
tarr = datautils.getlogarr(4000)
|
||||
if df['delta'][0] in tarr:
|
||||
return(df, df['delta'], df['cp'])
|
||||
try:
|
||||
return(df, df['delta'], df['cp'], df['cr'])
|
||||
except KeyError:
|
||||
return(df, df['delta'], df['cp'], 0*df['cp'])
|
||||
except Exception as e:
|
||||
try:
|
||||
os.remove(filename)
|
||||
@@ -565,7 +568,7 @@ def setcp(workout, background=False, recurrance=True):
|
||||
strokesdf = remove_nulls_pl(strokesdf)
|
||||
|
||||
if strokesdf.is_empty():
|
||||
return pl.DataFrame({'delta': [], 'cp': []}), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
return pl.DataFrame({'delta': [], 'cp': [], 'cr': []}), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
|
||||
totaltime = strokesdf['time'].max()
|
||||
maxt = totaltime/1000.
|
||||
@@ -580,7 +583,7 @@ def setcp(workout, background=False, recurrance=True):
|
||||
elif os.path.exists(csvfilename+'.gz'): # pragma: no cover
|
||||
csvfile = csvfilename+'.gz'
|
||||
else: # pragma: no cover
|
||||
return pl.DataFrame({'delta': [], 'cp': []}), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
return pl.DataFrame({'delta': [], 'cp': [], 'cr': []}), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
csvfile = os.path.abspath(csvfile)
|
||||
|
||||
with grpc.insecure_channel(
|
||||
@@ -593,7 +596,7 @@ def setcp(workout, background=False, recurrance=True):
|
||||
grpc.channel_ready_future(channel).result(timeout=10)
|
||||
except grpc.FutureTimeoutError: # pragma: no cover
|
||||
dologging('metrics.log','grpc channel time out in setcp')
|
||||
return pl.DataFrame({'delta': [], 'cp': []}), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
return pl.DataFrame({'delta': [], 'cp': [], 'cr':[]}), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
|
||||
stub = metrics_pb2_grpc.MetricsStub(channel)
|
||||
req = metrics_pb2.CPRequest(filename = csvfile, filetype = "CSV", tarr = logarr)
|
||||
@@ -602,16 +605,18 @@ def setcp(workout, background=False, recurrance=True):
|
||||
response = stub.GetCP(req, timeout=60)
|
||||
except Exception as e:
|
||||
dologging('metrics.log', traceback.format_exc())
|
||||
return pl.DataFrame({'delta': [], 'cp': []}), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
return pl.DataFrame({'delta': [], 'cp': [], 'cr': []}), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
|
||||
delta = pl.Series(np.array(response.delta))
|
||||
cpvalues = pl.Series(np.array(response.power))
|
||||
powermean = response.avgpower
|
||||
spmvalues = pl.Series(np.array(response.spm))
|
||||
|
||||
try:
|
||||
df = pl.DataFrame({
|
||||
'delta': delta,
|
||||
'cp': cpvalues,
|
||||
'cr': spmvalues,
|
||||
'id': workout.id,
|
||||
})
|
||||
|
||||
@@ -620,7 +625,7 @@ def setcp(workout, background=False, recurrance=True):
|
||||
|
||||
except Exception as e:
|
||||
dologging("metrics.log", "setcp: "+ str(e))
|
||||
return pl.DataFrame({'delta': [], 'cp': []}), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
return pl.DataFrame({'delta': [], 'cp': [], 'cr': []}), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
|
||||
#df.to_parquet(filename, engine='fastparquet', compression='GZIP')
|
||||
|
||||
@@ -631,7 +636,7 @@ def setcp(workout, background=False, recurrance=True):
|
||||
workout.goldmedalduration = goldmedalduration
|
||||
workout.save()
|
||||
|
||||
return df, delta, cpvalues
|
||||
return df, delta, cpvalues, spmvalues # pragma: no cover
|
||||
|
||||
|
||||
|
||||
@@ -772,7 +777,7 @@ def fetchcp_new(rower, workouts):
|
||||
data = []
|
||||
|
||||
for workout in workouts:
|
||||
df, delta, cpvalues = setcp(workout)
|
||||
df, delta, cpvalues, cpvalues_spm = setcp(workout)
|
||||
df = df.drop('id')
|
||||
df = df.with_columns((pl.lit(str(workout))).alias("workout"))
|
||||
df = df.with_columns((pl.lit(workout.url())).alias("url"))
|
||||
@@ -780,7 +785,7 @@ def fetchcp_new(rower, workouts):
|
||||
data.append(df)
|
||||
|
||||
if len(data) == 0:
|
||||
return pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), 0, pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
return pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), 0, pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
if len(data) > 1:
|
||||
df = pl.concat(data)
|
||||
|
||||
@@ -791,11 +796,16 @@ def fetchcp_new(rower, workouts):
|
||||
pl.all().sort_by('cp').last(),
|
||||
])
|
||||
except (KeyError, ColumnNotFoundError): # pragma: no cover
|
||||
return pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), 0, pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
return pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64), 0, pl.Series(dtype=pl.Float64), pl.Series(dtype=pl.Float64)
|
||||
|
||||
df = df.filter(pl.col("cp")>20)
|
||||
|
||||
return df['delta'], df['cp'], 0, df['workout'], df['url']
|
||||
try:
|
||||
testje = df['cr']
|
||||
except KeyError:
|
||||
return df['delta'], df['cp'], 0*df['cp'], 0, df['workout'], df['url']
|
||||
|
||||
return df['delta'], df['cp'], df['cr'], 0, df['workout'], df['url']
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -84,7 +84,10 @@ def cpfit(powerdf, fraclimit=0.0001, nmax=1000):
|
||||
p1 = p0
|
||||
|
||||
thesecs = powerdf['Delta'].to_numpy()
|
||||
theavpower = powerdf['CP'].to_numpy()
|
||||
try:
|
||||
theavpower = powerdf['CP'].to_numpy()
|
||||
except: # pragma: no cover
|
||||
theavpower = powerdf['CR'].to_numpy()
|
||||
|
||||
|
||||
if len(thesecs) >= 4:
|
||||
|
||||
@@ -1299,6 +1299,7 @@ analysischoices = (
|
||||
('stats', 'Statistics'),
|
||||
('compare', 'Compare'),
|
||||
('cp', 'CP chart'),
|
||||
('cr', 'CR chart'),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1113,6 +1113,75 @@ def interactive_otwcpchart(powerdf, promember=0, rowername="", r=None,
|
||||
return [script, div, p1, ratio, message]
|
||||
|
||||
|
||||
def interactive_otwcrchart(powerdf, promember=0, rowername="", r=None,
|
||||
cpfit='data',
|
||||
title='', type='water'):
|
||||
|
||||
powerdf2 = powerdf.filter((pl.col("Delta") > 0) & (pl.col("CR") > 0))
|
||||
|
||||
# plot tools
|
||||
if (promember == 1): # pragma: no cover
|
||||
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
|
||||
else:
|
||||
TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
|
||||
|
||||
x_axis_type = 'log'
|
||||
|
||||
deltas = powerdf2['Delta'].apply(lambda x: timedeltaconv(x))
|
||||
powerdf2 = powerdf2.with_columns(
|
||||
ftime = deltas.apply(lambda x: strfdelta(x)),
|
||||
Deltaminutes = pl.col("Delta")/60.
|
||||
)
|
||||
|
||||
# there is no Paul's law for OTW
|
||||
|
||||
thesecs = powerdf2['Delta']
|
||||
theavpower = powerdf2['CR']
|
||||
|
||||
p1, fitt, fitpower, ratio = datautils.cpfit(powerdf2)
|
||||
if cpfit == 'automatic' and r is not None:
|
||||
if type == 'water':
|
||||
p1 = [r.r0, r.r1, r.r2, r.r3]
|
||||
ratio = r.cpratio
|
||||
elif type == 'erg': # pragma: no cover
|
||||
p1 = [r.er0, r.er1, r.er2, r.er3]
|
||||
ratio = r.ecrratio
|
||||
|
||||
def fitfunc(pars, x):
|
||||
return abs(pars[0])/(1+(x/abs(pars[2]))) + abs(pars[1])/(1+(x/abs(pars[3])))
|
||||
|
||||
fitpower = fitfunc(p1, fitt)
|
||||
|
||||
message = ""
|
||||
# if len(fitpower[fitpower<0]) > 0:
|
||||
# message = "CP model fit didn't give correct results"
|
||||
|
||||
deltas = fitt.apply(lambda x: timedeltaconv(x))
|
||||
ftime = niceformat(deltas)
|
||||
|
||||
|
||||
|
||||
fit_data = pl.DataFrame(dict(
|
||||
CR=fitpower,
|
||||
CRmax=ratio*fitpower,
|
||||
duration=fitt/60.,
|
||||
ftime=ftime,
|
||||
))
|
||||
|
||||
if not title:
|
||||
title = "Critical StrokeRate for "+rowername
|
||||
|
||||
chart_dict = {
|
||||
'data': powerdf2.to_dicts(),
|
||||
'fitdata': fit_data.to_dicts(),
|
||||
'title': title,
|
||||
}
|
||||
|
||||
script, div = get_chart("/cr", chart_dict)
|
||||
|
||||
return [script, div, p1, ratio, message]
|
||||
|
||||
|
||||
def interactive_agegroup_plot(df, distance=2000, duration=None,
|
||||
sex='male', weightcategory='hwt'):
|
||||
|
||||
|
||||
@@ -1104,6 +1104,18 @@ class Rower(models.Model):
|
||||
ep3 = models.FloatField(default=1.0, verbose_name="erg CP p4")
|
||||
ecpratio = models.FloatField(default=1.0, verbose_name="erg CP fit ratio")
|
||||
|
||||
r0 = models.FloatField(default=1.0, verbose_name="CR r1")
|
||||
r1 = models.FloatField(default=1.0, verbose_name="CR r2")
|
||||
r2 = models.FloatField(default=1.0, verbose_name="CR r3")
|
||||
r3 = models.FloatField(default=1.0, verbose_name="CR r4")
|
||||
crratio = models.FloatField(default=1.0, verbose_name="CR fit ratio")
|
||||
|
||||
er0 = models.FloatField(default=1.0, verbose_name="erg CR r1")
|
||||
er1 = models.FloatField(default=1.0, verbose_name="erg CR r2")
|
||||
er2 = models.FloatField(default=1.0, verbose_name="erg CR r3")
|
||||
er3 = models.FloatField(default=1.0, verbose_name="erg CR r4")
|
||||
ecpratio = models.FloatField(default=1.0, verbose_name="erg CP fit ratio")
|
||||
|
||||
cprange = models.IntegerField(default=42, verbose_name="Range for calculation of breakthrough workouts and fitness (CP)",
|
||||
choices=cppresets)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1crowing-workout-metrics.proto\x12\x16rowing_workout_metrics\"\x80\x01\n\x15WorkoutMetricsRequest\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x0b\n\x03sex\x18\x02 \x01(\t\x12\x0b\n\x03\x66tp\x18\x03 \x01(\x01\x12\r\n\x05hrftp\x18\x04 \x01(\x01\x12\r\n\x05hrmax\x18\x05 \x01(\x01\x12\r\n\x05hrmin\x18\x06 \x01(\x01\x12\x0e\n\x06wpsavg\x18\x07 \x01(\x01\"\x80\x01\n\x16WorkoutMetricsResponse\x12\x0b\n\x03tss\x18\x01 \x01(\x01\x12\r\n\x05normp\x18\x02 \x01(\x01\x12\r\n\x05trimp\x18\x03 \x01(\x01\x12\r\n\x05hrtss\x18\x04 \x01(\x01\x12\r\n\x05normv\x18\x05 \x01(\x01\x12\r\n\x05normw\x18\x06 \x01(\x01\x12\x0e\n\x06spmtss\x18\x07 \x01(\x01\"=\n\tCPRequest\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x10\n\x08\x66iletype\x18\x02 \x01(\t\x12\x0c\n\x04tarr\x18\x03 \x03(\x01\"<\n\nCPResponse\x12\r\n\x05\x64\x65lta\x18\x01 \x03(\x01\x12\r\n\x05power\x18\x02 \x03(\x01\x12\x10\n\x08\x61vgpower\x18\x03 \x01(\x01\x32\xc7\x01\n\x07Metrics\x12l\n\x0b\x43\x61lcMetrics\x12-.rowing_workout_metrics.WorkoutMetricsRequest\x1a..rowing_workout_metrics.WorkoutMetricsResponse\x12N\n\x05GetCP\x12!.rowing_workout_metrics.CPRequest\x1a\".rowing_workout_metrics.CPResponseB\x1aZ\x18./rowing-workout-metricsb\x06proto3')
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1crowing-workout-metrics.proto\x12\x16rowing_workout_metrics\"\x80\x01\n\x15WorkoutMetricsRequest\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x0b\n\x03sex\x18\x02 \x01(\t\x12\x0b\n\x03\x66tp\x18\x03 \x01(\x01\x12\r\n\x05hrftp\x18\x04 \x01(\x01\x12\r\n\x05hrmax\x18\x05 \x01(\x01\x12\r\n\x05hrmin\x18\x06 \x01(\x01\x12\x0e\n\x06wpsavg\x18\x07 \x01(\x01\"\x80\x01\n\x16WorkoutMetricsResponse\x12\x0b\n\x03tss\x18\x01 \x01(\x01\x12\r\n\x05normp\x18\x02 \x01(\x01\x12\r\n\x05trimp\x18\x03 \x01(\x01\x12\r\n\x05hrtss\x18\x04 \x01(\x01\x12\r\n\x05normv\x18\x05 \x01(\x01\x12\r\n\x05normw\x18\x06 \x01(\x01\x12\x0e\n\x06spmtss\x18\x07 \x01(\x01\"=\n\tCPRequest\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x10\n\x08\x66iletype\x18\x02 \x01(\t\x12\x0c\n\x04tarr\x18\x03 \x03(\x01\"I\n\nCPResponse\x12\r\n\x05\x64\x65lta\x18\x01 \x03(\x01\x12\r\n\x05power\x18\x02 \x03(\x01\x12\x10\n\x08\x61vgpower\x18\x03 \x01(\x01\x12\x0b\n\x03spm\x18\x04 \x03(\x01\x32\xc7\x01\n\x07Metrics\x12l\n\x0b\x43\x61lcMetrics\x12-.rowing_workout_metrics.WorkoutMetricsRequest\x1a..rowing_workout_metrics.WorkoutMetricsResponse\x12N\n\x05GetCP\x12!.rowing_workout_metrics.CPRequest\x1a\".rowing_workout_metrics.CPResponseB\x1aZ\x18./rowing-workout-metricsb\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
@@ -39,7 +39,7 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
||||
_globals['_CPREQUEST']._serialized_start=318
|
||||
_globals['_CPREQUEST']._serialized_end=379
|
||||
_globals['_CPRESPONSE']._serialized_start=381
|
||||
_globals['_CPRESPONSE']._serialized_end=441
|
||||
_globals['_METRICS']._serialized_start=444
|
||||
_globals['_METRICS']._serialized_end=643
|
||||
_globals['_CPRESPONSE']._serialized_end=454
|
||||
_globals['_METRICS']._serialized_start=457
|
||||
_globals['_METRICS']._serialized_end=656
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
20
rowers/templates/otwcr.html
Normal file
20
rowers/templates/otwcr.html
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
{{ the_div|safe }}
|
||||
<p>
|
||||
<table width="100%" class="listtable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> Duration</th>
|
||||
<th> Stroke Estimate 1</th>
|
||||
<th> Stroke Estimate 2</th>
|
||||
<tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ duration }}</td>
|
||||
<td>{{ power }}</td>
|
||||
<td>{{ upper }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
@@ -124,13 +124,13 @@
|
||||
<script>
|
||||
// script for chart options form
|
||||
$(function() {
|
||||
|
||||
|
||||
// Get the form fields and hidden div
|
||||
var functionfield = $("#id_function");
|
||||
var plotfield = $("#id_plotfield").parent().parent();
|
||||
var x_param = $("#id_xparam").parent().parent();
|
||||
var y_param = $("#id_yparam").parent().parent();
|
||||
|
||||
|
||||
var groupby = $("#id_groupby").parent().parent();
|
||||
var binsize = $("#id_binsize").parent().parent();
|
||||
var errorbars = $("#id_ploterrorbars").parent().parent();
|
||||
@@ -139,17 +139,18 @@
|
||||
var spmmax = $("#id_spmmax").parent().parent();
|
||||
var workmin = $("#id_workmin").parent().parent();
|
||||
var workmax = $("#id_workmax").parent().parent();
|
||||
|
||||
|
||||
var xaxis = $("#id_xaxis").parent().parent();
|
||||
var yaxis1 = $("#id_yaxis1").parent().parent();
|
||||
var yaxis2 = $("#id_yaxis2").parent().parent();
|
||||
var plottype = $("#id_plottype").parent().parent();
|
||||
|
||||
var reststrokes = $("#id_includereststrokes").parent().parent();
|
||||
var trendline = $("#id_trendline").parent().parent();
|
||||
var piece = $("#id_piece").parent().parent();
|
||||
var cpfit = $("#id_cpfit").parent().parent();
|
||||
var cpoverlay = $("#id_cpoverlay").parent().parent();
|
||||
|
||||
var reststrokes = $("#id_includereststrokes").parent().parent();
|
||||
var trendline = $("#id_trendline").parent().parent();
|
||||
var piece = $("#id_piece").parent().parent();
|
||||
var cpfit = $("#id_cpfit").parent().parent();
|
||||
var crfit = $("#id_crfit").parent().parent();
|
||||
var cpoverlay = $("#id_cpoverlay").parent().parent();
|
||||
|
||||
|
||||
// Hide the fields.
|
||||
@@ -166,15 +167,15 @@
|
||||
yaxis1.hide();
|
||||
yaxis2.hide();
|
||||
plottype.hide();
|
||||
// reststrokes.hide();
|
||||
workmin.hide();
|
||||
workmax.hide();
|
||||
spmmin.hide();
|
||||
spmmax.hide();
|
||||
cpfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
trendline.hide();
|
||||
// reststrokes.hide();
|
||||
workmin.hide();
|
||||
workmax.hide();
|
||||
spmmin.hide();
|
||||
spmmax.hide();
|
||||
cpfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
trendline.hide();
|
||||
|
||||
if (functionfield.val() == 'boxplot') {
|
||||
plotfield.show();
|
||||
@@ -214,11 +215,16 @@
|
||||
reststrokes.show();
|
||||
}
|
||||
|
||||
if (functionfield.val() == 'cp') {
|
||||
cpfit.show();
|
||||
piece.show();
|
||||
cpoverlay.show();
|
||||
}
|
||||
if (functionfield.val() == 'cp') {
|
||||
cpfit.show();
|
||||
piece.show();
|
||||
cpoverlay.show();
|
||||
}
|
||||
|
||||
if (functionfield.val() == 'cr') {
|
||||
crfit.show();
|
||||
piece.show();
|
||||
}
|
||||
|
||||
|
||||
// Setup an event listener for when the state of the
|
||||
@@ -241,15 +247,16 @@
|
||||
palette.hide();
|
||||
binsize.hide();
|
||||
errorbars.hide();
|
||||
trendline.hide();
|
||||
trendline.hide();
|
||||
xaxis.hide();
|
||||
yaxis1.hide();
|
||||
yaxis2.hide();
|
||||
plottype.hide();
|
||||
reststrokes.show();
|
||||
cpfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
reststrokes.show();
|
||||
cpfit.hide();
|
||||
crfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
}
|
||||
else if (Value=='histo') {
|
||||
plotfield.show();
|
||||
@@ -262,16 +269,17 @@
|
||||
groupby.hide();
|
||||
palette.hide();
|
||||
binsize.hide();
|
||||
trendline.hide();
|
||||
trendline.hide();
|
||||
errorbars.hide();
|
||||
xaxis.hide();
|
||||
yaxis1.hide();
|
||||
yaxis2.hide();
|
||||
plottype.hide();
|
||||
reststrokes.show();
|
||||
cpfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
reststrokes.show();
|
||||
cpfit.hide();
|
||||
crfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
|
||||
}
|
||||
else if (Value=='trendflex') {
|
||||
@@ -284,17 +292,18 @@
|
||||
spmmin.show();
|
||||
spmmax.show();
|
||||
workmin.show();
|
||||
trendline.hide();
|
||||
trendline.hide();
|
||||
workmax.show();
|
||||
plotfield.hide();
|
||||
xaxis.hide();
|
||||
yaxis1.hide();
|
||||
yaxis2.hide();
|
||||
plottype.hide();
|
||||
reststrokes.show();
|
||||
cpfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
reststrokes.show();
|
||||
cpfit.hide();
|
||||
crfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
|
||||
}
|
||||
else if (Value=='flexall') {
|
||||
@@ -305,7 +314,7 @@
|
||||
y_param.hide();
|
||||
groupby.hide();
|
||||
spmmin.hide();
|
||||
trendline.show();
|
||||
trendline.show();
|
||||
spmmax.hide();
|
||||
workmin.hide();
|
||||
workmax.hide();
|
||||
@@ -314,10 +323,11 @@
|
||||
binsize.hide();
|
||||
plottype.hide();
|
||||
errorbars.hide();
|
||||
reststrokes.show();
|
||||
cpfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
reststrokes.show();
|
||||
cpfit.hide();
|
||||
crfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
}
|
||||
else if (Value=='stats') {
|
||||
xaxis.hide();
|
||||
@@ -331,11 +341,12 @@
|
||||
binsize.hide();
|
||||
errorbars.hide();
|
||||
plottype.hide();
|
||||
trendline.hide();
|
||||
reststrokes.show();
|
||||
cpfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
trendline.hide();
|
||||
reststrokes.show();
|
||||
cpfit.hide();
|
||||
crfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.hide();
|
||||
}
|
||||
else if (Value=='compare') {
|
||||
xaxis.show();
|
||||
@@ -350,18 +361,19 @@
|
||||
workmax.hide();
|
||||
plotfield.hide();
|
||||
palette.hide();
|
||||
trendline.hide();
|
||||
trendline.hide();
|
||||
binsize.hide();
|
||||
plottype.show();
|
||||
errorbars.hide();
|
||||
piece.hide();
|
||||
cpfit.hide();
|
||||
cpoverlay.hide();
|
||||
reststrokes.show();
|
||||
piece.hide();
|
||||
cpfit.hide();
|
||||
crfit.hide();
|
||||
cpoverlay.hide();
|
||||
reststrokes.show();
|
||||
|
||||
|
||||
}
|
||||
else if (Value=='cp') {
|
||||
else if (Value=='cp') {
|
||||
plotfield.hide();
|
||||
spmmin.hide();
|
||||
spmmax.hide();
|
||||
@@ -369,7 +381,7 @@
|
||||
workmax.hide();
|
||||
x_param.hide();
|
||||
y_param.hide();
|
||||
trendline.hide();
|
||||
trendline.hide();
|
||||
groupby.hide();
|
||||
palette.hide();
|
||||
binsize.hide();
|
||||
@@ -378,10 +390,34 @@
|
||||
yaxis1.hide();
|
||||
yaxis2.hide();
|
||||
plottype.hide();
|
||||
reststrokes.hide();
|
||||
cpfit.show();
|
||||
cpoverlay.hide();
|
||||
piece.show();
|
||||
reststrokes.hide();
|
||||
cpfit.show();
|
||||
crfit.hide();
|
||||
cpoverlay.hide();
|
||||
piece.show();
|
||||
}
|
||||
else if (Value=='cr') {
|
||||
plotfield.hide();
|
||||
spmmin.hide();
|
||||
spmmax.hide();
|
||||
workmin.hide();
|
||||
workmax.hide();
|
||||
x_param.hide();
|
||||
y_param.hide();
|
||||
trendline.hide();
|
||||
groupby.hide();
|
||||
palette.hide();
|
||||
binsize.hide();
|
||||
errorbars.hide();
|
||||
xaxis.hide();
|
||||
yaxis1.hide();
|
||||
yaxis2.hide();
|
||||
plottype.hide();
|
||||
reststrokes.hide();
|
||||
cpfit.hide();
|
||||
crfit.show();
|
||||
cpoverlay.hide();
|
||||
piece.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -294,6 +294,8 @@ def analysis_new(request,
|
||||
df = comparisondata(tw, options)
|
||||
elif function == 'cp': # pragma: no cover
|
||||
df = cpdata(tw, options)
|
||||
elif function == 'cr': # pragma: no cover
|
||||
df = crdata(tw, options)
|
||||
options['savedata'] = False
|
||||
request.session['options'] = options
|
||||
try:
|
||||
@@ -661,7 +663,7 @@ def cpdata(workouts, options):
|
||||
r = u.rower
|
||||
|
||||
|
||||
delta, cpvalue, avgpower, workoutnames, urls = dataprep.fetchcp_new(
|
||||
delta, cpvalue, crvalue, avgpower, workoutnames, urls = dataprep.fetchcp_new(
|
||||
r, workouts)
|
||||
|
||||
powerdf = pl.DataFrame({
|
||||
@@ -811,6 +813,139 @@ def cpdata(workouts, options):
|
||||
|
||||
return (script, html_content)
|
||||
|
||||
def crdata(workouts, options):
|
||||
start = timezone.now()
|
||||
userid = options['userid']
|
||||
cpfit = options['cpfit']
|
||||
cpoverlay = options['cpoverlay']
|
||||
|
||||
u = User.objects.get(id=userid)
|
||||
r = u.rower
|
||||
|
||||
|
||||
delta, cpvalue, crvalue, avgpower, workoutnames, urls = dataprep.fetchcp_new(
|
||||
r, workouts)
|
||||
|
||||
powerdf = pl.DataFrame({
|
||||
'Delta': delta,
|
||||
'CR': crvalue,
|
||||
'workout': workoutnames,
|
||||
'url': urls,
|
||||
})
|
||||
|
||||
savedata = options.get('savedata',False)
|
||||
if savedata: # pragma: no cover
|
||||
return powerdf.to_pandas()
|
||||
|
||||
if powerdf.is_empty(): # pragma: no cover
|
||||
return('', '<p>No valid data found</p>')
|
||||
|
||||
|
||||
powerdf = powerdf.lazy().filter(pl.col("CR")>0)
|
||||
powerdf = powerdf.sort(["Delta", "CR"], descending=[False, True])
|
||||
powerdf = powerdf.unique(subset="Delta", keep="first")
|
||||
powerdf = powerdf.fill_nan(None).drop_nulls()
|
||||
powerdf = powerdf.collect()
|
||||
|
||||
rowername = r.user.first_name+" "+r.user.last_name
|
||||
|
||||
wcdurations = []
|
||||
wcpower = []
|
||||
|
||||
if len(powerdf) != 0:
|
||||
datefirst = pd.Series(w.date for w in workouts).min()
|
||||
datelast = pd.Series(w.date for w in workouts).max()
|
||||
title = 'Critical Stroke Rate chart for {name}, from {d1} to {d2}'.format(
|
||||
name=rowername,
|
||||
d1=datefirst,
|
||||
d2=datelast,
|
||||
)
|
||||
wtype = 'water'
|
||||
if workouts[0].workouttype in mytypes.otetypes: # pragma: no cover
|
||||
wtype = 'erg'
|
||||
if workouts[0].workouttype == 'bikeerg': # pragma: no cover
|
||||
# for Mike
|
||||
wtype = 'erg'
|
||||
|
||||
|
||||
res = interactive_otwcrchart(powerdf, promember=True, rowername=rowername, r=r,
|
||||
cpfit=cpfit, title=title, type=wtype,)
|
||||
|
||||
script = res[0]
|
||||
div = res[1]
|
||||
p1 = res[2]
|
||||
ratio = res[3]
|
||||
else: # pragma: no cover
|
||||
script = ''
|
||||
div = '<p>No ranking pieces found.</p>'
|
||||
p1 = [1, 1, 1, 1]
|
||||
ratio = 1
|
||||
|
||||
|
||||
|
||||
|
||||
minutes = options['piece']
|
||||
if minutes != 0:
|
||||
# minutes = 77
|
||||
try:
|
||||
hourvalue, tvalue = divmod(minutes, 60)
|
||||
except: # pragma: no cover
|
||||
hourvalue = 0
|
||||
tvalue = minutes
|
||||
# hourvalue = 1, tvalue = 17
|
||||
try:
|
||||
hourvalue = int(hourvalue)
|
||||
except TypeError: # pragma: no cover
|
||||
hourvalue = 0
|
||||
try:
|
||||
minutevalue = int(tvalue)
|
||||
except TypeError: # pragma: no cover
|
||||
minutevalue = 0
|
||||
|
||||
tvalue = int(60*(tvalue-minutevalue))
|
||||
|
||||
if hourvalue >= 24: # pragma: no cover
|
||||
hourvalue = 23
|
||||
pieceduration = datetime.time(
|
||||
minute=minutevalue,
|
||||
hour=hourvalue,
|
||||
second=tvalue,
|
||||
)
|
||||
|
||||
pieceseconds = 3600.*pieceduration.hour+60. * \
|
||||
pieceduration.minute+pieceduration.second
|
||||
# CP model
|
||||
pwr = p1[0]/(1+pieceseconds/p1[2])
|
||||
pwr += p1[1]/(1+pieceseconds/p1[3])
|
||||
|
||||
if pwr <= 0: # pragma: no cover
|
||||
pwr = 50.
|
||||
|
||||
if not np.isnan(pwr):
|
||||
try:
|
||||
pwr2 = pwr*ratio
|
||||
except: # pragma: no cover
|
||||
pwr2 = pwr
|
||||
|
||||
duration = timedeltaconv(pieceseconds)
|
||||
power = int(pwr)
|
||||
upper = int(pwr2)
|
||||
else: # pragma: no cover
|
||||
duration = timedeltaconv(0)
|
||||
power = 0
|
||||
upper = 0
|
||||
|
||||
htmly = env.get_template('otwcr.html')
|
||||
html_content = htmly.render({
|
||||
'script': script,
|
||||
'the_div': div,
|
||||
'duration': duration,
|
||||
'power': power,
|
||||
'upper': upper,
|
||||
})
|
||||
|
||||
return (script, html_content)
|
||||
|
||||
|
||||
def statsdata(workouts, options):
|
||||
#try:
|
||||
@@ -1063,6 +1198,8 @@ def analysis_view_data(request, userid=0):
|
||||
script, div = comparisondata(workouts, options)
|
||||
elif function == 'cp': # pragma: no cover
|
||||
script, div = cpdata(workouts, options)
|
||||
elif function == 'cr': # pragma: no cover
|
||||
script, div = crdata(workouts, options)
|
||||
else: # pragma: no cover
|
||||
script = ''
|
||||
div = 'Unknown analysis functions'
|
||||
|
||||
Reference in New Issue
Block a user