Skip to main content

ibo-biomech

Python tools for motion-capture workflows: load C3D and the institute's HDF5 format, process markers and signals, export OpenSim inputs, and inspect IK/ID results. Both file handlers return a TrialData containing named channels.

The package is in alpha. See the current limitations and development priorities for the status of HDF5 saving, force resampling, and coordinate assumptions.

Install

python -m pip install ibo-biomech

For this checkout, including the latest local changes:

python -m pip install -e .

Plotting methods require matplotlib, installed separately:

python -m pip install matplotlib

OpenSim is only required to run scaling, inverse kinematics, or inverse dynamics. File conversion and result containers work without it. Follow the OpenSim Python setup instructions and verify import opensim in the same Python environment.

Try a complete example without a data file

This example creates a marker sampled at 100 Hz, filters it, crops a copy, and exports a DataFrame with timestamps. The cutoff is illustrative; choose processing parameters for your recording and analysis.

from copy import deepcopy
import numpy as np
from ibo_biomech import MarkerData, TrialData

time = np.arange(300) / 100.0
marker = MarkerData(
    name="R_Ankle",
    x=1000.0 + 50.0 * np.sin(2 * np.pi * time),
    y=np.zeros_like(time),
    z=np.full_like(time, 100.0),
    unit="mm",
    sampling_rate=100.0,
    time=time,
)
trial = TrialData(name="demo", markers={marker.name: marker})
processed = deepcopy(trial)
processed.lowpass_filter_markers(cutoff_freq=6.0, order=4)
processed.crop("markers", start_idx=50, end_idx=200)

frame = processed.as_df(processed.markers)
frame.insert(0, "time", processed.markers["R_Ankle"].time)
print(processed.name, frame.shape)  # demo (150, 4)
# processed.markers["R_Ankle"].plot()  # requires matplotlib

Filtering, cropping, rotation, and unit conversion modify containers in place. Use deepcopy() to keep a raw trial. Marker arithmetic returns a new marker; EMGData.process_emg() returns an envelope, while also cleaning NaNs in raw data.

Load a recording

Replace the paths with your files. HDF5 support is specific to the institute's schema, not arbitrary .h5 files.

from ibo_biomech import C3DHandler, H5Handler

trial = C3DHandler("walking.c3d").load_data()
# Alternatively:
# trial = H5Handler("walking.h5").load_data()

print(trial.name)
print(trial.get_marker_names())
print(trial.get_force_names())
print(trial.get_analog_names())
print(trial.marker_rate, trial.analog_rate, trial.force_rate)

# Use labels present in your recording:
# marker = trial.markers["R_Ankle"]
# plate = trial.forces["forceplate_0"]
# analog = trial.get_analog_by_channel(3)

A C3D handler's returned trial is a separate copy. Processing that trial does not update the handler's raw C3D structure. For processed TRC/MOT output, use the export tutorial.

Current processing API

Operation Method Notes
Filter markers trial.lowpass_filter_markers(cutoff_freq=6.0) Frequency in Hz; no automatic gap filling.
Filter analogs trial.lowpass_filter_analogs(cutoff_freq=100.0) Cutoff must be below every affected channel's Nyquist frequency.
Filter forces trial.lowpass_filter_forces(cutoff_freq=20.0) Also processes Tz and plate position in the current implementation.
Filter EMG channels trial.lowpass_filter_emgs(cutoff_freq=10.0) Filters raw EMG; this is not the envelope pipeline.
Filter one channel marker.lowpass_filter(cutoff=6.0) Channel methods use cutoff; trial methods use cutoff_freq.
Fill marker gaps marker.clean_nan() Linear interpolation of interior NaNs; inspect gaps first.
Crop one data type trial.crop("markers", 100, 200) End index excluded; indices belong to the selected data type.
Rotate markers trial.rotate_markers(axis="x", angle_deg=-90) Requires the correct lab-to-model transform.
Rotate forces trial.rotate_forces(axis="x", angle_deg=-90) See HDF5 geometry limitation before using loaded HDF5 forces.
Convert units trial.convert_units("m") Supports mm ↔ m; force magnitudes remain unchanged.
Select EMG channels trial.parse_EMG_data([3]) Channel indices are zero-based for C3D imports.
Attach results trial.attach_IK_results("ik.mot") / trial.attach_ID_results("id.sto") Results have named Data columns.

There is no single trial-wide lowpass_filter(), rotate_data(), or convert_to_meters() method. To crop the same interval across sampling rates, select indices using each channel's time vector; see the processing tutorial.

File conversion and results

FileConverter.c3d_to_h5(c3d_path, h5_path, **metadata) writes an HDF5 file in acquisition coordinates and units. It currently requires analog channels.

OpenSim converters are h5_to_trc, h5_to_mot, h5_to_opensim, c3d_to_trc, c3d_to_mot, and c3d_to_opensim. Their defaults are axis="x", angle=-90, and convert_to_meters=True. Those defaults describe one lab convention. The combined converters accept (source_path, mot_path, trc_path).

The current HDF5 geometry mismatch also affects the convenience force converters. The export tutorial shows a working route from a processed C3D trial to TRC/MOT using write_trc() and write_mot().

from ibo_biomech import IKResults, IDResults

ik = IKResults(filepath="walking_IK.mot")
ik.to_rad()
print(ik["hip_flexion_r"].data)
ik.write("walking_IK_radians.mot")

id_results = IDResults(filepath="walking_ID.sto")
print(id_results.columns)

Check per-column units when reading results: the current shared reader assigns angle units to all columns, including translations and ID forces/moments. See results and subjects for explicit units, DataFrames, normalization, and multi-trial organization.

Tutorials and reference

Start with the documentation overview:

API reference pages are in docs/api/. To build the documentation locally:

python -m pip install -e ".[docs]"
python -m sphinx -b html docs docs/_build/html

Open docs/_build/html/index.html. To run the existing tests:

python -m pip install pytest
python -m pytest tests

Release files for ibo-biomech 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ibo-biomech 0.3.2
File Size Uploaded
ibo_biomech-0.3.2.tar.gz 165.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ibo-biomech 0.3.2
File Interpreter ABI Platform
ibo_biomech-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 217.6 kB

Release files / ibo_biomech-0.3.2.tar.gz

Download URL ibo_biomech-0.3.2.tar.gz
Size 165.2 kB
Tags Source
SHA-256 checksum
How to use checksums
c1e50ba1e26befd62fd150762dce746a24942ac73c5939e1cc168fdf5af0294a
BLAKE2b-256 checksum
How to use checksums
5540ec9ea89eef5cdaf67b093c49f0cbedec2e3ea9a9265bd0311d7e98192bb2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / ibo_biomech-0.3.2-py3-none-any.whl

Download URL ibo_biomech-0.3.2-py3-none-any.whl
Size 52.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3d516acb230c282e74261d00310398da6038f5ed802ecc96ce7d00cb3a842888
BLAKE2b-256 checksum
How to use checksums
8642a16031b194edc0b6b2371ee3da72e014de6f15a02c016fde0811a297f32f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.5

2 release files

0.3.4

2 release files

This release

0.3.2 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.13

2 release files

0.2.12

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.2

2 release files

0.2.0

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release 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