Skip to content

motionbids

A lightweight Python package for creating BIDS-compliant motion capture data.

Quick Start

from motionbids import MotionData, Channel, export_bids_motion
import numpy as np

# Your motion data (rows=timepoints, columns=channels)
data = np.random.randn(1200, 30)

# Define channels following BIDS schema
channels = [
    Channel(
        channel_name=f"marker{i}_{axis}",
        channel_component=axis,
        channel_type="POS",
        channel_tracked_point=f"marker{i}",
        channel_units="mm"
    )
    for i in range(10)
    for axis in ['x', 'y', 'z']
]

# Create BIDS motion object
motion = MotionData(
    subject="01",
    task_name="walk",
    tracksys="optical",
    sampling_frequency=120.0,
    tracked_points_count=10,
    data=data,
    channels=channels
)

# Export to BIDS format
export_bids_motion(motion, out_dir="bids_dataset/")

Installation

pip install motionbids

Or with uv:

uv pip install motionbids

For development:

git clone https://github.com/JuliusWelzel/motionbids.git
cd motionbids
pip install -e ".[dev]"

Features

Schema-driven - Auto-syncs with BIDS specification
Convenience validation - Basic checks (use official BIDS Validator for compliance)
Simple API - Create BIDS datasets with minimal code
Complete export - JSON metadata, TSV data, channels, scans files
Reference frames - Describe axis directions and rotation conventions in channels.json
Lightweight - Minimal dependencies

Supported Systems

In general the goal of this package is to that data from any system can be converted to MOTION BIDS format:

  • Optical: Vicon, Optitrack, Qualisys
  • IMU: Xsens, APDM, Movella
  • Video: OpenPose, MediaPipe, DeepLabCut
  • Other: Custom tracking systems

Some systems might get a dedicated import function in the future, look out for the release notes.

Output Structure

your-study/
├── dataset_description.json
└── sub-01/
    ├── sub-01_ses-01_scans.tsv
    └── ses-01/
        └── motion/
            ├── *_motion.json      # Metadata
            ├── *_motion.tsv       # Time series
            ├── *_channels.tsv     # Channel info
            └── *_channels.json    # Reference frame description (optional)

*_channels.json is written whenever MotionData.reference_frames is set and a *_channels.tsv is exported alongside it, since it is that file's sidecar. It explains what the labels in the reference_frame column of *_channels.tsv mean — where the X, Y, Z axes point (SpatialAxes, e.g. "PLS" for X to the back, Y to the left, Z up) and how rotations around them are applied. See the reference frame example.

Documentation

Importing Data

motionbids focuses on exporting to BIDS format. Since motion capture systems vary widely, importing raw data is left to the user. The Workflow Guide includes snippets for loading data from CSV, C3D, and IMU sensors, and the Examples section provides complete, runnable conversion scripts (Vicon .c3d and Movella .xdf).

Citation

@software{welzel2025motionbids,
  title = {motionbids: BIDS-compliant motion capture data converter},
  author = {Welzel, Julius},
  year = {2025},
  url = {https://github.com/JuliusWelzel/motionbids}
}

License: MIT | Python: 3.10+ | Dependencies: NumPy, bidsschematools, dataclasses-json