biomechzoo 0.4.5__tar.gz → 0.4.8__tar.gz

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.

Files changed (56) hide show
  1. {biomechzoo-0.4.5/src/biomechzoo.egg-info → biomechzoo-0.4.8}/PKG-INFO +1 -1
  2. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/pyproject.toml +1 -1
  3. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/conversion/c3d2zoo_data.py +7 -4
  4. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/conversion/csv2zoo_data.py +8 -4
  5. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/conversion/mvnx2zoo_data.py +8 -6
  6. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/partition_data.py +10 -4
  7. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/engine.py +16 -5
  8. biomechzoo-0.4.8/src/biomechzoo/utils/set_zoosystem.py +66 -0
  9. biomechzoo-0.4.8/src/biomechzoo/utils/version.py +5 -0
  10. {biomechzoo-0.4.5 → biomechzoo-0.4.8/src/biomechzoo.egg-info}/PKG-INFO +1 -1
  11. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo.egg-info/SOURCES.txt +2 -0
  12. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/LICENSE +0 -0
  13. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/README.md +0 -0
  14. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/setup.cfg +0 -0
  15. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/__init__.py +0 -0
  16. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/__init__.py +0 -0
  17. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/__main__.py +0 -0
  18. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/__init__.py +0 -0
  19. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/continuous_relative_phase_data.py +0 -0
  20. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/continuous_relative_phase_line.py +0 -0
  21. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/filter_data.py +0 -0
  22. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/filter_line.py +0 -0
  23. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/normalize_data.py +0 -0
  24. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/normalize_line.py +0 -0
  25. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/phase_angle_data.py +0 -0
  26. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/phase_angle_line.py +0 -0
  27. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomechzoo.py +0 -0
  28. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/conversion/__init__.py +0 -0
  29. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/conversion/opencap2zoo_data.py +0 -0
  30. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/mvn/__init__.py +0 -0
  31. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/mvn/load_mvnx.py +0 -0
  32. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/mvn/main_mvnx.py +0 -0
  33. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/mvn/mvn.py +0 -0
  34. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/mvn/mvnx_file_accessor.py +0 -0
  35. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/__init__.py +0 -0
  36. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/add_channel_data.py +0 -0
  37. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/addchannel_data.py +0 -0
  38. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/addevent_data.py +0 -0
  39. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/explodechannel_data.py +0 -0
  40. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/removechannel_data.py +0 -0
  41. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/renamechannel_data.py +0 -0
  42. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/renameevent_data.py +0 -0
  43. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/split_trial_by_gait_cycle.py +0 -0
  44. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/__init__.py +0 -0
  45. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/batchdisp.py +0 -0
  46. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/compute_sampling_rate_from_time.py +0 -0
  47. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/findfield.py +0 -0
  48. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/get_split_events.py +0 -0
  49. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/split_trial.py +0 -0
  50. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/zload.py +0 -0
  51. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/zplot.py +0 -0
  52. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/zsave.py +0 -0
  53. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo.egg-info/dependency_links.txt +0 -0
  54. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo.egg-info/entry_points.txt +0 -0
  55. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo.egg-info/requires.txt +0 -0
  56. {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: biomechzoo
3
- Version: 0.4.5
3
+ Version: 0.4.8
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,6 +1,6 @@
1
1
  [project]
2
2
  name = "biomechzoo"
3
- version = "0.4.5"
3
+ version = "0.4.8"
4
4
  description = "Python implementation of the biomechZoo toolbox"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11,<3.12" # max version for opencap-process tools is 3.11
@@ -1,3 +1,5 @@
1
+ from biomechzoo.utils.set_zoosystem import set_zoosystem
2
+
1
3
  def c3d2zoo_data(c3d_obj):
2
4
  """
3
5
  Converts an ezc3d C3D object to zoo format.
@@ -21,7 +23,7 @@ def c3d2zoo_data(c3d_obj):
21
23
  video_freq = c3d_obj['parameters']['POINT']['RATE']['value'][0]
22
24
  if 'EVENT' in params and 'TIMES' in params['EVENT']:
23
25
  times_array = params['EVENT']['TIMES']['value']
24
- frames = times_array[1] # second row = frames (or time, depending on C3D file)
26
+ frames = times_array[1] # should be time depending on C3D file
25
27
 
26
28
  # Extract sides, types, subjects
27
29
  contexts = params['EVENT']['CONTEXTS']['value'] if 'CONTEXTS' in params['EVENT'] else ['']
@@ -55,11 +57,12 @@ def c3d2zoo_data(c3d_obj):
55
57
 
56
58
  # Place in correct channel
57
59
  if 'SACR' in data:
58
- data['SACR']['event'][key_name] = [frame, 0, 0]
60
+ data['SACR']['event'][key_name] = [frame-1, 0, 0] # remove 1 to follow python
59
61
  else:
60
- data[labels[0]]['event'][key_name] = [frame, 0, 0]
62
+ data[labels[0]]['event'][key_name] = [frame-1, 0, 0] # remove 1 to follow python
61
63
 
62
64
  # todo add relevant meta data to zoosystem
63
- data['zoosystem'] = params['EVENT']
65
+ data['zoosystem'] = set_zoosystem()
66
+ data['zoosystem']['Analog']['Freq'] = int(params['ANALOG']['RATE']['value'][0])
64
67
 
65
68
  return data
@@ -2,10 +2,11 @@ import pandas as pd
2
2
  import os
3
3
  import re
4
4
 
5
+ from biomechzoo.utils.set_zoosystem import set_zoosystem
5
6
  from biomechzoo.utils.compute_sampling_rate_from_time import compute_sampling_rate_from_time
6
7
 
7
8
 
8
- def csv2zoo_data(csv_path, type='csv',skip_rows=0, freq=None):
9
+ def csv2zoo_data(csv_path, type='csv', skip_rows=0, freq=None):
9
10
  # todo: check calculation for sampling rate
10
11
 
11
12
  # Read header lines until 'endheader'
@@ -51,13 +52,16 @@ def csv2zoo_data(csv_path, type='csv',skip_rows=0, freq=None):
51
52
  if freq is None:
52
53
  time_col = [col for col in df.columns if 'time' in col.lower()]
53
54
  if time_col is not None:
54
- time_data = df[time_col].to_numpy()[:,0]
55
+ time_data = df[time_col].to_numpy()[:, 0]
55
56
  freq = compute_sampling_rate_from_time(time_data)
56
57
 
57
58
  # add metadata
58
59
  # todo update zoosystem to match biomechzoo requirements
59
- zoo_data['zoosystem'] = metadata
60
- zoo_data['zoosystem']['Freq'] = freq
60
+ zoo_data['zoosystem'] = set_zoosystem(csv_path)
61
+ zoo_data['zoosystem']['Video']['Freq'] = freq
62
+ zoo_data['zoosystem']['Analog']['Freq'] = 'None'
63
+ if 'version' in metadata:
64
+ zoo_data['zoosystem']['collection_system_version'] = metadata['version']
61
65
 
62
66
  return zoo_data
63
67
 
@@ -1,6 +1,7 @@
1
1
  import numpy as np
2
2
  from biomechzoo.mvn.load_mvnx import load_mvnx
3
3
  from biomechzoo.mvn.mvn import JOINTS, SEGMENTS
4
+ from biomechzoo.utils.set_zoosystem import set_zoosystem
4
5
 
5
6
  def mvnx2zoo_data(fl):
6
7
  """ loads mvnx file from xsens"""
@@ -37,10 +38,11 @@ def mvnx2zoo_data(fl):
37
38
  data = _get_foot_strike_events(mvnx_file, data)
38
39
 
39
40
  # add meta information
40
- data = _get_meta_info(mvnx_file, data)
41
+ data = _get_meta_info(fl, mvnx_file, data)
41
42
 
42
43
  return data
43
44
 
45
+
44
46
  def is_valid_for_zoo(val):
45
47
  """
46
48
  Returns True if the value is valid for a MATLAB-compatible zoo structure.
@@ -53,13 +55,13 @@ def is_valid_for_zoo(val):
53
55
  return False
54
56
  return True
55
57
 
56
- def _get_meta_info(mvnx_file, data):
58
+
59
+ def _get_meta_info(fl, mvnx_file, data):
57
60
  # todo: add more, see mvnx_file object
58
- data['zoosystem'] = {}
59
- data['zoosystem']['Video'] = {}
61
+ data['zoosystem'] = set_zoosystem(fl)
60
62
  data['zoosystem']['Video']['Freq'] = int(mvnx_file.frame_rate)
61
- data['zoosystem']['Version'] = mvnx_file.version
62
- data['zoosystem']['configuration'] = mvnx_file.configuration
63
+ data['zoosystem']['mvnx_version'] = mvnx_file.version
64
+ data['zoosystem']['mvnx_configuration'] = mvnx_file.configuration
63
65
  data['zoosystem']['recording_date'] = mvnx_file.recording_date
64
66
  data['zoosystem']['original_file_name'] = mvnx_file.original_file_name
65
67
  data['zoosystem']['frame_count'] = mvnx_file.frame_count
@@ -10,11 +10,19 @@ def partition_data(data, evt_start, evt_end):
10
10
  e1, _ = findfield(data, evt_start)
11
11
  e2, _ = findfield(data, evt_end)
12
12
 
13
+ if e1 is None or e2 is None or len(e1) == 0 or len(e2) == 0:
14
+ raise ValueError(f"Event not found: evt_start='{evt_start}' returned {e1}, evt_end='{evt_end}' returned {e2}")
15
+
13
16
  data_new = copy.deepcopy(data)
14
17
  for ch_name, ch_data in data_new.items():
15
18
  if ch_name != 'zoosystem':
19
+ print(ch_name)
20
+ line = ch_data['line']
16
21
  try:
17
- data_new[ch_name]['line'] = ch_data[e1[0]:e2[0],]
22
+ if line.ndim == 1:
23
+ data_new[ch_name]['line'] = line[e1[0]:e2[0]]
24
+ else:
25
+ data_new[ch_name]['line'] = line[e1[0]:e2[0], :]
18
26
  except (IndexError, ValueError) as e:
19
27
  # IndexError: if e1[0]:e2[0] goes beyond the available indices
20
28
  # ValueError: less likely, but may arise with shape mismatches
@@ -24,9 +32,7 @@ def partition_data(data, evt_start, evt_end):
24
32
  events = ch_data['event']
25
33
  for event_name, value in events.items():
26
34
  original_frame = value[0]
27
- if original_frame == 1:
28
- continue # leave index 1 as is (per MATLAB version)
29
- elif original_frame == 999:
35
+ if original_frame == 999:
30
36
  continue # do not change outlier markers
31
37
  else:
32
38
  new_frame = original_frame - e1[0] + 1
@@ -22,7 +22,7 @@ def engine(root_folder, extension='.zoo', subfolders=None, name_contains=None, v
22
22
  subfolders (list or str, optional): List of folder names to restrict the search to.
23
23
  Only files inside these folders (or their subfolders) are included.
24
24
  If None, search all subfolders.
25
- name_contains (str, optional): Substring that must be present in the filename
25
+ name_contains (str, or list; optional): Substring that must be present in the filename
26
26
  (case-insensitive). If None, no substring filtering is applied.
27
27
  verbose (bool, optional): If true, displays additional information to user
28
28
  Returns:
@@ -33,10 +33,14 @@ def engine(root_folder, extension='.zoo', subfolders=None, name_contains=None, v
33
33
  if type(subfolders) is str:
34
34
  subfolders = [subfolders]
35
35
 
36
+ # check format of name_contants (str or list)
37
+ if name_contains is not None:
38
+ if type(name_contains) is str:
39
+ name_contains = [name_contains]
40
+
36
41
  matched_files = []
37
42
 
38
43
  subfolders_set = set(subfolders) if subfolders else None
39
-
40
44
  for dirpath, _, filenames in os.walk(root_folder):
41
45
  if subfolders_set is not None:
42
46
  rel_path = os.path.relpath(dirpath, root_folder)
@@ -51,9 +55,16 @@ def engine(root_folder, extension='.zoo', subfolders=None, name_contains=None, v
51
55
  for file in filenames:
52
56
  if not file.lower().endswith(extension.lower()):
53
57
  continue
54
- if name_contains and name_contains.lower() not in file.lower():
55
- continue
56
- matched_files.append(os.path.join(dirpath, file))
58
+ full_path = os.path.join(dirpath, file)
59
+ if name_contains is not None:
60
+ match = False
61
+ for name_contain in name_contains:
62
+ if name_contain and name_contain.lower() in full_path.lower(): # <-- check full path
63
+ match = True
64
+ break
65
+ if not match:
66
+ continue
67
+ matched_files.append(full_path)
57
68
 
58
69
  if verbose:
59
70
  print("Found {} {} files in subfolders named {} with substring {}:".format(len(matched_files), extension, subfolders, name_contains))
@@ -0,0 +1,66 @@
1
+ import numpy as np
2
+ from pathlib import Path
3
+ from biomechzoo.utils.version import get_biomechzoo_version
4
+
5
+
6
+ def set_zoosystem(fl=None):
7
+ """
8
+ Create the 'zoosystem' branch for data being imported to BiomechZoo.
9
+
10
+ Args:
11
+ fl: str
12
+ Path to the source file (e.g., C3D or CSV).
13
+
14
+ Returns:
15
+ zoosystem: dict
16
+ Dictionary containing default BiomechZoo system parameters.
17
+ """
18
+
19
+ # Default top-level fields
20
+ zch = ['Analog', 'Anthro', 'AVR', 'CompInfo', 'SourceFile',
21
+ 'Units', 'Version', 'Video']
22
+
23
+ # Initialize top-level dict
24
+ zoosystem = {key: {} for key in zch}
25
+
26
+ # Section-specific defaults
27
+ section = ['Video', 'Analog']
28
+ for sec in section:
29
+ zoosystem[sec]['Channels'] = []
30
+ zoosystem[sec]['Freq'] = []
31
+ zoosystem[sec]['Indx'] = []
32
+ zoosystem[sec]['ORIGINAL_START_FRAME'] = []
33
+ zoosystem[sec]['ORIGINAL_END_FRAME'] = []
34
+ zoosystem[sec]['CURRENT_START_FRAME'] = []
35
+ zoosystem[sec]['CURRENT_END_FRAME'] = []
36
+
37
+ # Processing and AVR defaults
38
+ zoosystem['Processing'] = ''
39
+ zoosystem['AVR'] = 0
40
+
41
+ # Force plates defaults
42
+ zoosystem['Analog']['FPlates'] = {
43
+ 'CORNERS': [],
44
+ 'NUMUSED': 0,
45
+ 'LOCALORIGIN': [],
46
+ 'LABELS': []
47
+ }
48
+
49
+ # Version and source file
50
+ zoosystem['Version'] = get_biomechzoo_version()
51
+ if fl is None:
52
+ zoosystem['SourceFile'] = 'None' # ensure string
53
+ else:
54
+ zoosystem['SourceFile'] = str(Path(fl)) # ensure string
55
+
56
+ # Units defaults
57
+ zoosystem['Units'] = {
58
+ 'Markers': 'mm',
59
+ 'Angles': 'deg',
60
+ 'Forces': 'N',
61
+ 'Moments': 'Nmm',
62
+ 'Power': 'W/kg',
63
+ 'Scalars': 'mm'
64
+ }
65
+
66
+ return zoosystem
@@ -0,0 +1,5 @@
1
+ from importlib.metadata import version as get_version
2
+
3
+
4
+ def get_biomechzoo_version() -> str:
5
+ return get_version("biomechzoo")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: biomechzoo
3
- Version: 0.4.5
3
+ Version: 0.4.8
4
4
  Summary: Python implementation of the biomechZoo toolbox
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/mcgillmotionlab/biomechzoo
@@ -46,7 +46,9 @@ src/biomechzoo/utils/compute_sampling_rate_from_time.py
46
46
  src/biomechzoo/utils/engine.py
47
47
  src/biomechzoo/utils/findfield.py
48
48
  src/biomechzoo/utils/get_split_events.py
49
+ src/biomechzoo/utils/set_zoosystem.py
49
50
  src/biomechzoo/utils/split_trial.py
51
+ src/biomechzoo/utils/version.py
50
52
  src/biomechzoo/utils/zload.py
51
53
  src/biomechzoo/utils/zplot.py
52
54
  src/biomechzoo/utils/zsave.py
File without changes
File without changes
File without changes
File without changes