rowingdata 3.6.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. rowingdata/__init__.py +2 -0
  2. rowingdata/__main__.py +2 -0
  3. rowingdata/boatedit.py +15 -0
  4. rowingdata/checkdatafiles.py +216 -0
  5. rowingdata/copystats.py +22 -0
  6. rowingdata/crewnerdplot.py +37 -0
  7. rowingdata/crewnerdplottime.py +37 -0
  8. rowingdata/csvparsers.py +3114 -0
  9. rowingdata/ergdataplot.py +31 -0
  10. rowingdata/ergdataplottime.py +31 -0
  11. rowingdata/ergdatatotcx.py +32 -0
  12. rowingdata/ergstickplot.py +31 -0
  13. rowingdata/ergstickplottime.py +32 -0
  14. rowingdata/ergsticktotcx.py +32 -0
  15. rowingdata/example.csv +5171 -0
  16. rowingdata/gpxtools.py +70 -0
  17. rowingdata/gpxwrite.py +151 -0
  18. rowingdata/konkatenaadje.py +19 -0
  19. rowingdata/laptesting.py +293 -0
  20. rowingdata/obsolete.py +654 -0
  21. rowingdata/otherparsers.py +718 -0
  22. rowingdata/painsled_desktop_plot.py +30 -0
  23. rowingdata/painsled_desktop_plottime.py +29 -0
  24. rowingdata/painsled_desktop_toc2.py +30 -0
  25. rowingdata/painsledplot.py +27 -0
  26. rowingdata/painsledplottime.py +27 -0
  27. rowingdata/painsledtoc2.py +23 -0
  28. rowingdata/roweredit.py +15 -0
  29. rowingdata/rowingdata.py +6941 -0
  30. rowingdata/rowproplot.py +31 -0
  31. rowingdata/rowproplottime.py +31 -0
  32. rowingdata/speedcoachplot.py +31 -0
  33. rowingdata/speedcoachplottime.py +31 -0
  34. rowingdata/speedcoachtoc2.py +36 -0
  35. rowingdata/tcxplot.py +38 -0
  36. rowingdata/tcxplot_nogeo.py +38 -0
  37. rowingdata/tcxplottime.py +33 -0
  38. rowingdata/tcxplottime_nogeo.py +33 -0
  39. rowingdata/tcxtoc2.py +30 -0
  40. rowingdata/tcxtools.py +417 -0
  41. rowingdata/trainingparser.py +302 -0
  42. rowingdata/utils.py +135 -0
  43. rowingdata/windcorrected.py +48 -0
  44. rowingdata/writetcx.py +312 -0
  45. rowingdata-3.6.8.dist-info/LICENSE +21 -0
  46. rowingdata-3.6.8.dist-info/METADATA +1149 -0
  47. rowingdata-3.6.8.dist-info/RECORD +49 -0
  48. rowingdata-3.6.8.dist-info/WHEEL +5 -0
  49. rowingdata-3.6.8.dist-info/top_level.txt +1 -0
