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.7

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.7
File Size Uploaded
ibo_biomech-0.3.7.tar.gz 197.7 kB Details

Built distribution (wheel)

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

Total release size: 265.1 kB

Release files / ibo_biomech-0.3.7.tar.gz

Download URL ibo_biomech-0.3.7.tar.gz
Size 197.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4283efc2437b56d5d7ac62cd9f47ee88492860bab9281ad2ccdd27ffce3b8f10
BLAKE2b-256 checksum
How to use checksums
d4d1d5007689b7d1c49ffec485c1959e000a69bfdf33f15d9d153fc917faff32
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 8, 2026.

Transparency log

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

Download URL ibo_biomech-0.3.7-py3-none-any.whl
Size 67.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f1b56f3f84a4620e747b5b1c6f16741cc10a29f67cd176f8c716e9cf149aedf6
BLAKE2b-256 checksum
How to use checksums
239343fc60d9edbf122d1c925bef7cd8666310f39d718172b93771550d04c6a8
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 8, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.9

2 release files

0.3.8

2 release files

This release

0.3.7 This release

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