biomechzoo 0.4.10__py3-none-any.whl → 0.4.11__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.

@@ -13,10 +13,10 @@ def filter_data(data, ch, filt=None):
13
13
  The name(s) of the channel(s) to filter.
14
14
  filt : dict, optional
15
15
  Dictionary specifying filter parameters. Keys may include:
16
- - 'type': 'butter' (default)
16
+ - 'ftype': 'butter' (default)
17
17
  - 'order': filter order (default: 4)
18
18
  - 'cutoff': cutoff frequency or tuple (Hz)
19
- - 'btype': 'low', 'high', 'bandpass', 'bandstop' (default: 'low')
19
+ - 'btype': 'low', 'high', 'bandpass', 'bandstop' (default: 'lowpass')
20
20
 
21
21
  Returns
22
22
  -------
@@ -25,32 +25,34 @@ def filter_data(data, ch, filt=None):
25
25
  """
26
26
 
27
27
  if filt is None:
28
- filt = {}
28
+ filt = {'ftype': 'butter',
29
+ 'order': 4,
30
+ 'cutoff': 10,
31
+ 'btype': 'lowpass',
32
+ 'filtfilt': True}
29
33
 
30
34
  if isinstance(ch, str):
31
35
  ch = [ch]
32
36
 
33
- analog_channels = data['zoosystem']['Analog']['Channels']
34
- if analog_channels:
35
- analog_freq = data['zoosystem']['Analog']['Freq']
36
- video_channels = data['zoosystem']['Video']['Channels']
37
- if video_channels:
38
- video_freq = data['zoosystem']['Video']['Freq']
39
-
37
+ # loop through all channels and filter
40
38
  for c in ch:
41
39
  if c not in data:
42
40
  raise KeyError('Channel {} not found in data'.format(c))
43
41
 
44
42
  if 'fs' not in filt:
43
+
44
+ video_channels = data['zoosystem']['Video']['Channels']
45
+ analog_channels = data['zoosystem']['Analog']['Channels']
46
+
45
47
  if c in analog_channels:
46
- filt['fs'] = analog_freq
47
- elif c in video_freq:
48
- filt['fs'] = video_freq
48
+ filt['fs'] = data['zoosystem']['Analog']['Freq']
49
+ elif c in video_channels:
50
+ filt['fs'] = data['zoosystem']['Video']['Freq']
49
51
  else:
50
- raise ValueError('frequency not provided and cannot be inferred from zoosystem for channel'.format(c))
52
+ raise ValueError('Channel not analog or video')
51
53
 
52
54
  signal_raw = data[c]['line']
53
- signal_filtered = filter_line(signal_raw, filt)
55
+ signal_filtered = filter_line(signal_raw=signal_raw, filt=filt)
54
56
  data[c]['line'] = signal_filtered
55
57
 
56
58
  return data
@@ -1,88 +1,85 @@
1
1
  import numpy as np
2
- from scipy.signal import butter, filtfilt
2
+ import scipy.signal as sgl
3
3
 
4
4
 
5
- def filter_line(signal_raw, filt):
6
- """ filter an array
5
+ def filter_line(signal_raw, filt=None, fs=None):
6
+ """Filter an array using a Butterworth filter."""
7
+ #todo: verify that filter is working correctly
8
+ #todo add more filters
9
+ #todo: consider using kineticstoolkit
7
10
 