@@ -0,0 +1,302 @@
1
+ from __future__ import absolute_import
2
+ import numpy as np
3
+ import string
4
+ import re
5
+ from six.moves import range
6
+
7
+
8
+ def cleanzeros(values):
9
+ newlist = []
10
+ oldlist = values
11
+ while oldlist:
12
+ interval = oldlist[0:3]
13
+ if interval[0] != 0:
14
+ newlist += interval
15
+ oldlist = oldlist[3:]
16
+
17
+ return newlist
18
+
19
+ from pyparsing import (
20
+ Literal,Word,ZeroOrMore,Forward,nums,oneOf,Group,
21
+ alphas
22
+ )
23
+
24
+ def Syntax():
25
+ op = "+"
26
+ restop = "/"
27
+ times = "x"
28
+ minsep = ":"
29
+ targetop = "@"
30
+
31
+
32
+ lpar = Literal( '(' ).suppress()
33
+ rpar = Literal( ')' ).suppress()
34
+ num = Word(nums)
35
+ num2 = Word(nums,exact=2)
36
+ timeordist = Group(num+":"+num) | num
37
+ ntimes = num+"x"
38
+ unit = Word(alphas)
39
+ interval = Group(timeordist+unit) | timeordist # 5min
40
+ target = Group(num+unit)
41
+
42
+ multipleinterval = Group(ntimes+interval) # 3x5min
43
+ set = multipleinterval | interval # 5min or 3x5min
44
+ intervalwithrest = Group(set+"/"+interval) # 5min/3min or 3x5min/3min
45
+ intervalwithtarget = Group(set+"@"+target)
46
+ intervalwithtargetandrest = Group(intervalwithtarget+"/"+interval)
47
+ expr = Forward()
48
+
49
+ atom = intervalwithtargetandrest | intervalwithtarget | intervalwithrest | set | multipleinterval | interval | Group(lpar+expr+rpar)
50
+
51
+ bigset = Group(ntimes+atom) | atom
52
+ bigsetwithrest = Group(bigset+"/"+interval)
53
+ bigsetwithtarget = Group(bigset+"@"+target)
54
+ bigsetwithtargetandrest = Group(bigsetwithtarget+"/"+interval)
55
+ majorset = bigsetwithtargetandrest | bigsetwithtarget | bigsetwithrest | bigset
56
+
57
+
58
+ expr << majorset + ZeroOrMore( "+" + expr )
59
+ return expr
60
+
61
+ def getintervalasdict(l,target=None):
62
+ if len(l)==0:
63
+ return [{}]
64
+ elif len(l)==2:
65
+ try:
66
+ value = int(l[0])
67
+ unit = l[1]
68
+ except TypeError:
69
+ valuemin = int(l[0][0])
70
+ valuesec = int(l[0][2])
71
+ value = 60*valuemin+valuesec
72
+ unit = 'sec'
73
+ d = {
74
+ 'value': value,
75
+ 'unit': unit,
76
+ 'type': 'work'
77
+ }
78
+ if target is not None:
79
+ try:
80
+ d['target'] = int(target[0])
81
+ d['targetunit'] = target[1]
82
+ except ValueError:
83
+ pass
84
+ return [d]
85
+ elif len(l)==3 and l[1] == '/':
86
+ a = getintervalasdict(l[0])
87
+ b = getintervalasdict(l[2])
88
+ b[0]['type'] = 'rest'
89
+ return [a,b]
90
+ elif len(l)==3 and l[1] == 'x':
91
+ u = []
92
+ u.append({'value':int(l[0]),'type':'repeatstart','unit':'m'})
93
+ u.append(getintervalasdict(l[2]))
94
+ u.append({'value':int(l[0]),'type':'repeat','unit':'m'})
95
+ #for i in range(int(l[0])):
96
+ # u.append(getintervalasdict(l[2]))
97
+ return u
98
+ elif len(l)==3 and l[1] == '@':
99
+ return getintervalasdict(l[0],target=l[2])
100
+ elif len(l)==1:
101
+ return getintervalasdict(l[0])
102
+ else:
103
+ return [getintervalasdict(l[0]),getintervalasdict(l[2:])]
104
+
105
+
106
+ def getinterval(l):
107
+ if len(l)==0:
108
+ return []
109
+ elif len(l)==2:
110
+ try:
111
+ value = int(l[0])
112
+ unit = l[1]
113
+ except TypeError:
114
+ valuemin = int(l[0][0])
115
+ valuesec = int(l[0][2])
116
+ value = 60*valuemin+valuesec
117
+ unit = 'sec'
118
+ return [value,unit,'work']
119
+ elif len(l)==3 and l[1] == '/':
120
+ a = getinterval(l[0])
121
+ b = getinterval(l[2])
122
+ b[2] = 'rest'
123
+ return a+b
124
+ elif len(l)==3 and l[1] == 'x':
125
+ u = []
126
+ for i in range(int(l[0])):
127
+ u+=getinterval(l[2])
128
+ return u
129
+ elif len(l)==3 and l[1] == '@':
130
+ return getinterval(l[0])
131
+ elif len(l)==1:
132
+ return getinterval(l[0])
133
+ else:
134
+ return getinterval(l[0])+getinterval(l[2:])
135
+
136
+ def pieceparse(v):
137
+ value = int(v[0])
138
+ unit = 'seconds'
139
+ if v[1] in ['meter','meters','m']:
140
+ unit = 'meters'
141
+ if v[1] in ['km','k','kilometer']:
142
+ value *= 1000
143
+ unit = 'meters'
144
+ if v[1] in ['min','minute','minutes',"'"]:
145
+ unit = 'seconds'
146
+ value *= 60
147
+
148
+ return [value,unit]
149
+
150
+ def pieceparsedict(v):
151
+ value = v['value']
152
+ unit = 'seconds'
153
+ if v['unit'] in ['meter','meters','m']:
154
+ unit = 'meters'
155
+ if v['unit'] in ['km','k','kilometer']:
156
+ value *= 1000
157
+ unit = 'meters'
158
+ if v['unit'] in ['min','minute','minutes',"'"]:
159
+ unit = 'seconds'
160
+ value *= 60
161
+
162
+ v['value'] = value
163
+ v['unit'] = unit
164
+ return v
165
+
166
+ def getlist(s,sel='value'):
167
+ s1=s[0:3]
168
+ s2=s[3:]
169
+
170
+ if s2 != []:
171
+ if sel == 'value':
172
+ return [s1[0]]+getlist(s2,sel=sel)
173
+ if sel == 'unit':
174
+ return [s1[1]]+getlist(s2,sel=sel)
175
+ if sel == 'type':
176
+ return [s1[2]]+getlist(s2,sel=sel)
177
+ else:
178
+ if sel == 'value':
179
+ return [s[0]]
180
+ if sel == 'unit':
181
+ return [s[1]]
182
+ if sel == 'type':
183
+ return [s[2]]
184
+
185
+ return 0
186
+
187
+ def flattenlist(l):
188
+ flatlist = []
189
+ for sublist in l:
190
+ if type(sublist)==dict:
191
+ flatlist.append(pieceparsedict(sublist))
192
+ continue
193
+ elif type(sublist)==list:
194
+ for item in flattenlist(sublist):
195
+ flatlist.append(item)
196
+ else:
197
+ pass
198
+
199
+ return(flatlist)
200
+
201
+ def parsetodict(s):
202
+ try:
203
+ r = Syntax().parseString(s).asList()
204
+ except:
205
+ return {}
206
+ res = getintervalasdict(r)
207
+
208
+ xres = flattenlist(res)
209
+
210
+ return xres
211
+
212
+ def simpletofit(step,message_index=0,name=''):
213
+ type = step['type']
214
+ value = step['value']
215
+ unit = step['unit']
216
+
217
+ d = {
218
+ 'wkt_step_name': name,
219
+ 'stepId': message_index,
220
+ }
221
+
222
+ if unit == 'seconds':
223
+ d['durationType'] = 'Time'
224
+ d['durationValue'] = value*1000
225
+ else:
226
+ d['durationType'] = 'Distance'
227
+ d['durationValue'] = value*100
228
+
229
+ d['intensity'] = 'Active'
230
+ if type == 'rest':
231
+ d['intensity'] = 'Rest'
232
+
233
+ try:
234
+ target = step['target']
235
+ targetunit = step['targetunit']
236
+ if targetunit == 'W':
237
+ d['targetType'] = 'Power'
238
+ d['targetValue'] = target+1000
239
+ if targetunit == 'spm':
240
+ d['targetType'] = 'Cadence'
241
+ d['targetValue'] = target
242
+ if targetunit in ['bpm','hr']:
243
+ d['targetType'] = 'HeartRate'
244
+ d['targetValue'] = target+100
245
+ except KeyError:
246
+ pass
247
+
248
+ return d
249
+
250
+ def repeatstep(step,startindex,name='',message_index=0):
251
+ value = step['value']
252
+
253
+ d = {
254
+ 'wkt_step_name': name,
255
+ 'stepId': message_index,
256
+ }
257
+
258
+ d['durationType'] = 'RepeatUntilStepsCmplt'
259
+ d['targetValue'] = value
260
+ d['durationValue'] = startindex
261
+
262
+ return d
263
+
264
+ def tofitdict(steps,name='',sport='rowing'):
265
+ newsteps = []
266
+ message_index = 0
267
+ repeatstack = []
268
+ for step in steps:
269
+ if step['type'] == 'repeatstart':
270
+ repeatstack.append(message_index)
271
+ continue
272
+ if step['type'] == 'repeat':
273
+ newsteps.append(repeatstep(step,repeatstack.pop(),message_index=message_index,name=str(message_index)))
274
+ message_index = message_index+1
275
+ continue
276
+ newsteps.append(simpletofit(step,message_index=message_index,name=str(message_index)))
277
+ message_index = message_index+1
278
+
279
+ d = {
280
+ 'name':name,
281
+ 'sport':sport,
282
+ 'filename':'',
283
+ 'steps':newsteps
284
+ }
285
+
286
+ return d
287
+
288
+ def parse(s):
289
+ try:
290
+ r = Syntax().parseString(s).asList()
291
+ except:
292
+ return []
293
+
294
+ res = getinterval(r)
295
+
296
+ xres = []
297
+
298
+ while len(res):
299
+ xres += pieceparse(res[0:2]) + [res[2]]
300
+ res = res[3:]
301
+
302
+ return xres
rowingdata/utils.py ADDED
@@ -0,0 +1,135 @@
1
+ from __future__ import absolute_import
2
+ import math
3
+ import numpy as np
4
+ np.seterr(divide='ignore', invalid='ignore')
5
+ import re
6
+ import time
7
+ import matplotlib
8
+ import iso8601
9
+ import os
10
+ import pytz
11
+ import pickle
12
+ import pandas as pd
13
+ import datetime
14
+ import arrow
15
+ from math import sin,cos,atan2,sqrt
16
+ from pandas import Series,DataFrame
17
+
18
+ def ewmovingaverage(interval,window_size):
19
+ # Experimental code using Exponential Weighted moving average
20
+
21
+ intervaldf=DataFrame({'v':interval})
22
+ try:
23
+ idf_ewma1=intervaldf.ewm(span=window_size)
24
+ idf_ewma2=intervaldf[::-1].ewm(span=window_size)
25
+ except AttributeError:
26
+ return interval
27
+
28
+ i_ewma1=idf_ewma1.mean().loc[:,'v']
29
+ i_ewma2=idf_ewma2.mean().loc[:,'v']
30
+
31
+ interval2=np.vstack((i_ewma1,i_ewma2[::-1]))
32
+ interval2=np.mean( interval2, axis=0) # average
33
+
34
+ return interval2
35
+
36
+ def movingaverage(interval, window_size):
37
+ window=np.ones(int(window_size))/float(window_size)
38
+ return np.convolve(interval, window, 'same')
39
+
40
+ def geo_distance(lat1,lon1,lat2,lon2):
41
+ """ Approximate distance and bearing between two points
42
+ defined by lat1,lon1 and lat2,lon2
43
+ This is a slight underestimate but is close enough for our purposes,
44
+ We're never moving more than 10 meters between trackpoints
45
+
46
+ Bearing calculation fails if one of the points is a pole.
47
+
48
+ """
49
+
50
+ # radius of earth in km
51
+ R=6373.0
52
+
53
+ # pi
54
+ pi=math.pi
55
+
56
+ lat1=math.radians(lat1)
57
+ lat2=math.radians(lat2)
58
+ lon1=math.radians(lon1)
59
+ lon2=math.radians(lon2)
60
+
61
+ dlon=lon2 - lon1
62
+ dlat=lat2 - lat1
63
+
64
+ a=sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
65
+ c=2 * atan2(sqrt(a), sqrt(1 - a))
66
+
67
+ distance=R * c
68
+
69
+ tc1=atan2(sin(lon2-lon1)*cos(lat2),
70
+ cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1))
71
+
72
+
73
+ tc1=tc1 % (2*pi)
74
+
75
+ bearing=math.degrees(tc1)
76
+
77
+ return [distance,bearing]
78
+
79
+ def totimestamp(dt, epoch=datetime.datetime(1970,1,1,0,0,0,0,pytz.UTC)):
80
+ try:
81
+ td=dt - epoch
82
+ except TypeError:
83
+ try:
84
+ dt = pytz.utc.localize(dt)
85
+ td = dt - epoch
86
+ except AttributeError:
87
+ td = arrow.get(dt)
88
+ return td.timestamp() + td.microsecond/10.**6
89
+
90
+ # return td.total_seconds()
91
+ return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6
92
+
93
+
94
+ def format_pace(x,pos=None):
95
+ try:
96
+ secstime = datetime.datetime.fromtimestamp(x+0.05)
97
+ except (OverflowError,ValueError,OSError):
98
+ try:
99
+ date = datetime.datetime(1970, 1, 1) + datetime.timedelta(x)
100
+ except (OverflowError,ValueError,OSError):
101
+ return '00:00.0'
102
+
103
+ stime = '%s.%i' % (secstime.strftime("%M:%S"), secstime.microsecond/100000)
104
+ return stime
105
+
106
+
107
+ def format_time(x,pos=None):
108
+ try:
109
+ secstime = datetime.datetime.fromtimestamp(x+0.05)
110
+ except OverflowError:
111
+ try:
112
+ date = datetime.datetime(1970, 1, 1) + datetime.timedelta(x)
113
+ except OverflowError:
114
+ return '00:00:00.0'
115
+
116
+ if x < 3600:
117
+ secstime = secstime.replace(hour=0)
118
+
119
+ stime = '%s.%i' % (secstime.strftime("%H:%M:%S"), secstime.microsecond/100000)
120
+
121
+ return stime
122
+
123
+ def wavg(group, avg_name, weight_name):
124
+ """ http://stackoverflow.com/questions/10951341/pandas-dataframe-aggregate-function-using-multiple-columns
125
+ In rare instance, we may not have weights, so just return the mean. Customize this if your business case
126
+ should return otherwise.
127
+ """
128
+ d = group[avg_name]
129
+ w = group[weight_name]
130
+ if w.sum() == 0:
131
+ return d.mean()
132
+ try:
133
+ return (d * w).sum() / w.sum()
134
+ except ZeroDivisionError:
135
+ return d.mean()
@@ -0,0 +1,48 @@
1
+ #! /usr/bin/python
2
+ from __future__ import absolute_import
3
+ from __future__ import print_function
4
+ from . import rowingdata
5
+ from sys import argv
6
+ from six.moves import input
7
+
8
+ def main():
9
+ readFile=argv[1]
10
+
11
+ try:
12
+ rowerFile=argv[2]
13
+ except IndexError:
14
+ rowerFile="defaultrower.txt"
15
+
16
+ rower=rowingdata.getrower(rowerFile)
17
+
18
+ try:
19
+ boatFile=argv[3]
20
+ except IndexError:
21
+ boatFile="my1x.txt"
22
+
23
+
24
+ csvoutput=readFile+'_p.csv'
25
+
26
+ tcx=rowingdata.TCXParser(readFile)
27
+ tcx.write_csv(csvoutput,window_size=20)
28
+
29
+ res=rowingdata.rowingdata(csvoutput,rowtype="On-water",
30
+ rower=rower)
31
+
32
+ s=input('Enter wind speed: ')
33
+ windv=float(s)
34
+ u=input('Enter wind speed units m=m/s, b=beaufort, k=knots: ')
35
+ s=input('Enter wind bearing (N=0, E=90, S=180, W=270): ')
36
+ winddirection=float(s)
37
+
38
+ res.add_wind(windv,winddirection,units=u)
39
+ res.add_bearing()
40
+
41
+ res.otw_setpower(skiprows=9,rg=rowingdata.getrigging(boatFile))
42
+
43
+ res.write_csv(csvoutput)
44
+
45
+ res.plottime_otwpower()
46
+
47
+
48
+ print(("done "+readFile))