biomechzoo 0.4.11__py3-none-any.whl → 0.5.1__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.
Potentially problematic release.
This version of biomechzoo might be problematic. Click here for more details.
- biomechzoo/biomech_ops/movement_onset.py +2 -0
- biomechzoo/biomech_ops/normalize_data.py +4 -3
- biomechzoo/biomechzoo.py +64 -8
- biomechzoo/conversion/mvnx2zoo_data.py +1 -3
- biomechzoo/conversion/table2zoo_data.py +50 -41
- biomechzoo/imu/tilt_algoirthm.py +112 -0
- biomechzoo/processing/addevent_data.py +60 -11
- biomechzoo/processing/partition_data.py +14 -27
- biomechzoo/processing/removeevent_data.py +57 -0
- biomechzoo/processing/renameevent_data.py +0 -6
- biomechzoo/utils/engine.py +7 -3
- biomechzoo/utils/peak_sign.py +24 -0
- biomechzoo/utils/split_trial.py +24 -12
- {biomechzoo-0.4.11.dist-info → biomechzoo-0.5.1.dist-info}/METADATA +1 -1
- {biomechzoo-0.4.11.dist-info → biomechzoo-0.5.1.dist-info}/RECORD +19 -15
- {biomechzoo-0.4.11.dist-info → biomechzoo-0.5.1.dist-info}/WHEEL +0 -0
- {biomechzoo-0.4.11.dist-info → biomechzoo-0.5.1.dist-info}/entry_points.txt +0 -0
- {biomechzoo-0.4.11.dist-info → biomechzoo-0.5.1.dist-info}/licenses/LICENSE +0 -0
- {biomechzoo-0.4.11.dist-info → biomechzoo-0.5.1.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import warnings
|
|
2
|
+
import copy
|
|
2
3
|
from biomechzoo.biomech_ops.normalize_line import normalize_line
|
|
3
4
|
|
|
4
5
|
|
|
@@ -14,14 +15,14 @@ def normalize_data(data, nlength=101):
|
|
|
14
15
|
"""
|
|
15
16
|
|
|
16
17
|
# normalize channel length
|
|
17
|
-
data_new =
|
|
18
|
+
data_new = copy.deepcopy(data)
|
|
18
19
|
for ch_name, ch_data in data_new.items():
|
|
19
20
|
if ch_name != 'zoosystem':
|
|
20
21
|
ch_data_line = ch_data['line']
|
|
21
22
|
ch_data_event = ch_data['event']
|
|
22
23
|
ch_data_normalized = normalize_line(ch_data_line, nlength)
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
data_new[ch_name]['line'] = ch_data_normalized
|
|
25
|
+
data_new[ch_name]['event'] = ch_data_event
|
|
25
26
|
warnings.warn('event data have not been normalized')
|
|
26
27
|
|
|
27
28
|
# update zoosystem
|
biomechzoo/biomechzoo.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import inspect
|
|
3
3
|
import time
|
|
4
|
+
|
|
5
|
+
from biomechzoo.imu.tilt_algoirthm import tilt_algorithm_data
|
|
4
6
|
from biomechzoo.utils.engine import engine # assumes this returns .zoo files in folder
|
|
5
7
|
from biomechzoo.utils.zload import zload
|
|
6
8
|
from biomechzoo.utils.zsave import zsave
|
|
@@ -12,6 +14,7 @@ from biomechzoo.conversion.table2zoo_data import table2zoo_data
|
|
|
12
14
|
from biomechzoo.conversion.mvnx2zoo_data import mvnx2zoo_data
|
|
13
15
|
from biomechzoo.processing.removechannel_data import removechannel_data
|
|
14
16
|
from biomechzoo.processing.renamechannel_data import renamechannel_data
|
|
17
|
+
from biomechzoo.processing.removeevent_data import removeevent_data
|
|
15
18
|
from biomechzoo.processing.explodechannel_data import explodechannel_data
|
|
16
19
|
from biomechzoo.processing.addevent_data import addevent_data
|
|
17
20
|
from biomechzoo.processing.partition_data import partition_data
|
|
@@ -62,6 +65,8 @@ class BiomechZoo:
|
|
|
62
65
|
in_folder_path = os.path.dirname(in_folder)
|
|
63
66
|
self.in_folder = os.path.join(in_folder_path, out_folder)
|
|
64
67
|
|
|
68
|
+
batchdisp('all files saved to: {}'.format(self.in_folder ), level=1, verbose=self.verbose)
|
|
69
|
+
|
|
65
70
|
def mvnx2zoo(self, out_folder=None, inplace=False):
|
|
66
71
|
""" Converts all .mvnx files in the folder to .zoo format """
|
|
67
72
|
start_time = time.time()
|
|
@@ -76,7 +81,7 @@ class BiomechZoo:
|
|
|
76
81
|
f_zoo = f.replace('.mvnx', '.zoo')
|
|
77
82
|
zsave(f_zoo, data, inplace=inplace, out_folder=out_folder, root_folder=in_folder)
|
|
78
83
|
method_name = inspect.currentframe().f_code.co_name
|
|
79
|
-
batchdisp('{}
|
|
84
|
+
batchdisp('{} process complete for {} file(s) in {:.2f} secs'.format(method_name, len(fl), time.time() - start_time), level=1, verbose=verbose)
|
|
80
85
|
# Update self.folder after processing
|
|
81
86
|
self._update_folder(out_folder, inplace, in_folder)
|
|
82
87
|
|
|
@@ -100,17 +105,21 @@ class BiomechZoo:
|
|
|
100
105
|
# Update self.folder after processing
|
|
101
106
|
self._update_folder(out_folder, inplace, in_folder)
|
|
102
107
|
|
|
103
|
-
def table2zoo(self, out_folder=None, inplace=None, skip_rows=0,
|
|
108
|
+
def table2zoo(self, extension, out_folder=None, inplace=None, skip_rows=0, freq=None):
|
|
104
109
|
""" Converts generic .csv file in the folder to .zoo format """
|
|
105
110
|
start_time = time.time()
|
|
106
111
|
verbose = self.verbose
|
|
107
112
|
in_folder = self.in_folder
|
|
113
|
+
|
|
114
|
+
if extension.startswith('.'):
|
|
115
|
+
extension = extension[1:]
|
|
116
|
+
|
|
108
117
|
if inplace is None:
|
|
109
118
|
inplace = self.inplace
|
|
110
119
|
fl = engine(in_folder, extension=extension, name_contains=self.name_contains, subfolders=self.subfolders)
|
|
111
120
|
for f in fl:
|
|
112
121
|
batchdisp('converting {} to zoo for {}'.format(extension, f), level=2, verbose=verbose)
|
|
113
|
-
data = table2zoo_data(f,
|
|
122
|
+
data = table2zoo_data(f, extension=extension, skip_rows=skip_rows, freq=freq)
|
|
114
123
|
f_zoo = f.replace(extension, '.zoo')
|
|
115
124
|
zsave(f_zoo, data, inplace=inplace, out_folder=out_folder, root_folder=in_folder)
|
|
116
125
|
method_name = inspect.currentframe().f_code.co_name
|
|
@@ -119,8 +128,33 @@ class BiomechZoo:
|
|
|
119
128
|
self._update_folder(out_folder, inplace, in_folder)
|
|
120
129
|
|
|
121
130
|
def xls2zoo(self, out_folder=None, inplace=None):
|
|
122
|
-
|
|
123
|
-
|
|
131
|
+
raise NotImplementedError('Use table2zoo instead')
|
|
132
|
+
|
|
133
|
+
def csv2zoo(self, out_folder=None, inplace=None):
|
|
134
|
+
raise NotImplementedError('Use table2zoo instead')
|
|
135
|
+
|
|
136
|
+
def parquet2zoo(self, out_folder=None, inplace=None):
|
|
137
|
+
raise NotImplementedError('Use table2zoo instead')
|
|
138
|
+
|
|
139
|
+
def tilt_algorithm(self, chname_avert, chname_medlat, chname_antpost, out_folder=None, inplace=False):
|
|
140
|
+
""" tilt correction for acceleration data """
|
|
141
|
+
start_time = time.time()
|
|
142
|
+
verbose = self.verbose
|
|
143
|
+
in_folder = self.in_folder
|
|
144
|
+
if inplace is None:
|
|
145
|
+
inplace = self.inplace
|
|
146
|
+
fl = engine(in_folder, name_contains=self.name_contains, subfolders=self.subfolders)
|
|
147
|
+
for f in fl:
|
|
148
|
+
batchdisp('tilt correction of acceleration channels for {}'.format(f), level=2, verbose=verbose)
|
|
149
|
+
data = zload(f)
|
|
150
|
+
data = tilt_algorithm_data(data, chname_avert, chname_medlat, chname_antpost)
|
|
151
|
+
zsave(f, data, inplace=inplace, out_folder=out_folder, root_folder=in_folder)
|
|
152
|
+
method_name = inspect.currentframe().f_code.co_name
|
|
153
|
+
batchdisp(
|
|
154
|
+
'{} process complete for {} file(s) in {:.2f} secs'.format(method_name, len(fl), time.time() - start_time),
|
|
155
|
+
level=1, verbose=verbose)
|
|
156
|
+
# Update self.folder after processing
|
|
157
|
+
self._update_folder(out_folder, inplace, in_folder)
|
|
124
158
|
|
|
125
159
|
def phase_angle(self, ch, out_folder=None, inplace=None):
|
|
126
160
|
""" computes phase angles"""
|
|
@@ -185,7 +219,8 @@ class BiomechZoo:
|
|
|
185
219
|
batchdisp('splitting by gait cycle from {} to {} for {}'.format(start, end, f), level=2,
|
|
186
220
|
verbose=verbose)
|
|
187
221
|
data_new = split_trial(data, start, end)
|
|
188
|
-
|
|
222
|
+
if data_new is not None:
|
|
223
|
+
zsave(fl_new, data_new, inplace=inplace, out_folder=out_folder, root_folder=in_folder)
|
|
189
224
|
method_name = inspect.currentframe().f_code.co_name
|
|
190
225
|
batchdisp('{} process complete for {} file(s) in {:.2f} secs'.format(method_name, len(fl), time.time() - start_time), level=1, verbose=verbose)
|
|
191
226
|
|
|
@@ -267,6 +302,27 @@ class BiomechZoo:
|
|
|
267
302
|
# Update self.folder after processing
|
|
268
303
|
self._update_folder(out_folder, inplace, in_folder)
|
|
269
304
|
|
|
305
|
+
|
|
306
|
+
def removeevent(self, events, mode='remove', out_folder=None, inplace=None):
|
|
307
|
+
""" removes channels from zoo files """
|
|
308
|
+
start_time = time.time()
|
|
309
|
+
verbose = self.verbose
|
|
310
|
+
in_folder = self.in_folder
|
|
311
|
+
if inplace is None:
|
|
312
|
+
inplace = self.inplace
|
|
313
|
+
fl = engine(in_folder, extension='.zoo', name_contains=self.name_contains, subfolders=self.subfolders)
|
|
314
|
+
for f in fl:
|
|
315
|
+
batchdisp('removing events {} for {}'.format(events, f), level=2, verbose=verbose)
|
|
316
|
+
data = zload(f)
|
|
317
|
+
data = removeevent_data(data, events, mode)
|
|
318
|
+
zsave(f, data, inplace=inplace, out_folder=out_folder, root_folder=in_folder)
|
|
319
|
+
method_name = inspect.currentframe().f_code.co_name
|
|
320
|
+
batchdisp('{} process complete for {} file(s) in {:.2f} secs'.format(method_name, len(fl), time.time() - start_time), level=1, verbose=verbose)
|
|
321
|
+
|
|
322
|
+
# Update self.folder after processing
|
|
323
|
+
self._update_folder(out_folder, inplace, in_folder)
|
|
324
|
+
|
|
325
|
+
|
|
270
326
|
def explodechannel(self, out_folder=None, inplace=None):
|
|
271
327
|
""" explodes all channels in a zoo file """
|
|
272
328
|
start_time = time.time()
|
|
@@ -307,7 +363,7 @@ class BiomechZoo:
|
|
|
307
363
|
# Update self.folder after processing
|
|
308
364
|
self._update_folder(out_folder, inplace, in_folder)
|
|
309
365
|
|
|
310
|
-
def addevent(self, ch, event_type, event_name, out_folder=None, inplace=None):
|
|
366
|
+
def addevent(self, ch, event_type, event_name, out_folder=None, inplace=None, constant=None):
|
|
311
367
|
""" adds events of type evt_type with name evt_name to channel ch """
|
|
312
368
|
start_time = time.time()
|
|
313
369
|
verbose = self.verbose
|
|
@@ -319,7 +375,7 @@ class BiomechZoo:
|
|
|
319
375
|
if verbose:
|
|
320
376
|
batchdisp('adding event {} to channel {} for {}'.format(event_type, ch, f), level=2, verbose=verbose)
|
|
321
377
|
data = zload(f)
|
|
322
|
-
data = addevent_data(data, ch, event_type, event_name)
|
|
378
|
+
data = addevent_data(data, ch, event_type, event_name, constant)
|
|
323
379
|
zsave(f, data, inplace=inplace, out_folder=out_folder, root_folder=in_folder)
|
|
324
380
|
method_name = inspect.currentframe().f_code.co_name
|
|
325
381
|
batchdisp('{} process complete for {} file(s) in {:.2f} secs'.format(method_name, len(fl), time.time() - start_time), level=1, verbose=verbose)
|
|
@@ -9,9 +9,7 @@ def mvnx2zoo_data(fl):
|
|
|
9
9
|
mvnx_file = load_mvnx(fl)
|
|
10
10
|
|
|
11
11
|
# create zoo data dict
|
|
12
|
-
data = {}
|
|
13
|
-
data['zoosystem'] = set_zoosystem()
|
|
14
|
-
|
|
12
|
+
data = {'zoosystem': set_zoosystem()}
|
|
15
13
|
# extract joint angle data (All JOINTS may not exist in a given dataset)
|
|
16
14
|
for key, val in JOINTS.items():
|
|
17
15
|
try:
|
|
@@ -6,69 +6,76 @@ from biomechzoo.utils.set_zoosystem import set_zoosystem
|
|
|
6
6
|
from biomechzoo.utils.compute_sampling_rate_from_time import compute_sampling_rate_from_time
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def table2zoo_data(
|
|
10
|
-
# todo: check calculation for sampling rate
|
|
9
|
+
def table2zoo_data(fl, extension, skip_rows=0, freq=None):
|
|
11
10
|
|
|
12
|
-
if
|
|
13
|
-
|
|
11
|
+
if extension == 'csv':
|
|
12
|
+
df, metadata, freq = _csv2zoo(fl, skip_rows=skip_rows, freq=freq)
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if type == 'csv' and skip_rows > 0:
|
|
18
|
-
header_lines = []
|
|
19
|
-
with open(csv_path, 'r') as f:
|
|
20
|
-
for line in f:
|
|
21
|
-
header_lines.append(line.strip())
|
|
22
|
-
if line.strip().lower() == 'endheader':
|
|
23
|
-
break
|
|
24
|
-
# Parse metadata
|
|
25
|
-
metadata = _parse_metadata(header_lines)
|
|
26
|
-
|
|
27
|
-
if type == 'csv':
|
|
28
|
-
df = pd.read_csv(csv_path, skiprows=skip_rows)
|
|
29
|
-
elif type =='parquet':
|
|
30
|
-
df = pd.read_parquet(csv_path)
|
|
14
|
+
elif extension == 'parquet':
|
|
15
|
+
df, metadata, freq = _parquet2zoo(fl, skip_rows=skip_rows, freq=freq)
|
|
31
16
|
else:
|
|
32
|
-
raise ValueError('
|
|
33
|
-
|
|
34
|
-
# Use all columns
|
|
35
|
-
df_data = df.iloc[:, 0:]
|
|
17
|
+
raise ValueError('extension {} not implemented'.format(extension))
|
|
36
18
|
|
|
37
19
|
# assemble zoo data
|
|
38
|
-
data = {}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
for ch in df_data.columns:
|
|
20
|
+
data = {'zoosystem': set_zoosystem()}
|
|
21
|
+
for ch in df.columns:
|
|
42
22
|
data[ch] = {
|
|
43
|
-
'line':
|
|
23
|
+
'line': df[ch].values,
|
|
44
24
|
'event': []
|
|
45
25
|
}
|
|
46
26
|
|
|
47
|
-
# try to find frequency in metadata
|
|
48
|
-
if freq is None:
|
|
49
|
-
if 'freq' in metadata:
|
|
50
|
-
freq = metadata['freq']
|
|
51
|
-
elif 'sampling_rate' in metadata:
|
|
52
|
-
freq = metadata['sampling_rate']
|
|
53
|
-
else:
|
|
54
|
-
freq = None # or raise an error
|
|
55
27
|
|
|
56
28
|
# now try to calculate freq from a time column
|
|
57
29
|
if freq is None:
|
|
58
30
|
time_col = [col for col in df.columns if 'time' in col.lower()]
|
|
59
|
-
if time_col is not None:
|
|
31
|
+
if time_col is not None and len(time_col) > 0:
|
|
60
32
|
time_data = df[time_col].to_numpy()[:, 0]
|
|
61
33
|
freq = compute_sampling_rate_from_time(time_data)
|
|
62
|
-
|
|
34
|
+
else:
|
|
35
|
+
raise ValueError('Unable to compute sampling rate for time column, please specify a sampling frequency'
|
|
36
|
+
)
|
|
63
37
|
# add metadata
|
|
64
38
|
data['zoosystem']['Video']['Freq'] = freq
|
|
65
39
|
data['zoosystem']['Analog']['Freq'] = 'None'
|
|
66
|
-
|
|
67
|
-
|
|
40
|
+
|
|
41
|
+
if metadata is not None:
|
|
42
|
+
data['zoosystem']['Other'] = metadata
|
|
68
43
|
|
|
69
44
|
return data
|
|
70
45
|
|
|
71
46
|
|
|
47
|
+
def _parquet2zoo(fl, skip_rows=0, freq=None):
|
|
48
|
+
df = pd.read_parquet(fl)
|
|
49
|
+
metadata = None
|
|
50
|
+
return df, metadata, freq
|
|
51
|
+
|
|
52
|
+
def _csv2zoo(fl, skip_rows=0, freq=None):
|
|
53
|
+
header_lines = []
|
|
54
|
+
with open(fl, 'r') as f:
|
|
55
|
+
for line in f:
|
|
56
|
+
header_lines.append(line.strip())
|
|
57
|
+
if line.strip().lower() == 'endheader':
|
|
58
|
+
break
|
|
59
|
+
# Parse metadata
|
|
60
|
+
metadata = _parse_metadata(header_lines)
|
|
61
|
+
|
|
62
|
+
# try to find frequency in metadata
|
|
63
|
+
if freq is None:
|
|
64
|
+
if 'freq' in metadata:
|
|
65
|
+
freq = metadata['freq']
|
|
66
|
+
elif 'sampling_rate' in metadata:
|
|
67
|
+
freq = metadata['sampling_rate']
|
|
68
|
+
else:
|
|
69
|
+
freq = None # or raise an error
|
|
70
|
+
|
|
71
|
+
# read csv
|
|
72
|
+
df = pd.read_csv(fl, skiprows=skip_rows)
|
|
73
|
+
|
|
74
|
+
return df, metadata, freq
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
72
79
|
def _parse_metadata(header_lines):
|
|
73
80
|
metadata = {}
|
|
74
81
|
for line in header_lines:
|
|
@@ -96,6 +103,8 @@ def _parse_metadata(header_lines):
|
|
|
96
103
|
return metadata
|
|
97
104
|
|
|
98
105
|
|
|
106
|
+
|
|
107
|
+
|
|
99
108
|
if __name__ == '__main__':
|
|
100
109
|
""" for unit testing"""
|
|
101
110
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import math
|
|
3
|
+
import pandas as pd
|
|
4
|
+
from biomechzoo.processing.add_channel_data import add_channel_data
|
|
5
|
+
|
|
6
|
+
def tilt_algorithm_data(data,ch_vert, ch_medlat, ch_antpost, plot_or_not=None):
|
|
7
|
+
|
|
8
|
+
# extract channels from data
|
|
9
|
+
avert = data[ch_vert]['line']
|
|
10
|
+
amedlat = data[ch_medlat]['line']
|
|
11
|
+
aantpost = data[ch_antpost]['line']
|
|
12
|
+
|
|
13
|
+
_, avert_corr, amedlat_corr, aantpost_corr = tilt_algorithm_line(avert, amedlat, aantpost)
|
|
14
|
+
|
|
15
|
+
data = add_channel_data(data, ch_vert + '_tilt_corr', avert_corr)
|
|
16
|
+
data = add_channel_data(data, ch_medlat + '_tilt_corr', amedlat_corr)
|
|
17
|
+
data = add_channel_data(data, ch_antpost + '_tilt_corr', aantpost_corr)
|
|
18
|
+
|
|
19
|
+
return data
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def tilt_algorithm_line(avert, amedlat, aantpost, plot_or_not=None):
|
|
23
|
+
"""
|
|
24
|
+
TiltAlgorithm - to account for gravity and improper tilt alignment of a tri-axial trunk accelerometer.
|
|
25
|
+
Step 1: Extract raw measured (mean) accelerations
|
|
26
|
+
Step 2: Calculate tilt angles
|
|
27
|
+
Step 3: Calculate horizontal dynamic accelerations vectors
|
|
28
|
+
Step 4: Calculate estimated provisional vertical vector
|
|
29
|
+
Step 5: Calculate vertical dynamic vector
|
|
30
|
+
step 6.1: Calculate the contribution of static components
|
|
31
|
+
step 6.2 Transpose static component matrices
|
|
32
|
+
step 7: Remove the static components from the templates of pre and post
|
|
33
|
+
|
|
34
|
+
:param avert: signal predominantly in vertical direction
|
|
35
|
+
:param amedlat: signal predominantly in medio-lateral direction
|
|
36
|
+
:param aantpost: signal predominantly in anterior-posterior direction
|
|
37
|
+
:param plot_or_not: whether to plot the results
|
|
38
|
+
:return: dataframe of the tilt corrected and gravity subtracted vertical, medio-lateral and anterior-posterior
|
|
39
|
+
acceleration signals
|
|
40
|
+
"""
|
|
41
|
+
#
|
|
42
|
+
|
|
43
|
+
a_vt = avert.mean()
|
|
44
|
+
a_ml = amedlat.mean()
|
|
45
|
+
a_ap = aantpost.mean()
|
|
46
|
+
|
|
47
|
+
# if avert is negative than turn the sensor around.
|
|
48
|
+
if a_vt < 0.5:
|
|
49
|
+
avert *= -1
|
|
50
|
+
amedlat *= -1
|
|
51
|
+
a_vt = avert.mean()
|
|
52
|
+
a_ml = amedlat.mean()
|
|
53
|
+
|
|
54
|
+
# Anterior tilt
|
|
55
|
+
TiltAngle_ap_rad = np.arcsin(a_ap)
|
|
56
|
+
TiltAngle_ap_deg = math.degrees(TiltAngle_ap_rad)
|
|
57
|
+
|
|
58
|
+
# mediolateral tilt
|
|
59
|
+
TiltAngle_ml_rad = np.arcsin(a_ml)
|
|
60
|
+
TiltAngle_ml_deg = math.degrees(TiltAngle_ml_rad)
|
|
61
|
+
|
|
62
|
+
# Anterior posterior
|
|
63
|
+
a_AP = (a_ap * np.cos(TiltAngle_ap_rad)) - (a_vt * np.sin(TiltAngle_ap_rad))
|
|
64
|
+
# AMediolateral
|
|
65
|
+
a_ML = (a_ml * np.cos(TiltAngle_ml_rad)) - (a_vt * np.sin(TiltAngle_ml_rad))
|
|
66
|
+
|
|
67
|
+
# a_vt_prov = a_ap*Sin(theta_ap) + a_vt*Cos(theta_ap)
|
|
68
|
+
a_vt_prov = (a_ap * np.sin(TiltAngle_ap_rad)) + (a_vt * np.cos(TiltAngle_ap_rad))
|
|
69
|
+
|
|
70
|
+
# a_VT = a_ml*sin(theta_ml) + a_vt_prov*cos(theta_ml) - 1
|
|
71
|
+
a_VT = (a_ml * np.sin(TiltAngle_ml_rad)) + (a_vt_prov * np.cos(TiltAngle_ml_rad)) - 1
|
|
72
|
+
|
|
73
|
+
a_AP_static = a_ap - a_AP
|
|
74
|
+
a_ML_static = a_ml - a_ML
|
|
75
|
+
a_VT_static = a_vt - a_VT
|
|
76
|
+
|
|
77
|
+
a_AP_static = np.transpose(a_AP_static)
|
|
78
|
+
a_ML_static = np.transpose(a_ML_static)
|
|
79
|
+
a_VT_static = np.transpose(a_VT_static)
|
|
80
|
+
|
|
81
|
+
amedlat2 = amedlat - a_ML_static
|
|
82
|
+
avert2 = avert - a_VT_static
|
|
83
|
+
aantpost2 = aantpost - a_AP_static
|
|
84
|
+
|
|
85
|
+
data = {'avert': avert2,
|
|
86
|
+
'amedlat': amedlat2,
|
|
87
|
+
'aantpost': aantpost2}
|
|
88
|
+
df_corrected = pd.DataFrame(data)
|
|
89
|
+
|
|
90
|
+
# if plot_or_not:
|
|
91
|
+
# f, ax = plt.subplots(nrows=3, ncols=1, sharex=True, dpi=300)
|
|
92
|
+
# sns.despine(offset=10)
|
|
93
|
+
# f.tight_layout()
|
|
94
|
+
# offset = 0.1
|
|
95
|
+
# f.subplots_adjust(left=0.15, top=0.95)
|
|
96
|
+
#
|
|
97
|
+
# sns.lineplot(avert, ax=ax[0], label='Raw')
|
|
98
|
+
# sns.lineplot(avert2, ax=ax[0], label='tilt corrected')
|
|
99
|
+
# ax[0].set_ylabel('vert acc (g)')
|
|
100
|
+
# ax[0].set_title('Vertical acceleration corrected with {}'.format(np.round(a_VT_static, 2)))
|
|
101
|
+
#
|
|
102
|
+
# sns.lineplot(amedlat, ax=ax[1], label='Raw')
|
|
103
|
+
# sns.lineplot(amedlat2, ax=ax[1], label='Tilt corrected')
|
|
104
|
+
# ax[1].set_ylabel('ml acc (g)')
|
|
105
|
+
# ax[1].set_title('Medio-lateral tilt angle corrected with {} degrees'.format(np.round(TiltAngle_ml_deg, 2)))
|
|
106
|
+
#
|
|
107
|
+
# sns.lineplot(aantpost, ax=ax[2], label='Raw')
|
|
108
|
+
# sns.lineplot(aantpost2, ax=ax[2], label='Tilt corrected')
|
|
109
|
+
# ax[2].set_ylabel('ap acc (g)')
|
|
110
|
+
# ax[2].set_title('Anterior-posterior tilt angle corrected with {} degrees'.format(np.round(TiltAngle_ap_deg, 2)))
|
|
111
|
+
|
|
112
|
+
return df_corrected, avert2, amedlat2, aantpost2
|
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
import copy
|
|
3
|
+
import warnings
|
|
4
|
+
from biomechzoo.utils.peak_sign import peak_sign
|
|
5
|
+
from biomechzoo.biomech_ops.movement_onset import movement_onset
|
|
2
6
|
|
|
7
|
+
def addevent_data(data, channels, ename, etype, constant=None):
|
|
3
8
|
|
|
4
|
-
|
|
5
|
-
if isinstance(ch, str):
|
|
6
|
-
ch = [ch]
|
|
9
|
+
data_new = copy.deepcopy(data)
|
|
7
10
|
|
|
8
|
-
if
|
|
9
|
-
|
|
11
|
+
if isinstance(channels, str):
|
|
12
|
+
channels = [channels]
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
if len(channels) == 1 and channels[0].lower() == 'all':
|
|
15
|
+
channels = [key for key in data if key != 'zoosystem']
|
|
16
|
+
|
|
17
|
+
for channel in channels:
|
|
12
18
|
if ename == '':
|
|
13
19
|
data[channel]['event'] = {}
|
|
14
20
|
continue
|
|
15
21
|
|
|
16
22
|
if channel not in data:
|
|
17
|
-
|
|
18
|
-
continue
|
|
23
|
+
raise KeyError('Channel {} does not exist'.format(channel))
|
|
19
24
|
|
|
20
|
-
yd =
|
|
25
|
+
yd = data_new[channel]['line'] # 1D array
|
|
21
26
|
etype = etype.lower()
|
|
22
27
|
if etype == 'absmax':
|
|
23
28
|
exd = int(np.argmax(np.abs(yd)))
|
|
@@ -42,13 +47,57 @@ def addevent_data(data, ch, ename, etype):
|
|
|
42
47
|
exd = max_stance(yd)
|
|
43
48
|
eyd = float(yd[exd])
|
|
44
49
|
eyd = float(yd[exd])
|
|
50
|
+
elif etype == 'movement_onset':
|
|
51
|
+
exd = movement_onset(yd, constant)
|
|
52
|
+
eyd = yd[exd]
|
|
53
|
+
elif etype == 'movement_offset':
|
|
54
|
+
exd = movement_onset(yd,constant)
|
|
55
|
+
eyd = yd[exd]
|
|
56
|
+
elif etype in ['fs_fp', 'fo_fp']:
|
|
57
|
+
# --- Handle constant ---
|
|
58
|
+
if constant is None:
|
|
59
|
+
print('Warning: Force plate threshold not set, defaulting to 0.')
|
|
60
|
+
constant = 0.0
|
|
61
|
+
|
|
62
|
+
# --- Check sampling rates ---
|
|
63
|
+
AVR = data['zoosystem']['AVR']
|
|
64
|
+
if AVR != 1:
|
|
65
|
+
warnings.warn('Video and Analog channels must be at the same sampling rate or events will be incorrect.')
|
|
66
|
+
|
|
67
|
+
# --- Handle units ---
|
|
68
|
+
units = data['zoosystem']['Units']['Forces']
|
|
69
|
+
if units == 'N/kg':
|
|
70
|
+
m = data['zoosystem']['Anthro']['Bodymass']
|
|
71
|
+
else:
|
|
72
|
+
m = 1.0
|
|
73
|
+
|
|
74
|
+
# --- Extract force signal ---
|
|
75
|
+
if '_' not in channel:
|
|
76
|
+
yd = data_new[channel]['line'][:, 2] # looking for GRF Z
|
|
77
|
+
else:
|
|
78
|
+
yd = data_new[channel]['line']
|
|
79
|
+
|
|
80
|
+
# --- Determine peak sign ---
|
|
81
|
+
peak = peak_sign(yd) # user-defined function
|
|
82
|
+
|
|
83
|
+
# --- Find threshold crossing ---
|
|
84
|
+
threshold_signal = peak * yd * m
|
|
85
|
+
if 'fs' in etype:
|
|
86
|
+
exd_array = np.where(threshold_signal > constant)[0]
|
|
87
|
+
exd = exd_array[0] - 1 # MATLAB indexing correction
|
|
88
|
+
eyd = yd[exd]
|
|
89
|
+
else: # 'FO' type
|
|
90
|
+
exd_array = np.where(threshold_signal > constant)[0]
|
|
91
|
+
exd = exd_array[-1] + 1
|
|
92
|
+
eyd = yd[exd]
|
|
93
|
+
|
|
45
94
|
else:
|
|
46
95
|
raise ValueError(f'Unknown event type: {etype}')
|
|
47
96
|
|
|
48
97
|
# Add event to the channel's event dict
|
|
49
|
-
|
|
98
|
+
data_new[channel]['event'][ename] = [exd, eyd, 0]
|
|
50
99
|
|
|
51
|
-
return
|
|
100
|
+
return data_new
|
|
52
101
|
|
|
53
102
|
def max_stance(yd):
|
|
54
103
|
""" extracts max from first 40% of the gait cycle"""
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from biomechzoo.utils.findfield import findfield
|
|
2
2
|
import warnings
|
|
3
3
|
import copy
|
|
4
|
+
import numpy as np
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def partition_data(data, evt_start, evt_end):
|
|
@@ -13,16 +14,19 @@ def partition_data(data, evt_start, evt_end):
|
|
|
13
14
|
if e1 is None or e2 is None or len(e1) == 0 or len(e2) == 0:
|
|
14
15
|
raise ValueError(f"Event not found: evt_start='{evt_start}' returned {e1}, evt_end='{evt_end}' returned {e2}")
|
|
15
16
|
|
|
17
|
+
# convert to int and get first value
|
|
18
|
+
e1 = int(e1[0])
|
|
19
|
+
e2 = int(e2[0])
|
|
20
|
+
|
|
16
21
|
data_new = copy.deepcopy(data)
|
|
17
|
-
for ch_name, ch_data in data_new.items():
|
|
22
|
+
for ch_name, ch_data in sorted(data_new.items()):
|
|
18
23
|
if ch_name != 'zoosystem':
|
|
19
|
-
|
|
20
|
-
line = ch_data['line']
|
|
24
|
+
r = ch_data['line']
|
|
21
25
|
try:
|
|
22
|
-
if
|
|
23
|
-
data_new[ch_name]['line'] =
|
|
26
|
+
if r.ndim == 1:
|
|
27
|
+
data_new[ch_name]['line'] = r[e1:e2]
|
|
24
28
|
else:
|
|
25
|
-
data_new[ch_name]['line'] =
|
|
29
|
+
data_new[ch_name]['line'] = r[e1:e2, :]
|
|
26
30
|
except (IndexError, ValueError) as e:
|
|
27
31
|
# IndexError: if e1[0]:e2[0] goes beyond the available indices
|
|
28
32
|
# ValueError: less likely, but may arise with shape mismatches
|
|
@@ -31,29 +35,12 @@ def partition_data(data, evt_start, evt_end):
|
|
|
31
35
|
# partition events
|
|
32
36
|
events = ch_data['event']
|
|
33
37
|
for event_name, value in events.items():
|
|
34
|
-
original_frame = value[0]
|
|
38
|
+
original_frame = int(value[0])
|
|
35
39
|
if original_frame == 999:
|
|
36
40
|
continue # do not change outlier markers
|
|
37
41
|
else:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
data_new[ch_name]['event'][event_name]
|
|
42
|
+
arr = np.array(data_new[ch_name]['event'][event_name], dtype=np.int32)
|
|
43
|
+
arr[0] = original_frame - e1
|
|
44
|
+
data_new[ch_name]['event'][event_name] = arr
|
|
41
45
|
|
|
42
46
|
return data_new
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def _partition_line(arr, evt_start, evt_end):
|
|
46
|
-
arr_new = arr[evt_start:evt_end, :]
|
|
47
|
-
return arr_new
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def _partition_event(event_dict, evt_start, evt_end, arr_len):
|
|
51
|
-
raise NotImplementedError
|
|
52
|
-
# event_dict_new = {}
|
|
53
|
-
# for event, event_val in event_dict:
|
|
54
|
-
# event_val_new =
|
|
55
|
-
# event_dict_new[event] =
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
# return event_dict_new
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
import warnings
|
|
3
|
+
from biomechzoo.utils.findfield import findfield
|
|
4
|
+
|
|
5
|
+
def removeevent_data(data, events, mode='remove'):
|
|
6
|
+
"""
|
|
7
|
+
Remove or keep specified events in all channels of a zoo dictionary.
|
|
8
|
+
|
|
9
|
+
Parameters
|
|
10
|
+
----------
|
|
11
|
+
data : dict
|
|
12
|
+
Zoo data loaded from a file
|
|
13
|
+
events : list of str
|
|
14
|
+
Events to remove or keep
|
|
15
|
+
mode : str
|
|
16
|
+
'remove' or 'keep'
|
|
17
|
+
|
|
18
|
+
Returns
|
|
19
|
+
-------
|
|
20
|
+
dict
|
|
21
|
+
Modified zoo dictionary with events removed or kept
|
|
22
|
+
"""
|
|
23
|
+
if mode not in ['remove', 'keep']:
|
|
24
|
+
raise ValueError("mode must be 'remove' or 'keep'.")
|
|
25
|
+
|
|
26
|
+
if isinstance(events, str):
|
|
27
|
+
events = [events]
|
|
28
|
+
|
|
29
|
+
# check if any events are not present
|
|
30
|
+
valid_events = []
|
|
31
|
+
for evt in events:
|
|
32
|
+
e, _ = findfield(data, evt)
|
|
33
|
+
if e is None:
|
|
34
|
+
warnings.warn('Could not find event {} in zoo file, skipping'.format(evt))
|
|
35
|
+
else:
|
|
36
|
+
valid_events.append(evt)
|
|
37
|
+
events = valid_events
|
|
38
|
+
|
|
39
|
+
data_new = copy.deepcopy(data)
|
|
40
|
+
channels = sorted([ch for ch in data_new if ch != 'zoosystem'])
|
|
41
|
+
for ch in channels:
|
|
42
|
+
event_dict = data_new[ch].get('event', {})
|
|
43
|
+
events_to_remove = []
|
|
44
|
+
|
|
45
|
+
for evt in list(event_dict.keys()):
|
|
46
|
+
if mode == 'remove' and evt in events:
|
|
47
|
+
events_to_remove.append(evt)
|
|
48
|
+
elif mode == 'keep' and evt not in events:
|
|
49
|
+
events_to_remove.append(evt)
|
|
50
|
+
|
|
51
|
+
for evt in events_to_remove:
|
|
52
|
+
event_dict.pop(evt, None)
|
|
53
|
+
# print('Removed event "{}" from channel "{}"'.format(evt, ch))
|
|
54
|
+
|
|
55
|
+
data_new[ch]['event'] = event_dict
|
|
56
|
+
|
|
57
|
+
return data_new
|
|
@@ -28,17 +28,11 @@ def renameevent_data(data, evt, nevt):
|
|
|
28
28
|
# Get all data channels except 'zoosystem'
|
|
29
29
|
channels = [ch for ch in data if ch != 'zoosystem']
|
|
30
30
|
for old_name, new_name in zip(evt, nevt):
|
|
31
|
-
eventsRenamed = False
|
|
32
31
|
for ch in channels:
|
|
33
32
|
events = data[ch].get('event', {})
|
|
34
33
|
if old_name in events:
|
|
35
|
-
print('Renaming event {} in channel {} to {}'.format(old_name, ch, new_name))
|
|
36
34
|
data[ch]['event'][new_name] = events[old_name]
|
|
37
35
|
del data[ch]['event'][old_name]
|
|
38
|
-
eventsRenamed = True
|
|
39
|
-
|
|
40
|
-
if not eventsRenamed:
|
|
41
|
-
print('no event {} found in any channel'.format(old_name))
|
|
42
36
|
|
|
43
37
|
return data
|
|
44
38
|
|
biomechzoo/utils/engine.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import numpy as np
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
def engine(root_folder, extension='.zoo', subfolders=None, name_contains=None, verbose=False):
|
|
@@ -66,10 +67,13 @@ def engine(root_folder, extension='.zoo', subfolders=None, name_contains=None, v
|
|
|
66
67
|
continue
|
|
67
68
|
matched_files.append(full_path)
|
|
68
69
|
|
|
70
|
+
# sort list
|
|
71
|
+
matched_files = np.sort(matched_files)
|
|
72
|
+
|
|
69
73
|
if verbose:
|
|
70
|
-
print("Found {} {} files in
|
|
74
|
+
print("Found {} {} files in subfolder(s) named {} with substring {}:".format(len(matched_files), extension, subfolders, name_contains))
|
|
71
75
|
for f in matched_files:
|
|
72
|
-
print(
|
|
76
|
+
print('{}'.format(f))
|
|
73
77
|
|
|
74
78
|
return matched_files
|
|
75
79
|
|
|
@@ -79,6 +83,6 @@ if __name__ == '__main__':
|
|
|
79
83
|
with extension .c3d in the sample study folder (data)"""
|
|
80
84
|
# -------TESTING--------
|
|
81
85
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
82
|
-
project_root = os.path.dirname(current_dir)
|
|
86
|
+
project_root = os.path.dirname(os.path.dirname(os.path.dirname(current_dir)))
|
|
83
87
|
sample_dir = os.path.join(project_root, 'data', 'sample_study', 'raw c3d files')
|
|
84
88
|
c3d_files = engine(sample_dir, '.c3d', subfolders=['Straight'], name_contains='HC03', verbose=True)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
def peak_sign(r):
|
|
4
|
+
"""
|
|
5
|
+
Determine whether the largest absolute peak in the signal is positive or negative.
|
|
6
|
+
|
|
7
|
+
Parameters
|
|
8
|
+
----------
|
|
9
|
+
r : array-like
|
|
10
|
+
Signal vector.
|
|
11
|
+
|
|
12
|
+
Returns
|
|
13
|
+
-------
|
|
14
|
+
sign : int
|
|
15
|
+
1 if the maximum peak is positive, -1 if negative.
|
|
16
|
+
"""
|
|
17
|
+
r = np.asarray(r)
|
|
18
|
+
max_val = np.max(r)
|
|
19
|
+
min_val = np.min(r)
|
|
20
|
+
|
|
21
|
+
if abs(max_val) > abs(min_val):
|
|
22
|
+
return 1
|
|
23
|
+
else:
|
|
24
|
+
return -1
|
biomechzoo/utils/split_trial.py
CHANGED
|
@@ -1,23 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
import copy
|
|
2
|
+
from biomechzoo.utils.findfield import findfield
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def split_trial(data, start_event, end_event):
|
|
2
6
|
# todo check index problem compared to matlab start at 0 or 1
|
|
3
|
-
data_new =
|
|
7
|
+
data_new = copy.deepcopy(data)
|
|
8
|
+
|
|
9
|
+
start_event_indx, _ = findfield(data_new, start_event)
|
|
10
|
+
end_event_indx, _ = findfield(data_new, end_event)
|
|
4
11
|
|
|
5
12
|
for key, value in data_new.items():
|
|
6
13
|
if key == 'zoosystem':
|
|
7
14
|
continue
|
|
8
15
|
|
|
9
16
|
# Slice the line data
|
|
10
|
-
data_new[key]['line']
|
|
17
|
+
trial_length = len(data_new[key]['line'])
|
|
18
|
+
if trial_length > end_event_indx[0]:
|
|
19
|
+
data_new[key]['line'] = value['line'][start_event_indx[0]:end_event_indx[0]]
|
|
20
|
+
else:
|
|
21
|
+
print('skipping split trial since event is outside range of data')
|
|
22
|
+
return None
|
|
11
23
|
|
|
12
24
|
# Update events if present
|
|
13
|
-
if 'event' in value:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
# if 'event' in value:
|
|
26
|
+
# new_events = {}
|
|
27
|
+
# for evt_name, evt_val in value['event'].items():
|
|
28
|
+
# event_frame = evt_val[0]
|
|
29
|
+
# # Check if event falls within the new window
|
|
30
|
+
# if start_event_indx <= event_frame < end_event_indx:
|
|
31
|
+
# # Adjust index relative to new start
|
|
32
|
+
# new_events[evt_name] = [event_frame - start_event_indx, 0, 0]
|
|
33
|
+
# data_new[key]['event'] = new_events
|
|
22
34
|
|
|
23
35
|
return data_new
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
__init__.py,sha256=Uy3ykqw4l_lZKiUWSUFPRZpkZajYUfZLBaQLVhKzxdI,772
|
|
2
2
|
biomechzoo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
biomechzoo/__main__.py,sha256=hSMHN1Rxn2367fSGTLHoOQ4_pocZw0IWI7HFxl-74oY,88
|
|
4
|
-
biomechzoo/biomechzoo.py,sha256=
|
|
4
|
+
biomechzoo/biomechzoo.py,sha256=3PviTE-zv0TVp3pYayL2ZrMopj5LJtcSLjwxEsGMtxw,22515
|
|
5
5
|
biomechzoo/biomech_ops/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
biomechzoo/biomech_ops/continuous_relative_phase_data.py,sha256=RePbt6zyOI1iv74CWhxSrunIokTFYVfFmFnoW51781E,1300
|
|
7
7
|
biomechzoo/biomech_ops/continuous_relative_phase_line.py,sha256=Fa1LFRuPlmGPLQLvln6HVnJy3zMSm9z5YeooHmTu0lc,1365
|
|
8
8
|
biomechzoo/biomech_ops/filter_data.py,sha256=Q9knW23Ft_WeWVCBjaIQ5GkKU0NYV4SdGiDZV8Fm-hM,1805
|
|
9
9
|
biomechzoo/biomech_ops/filter_line.py,sha256=XKUdRsxU5AO1gSldnwp3qNzsUUL8qpOpAMyQbEMo5uI,2600
|
|
10
|
-
biomechzoo/biomech_ops/
|
|
10
|
+
biomechzoo/biomech_ops/movement_onset.py,sha256=3VAoOp01P08BKMaOZW3CwbMdoSMOufDaoMkWeYRcPmo,51
|
|
11
|
+
biomechzoo/biomech_ops/normalize_data.py,sha256=ESdXeUkKdd0WpjP6FW2EYrOAd7NKWkX1JWUNn1SzDB4,1335
|
|
11
12
|
biomechzoo/biomech_ops/normalize_line.py,sha256=KUE8gEkIolA-VDFCdUuaskk-waO8jjJ20ZMZaS8Qha8,854
|
|
12
13
|
biomechzoo/biomech_ops/phase_angle_data.py,sha256=_ekUBW2v3iC4UawcDL38ZZLYJmQsAmyqA61Q6_AMtmQ,1435
|
|
13
14
|
biomechzoo/biomech_ops/phase_angle_line.py,sha256=p6osB17_3QQSyKLNojuc6nYhv-k0K6EUUH75EXu8ifc,1391
|
|
14
15
|
biomechzoo/conversion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
16
|
biomechzoo/conversion/c3d2zoo_data.py,sha256=28JCj1Jpn7zsv2HjQdzH2F30jnGMwzmbBwYuRoWPJHo,4052
|
|
16
|
-
biomechzoo/conversion/mvnx2zoo_data.py,sha256=
|
|
17
|
+
biomechzoo/conversion/mvnx2zoo_data.py,sha256=uMAZ4pNSSZ7NToW1WnawrXeVP8D-xE3dNDnooPvALE4,3545
|
|
17
18
|
biomechzoo/conversion/opencap2zoo_data.py,sha256=n4bLsrJI0wTSzG5bgJcmxj1dp2plnUKFNRzcTIbmV1o,608
|
|
18
|
-
biomechzoo/conversion/table2zoo_data.py,sha256=
|
|
19
|
+
biomechzoo/conversion/table2zoo_data.py,sha256=rAP7OrKbVrb50NHJ6h8fgoMntV87-t9wT2xQ30AD96I,3330
|
|
20
|
+
biomechzoo/imu/tilt_algoirthm.py,sha256=PYVErXHeY-Wgi0aXCQxDodohTDzirRXo8BEW3_Pskqo,4312
|
|
19
21
|
biomechzoo/mvn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
22
|
biomechzoo/mvn/load_mvnx.py,sha256=B4VGuidQ-5G_5E1t5vpU51Nb_Lu85_EOS_FmGZYjfX8,22499
|
|
21
23
|
biomechzoo/mvn/main_mvnx.py,sha256=e1LasJQ9icyzjWnRCEcAWQq_-L13-mIzf7PzYA3QYDg,2394
|
|
@@ -24,28 +26,30 @@ biomechzoo/mvn/mvnx_file_accessor.py,sha256=Gk2vKq9v_gPbnOS_12zgeJehjFz7v3ClTnN2
|
|
|
24
26
|
biomechzoo/processing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
27
|
biomechzoo/processing/add_channel_data.py,sha256=U1xLLBSnyJeeDWzgmHSxOz1hyguzuuDXxQCQ8IFoZkw,1955
|
|
26
28
|
biomechzoo/processing/addchannel_data.py,sha256=rmnnlMRVkoMlQCR-nRg1jjh-hzMDt37Sx9fAmocrpqA,1953
|
|
27
|
-
biomechzoo/processing/addevent_data.py,sha256=
|
|
29
|
+
biomechzoo/processing/addevent_data.py,sha256=Z7vsHqhsn8byw4d9atinjGpvglwj6tu38uqZfXVvluQ,3573
|
|
28
30
|
biomechzoo/processing/explodechannel_data.py,sha256=ceyXfcCmeNqj4p0zCksVdrnmsYR4t-JHLIyv3JlfNpU,2484
|
|
29
|
-
biomechzoo/processing/partition_data.py,sha256=
|
|
31
|
+
biomechzoo/processing/partition_data.py,sha256=4wuKrnMmRMNobymYwZ0WuRvNGsvkhThZ2ZhoSkkhntg,1741
|
|
30
32
|
biomechzoo/processing/removechannel_data.py,sha256=uO7jjuHapRr2CGLsrvYQ1eJLvb1y_8KR6Ct4M6TPALA,1740
|
|
33
|
+
biomechzoo/processing/removeevent_data.py,sha256=DC1vBIwuo_mk5Oz0UGLK7Nx3BVqAeVDfT29XgUM_1Rc,1631
|
|
31
34
|
biomechzoo/processing/renamechannel_data.py,sha256=5lEnWJknAwnJYXDlwO6cFe7C8ct5o42tTHW0Y4GeIL4,2210
|
|
32
|
-
biomechzoo/processing/renameevent_data.py,sha256=
|
|
35
|
+
biomechzoo/processing/renameevent_data.py,sha256=PRGHEs-t9qJMzDY1DCNgQz_h-aAOIII4ryQeCYBXwGo,1952
|
|
33
36
|
biomechzoo/processing/split_trial_by_gait_cycle.py,sha256=maMUwumSlFLFc5LHdNdBO9JCoT06aaLbpdp43dgowDA,1684
|
|
34
37
|
biomechzoo/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
38
|
biomechzoo/utils/batchdisp.py,sha256=Ke7yeZ4cYQvyf8bmgsiLaRElUeQm49TYIYzAcPWan9s,839
|
|
36
39
|
biomechzoo/utils/compute_sampling_rate_from_time.py,sha256=iyHbN734vYe5bXEoAsHScJN7Qw--2quUgII7judSQDk,579
|
|
37
|
-
biomechzoo/utils/engine.py,sha256=
|
|
40
|
+
biomechzoo/utils/engine.py,sha256=tatGMBbgIe8DIHx2_z_JQwA9TJYCeVYqyWiKiMoRHw4,3971
|
|
38
41
|
biomechzoo/utils/findfield.py,sha256=i7ewGQOMIiTC06tYFK-JctehHLCippkY9FoXIygx14w,381
|
|
39
42
|
biomechzoo/utils/get_split_events.py,sha256=xNhEuG6Yqsr1bjWIBHLbepfX-fcqcCYIXZzS3eaDDHQ,911
|
|
43
|
+
biomechzoo/utils/peak_sign.py,sha256=4XNqVIrAmpLw9C9RmWwIKkI1rluBTzeCXJE4-AHCzC4,465
|
|
40
44
|
biomechzoo/utils/set_zoosystem.py,sha256=oubEc3fy0x6y-AlqQWL3v7QYJA951jU9CRnlJ9ikwQo,1750
|
|
41
|
-
biomechzoo/utils/split_trial.py,sha256=
|
|
45
|
+
biomechzoo/utils/split_trial.py,sha256=0SNpKKkRoizRe9MCuMrQ6Ev6O5V51rN0D-e8FGlLlo4,1302
|
|
42
46
|
biomechzoo/utils/version.py,sha256=JIXDUuOcaJiZv9ruMP6PtWvJBh4sP0D5kAvlqPiZK_I,130
|
|
43
47
|
biomechzoo/utils/zload.py,sha256=_qmbQpiEwUNRcB86aS6dHiytOrz1ZXJVjYkk8h5fg8s,2039
|
|
44
48
|
biomechzoo/utils/zplot.py,sha256=WVA8aCy1Pqy_bo_HXab9AmW-cBd8J8MPX2LAOd6dznU,1512
|
|
45
49
|
biomechzoo/utils/zsave.py,sha256=wnRNuDxQc8bwCji4UrfoGjYrSZmka4eaDxQ5rMa78pE,1759
|
|
46
|
-
biomechzoo-0.
|
|
47
|
-
biomechzoo-0.
|
|
48
|
-
biomechzoo-0.
|
|
49
|
-
biomechzoo-0.
|
|
50
|
-
biomechzoo-0.
|
|
51
|
-
biomechzoo-0.
|
|
50
|
+
biomechzoo-0.5.1.dist-info/licenses/LICENSE,sha256=Fsz62nrgRORre3A1wNXUDISaHoostodMvocRPDdXc9w,1076
|
|
51
|
+
biomechzoo-0.5.1.dist-info/METADATA,sha256=Jp2p2d6SsnirRpmQjUb91GyEX9sY5fRGG4jfVqRvwPA,1579
|
|
52
|
+
biomechzoo-0.5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
53
|
+
biomechzoo-0.5.1.dist-info/entry_points.txt,sha256=VdryUUiwwvx0WZxrgmMrsyfe5Z1jtyaxdXOi0zWHOqk,41
|
|
54
|
+
biomechzoo-0.5.1.dist-info/top_level.txt,sha256=nJEtuEZ9UPoN3EOR-BJ6myevEu7B5quWsWhaM_YeQpw,20
|
|
55
|
+
biomechzoo-0.5.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|