Skip to main content

ibo-biomech

A Python library for loading, processing, and converting biomechanical motion capture data. Supports C3D files, lab-specific HDF5 files, and OpenSim formats (.trc, .mot).

Full API documentation will be available as a generated docs site in a future release.

Installation

pip install ibo-biomech

Imports

Everything commonly used is available directly from the top-level package:

from ibo_biomech import C3DHandler, H5Handler, FileConverter
from ibo_biomech import MarkerData, ForceData, AnalogData, TrialData, Subject

You can also import from submodules directly:

from ibo_biomech.handlers import C3DHandler, H5Handler
from ibo_biomech.containers import MarkerData, ForceData, AnalogData, TrialData, Subject
from ibo_biomech.biomech_io import FileConverter

Loading an HDF5 File

H5Handler reads lab HDF5 files and returns a TrialData object.

from ibo_biomech import H5Handler

handler = H5Handler("trial.h5")
trial = handler.load_data()   # returns TrialData

print(trial.trial_name)
print(trial.marker_labels)
print(trial.analog_labels)
print(trial.marker_rate)

# Access individual channels
marker = trial.markers["L_Ankle"]
force  = trial.forces["forceplate_0"]
emg    = trial.analogs["EMG_VastusLat"]

Saving processed data back to HDF5

The handler uses the original file as a template and overwrites only the data arrays, preserving all other groups (events, rigid bodies, etc.).

handler.save_data(trial, out_path="trial_processed.h5")

File Conversion

FileConverter provides static methods for converting between formats. No instance needed.

from ibo_biomech import FileConverter

# C3D → HDF5
FileConverter.c3d_to_h5("trial.c3d", "trial.h5")

# HDF5 → OpenSim TRC (markers) and MOT (forces)
FileConverter.h5_to_trc("trial.h5", "trial.trc")
FileConverter.h5_to_mot("trial.h5", "trial.mot")
FileConverter.h5_to_opensim("trial.h5", "trial.mot", "trial.trc")

# C3D → OpenSim (direct, no intermediate file kept)
FileConverter.c3d_to_trc("trial.c3d", "trial.trc")
FileConverter.c3d_to_mot("trial.c3d", "trial.mot")
FileConverter.c3d_to_opensim("trial.c3d", "trial.mot", "trial.trc")

All conversion methods apply a default -90° rotation around the X axis and convert units to metres to match OpenSim's coordinate system. You can override these:

FileConverter.h5_to_trc("trial.h5", "trial.trc", axis='x', angle=-90, convert_to_meters=True)

Working with TrialData

TrialData is the central data container returned by H5Handler.load_data().

trial = H5Handler("trial.h5").load_data()

# Convenience accessors
print(trial.get_marker_names())
print(trial.get_force_names())
print(trial.get_analog_names())

marker = trial.get_marker("R_Knee")
fp     = trial.get_force("forceplate_0")
emg    = trial.get_analog("EMG_VastusLat")
emg2   = trial.get_analog_by_channel(3)

# Add a virtual marker
import numpy as np
mid = MarkerData(
    name="MidKnee",
    x=(trial.markers["R_Knee"].x + trial.markers["L_Knee"].x) / 2,
    y=(trial.markers["R_Knee"].y + trial.markers["L_Knee"].y) / 2,
    z=(trial.markers["R_Knee"].z + trial.markers["L_Knee"].z) / 2,
    sampling_rate=trial.marker_rate
)
trial.add_marker(mid)

# Filter all channels with separate cutoffs per data type
trial.lowpass_filter(cutoff_marker=10, cutoff_analog=500, cutoff_force=50)

Signal Processing

All filtering and processing methods modify data in-place.

Filtering markers

marker = trial.markers["R_Knee"]
marker.lowpass_filter(cutoff=10.0, order=4)   # 4th-order Butterworth
marker.highpass_filter(cutoff=20.0, order=4)

Filtering force data

fp = trial.forces["forceplate_0"]
fp.lowpass_filter(cutoff=50.0, order=4)
fp.highpass_filter(cutoff=10.0, order=4)
fp.filter_low_forces(threshold=10.0)  # zero out frames where |F| < 10 N
fp.downsample(factor=4)

Filtering analog signals

emg = trial.analogs["EMG_VastusLat"]
emg.lowpass_filter(cutoff=500.0)
emg.highpass_filter(cutoff=20.0)

Filtering everything at once via C3DHandler

handler.lowpass_filter_all(cutoff=10.0, order=4)   # markers + forces
handler.lowpass_filter_markers(cutoff=10.0)
handler.lowpass_filter_force(cutoff=50.0)

Cropping

# Crop a single channel
trial.markers["R_Knee"].crop(start_idx=100, end_idx=500)