8
- Arguments
9
- ----------
10
- signal_raw : n, or n x 3 array signal to be filtered
11
- filt : dict, optional
12
- Dictionary specifying filter parameters. Keys may include:
13
- - 'type': 'butter' (default)
14
- - 'order': filter order (default: 4)
15
- - 'cutoff': cutoff frequency or tuple (Hz)
16
- - 'btype': 'low', 'high', 'bandpass', 'bandstop' (default: 'low')
17
- - 'fs' frequency
18
-
19
- Returns
20
- -------
21
- signal_filtered: filtered version of signal_raw"""
22
- # todo allow for missing frequency to be obtained from zoosystem metadata
23
11
  if filt is None:
24
- filt = {}
25
- if filt['type'] is 'butterworth':
26
- filt['type'] = 'butter'
27
- # Set default filter parameters
28
- ftype = filt.get('type', 'butter')
29
- order = filt.get('order', 4)
30
- cutoff = filt.get('cutoff', None)
31
- btype = filt.get('btype', 'low')
32
- fs = filt.get('fs', None)
33
-
34
- if ftype != 'butter':
35
- raise NotImplementedError(f"Filter type '{ftype}' not implemented.")
36
-
37
- if fs is None:
38
- raise ValueError("Sampling frequency 'fs' must be specified in filt.")
39
-
40
- if cutoff is None:
41
- raise ValueError("Cutoff frequency 'cutoff' must be specified in filt.")
12
+ filt = {'ftype': 'butter',
13
+ 'order': 4,
14
+ 'cutoff': 10,
15
+ 'btype': 'lowpass',
16
+ 'filtfilt': True}
17
+ if fs is None:
18
+ raise ValueError('fs is required if no filt is specified')
42
19
 
20
+ else:
21
+ if 'fs' not in filt:
22
+ raise ValueError('fs is a required key of filt')
23
+
24
+ # Normalize filter type strings
25
+ if filt['ftype'] == 'butterworth':
26
+ filt['ftype'] = 'butter'
27
+ if filt['btype'] is 'low':
28
+ filt['btype'] = 'lowpass'
29
+ if filt['btype'] is 'high':
30
+ filt['btype'] = 'highpass'
31
+
32
+ # Extract parameters
33
+ ftype = filt['ftype']
34
+ order = filt['order']
35
+ cutoff = filt['cutoff']
36
+ btype = filt['btype']
37
+ filtfilt = filt['filtfilt']
38
+ fs = filt['fs']
39
+
40
+ # prepare normalized cutoff(s)
43
41
  nyq = 0.5 * fs
44
- norm_cutoff = np.array(cutoff) / nyq
45
-
46
- b, a = butter(order, norm_cutoff, btype=btype, analog=False)
42
+ norm_cutoff = np.atleast_1d(np.array(cutoff) / nyq)
47
43
 
48
- if signal_raw.ndim == 1:
49
- signal_filtered = filtfilt(b, a, signal_raw)
44
+ if ftype is 'butter':
45
+ signal_filtered = kt_butter(ts=signal_raw, fc=norm_cutoff, fs=fs, order=order, btype=btype, filtfilt=filtfilt)
50
46
  else:
51
- # Apply filter to each column if multivariate
52
- signal_filtered = np.array([filtfilt(b, a, signal_raw[:, i]) for i in range(signal_raw.shape[1])]).T
47
+ raise NotImplementedError(f"Filter type '{ftype}' not implemented.")
53
48
 
54
49
  return signal_filtered
55
50
 
56
51
 
57
- if __name__ == '__main__':
58
- """ -------TESTING--------"""
59
- import os
60
- import matplotlib.pyplot as plt
61
- from src.biomechzoo.utils.zload import zload
62
- current_dir = os.path.dirname(os.path.abspath(__file__))
63
- project_root = os.path.dirname(current_dir)
64
- fl = os.path.join(project_root, 'data', 'other', 'HC030A05.zoo')
65
- data = zload(fl)
66
- data = data['data']
67
- signal_raw = data['ForceFz1']['line']
68
- filt = {'type': 'butterworth',
69
- 'order': 3,
70
- 'cutoff': 20,
71
- 'btype': 'low',
72
- 'fs': data['zoosystem']['Analog']['Freq']
73
- }
74
- signal_filtered = filter_line(signal_raw, filt)
75
-
76
- # now plot
77
- plt.figure(figsize=(10, 4))
78
- plt.plot(signal_raw, label='Raw', alpha=0.6)
79
- plt.plot(signal_filtered, label='Filtered', linewidth=2)
80
- plt.xlabel('Frame')
81
- plt.ylabel('Amplitude')
82
- plt.title('Testing filter_line')
83
- plt.legend()
84
- plt.grid(True)
85
- plt.tight_layout()
86
- plt.show()
52
+ def kt_butter(ts, fc, fs, order=2, btype='lowpass', filtfilt=True):
53
+ """
54
+ Apply a Butterworth filter to data.
55
+
56
+ Parameters
57
+ ----------
58
+ ts, ndarray, 1d.
59
+ fc, Cut-off frequency in Hz. This is a float for single-frequency filters
60
+ (lowpass, highpass), or a tuple of two floats (e.g., (10., 13.)
61
+ for two-frequency filters (bandpass, bandstop)).
62
+ order, Optional. Order of the filter. Default is 2.
63
+ btype, Optional. Can be either "lowpass", "highpass", "bandpass" or
64
+ "bandstop". Default is "lowpass".
65
+ filtfilt, Optional. If True, the filter is applied two times in reverse direction
66
+ to eliminate time lag. If False, the filter is applied only in forward
67
+ direction. Default is True.
68
+
69
+ Returns
70
+ -------
71
+ ts_f, A copy of the input data which each data being filtered.
72
+
73
+ Notes:
74
+ - This code was adapted from kineticstoolkit Thanks @felxi
75
+ """
76
+
77
+ sos = sgl.butter(order, fc, btype, analog=False, output="sos", fs=fs)
87
78
 
79
+ # Filter
80
+ if filtfilt:
81
+ ts_f = sgl.sosfiltfilt(sos, ts, axis=0)
82
+ else:
83
+ ts_f = sgl.sosfilt(sos,ts, axis=0)
88
84
 
85
+ return ts_f
biomechzoo/biomechzoo.py CHANGED
@@ -19,6 +19,7 @@ from biomechzoo.processing.renameevent_data import renameevent_data
19
19
  from biomechzoo.biomech_ops.normalize_data import normalize_data
20
20
  from biomechzoo.biomech_ops.phase_angle_data import phase_angle_data
21
21
  from biomechzoo.biomech_ops.continuous_relative_phase_data import continuous_relative_phase_data
22
+ from biomechzoo.biomech_ops.filter_data import filter_data
22
23
 
23
24
  class BiomechZoo:
24
25
  def __init__(self, in_folder, inplace=False, subfolders=None, name_contains=None, verbose=0):
@@ -346,28 +347,22 @@ class BiomechZoo:
346
347
  self._update_folder(out_folder, inplace, in_folder)
347
348
 
348
349
  def filter(self, ch, filt=None, out_folder=None, inplace=None):
349
- raise NotImplementedError
350
- # verbose = self.verbose
351
- # in_folder = self.in_folder
352
- # if inplace is None:
353
- # inplace = self.inplace
354
- #
355
- # # set filter type
356
- # if filt is None:
357
- # filt = {'type': 'butterworth',
358
- # 'order': 3,
359
- # 'pass': 'lowpass'}
360
- #
361
- # fl = engine(in_folder)
362
- # for f in fl:
363
- # batchdisp('filtering data in channels {} for {}'.format(ch, f), level=2, verbose=verbose)
364
- # data = zload(f)
365
- # data = filter_data(data, ch, filt)
366
- # zsave(f, data, inplace=inplace, root_folder=in_folder, out_folder=out_folder, verbose=verbose)
367
- # method_name = inspect.currentframe().f_code.co_name
368
- # batchdisp('{} computation complete for {} file(s)'.format(method_name, len(fl)), level=1, verbose=verbose)
369
- #
370
- # # Update self.folder after processing
371
- # self._update_folder(out_folder, inplace, in_folder)
372
-
350
+ """ filter data"""
351
+ start_time = time.time()
352
+ verbose = self.verbose
353
+ in_folder = self.in_folder
354
+ if inplace is None:
355
+ inplace = self.inplace
356
+ fl = engine(in_folder, name_contains=self.name_contains, subfolders=self.subfolders)
357
+ for f in fl:
358
+ if verbose:
359
+ batchdisp('filtering data for channel {} in {}'.format(ch, f), level=2, verbose=verbose)
360
+ data = zload(f)
361
+ data = filter_data(data, ch, filt)
362
+ zsave(f, data, inplace=inplace, out_folder=out_folder, root_folder=in_folder)
363
+ method_name = inspect.currentframe().f_code.co_name
364
+ batchdisp('{} process complete for {} file(s) in {:.2f} secs'.format(method_name, len(fl), time.time() - start_time),
365
+ level=1, verbose=verbose)
366
+ # Update self.folder after processing
367
+ self._update_folder(out_folder, inplace, in_folder)
373
368
 
@@ -8,10 +8,14 @@ def c3d2zoo_data(c3d_obj):
8
8
  - data (dict): Zoo dictionary with 'line' and 'event' fields per channel.
9
9
  """
