Private
Public Access
1
0

made metrics and strokedata model dynamic

This commit is contained in:
Sander Roosendaal
2017-09-21 16:47:39 +02:00
parent 79d2c7490a
commit 6db8b17ad6
4 changed files with 292 additions and 80 deletions

View File

@@ -1,32 +1,236 @@
from utils import lbstoN
axes = (
('time','Time',0,1e5,'basic'),
('distance', 'Distance (m)',0,1e5,'basic'),
('cumdist', 'Cumulative Distance (m)',0,1e5,'basic'),
('hr','Heart Rate (bpm)',100,200,'basic'),
('spm', 'Stroke Rate (spm)',15,45,'basic'),
('pace', 'Pace (/500m)',1.0e3*210,1.0e3*75,'basic'),
('power', 'Power (Watt)',0,600,'basic'),
('averageforce', 'Average Drive Force (N)',0,900,'pro'),
('drivelength', 'Drive Length (m)',0.5,2.0,'pro'),
('peakforce', 'Peak Drive Force (N)',0,900,'pro'),
('forceratio', 'Average/Peak Force Ratio',0,1,'pro'),
('driveenergy', 'Work per Stroke (J)',0,1000,'pro'),
('drivespeed', 'Drive Speed (m/s)',0,4,'pro'),
('slip', 'Slip (degrees)',0,20,'pro'),
('catch', 'Catch (degrees)',-40,-75,'pro'),
('finish', 'Finish (degrees)',20,55,'pro'),
('wash', 'Wash (degrees)',0,30,'pro'),
('peakforceangle', 'Peak Force Angle (degrees)',-20,20,'pro'),
('totalangle', 'Drive Length (deg)',40,140,'pro'),
('effectiveangle', 'Effective Drive Length (deg)',40,140,'pro'),
('rhythm', 'Stroke Rhythm (%)',20,55,'pro'),
('efficiency', 'OTW efficiency (%)',0,110,'pro'),
('distanceperstroke','Distance per Stroke (m)',0,15,'pro'),
('None', 'None',0,1,'basic'),
rowingmetrics = (
('time',{
'numtype':'float',
'null':True,
'verbose_name': 'Time',
'ax_min': 0,
'ax_max': 1e5,
'mode':'both',
'type': 'basic'}),
('hr',{
'numtype':'integer',
'null':True,
'verbose_name': 'Heart Rate (bpm)',
'ax_min': 100,
'ax_max': 200,
'mode':'both',
'type': 'basic'}),
('pace',{
'numtype':'float',
'null':True,
'verbose_name': 'Pace (/500m)',
'ax_min': 1.0e3*210,
'ax_max': 1.0e3*75,
'mode':'both',
'type': 'basic'}),
('spm',{
'numtype':'float',
'null':True,
'verbose_name': 'Stroke Rate (spm)',
'ax_min': 15,
'ax_max': 45,
'mode':'both',
'type': 'basic'}),
('driveenergy',{
'numtype':'float',
'null':True,
'verbose_name': 'Work Per Stroke (J)',
'ax_min': 0,
'ax_max': 1000,
'mode':'both',
'type': 'pro'}),
('power',{
'numtype':'float',
'null':True,
'verbose_name': 'Power (W)',
'ax_min': 0,
'ax_max': 600,
'mode':'both',
'type': 'basic'}),
('averageforce',{
'numtype':'float',
'null':True,
'verbose_name': 'Average Drive Force (N)',
'ax_min': 0,
'ax_max': 900,
'mode':'both',
'type': 'pro'}),
('peakforce',{
'numtype':'float',
'null':True,
'verbose_name': 'Peak Drive Force (N)',
'ax_min': 0,
'ax_max': 900,
'mode':'both',
'type': 'pro'}),
('drivelength',{
'numtype':'float',
'null':True,
'verbose_name': 'Drive Length (m)',
'ax_min': 15,
'ax_max': 45,
'mode':'both',
'type': 'pro'}),
('forceratio',{
'numtype':'float',
'null':True,
'verbose_name': 'Average/Peak Force Ratio',
'ax_min': 0,
'ax_max': 1,
'mode':'both',
'type': 'pro'}),
('distance',{
'numtype':'float',
'null':True,
'verbose_name': 'Distance (m)',
'ax_min': 0,
'ax_max': 1e5,
'mode':'both',
'type': 'basic'}),
('cumdist',{
'numtype':'float',
'null':True,
'verbose_name': 'Cumulative Distance (m)',
'ax_min': 0,
'ax_max': 1e5,
'mode':'both',
'type': 'basic'}),
('drivespeed',{
'numtype':'float',
'null':True,
'verbose_name': 'Drive Speed (m/s)',
'ax_min': 0,
'ax_max': 4,
'default': 0,
'mode':'both',
'type': 'pro'}),
('catch',{
'numtype':'float',
'null':True,
'verbose_name': 'Catch Angle (degrees)',
'ax_min': -40,
'ax_max': -75,
'default': 0,
'mode':'water',
'type': 'pro'}),
('slip',{
'numtype':'float',
'null':True,
'verbose_name': 'Slip (degrees)',
'ax_min': 0,
'ax_max': 20,
'default': 0,
'mode':'water',
'type': 'pro'}),
('finish',{
'numtype':'float',
'null':True,
'verbose_name': 'Finish Angle (degrees)',
'ax_min': 20,
'ax_max': 55,
'default': 0,
'mode':'water',
'type': 'pro'}),
('wash',{
'numtype':'float',
'null':True,
'verbose_name': 'Wash (degrees)',
'ax_min': 0,
'ax_max': 30,
'default': 0,
'mode':'water',
'type': 'pro'}),
('peakforceangle',{
'numtype':'float',
'null':True,
'verbose_name': 'Peak Force Angle',
'ax_min': -20,
'ax_max': 20,
'default': 0,
'mode':'water',
'type': 'pro'}),
('totalangle',{
'numtype':'float',
'null':True,
'verbose_name': 'Drive Length (deg)',
'ax_min': 40,
'ax_max': 140,
'default': 0,
'mode':'water',
'type': 'pro'}),
('effectiveangle',{
'numtype':'float',
'null':True,
'verbose_name': 'Effective Drive Length (deg)',
'ax_min': 40,
'ax_max': 140,
'default': 0,
'mode':'water',
'type': 'pro'}),
('rhythm',{
'numtype':'float',
'null':True,
'verbose_name': 'Stroke Rhythm',
'ax_min': 20,
'ax_max': 55,
'default': 1.0,
'mode':'erg',
'type': 'pro'}),
('efficiency',{
'numtype':'float',
'null':True,
'verbose_name': 'OTW Efficiency (%)',
'ax_min': 0,
'ax_max': 110,
'default': 0,
'mode':'water',
'type': 'pro'}),
('distanceperstroke',{
'numtype':'float',
'null':True,
'verbose_name': 'Distance per Stroke (m)',
'ax_min': 0,
'ax_max': 15,
'default': 0,
'mode':'both',
'type': 'pro'}),
)
axesnew = [
(name,d['verbose_name'],d['ax_min'],d['ax_max'],d['type']) for name,d in rowingmetrics
]
axes = tuple(axesnew+[('None','None',0,1,'basic')])
axlabels = {ax[0]:ax[1] for ax in axes}
yaxminima = {ax[0]:ax[2] for ax in axes}

View File

@@ -519,57 +519,65 @@ def auto_delete_strokedata_on_delete(sender, instance, **kwargs):
conn.close()
engine.dispose()
from rowers.metrics import rowingmetrics
strokedatafields = {
'workoutid':models.IntegerField(null=True),
'workoutstate':models.IntegerField(null=True,default=1),
'ftime':models.CharField(max_length=30),
'fpace':models.CharField(max_length=30),
'hr_ut2':models.IntegerField(null=True),
'hr_ut1':models.IntegerField(null=True),
'hr_at':models.IntegerField(null=True),
'hr_tr':models.IntegerField(null=True),
'hr_an':models.IntegerField(null=True),
'hr_max':models.IntegerField(null=True),
'hr_bottom':models.IntegerField(null=True),
'x_right':models.FloatField(null=True),
'ergpace':models.FloatField(null=True),
'nowindpace':models.FloatField(null=True),
'equivergpower':models.FloatField(null=True),
'fergpace':models.CharField(max_length=30),
'fnowindpace':models.CharField(max_length=30),
}
for name,d in rowingmetrics:
if d['numtype'] == 'float':
try:
strokedatafields[name] = models.FloatField(
null=d['null'],
default=d['default'],
verbose_name=d['verbose_name'])
except KeyError:
strokedatafields[name] = models.FloatField(
null=d['null'],
verbose_name=d['verbose_name'])
elif d['numtype'] == 'integer':
try:
strokedatafields[name] = models.IntegerField(
null=d['null'],
default=d['default'],
verbose_name=d['verbose_name'])
except KeyError:
strokedatafields[name] = models.IntegerField(
null=d['null'],
verbose_name=d['verbose_name'])
class Meta:
db_table = 'strokedata'
index_together = ['workoutid']
app_label = 'rowers'
attrs = {'__module__': '', 'Meta': Meta}
attrs.update(strokedatafields)
# Model of StrokeData table
# the definition here is used only to enable easy Django migration
# when the StrokeData are expanded.
# No Django Instances of this model are managed. Strokedata table is
# accesssed directly with SQL commands
class StrokeData(models.Model):
class Meta:
db_table = 'strokedata'
index_together = ['workoutid']
workoutid = models.IntegerField(null=True)
time = models.FloatField(null=True,verbose_name='Time')
hr = models.IntegerField(null=True,verbose_name='Heart Rate')
pace = models.FloatField(null=True,verbose_name='Pace')
workoutstate = models.IntegerField(null=True,default=1)
spm = models.FloatField(null=True,verbose_name='Stroke Rate')
cumdist = models.FloatField(null=True,verbose_name='Cumulative Distance')
ftime = models.CharField(max_length=30)
fpace = models.CharField(max_length=30)
driveenergy = models.FloatField(null=True,verbose_name='Work per Stroke')
power = models.FloatField(null=True,verbose_name='Power')
averageforce = models.FloatField(null=True,verbose_name='Average Force')
drivelength = models.FloatField(null=True,verbose_name='Drive Length')
peakforce = models.FloatField(null=True,verbose_name='Peak Force')
forceratio = models.FloatField(null=True,verbose_name='Average/Peak Force Ratio')
distance = models.FloatField(null=True,verbose_name='Distance')
drivespeed = models.FloatField(null=True,verbose_name='Drive Speed',
default=0)
hr_ut2 = models.IntegerField(null=True)
hr_ut1 = models.IntegerField(null=True)
hr_at = models.IntegerField(null=True)
hr_tr = models.IntegerField(null=True)
hr_an = models.IntegerField(null=True)
hr_max = models.IntegerField(null=True)
hr_bottom = models.IntegerField(null=True)
x_right = models.FloatField(null=True)
ergpace = models.FloatField(null=True)
nowindpace = models.FloatField(null=True)
equivergpower = models.FloatField(null=True)
fergpace = models.CharField(max_length=30)
fnowindpace = models.CharField(max_length=30)
catch = models.FloatField(default=0,null=True,verbose_name='Catch Angle')
slip = models.FloatField(default=0,null=True,verbose_name='Slip')
finish = models.FloatField(default=0,null=True,verbose_name='Finish Angle')
wash = models.FloatField(default=0,null=True,verbose_name='Wash')
peakforceangle = models.FloatField(default=0,null=True,verbose_name='Peak Force Angle')
rhythm = models.FloatField(default=1.0,null=True,verbose_name='Rhythm')
totalangle = models.FloatField(default=0.0,null=True,verbose_name='Total Stroke Length (deg)')
effectiveangle = models.FloatField(default=0.0,null=True,verbose_name='Effective Stroke Length (deg)')
efficiency = models.FloatField(default=-1,null=True,verbose_name='OTW Efficiency')
distanceperstroke = models.FloatField(default=-1,null=True,verbose_name='Distance per Stroke')
StrokeData = type(str('StrokeData'), (models.Model,),
attrs
)
# A wrapper around the png files
class GraphImage(models.Model):

View File

@@ -48,6 +48,7 @@ from rowers.models import (
WorkoutComment,WorkoutCommentForm,RowerExportForm,
)
from rowers.models import FavoriteForm,BaseFavoriteFormSet,SiteAnnouncement
from rowers.metrics import rowingmetrics
from django.forms.formsets import formset_factory
import StringIO
from django.contrib.auth.decorators import login_required,user_passes_test
@@ -5905,6 +5906,10 @@ def workout_flexchart3_view(request,*args,**kwargs):
axchoicesbasic.pop("cumdist")
if row.workouttype in ('water','coastal'):
for name,d in rowingmetrics:
if d['mode'] == 'erg':
axchoicespro.pop(name)
return render(request,
'flexchart3otw.html',
{'the_script':script,
@@ -5927,14 +5932,9 @@ def workout_flexchart3_view(request,*args,**kwargs):
'maxfav':maxfav,
})
else:
axchoicespro.pop('slip')
axchoicespro.pop('wash')
axchoicespro.pop('catch')
axchoicespro.pop('finish')
axchoicespro.pop('totalangle')
axchoicespro.pop('effectiveangle')
axchoicespro.pop('peakforceangle')
axchoicespro.pop('efficiency')
for name,d in rowingmetrics:
if d['mode'] == 'water':
axchoicespro.pop(name)
return render(request,
'flexchart3otw.html',

View File

@@ -63,7 +63,7 @@ INSTALLED_APPS = [
'analytical',
'cookielaw',
'django_extensions',
'tz_detect'
'tz_detect',
]
AUTHENTICATION_BACKENDS = (