GeorgyVlasov commited on
Commit
2b283cb
·
1 Parent(s): 6b6eae1

Upload mvnx.py

Browse files
Files changed (1) hide show
  1. mvnx.py +244 -0
mvnx.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Wed Mar 13 15:21:03 2019
4
+
5
+ @author: BIEL
6
+ """
7
+ import untangle
8
+ import matplotlib
9
+ import matplotlib.pyplot as plt
10
+ import scipy.signal
11
+ import copy
12
+ import numpy as np
13
+
14
+ def plotData(data,tag,labels=None, dataRange=None, secondsRange=None,
15
+ showDataPlot=True):
16
+ total=len(data)
17
+ info=[]
18
+
19
+ for i in range(total): info.append(data[i][tag])
20
+
21
+ if labels==None:
22
+ labels=list(map(lambda x: str(x), list(range(len(info[0])))))
23
+
24
+ if secondsRange!=None:
25
+ dataRange=list(map(lambda x:int(x*60), secondsRange))
26
+
27
+ if dataRange!=None:
28
+ info=info[dataRange[0]:dataRange[1]]
29
+ else:
30
+ dataRange=[0, len(data)]
31
+
32
+ separated={}
33
+ for i in range(len(info)):
34
+ for j in range(len(info[0])):
35
+ if i==0:
36
+ separated[labels[j]]=[info[i][j]]
37
+ else:
38
+ separated[labels[j]].append(info[i][j])
39
+
40
+ t=list(range(dataRange[0],dataRange[1]))
41
+
42
+ if showDataPlot:
43
+ fig=plt.figure()
44
+ ax = fig.add_subplot(1, 1, 1)
45
+ for i in separated:
46
+ ax.plot(t,separated[i], label=i)
47
+ plt.show()
48
+
49
+ return separated
50
+
51
+ def findClaps(data,tag,n_claps=2,labels=None, dataRange=None, secondsRange=None, spikeSep=10,
52
+ showDataPlot=True, drop=None):
53
+ separated=plotData(data,tag,labels=labels, dataRange=dataRange, secondsRange=secondsRange,
54
+ showDataPlot=showDataPlot)
55
+ #lets found the spikes in each data
56
+ fcs=[]
57
+ for i in separated:
58
+ globalMax=max(separated[i])
59
+ fc=[]
60
+ count=0
61
+ factor=0.01
62
+ while len(fc)!=n_claps and count<10000:
63
+ x=copy.deepcopy(separated[i])
64
+ #
65
+ # x=list(map(lambda x: x if x>globalMax*factor else globalMax*factor,x))
66
+ # x=np.array(x)
67
+ # fc=scipy.signal.argrelextrema(x,np.greater,order=10)
68
+ fc,_=scipy.signal.find_peaks(x,height=globalMax*factor, distance=spikeSep)
69
+
70
+ factor*=1.05
71
+ if factor>=1:
72
+ break
73
+ count+=1
74
+
75
+ fcs.append([i,fc])
76
+
77
+ n=n_claps
78
+ if drop!=None:
79
+ if type(drop)==int:
80
+ fcs.remove(fcs[drop])
81
+ else:
82
+ cpfcs=[]
83
+ for i in range(len(fcs)):
84
+ if i not in drop:
85
+ cpfcs.append(fcs[i])
86
+ fcs=cpfcs
87
+
88
+
89
+ if not all(len(i[1])==n for i in fcs):
90
+ goods=[]
91
+ for j in fcs:
92
+ if len(j[1])==n:
93
+ goods.append(j[1])
94
+ if len(goods)==0:
95
+ raise ValueError ('no solution')
96
+ else:
97
+ claps=sum([i for i in goods])
98
+ res=[int(i/len(goods)) for i in claps]
99
+ else:
100
+ claps=sum([i[1] for i in fcs])
101
+ res=[int(i/len(fcs)) for i in claps]
102
+
103
+ res=[res[i]+dataRange[0] for i in range(len(res))]
104
+ return res
105
+
106
+
107
+ def get_default_segment_index():
108
+ index=['pelvis','l5','l3','t12','t8','neck','head','right_shoulder',
109
+ 'right_upper_arm','right_forearm','right_hand','left_shoulder',
110
+ 'left_upper_arm','left_forearm','left_hand','right_upper_leg',
111
+ 'right_lower_leg','right_foot','right_toe','left_upper_leg',
112
+ 'left_lower_leg','left_foot','left_toe']
113
+ return index
114
+ def get_default_sensor_index():
115
+ index=['pelvis','t8','head','right_shoulder','right_upper_arm','right_fore_arm',
116
+ 'right_hand','left_shoulder','left_upper_arm','left_fore_arm', 'left_hand',
117
+ 'right_upper_leg','right_lower_leg','right_foot',
118
+ 'left_upper_leg','left_lower_leg','left_foot']
119
+ return index
120
+ def get_default_joint_index():
121
+ index=['L5S1','L4L3','L1T12','T9T8','T1C7','C1Head','RightC7Shoulder',
122
+ 'RightShoulder','RightElbow','RightWrist','LeftC7Shoulder',
123
+ 'LeftShoulder','LeftElbow','LeftWrist', 'RightHip','RightKnee',
124
+ 'RightAnkle','RightBallFoot','LeftHip','LeftKnee','LeftAnkle',
125
+ 'LeftBallFoot']
126
+ index=list(map(lambda x:x+'j',index))
127
+ return index
128
+ def get_dictionary_from_class(obj):
129
+ ll_atrib=dir(obj)
130
+ d={}
131
+ for attribute in ll_atrib:
132
+ d[attribute]=getattr(obj,attribute)
133
+ return d
134
+
135
+ def prepareline(line, tag, index, scaled):
136
+ linep=line.split(' ')
137
+ # Only the information of sensor, segments or joints pass through this function
138
+ #First two lines: segments, 3rd line: sensors,
139
+ how_many_info={'position':3, 'orientation':4, 'velocity':3, 'acceleration': 3,
140
+ 'angularVelocity': 3, 'angularAcceleration':3,
141
+ 'sensorMagneticField':3,'sensorOrientation': 4, 'sensorFreeAcceleration':3,
142
+ 'jointAngle':3, 'jointAngleXZY':3,'jointAngleErgo':3,
143
+ 'centerOfMass':3, 'footContacts':1}
144
+
145
+ linep=list(map(lambda x: scaled*float(x), linep)) #pass to float
146
+ if tag in how_many_info:
147
+ n=how_many_info[tag]
148
+ else:
149
+ s='No tag <'+tag+'> in how_many_info'
150
+ raise ValueError (s)
151
+
152
+ linep=[linep[x:x+n] for x in range(0, len(linep),n)]
153
+ if len(linep)!=len(index):
154
+ print(index)
155
+ s='Error using '+tag
156
+ raise ValueError (s)
157
+ coord={}
158
+ for i in range(len(index)):coord[index[i]]=linep[i]
159
+ return coord
160
+ class MVNX_Index():
161
+ def __init__(self, info, prop=False):
162
+ self.segment_index=get_default_segment_index()
163
+ self.sensor_index=get_default_sensor_index()
164
+ self.joint_index=get_default_joint_index()
165
+ self.footContacts_index=['LeftFoot_Heel', 'LeftFoot_Toe','RightFoot_Heel', 'RightFoot_Toe']
166
+ self.mass_index=['Center_Of_Mass']
167
+ self.ergo_index=['jnt1','jnt2','jnt3','jnt4']
168
+ self.info=info
169
+ if prop:
170
+ for index in [self.segment_index, self.sensor_index, self.joint_index]:
171
+ index.append('prop')
172
+ def __getitem__(self, tag):
173
+ if tag in self.info:
174
+ if tag in ['position','orientation','velocity','acceleration',
175
+ 'angularVelocity', 'angularAcceleration']:
176
+ return self.segment_index
177
+ elif tag in ['sensorMagneticField','sensorOrientation','sensorFreeAcceleration']:
178
+ return self.sensor_index
179
+ elif tag in ['jointAngle', 'jointAngleXZY']:
180
+ return self.joint_index
181
+ elif tag=='jointAngleErgo':
182
+ return self.ergo_index
183
+ elif tag=='footContacts':
184
+ return self.footContacts_index
185
+ elif tag=='centerOfMass':
186
+ return self.mass_index
187
+ else:
188
+ return None
189
+ class MVNX():
190
+ def __init__(self,mvnx_root):
191
+ self.root=mvnx_root
192
+ self.xml_file=untangle.parse(mvnx_root)
193
+ self.frames=self.xml_file.mvnx.subject.frames.frame
194
+ self.frames=self.frames[3:]
195
+ self.total_frames=len(self.frames)
196
+ self.available_info=[i for i in get_dictionary_from_class(self.frames[3])]
197
+ self.all_index=MVNX_Index(self.available_info)
198
+
199
+ self.mvn_version=self.xml_file.mvnx.mvn['version']
200
+ self.mvn_build=self.xml_file.mvnx.mvn['build']
201
+ self.subject=self.xml_file.mvnx.subject._attributes
202
+
203
+ def get_info(self,tag, scaled=1):
204
+ if tag not in self.available_info:
205
+ raise ValueError ('Not available info in MVNX')
206
+ else:
207
+ ll=[]
208
+ for i in range(self.total_frames):
209
+ s=getattr(self.frames[i],tag)
210
+ s=getattr(s,'cdata')
211
+ d=prepareline(s,tag, self.all_index[tag], scaled)
212
+ ll.append(d)
213
+ return ll
214
+ class MVNX_1_PROP():
215
+ def __init__(self,mvnx_root):
216
+ self.root=mvnx_root
217
+ self.xml_file=untangle.parse(mvnx_root)
218
+ self.frames=self.xml_file.mvnx.subject.frames.frame
219
+ self.frames=self.frames[3:]
220
+ self.total_frames=len(self.frames)
221
+ self.available_info=[i for i in get_dictionary_from_class(self.frames[3])]
222
+ self.all_index=MVNX_Index(self.available_info, prop=True)
223
+
224
+ self.mvn_version=self.xml_file.mvnx.mvn['version']
225
+ self.mvn_build=self.xml_file.mvnx.mvn['build']
226
+ self.subject=self.xml_file.mvnx.subject._attributes
227
+
228
+ def get_info(self,tag, scaled=1):
229
+ if tag not in self.available_info:
230
+ raise ValueError ('Not available info in MVNX')
231
+ else:
232
+ ll=[]
233
+ for i in range(self.total_frames):
234
+ s=getattr(self.frames[i],tag)
235
+ s=getattr(s,'cdata')
236
+ d=prepareline(s,tag, self.all_index[tag], scaled)
237
+ ll.append(d)
238
+ return ll
239
+
240
+ def obtainMVNX(mvnx_root):
241
+ mvnx_file=MVNX_1_PROP(mvnx_root)
242
+ if mvnx_file.xml_file.mvnx.subject['segmentCount']=='23':
243
+ mvnx_file=MVNX(mvnx_root)
244
+ return mvnx_file