10
10
  data = {}
11
-
11
+ data['zoosystem'] = set_zoosystem()
12
+ video_freq = None
13
+ analog_freq = None
14
+ # extract "video" data
12
15
  if 'points' in c3d_obj['data']:
13
16
  points = c3d_obj['data']['points'] # shape: (4, n_markers, n_frames)
14
- labels = c3d_obj['parameters']['POINT']['LABELS']['value']
17
+ labels = list(c3d_obj['parameters']['POINT']['LABELS']['value'])
18
+ video_freq = int(c3d_obj['parameters']['POINT']['RATE']['value'][0])
15
19
  for i, label in enumerate(labels):
16
20
  line_data = points[:3, i, :].T # shape: (frames, 3)
17
21
  data[label] = {
@@ -19,9 +23,32 @@ def c3d2zoo_data(c3d_obj):
19
23
  'event': {} # empty for now
20
24
  }
21
25
 
22
- params = c3d_obj['parameters']
23
- video_freq = c3d_obj['parameters']['POINT']['RATE']['value'][0]
24
- if 'EVENT' in params and 'TIMES' in params['EVENT']:
26
+ data['zoosystem']['Video']['Freq'] = video_freq
27
+ data['zoosystem']['Video']['Channels'] = labels
28
+
29
+ if 'analogs' in c3d_obj['data']:
30
+ analog_data = c3d_obj['data']['analogs'] # shape: (subframes, n_analog_channels, n_frames)
31
+ analog_labels = list(c3d_obj['parameters']['ANALOG']['LABELS']['value'])
32
+ analog_freq = int(c3d_obj['parameters']['ANALOG']['RATE']['value'][0])
33
+ # Flatten to 2D: (n_samples, n_channels)
34
+ # ezc3d stores analogs as subframes per frame, so we flatten across all
35
+ n_subframes, n_channels, n_frames = analog_data.shape
36
+ analog_data = analog_data.reshape(n_subframes * n_frames, n_channels)
37
+
38
+ for i, label in enumerate(analog_labels):
39
+ line_data = analog_data[:, i].reshape(-1, 1) # shape: (samples, 1)
40
+ data[label] = {
41
+ 'line': line_data,
42
+ 'event': {},
43
+ }
44
+
45
+ data['zoosystem']['Analog']['Freq'] = analog_freq
46
+ data['zoosystem']['Analog']['Channels'] = analog_labels
47
+
48
+ # extract event information
49
+ params = c3d_obj['parameters']
50
+ if 'EVENT' in params and 'TIMES' in params['EVENT']:
51
+ if 'points' in c3d_obj['data']:
25
52
  times_array = params['EVENT']['TIMES']['value']
