biomechzoo 0.5.0__py3-none-any.whl → 0.5.2__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 +51 -0
- biomechzoo/biomechzoo.py +24 -0
- biomechzoo/imu/tilt_algorithm.py +112 -0
- biomechzoo/processing/addevent_data.py +24 -6
- {biomechzoo-0.5.0.dist-info → biomechzoo-0.5.2.dist-info}/METADATA +1 -1
- {biomechzoo-0.5.0.dist-info → biomechzoo-0.5.2.dist-info}/RECORD +10 -8
- {biomechzoo-0.5.0.dist-info → biomechzoo-0.5.2.dist-info}/WHEEL +0 -0
- {biomechzoo-0.5.0.dist-info → biomechzoo-0.5.2.dist-info}/entry_points.txt +0 -0
- {biomechzoo-0.5.0.dist-info → biomechzoo-0.5.2.dist-info}/licenses/LICENSE +0 -0
- {biomechzoo-0.5.0.dist-info → biomechzoo-0.5.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
def movement_onset(yd, constant, etype=etype):
|
|
2
|
+
"""
|
|
3
|
+
Extracts movement onset based on the average and standard deviation of a sliding window
|
|
4
|
+
Standard thresholds for running are mean_thresh=1.2, std_thresh=0.2. For walking mean_thresh=0.6, std_thresh=0.2.
|
|
5
|
+
|
|
6
|
+
yd: 1d array of the vector
|
|
7
|
+
constants: [sample_frequency, mean_thresh, std_thresh]
|
|
8
|
+
"""
|
|
9
|
+
acc_mag = yd.copy()
|
|
10
|
+
|
|
11
|
+
# ----extract the constants----
|
|
12
|
+
fs = constant[0]
|
|
13
|
+
mean_thresh = constant[1]
|
|
14
|
+
std_thresh = constant[2]
|
|
15
|
+
|
|
16
|
+
# ----sliding window features----
|
|
17
|
+
features = []
|
|
18
|
+
timestamps = []
|
|
19
|
+
window_size = 2 * fs # windows van 2 seconds
|
|
20
|
+
step_size = 1 * fs # with an overlap of 1 seconds
|
|
21
|
+
|
|
22
|
+
for start in range(0, len(acc_mag) - window_size, step_size):
|
|
23
|
+
segment = acc_mag[start:start + window_size]
|
|
24
|
+
mean_val = segment.mean()
|
|
25
|
+
std_val = segment.std()
|
|
26
|
+
# entropy = -np.sum((segment / np.sum(segment)) * np.log2(segment / np.sum(segment) + 1e-12))
|
|
27
|
+
timestamps.append(start)
|
|
28
|
+
features.append((mean_val, std_val))
|
|
29
|
+
|
|
30
|
+
features = np.array(features)
|
|
31
|
+
timestamps = np.array(timestamps)
|
|
32
|
+
|
|
33
|
+
# ----Check already moving else find start----
|
|
34
|
+
initial_window = features[:5] # First few seconds
|
|
35
|
+
if np.all(initial_window[:, 0] > mean_thresh) and np.all(initial_window[:, 1] > std_thresh):
|
|
36
|
+
print("already moving")
|
|
37
|
+
if etype == 'movement_offset':
|
|
38
|
+
index = 0
|
|
39
|
+
else:
|
|
40
|
+
# features, timestamps = self.sliding_window_features(acc_mag)
|
|
41
|
+
movement_flags = (features[:, 0] > mean_thresh) & (features[:, 1] > std_thresh)
|
|
42
|
+
index = None
|
|
43
|
+
for i in range(len(movement_flags) - int(min_duration * self.fs / 50)):
|
|
44
|
+
if np.all(movement_flags[i:i + int(min_duration * self.fs / 50)]):
|
|
45
|
+
index = i
|
|
46
|
+
break
|
|
47
|
+
|
|
48
|
+
if etype == 'movement_offset':
|
|
49
|
+
index = len(yd) - end_time
|
|
50
|
+
|
|
51
|
+
return timestamps[index] if index is not None else timestamps[0]
|
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_algorithm 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
|
|
@@ -134,6 +136,28 @@ class BiomechZoo:
|
|
|
134
136
|
def parquet2zoo(self, out_folder=None, inplace=None):
|
|
135
137
|
raise NotImplementedError('Use table2zoo instead')
|
|
136
138
|
|
|
139
|
+
def rectify(self):
|
|
140
|
+
raise NotImplementedError
|
|
141
|
+
def tilt_algorithm(self, chname_avert, chname_medlat, chname_antpost, out_folder=None, inplace=False):
|
|
142
|
+
""" tilt correction for acceleration data """
|
|
143
|
+
start_time = time.time()
|
|
144
|
+
verbose = self.verbose
|
|
145
|
+
in_folder = self.in_folder
|
|
146
|
+
if inplace is None:
|
|
147
|
+
inplace = self.inplace
|
|
148
|
+
fl = engine(in_folder, name_contains=self.name_contains, subfolders=self.subfolders)
|
|
149
|
+
for f in fl:
|
|
150
|
+
batchdisp('tilt correction of acceleration channels for {}'.format(f), level=2, verbose=verbose)
|
|
151
|
+
data = zload(f)
|
|
152
|
+
data = tilt_algorithm_data(data, chname_avert, chname_medlat, chname_antpost)
|
|
153
|
+
zsave(f, data, inplace=inplace, out_folder=out_folder, root_folder=in_folder)
|
|
154
|
+
method_name = inspect.currentframe().f_code.co_name
|
|
155
|
+
batchdisp(
|
|
156
|
+
'{} process complete for {} file(s) in {:.2f} secs'.format(method_name, len(fl), time.time() - start_time),
|
|
157
|
+
level=1, verbose=verbose)
|
|
158
|
+
# Update self.folder after processing
|
|
159
|
+
self._update_folder(out_folder, inplace, in_folder)
|
|
160
|
+
|
|
137
161
|
def phase_angle(self, ch, out_folder=None, inplace=None):
|
|
138
162
|
""" computes phase angles"""
|
|
139
163
|
start_time = time.time()
|
|
@@ -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,7 +1,9 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import copy
|
|
3
3
|
import warnings
|
|
4
|
+
from scipy.signal import find_peaks
|
|
4
5
|
from biomechzoo.utils.peak_sign import peak_sign
|
|
6
|
+
from biomechzoo.biomech_ops.movement_onset import movement_onset
|
|
5
7
|
|
|
6
8
|
def addevent_data(data, channels, ename, etype, constant=None):
|
|
7
9
|
|
|
@@ -41,11 +43,17 @@ def addevent_data(data, channels, ename, etype, constant=None):
|
|
|
41
43
|
elif etype == 'rom':
|
|
42
44
|
eyd = float(np.max(yd) - np.min(yd))
|
|
43
45
|
exd = 0 # dummy index (like MATLAB version)
|
|
44
|
-
elif etype == '
|
|
46
|
+
elif etype == 'first peak':
|
|
45
47
|
# special event for gait and running
|
|
46
|
-
exd =
|
|
47
|
-
eyd = float(yd[exd])
|
|
48
|
+
exd = find_first_peak(yd, constant)
|
|
48
49
|
eyd = float(yd[exd])
|
|
50
|
+
elif etype == 'movement_onset':
|
|
51
|
+
exd = movement_onset(yd, constant, etype=etype)
|
|
52
|
+
eyd = yd[exd]
|
|
53
|
+
elif etype == 'movement_offset':
|
|
54
|
+
yd2 = yd[::-1].copy() # Reverse the time series.
|
|
55
|
+
exd = movement_onset(yd2, constant, etype=etype)
|
|
56
|
+
eyd = yd[exd]
|
|
49
57
|
elif etype in ['fs_fp', 'fo_fp']:
|
|
50
58
|
# --- Handle constant ---
|
|
51
59
|
if constant is None:
|
|
@@ -92,7 +100,17 @@ def addevent_data(data, channels, ename, etype, constant=None):
|
|
|
92
100
|
|
|
93
101
|
return data_new
|
|
94
102
|
|
|
95
|
-
def
|
|
96
|
-
""" extracts
|
|
97
|
-
|
|
103
|
+
def find_first_peak(yd, constant):
|
|
104
|
+
""" extracts first peak from a series of 2 peaks """
|
|
105
|
+
# Find peaks above threshold
|
|
106
|
+
peaks, _ = find_peaks(yd, height=constant)
|
|
107
|
+
|
|
108
|
+
if len(peaks) == 0:
|
|
109
|
+
raise ValueError('No peaks found')
|
|
110
|
+
elif len(peaks) == 1:
|
|
111
|
+
raise ValueError('Only 1 peak found')
|
|
112
|
+
else:
|
|
113
|
+
# Take the first valid peak
|
|
114
|
+
exd = peaks[0]
|
|
115
|
+
|
|
98
116
|
return exd
|
|
@@ -1,12 +1,13 @@
|
|
|
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=Dma-eZNCud0pSD-OjNkAVlMrynOCysCQwUQXMS3GcQk,22572
|
|
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/movement_onset.py,sha256=qKeNiVTDra_0wjjPTLfP_Gtoyz5cbHD2F_EDxOxo1oQ,1961
|
|
10
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
|
|
@@ -16,6 +17,7 @@ biomechzoo/conversion/c3d2zoo_data.py,sha256=28JCj1Jpn7zsv2HjQdzH2F30jnGMwzmbBwY
|
|
|
16
17
|
biomechzoo/conversion/mvnx2zoo_data.py,sha256=uMAZ4pNSSZ7NToW1WnawrXeVP8D-xE3dNDnooPvALE4,3545
|
|
17
18
|
biomechzoo/conversion/opencap2zoo_data.py,sha256=n4bLsrJI0wTSzG5bgJcmxj1dp2plnUKFNRzcTIbmV1o,608
|
|
18
19
|
biomechzoo/conversion/table2zoo_data.py,sha256=rAP7OrKbVrb50NHJ6h8fgoMntV87-t9wT2xQ30AD96I,3330
|
|
20
|
+
biomechzoo/imu/tilt_algorithm.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,7 +26,7 @@ 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=GGzXSGNNpZFTEMh0l3awqeBf5jHaCdV84K2Nwjuhqkk,3955
|
|
28
30
|
biomechzoo/processing/explodechannel_data.py,sha256=ceyXfcCmeNqj4p0zCksVdrnmsYR4t-JHLIyv3JlfNpU,2484
|
|
29
31
|
biomechzoo/processing/partition_data.py,sha256=4wuKrnMmRMNobymYwZ0WuRvNGsvkhThZ2ZhoSkkhntg,1741
|
|
30
32
|
biomechzoo/processing/removechannel_data.py,sha256=uO7jjuHapRr2CGLsrvYQ1eJLvb1y_8KR6Ct4M6TPALA,1740
|
|
@@ -45,9 +47,9 @@ biomechzoo/utils/version.py,sha256=JIXDUuOcaJiZv9ruMP6PtWvJBh4sP0D5kAvlqPiZK_I,1
|
|
|
45
47
|
biomechzoo/utils/zload.py,sha256=_qmbQpiEwUNRcB86aS6dHiytOrz1ZXJVjYkk8h5fg8s,2039
|
|
46
48
|
biomechzoo/utils/zplot.py,sha256=WVA8aCy1Pqy_bo_HXab9AmW-cBd8J8MPX2LAOd6dznU,1512
|
|
47
49
|
biomechzoo/utils/zsave.py,sha256=wnRNuDxQc8bwCji4UrfoGjYrSZmka4eaDxQ5rMa78pE,1759
|
|
48
|
-
biomechzoo-0.5.
|
|
49
|
-
biomechzoo-0.5.
|
|
50
|
-
biomechzoo-0.5.
|
|
51
|
-
biomechzoo-0.5.
|
|
52
|
-
biomechzoo-0.5.
|
|
53
|
-
biomechzoo-0.5.
|
|
50
|
+
biomechzoo-0.5.2.dist-info/licenses/LICENSE,sha256=Fsz62nrgRORre3A1wNXUDISaHoostodMvocRPDdXc9w,1076
|
|
51
|
+
biomechzoo-0.5.2.dist-info/METADATA,sha256=_2N7nddOIeDuoVCCXsD8aEggf84O21RBstPq4h3k7pM,1579
|
|
52
|
+
biomechzoo-0.5.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
53
|
+
biomechzoo-0.5.2.dist-info/entry_points.txt,sha256=VdryUUiwwvx0WZxrgmMrsyfe5Z1jtyaxdXOi0zWHOqk,41
|
|
54
|
+
biomechzoo-0.5.2.dist-info/top_level.txt,sha256=nJEtuEZ9UPoN3EOR-BJ6myevEu7B5quWsWhaM_YeQpw,20
|
|
55
|
+
biomechzoo-0.5.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|