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. The tutorials below describe the current processing, saving, and export workflows.

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 shares its processed containers with the returned trial. Use handler.write_c3d(path, trial) for supported marker/analog edits, or handler.write_raw_c3d(path) for the original structure. Derived force edits belong in HDF5/MOT; see 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) Processes vector Tz; plate geometry stays unchanged.
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) Rotates vectors and geometry in the declared frame.
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, including marker-only recordings. Only the current HDF5 force schema is supported; regenerate older files from C3D.

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 export tutorial shows a 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

Metadata

Release files for ibo-biomech 0.3.8

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.8
File Size Uploaded
ibo_biomech-0.3.8.tar.gz 201.0 kB Details

Built distribution (wheel)

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

Total release size: 269.4 kB

Release files / ibo_biomech-0.3.8.tar.gz

Download URL ibo_biomech-0.3.8.tar.gz
Size 201.0 kB
Tags Source
SHA-256 checksum
How to use checksums
8259c50c9e6eacafd9d7a517adcfa901fe8737c42e4d4ab0d357bbe418a90275
BLAKE2b-256 checksum
How to use checksums
731906674d9a8143912aef34127b8f4a979fa183ce8ee14daf5691c3b718135d
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 Oct 12, 2026.

Transparency log

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

Download URL ibo_biomech-0.3.8-py3-none-any.whl
Size 68.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
626c137755ed4a5c7e064bbab2d95c76dd31b763a5e761749fe7c9e2baea6643
BLAKE2b-256 checksum
How to use checksums
6cd4d9a707dd21c993cc357fc31358a3b471de6efedf9d8a2cdbb11207733509
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 Oct 12, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.9

2 release files

This release

0.3.8 This release

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.2

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