26
53
  frames = times_array[1] # should be time depending on C3D file
27
54
 
@@ -61,8 +88,8 @@ def c3d2zoo_data(c3d_obj):
61
88
  else:
62
89
  data[labels[0]]['event'][key_name] = [frame-1, 0, 0] # remove 1 to follow python
63
90
 
64
- # todo add relevant meta data to zoosystem
65
- data['zoosystem'] = set_zoosystem()
66
- data['zoosystem']['Analog']['Freq'] = int(params['ANALOG']['RATE']['value'][0])
91
+ # add more zoosystem
92
+ if analog_freq is not None and video_freq is not None:
93
+ data['zoosystem']['AVR'] = analog_freq/video_freq
67
94
 
68
95
  return data
@@ -10,6 +10,7 @@ def mvnx2zoo_data(fl):
10
10
 
11
11
  # create zoo data dict
12
12
  data = {}
13
+ data['zoosystem'] = set_zoosystem()
13
14
 
14
15
  # extract joint angle data (All JOINTS may not exist in a given dataset)
15
16
  for key, val in JOINTS.items():
@@ -58,7 +59,6 @@ def is_valid_for_zoo(val):
58
59
 
59
60
  def _get_meta_info(fl, mvnx_file, data):
60
61
  # todo: add more, see mvnx_file object