# Crop everything in a TrialData at once
trial.crop(start_idx=100, end_idx=500)

Rotation

Rotates all position data (markers, forces, CoP) around the specified axis.

trial.rotate_data(axis='x', angle_deg=-90)

# Or on an individual marker
marker.rotate(axis='x', angle_deg=90)

# Or on a TrialData (markers and forces)
trial.rotate_markers(axis='x', angle_deg=-90)
trial.rotate_forces(axis='x', angle_deg=-90)

Unit conversion

trial.convert_to_meters()                 # trial-level (mm or cm → m)

marker.convert_units('m')                   # single marker
trial.convert_marker_units('m')             # all markers in TrialData
trial.convert_force_units('m')              # CoP and moments in TrialData
trial.convert_units('m')                    # markers + forces together

Plotting

All container types have a .plot() method for quick inspection:

trial.markers["R_Knee"].plot()
trial.forces["forceplate_0"].plot()
trial.analogs["EMG_VastusLat"].plot()

Loading a C3D File

C3DHandler reads a C3D file and parses it into typed container objects.

from ibo_biomech import C3DHandler

handler = C3DHandler("trial.c3d")
handler.load_data()

# Markers: dict of {name: MarkerData}
print(handler.markers.keys())

# Force plates: dict of {"forceplate_0": ForceData, ...}
print(handler.forces.keys())

# Raw analog signals: dict of {name: AnalogData}
print(handler.analogs.keys())

Accessing marker data

marker = handler.markers["R_Knee"]

print(marker.x)            # np.ndarray, position along X axis
print(marker.y)
print(marker.z)
print(marker.sampling_rate)
print(marker.unit)         # e.g. 'mm'

traj = marker.get_trajectory()  # (3, n_samples) array

Accessing force plate data

fp = handler.forces["forceplate_0"]

print(fp.Fx)   # np.ndarray — force along X
print(fp.Fy)
print(fp.Fz)
print(fp.cop_x, fp.cop_y, fp.cop_z)  # center of pressure
print(fp.Mx, fp.My, fp.Mz)           # moments
print(fp.sampling_rate)

Accessing analog signals

emg = handler.analogs["EMG_VastusLat"]
print(emg.data)          # np.ndarray
print(emg.sampling_rate)
print(emg.unit)

Exporting directly from C3DHandler

If you have already loaded and processed a C3DHandler (e.g. filtered or rotated), you can export without going through HDF5:

handler = C3DHandler("trial.c3d")
handler.load_data()

# Rotate and export to TRC + MOT in one call
handler.process_and_export("output/trial", axis='x', angle_deg=-90, convert_to_meters=True)
# Writes: output/trial.trc and output/trial.mot

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ibo_biomech-0.1.10.tar.gz (84.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ibo_biomech-0.1.10-py3-none-any.whl (38.4 kB view details)

Uploaded Python 3

File details

Details for the file ibo_biomech-0.1.10.tar.gz.

File metadata

  • Download URL: ibo_biomech-0.1.10.tar.gz
  • Upload date:
  • Size: 84.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ibo_biomech-0.1.10.tar.gz
Algorithm Hash digest
SHA256 47f6052c7de294d7bf0a7206371911fe6d97804808a28fb6908c43bd937834c0
MD5 e41f667845065bc1006f34e03236c0c6
BLAKE2b-256 29ac966d950a5fd3df602a263a14d3df21b8a2f7a2c86d1ff3021a297939252c

See more details on using hashes here.

Provenance

The following attestation bundles were made for ibo_biomech-0.1.10.tar.gz:

Publisher: publish.yml on Talhauzumcu/ibo-biomech

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ibo_biomech-0.1.10-py3-none-any.whl.

File metadata

  • Download URL: ibo_biomech-0.1.10-py3-none-any.whl
  • Upload date:
  • Size: 38.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ibo_biomech-0.1.10-py3-none-any.whl
Algorithm Hash digest
SHA256 6b38bb59f21f2d81d482e9f13836b679fd65b09f06c42dae1bddb3e5505b544e
MD5 af897aca2b6b6034a5805a6dd4e579f1
BLAKE2b-256 00f24fb5594e15685190084929655034d170fbebc0152aa190a4b3531fc1b4c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for ibo_biomech-0.1.10-py3-none-any.whl:

Publisher: publish.yml on Talhauzumcu/ibo-biomech

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.0

2 files

0.2.13

2 files

0.2.12

2 files

0.2.11

2 files

0.2.10

2 files

0.2.9

2 files

0.2.8

2 files

0.2.7

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.2

2 files

0.2.0

2 files

This release

0.1.10 This release

2 files

0.1.9

2 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page