61
- data['zoosystem'] = set_zoosystem(fl)
62
62
  data['zoosystem']['Video']['Freq'] = int(mvnx_file.frame_rate)
63
63
  data['zoosystem']['mvnx_version'] = mvnx_file.version
64
64
  data['zoosystem']['mvnx_configuration'] = mvnx_file.configuration
@@ -32,13 +32,15 @@ def table2zoo_data(csv_path, type='csv', skip_rows=0, freq=None):
32
32
  raise ValueError('type must be csv or parquet')
33
33
 
34
34
  # Use all columns
35
- data = df.iloc[:, 0:]
35
+ df_data = df.iloc[:, 0:]
36
36
 
37
37
  # assemble zoo data
38
- zoo_data = {}
39
- for ch in data.columns:
40
- zoo_data[ch] = {
41
- 'line': data[ch].values,
38
+ data = {}
39
+ data['zoosystem'] = set_zoosystem()
40
+
41
+ for ch in df_data.columns:
42
+ data[ch] = {
43
+ 'line': df_data[ch].values,
42
44
  'event': []
43
45
  }
44
46
 
@@ -59,14 +61,12 @@ def table2zoo_data(csv_path, type='csv', skip_rows=0, freq=None):
59
61
  freq = compute_sampling_rate_from_time(time_data)
60
62
 
61
63
  # add metadata
62
- # todo update zoosystem to match biomechzoo requirements
63
- zoo_data['zoosystem'] = set_zoosystem(csv_path)
64
- zoo_data['zoosystem']['Video']['Freq'] = freq
65
- zoo_data['zoosystem']['Analog']['Freq'] = 'None'
64
+ data['zoosystem']['Video']['Freq'] = freq
65
+ data['zoosystem']['Analog']['Freq'] = 'None'
66
66
  if 'version' in metadata:
67
- zoo_data['zoosystem']['collection_system_version'] = metadata['version']
67
+ data['zoosystem']['collection_system_version'] = metadata['version']
68
68
 
69
- return zoo_data
69
+ return data
70
70
 
71
71
 
72
72
  def _parse_metadata(header_lines):
@@ -1,4 +1,5 @@
1
1
  import copy
2
+ import numpy as np
2
3
 
3
4
  def explodechannel_data(data, channels=None):
4
5
  """ Explodes 3D channels (n x 3 arrays) into separate X, Y, Z channels.
@@ -6,13 +7,23 @@ def explodechannel_data(data, channels=None):
6
7
  Arguments:
7
8
  data (dict): Zoo data loaded from a file
8
9
  channels (list of str or None): Channels to explode.
9
- If None, explode all channels with 'line' shaped (n x 3).
10
+ If None, explode all channels with 'line' shaped (n x 3).
10
11
 
11
12
  Returns:
12
13
  data_new (dict): Modified zoo dictionary with exploded channels.
13
14
  """
14
-
15
15
  data_new = copy.deepcopy(data)
16
+
17
+ # Ensure zoosystem channel lists are Python lists
18
+ for sys in ['Video', 'Analog']:
19
+ if sys in data_new.get('zoosystem', {}):
20
+ ch_list = data_new['zoosystem'][sys].get('Channels', [])
21
+ if isinstance(ch_list, np.ndarray):
22
+ ch_list = ch_list.tolist()
23
+ # strip whitespace
24
+ ch_list = [str(ch).strip() for ch in ch_list]
25
+ data_new['zoosystem'][sys]['Channels'] = ch_list
26
+
16
27
  # Find default channels if none provided
17
28
  if channels is None:
18
29
  channels = []
@@ -39,9 +50,20 @@ def explodechannel_data(data, channels=None):
39
50
  key = ch + axis
40
51
  data_new[key] = {
41
52
  'line': line,
42
- 'event': data[ch]['event']}
53
+ 'event': data_new[ch]['event']}
43
54
 
44
55
  # Remove original channel
45
56
  del data_new[ch]
46
57
 
58
+ # --- Update zoosystem lists ---
59
+ for sys in ['Video', 'Analog']:
60
+ if sys in data_new['zoosystem']:
61
+ ch_list = data_new['zoosystem'][sys]['Channels']
62
+ if ch in ch_list:
63
+ # Remove original channel
64
+ ch_list = [c for c in ch_list if c != ch]
65
+ # Add exploded channels
66
+ ch_list.extend([ch + '_x', ch + '_y', ch + '_z'])
67
+ data_new['zoosystem'][sys]['Channels'] = ch_list
68
+
47
69
  return data_new
@@ -13,7 +13,6 @@ def removechannel_data(data, channels, mode='remove'):
13
13
  if mode not in ['remove', 'keep']:
14
14
  raise ValueError("mode must be 'remove' or 'keep'.")
15
15
 
16
- zoosystem = data.get('zoosystem', {})
17
16
  all_channels = [ch for ch in data if ch != 'zoosystem']
18
17
 
19
18
  # Check for missing channels
@@ -28,9 +27,20 @@ def removechannel_data(data, channels, mode='remove'):
28
27
  else:
29
28
  raise ValueError("Mode must be 'remove' or 'keep'.")
30
29
 
31
- # Build new zoo dictionary
32
- data_new = {'zoosystem': zoosystem}
33
- for ch in keep_channels:
34
- data_new[ch] = data[ch]
30
+ # --- Compute channels to remove ---
31
+ remove_channels = [ch for ch in all_channels if ch not in keep_channels]
35
32
 
36
- return data_new
33
+ if remove_channels:
34
+ print('Removing channels: {}'.format(remove_channels))
35
+ else:
36
+ print('No channels to remove')
37
+
38
+ # Remove from main data dict ---
39
+ for ch in remove_channels:
40
+ data.pop(ch, None)
41
+ if ch in data['zoosystem']['Video']['Channels']:
42
+ data['zoosystem']['Video']['Channels'] = [c for c in data['zoosystem']['Video']['Channels'] if c != ch]
43
+ if ch in data['zoosystem']['Analog']['Channels']:
44
+ data['zoosystem']['Analog']['Channels'] = [c for c in data['zoosystem']['Analog']['Channels'] if c != ch]
45
+
46
+ return data
biomechzoo/utils/zload.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from scipy.io import loadmat
2
2
  import os
3
+ import numpy as np
3
4
 
4
5
 
5
6
  def zload(filepath):
@@ -29,6 +30,16 @@ def zload(filepath):
29
30
  if 'data' in data:
30
31
  data = data['data']
31
32
 
33
+ # Convert Video and Analog channel arrays to Python lists
34
+ for sys in ['Video', 'Analog']:
35
+ if 'zoosystem' in data and sys in data['zoosystem']:
36
+ channels = data['zoosystem'][sys].get('Channels', [])
37
+ # Convert to list and strip spaces
38
+ if isinstance(channels, np.ndarray):
39
+ channels = channels.tolist()
40
+ channels = [str(ch).strip() for ch in channels]
41
+ data['zoosystem'][sys]['Channels'] = channels
42
+
32
43
  return data
33
44
 
34
45
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: biomechzoo
3
- Version: 0.4.10
3
+ Version: 0.4.11
4
4
  Summary: Python implementation of the biomechZoo toolbox
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/mcgillmotionlab/biomechzoo
@@ -1,21 +1,21 @@
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=A60kTUaMVWaKl-4ZUZpW8pOKLiZLEpbPYvHZe6urd5w,19800
4
+ biomechzoo/biomechzoo.py,sha256=N2qqUJrSvWueB6TEOJjONdqGjy1pv1PmNXA177mvjGs,19772
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
- biomechzoo/biomech_ops/filter_data.py,sha256=LZSlemUfbBTrqbo7miFubgTf9R4pr1kEgdmvljmNWdQ,1742
9
- biomechzoo/biomech_ops/filter_line.py,sha256=BuUFALIkmdFhmVocFaZ3aczy_efh2CY_qX9-5CoQZr0,2716
8
+ biomechzoo/biomech_ops/filter_data.py,sha256=Q9knW23Ft_WeWVCBjaIQ5GkKU0NYV4SdGiDZV8Fm-hM,1805
9
+ biomechzoo/biomech_ops/filter_line.py,sha256=XKUdRsxU5AO1gSldnwp3qNzsUUL8qpOpAMyQbEMo5uI,2600
10
10
  biomechzoo/biomech_ops/normalize_data.py,sha256=gpoUh6EpxpCprBdrSjmZ4UsAWgonJgD41XUJWD8Yo9Y,1299
11
11
  biomechzoo/biomech_ops/normalize_line.py,sha256=KUE8gEkIolA-VDFCdUuaskk-waO8jjJ20ZMZaS8Qha8,854
12
12
  biomechzoo/biomech_ops/phase_angle_data.py,sha256=_ekUBW2v3iC4UawcDL38ZZLYJmQsAmyqA61Q6_AMtmQ,1435
13
13
  biomechzoo/biomech_ops/phase_angle_line.py,sha256=p6osB17_3QQSyKLNojuc6nYhv-k0K6EUUH75EXu8ifc,1391
14
14
  biomechzoo/conversion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- biomechzoo/conversion/c3d2zoo_data.py,sha256=gnSCw99Hg5JLdrGezZNVZ6EHqiD6i-mpsLRtWmEa-Mg,2855
16
- biomechzoo/conversion/mvnx2zoo_data.py,sha256=O6WuKe_5fZJfd1gUe3oP9rND_i5P4WGEuu2MDvI3ypY,3560
15
+ biomechzoo/conversion/c3d2zoo_data.py,sha256=28JCj1Jpn7zsv2HjQdzH2F30jnGMwzmbBwYuRoWPJHo,4052
16
+ biomechzoo/conversion/mvnx2zoo_data.py,sha256=fZBFFYHuTC0gsH4tjB0S8yszVtc5Ki7KosKN68-zTkU,3558
17
17
  biomechzoo/conversion/opencap2zoo_data.py,sha256=n4bLsrJI0wTSzG5bgJcmxj1dp2plnUKFNRzcTIbmV1o,608
18
- biomechzoo/conversion/table2zoo_data.py,sha256=OLiRlYB8GqOwv4MAlmwhIkGLxgAvmrgUjTb-Irev4lU,3297
18
+ biomechzoo/conversion/table2zoo_data.py,sha256=H_r6RNt_MGwkOr4JH-M844DT_ivScQx_byc6DIZa5go,3210
19
19
  biomechzoo/mvn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  biomechzoo/mvn/load_mvnx.py,sha256=B4VGuidQ-5G_5E1t5vpU51Nb_Lu85_EOS_FmGZYjfX8,22499
21
21
  biomechzoo/mvn/main_mvnx.py,sha256=e1LasJQ9icyzjWnRCEcAWQq_-L13-mIzf7PzYA3QYDg,2394
@@ -25,9 +25,9 @@ biomechzoo/processing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
25
25
  biomechzoo/processing/add_channel_data.py,sha256=U1xLLBSnyJeeDWzgmHSxOz1hyguzuuDXxQCQ8IFoZkw,1955
26
26
  biomechzoo/processing/addchannel_data.py,sha256=rmnnlMRVkoMlQCR-nRg1jjh-hzMDt37Sx9fAmocrpqA,1953
27
27
  biomechzoo/processing/addevent_data.py,sha256=L9xaoP0yBvaGbseotxpGCVqjr-eSV-gpnQaeRTz4VKE,1631
28
- biomechzoo/processing/explodechannel_data.py,sha256=AC2BOEw1tXcgJ1WuYWSE-yToS-q9XGdgkOHS4D3iUFo,1490
28
+ biomechzoo/processing/explodechannel_data.py,sha256=ceyXfcCmeNqj4p0zCksVdrnmsYR4t-JHLIyv3JlfNpU,2484
29
29
  biomechzoo/processing/partition_data.py,sha256=XF8dSqvHGpqsT-Q4i6qpoOajAT4LYjP-PJ6KbpoCfFc,2018
30
- biomechzoo/processing/removechannel_data.py,sha256=ndZcbWJRDvd7drlahGaq8MseT-rsxiu7pgdMtA1cTlo,1218
30
+ biomechzoo/processing/removechannel_data.py,sha256=uO7jjuHapRr2CGLsrvYQ1eJLvb1y_8KR6Ct4M6TPALA,1740
31
31
  biomechzoo/processing/renamechannel_data.py,sha256=5lEnWJknAwnJYXDlwO6cFe7C8ct5o42tTHW0Y4GeIL4,2210
32
32
  biomechzoo/processing/renameevent_data.py,sha256=9w7C_fQOsQ8XbdTr_hrg_iQe51oDczq2Rj7yJLyYG0M,2215
33
33
  biomechzoo/processing/split_trial_by_gait_cycle.py,sha256=maMUwumSlFLFc5LHdNdBO9JCoT06aaLbpdp43dgowDA,1684
@@ -40,12 +40,12 @@ biomechzoo/utils/get_split_events.py,sha256=xNhEuG6Yqsr1bjWIBHLbepfX-fcqcCYIXZzS
40
40
  biomechzoo/utils/set_zoosystem.py,sha256=oubEc3fy0x6y-AlqQWL3v7QYJA951jU9CRnlJ9ikwQo,1750
41
41
  biomechzoo/utils/split_trial.py,sha256=Fumz_ZukNBNtPauUhCge5EAHkg05dYDhA1_njQw0lHE,886
42
42
  biomechzoo/utils/version.py,sha256=JIXDUuOcaJiZv9ruMP6PtWvJBh4sP0D5kAvlqPiZK_I,130
43
- biomechzoo/utils/zload.py,sha256=FPT6_-gwaOOqOckjgPRfnKEVKMsmNVIcenmQZF2KOvo,1535
43
+ biomechzoo/utils/zload.py,sha256=_qmbQpiEwUNRcB86aS6dHiytOrz1ZXJVjYkk8h5fg8s,2039
44
44
  biomechzoo/utils/zplot.py,sha256=WVA8aCy1Pqy_bo_HXab9AmW-cBd8J8MPX2LAOd6dznU,1512
45
45
  biomechzoo/utils/zsave.py,sha256=wnRNuDxQc8bwCji4UrfoGjYrSZmka4eaDxQ5rMa78pE,1759
46
- biomechzoo-0.4.10.dist-info/licenses/LICENSE,sha256=Fsz62nrgRORre3A1wNXUDISaHoostodMvocRPDdXc9w,1076
47
- biomechzoo-0.4.10.dist-info/METADATA,sha256=P1enuQWmGLcQUQ5Q_6jy1e8o641FncZId2M5wUs1P9Y,1580
48
- biomechzoo-0.4.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
- biomechzoo-0.4.10.dist-info/entry_points.txt,sha256=VdryUUiwwvx0WZxrgmMrsyfe5Z1jtyaxdXOi0zWHOqk,41
50
- biomechzoo-0.4.10.dist-info/top_level.txt,sha256=nJEtuEZ9UPoN3EOR-BJ6myevEu7B5quWsWhaM_YeQpw,20
51
- biomechzoo-0.4.10.dist-info/RECORD,,
46
+ biomechzoo-0.4.11.dist-info/licenses/LICENSE,sha256=Fsz62nrgRORre3A1wNXUDISaHoostodMvocRPDdXc9w,1076
47
+ biomechzoo-0.4.11.dist-info/METADATA,sha256=IAMgsVbJdayIURX7FwWfT5XNsBy4JfvOnqbTu-jlbYE,1580
48
+ biomechzoo-0.4.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
+ biomechzoo-0.4.11.dist-info/entry_points.txt,sha256=VdryUUiwwvx0WZxrgmMrsyfe5Z1jtyaxdXOi0zWHOqk,41
50
+ biomechzoo-0.4.11.dist-info/top_level.txt,sha256=nJEtuEZ9UPoN3EOR-BJ6myevEu7B5quWsWhaM_YeQpw,20
51
+ biomechzoo-0.4.11.dist-info/RECORD,,