Skip to main content

respyra logo

respyra

A general-purpose respiratory tracking toolbox for interoception research

Tests PyPI Docs License: MIT Python 3.10


respyra is a Python toolbox that integrates a Vernier Go Direct Respiration Belt (GDX-RB) with PsychoPy to enable real-time respiratory tracking experiments. Participants follow a sinusoidal target dot with their breathing while receiving continuous visual biofeedback. The toolbox supports configurable experimental conditions including multi-frequency target waveforms and visuomotor perturbations (visual gain manipulation).

Full documentation | PyPI | Paper

Task Schematic

Task schematic

Task Screenshots

Range Calibration Baseline
Range Calibration Baseline
Countdown Tracking (good) Tracking (poor)
Countdown Tracking veridical Tracking bad

Installation

pip install respyra

For post-session visualization (adds pandas and matplotlib):

pip install "respyra[vis]"

Development install

git clone https://github.com/embodied-computation-group/respyra.git
cd respyra

Create a virtual environment with Python 3.10:

# Windows (with Python Launcher)
py -3.10 -m venv .venv
.venv\Scripts\activate

# macOS / Linux
python3.10 -m venv .venv
source .venv/bin/activate

Install in editable mode with dev extras:

pip install -e ".[dev,vis]"

Running tests

pytest tests/ -v

PsychoPy and godirect are mocked at the sys.modules level so the test suite runs without hardware or heavy dependencies. See CONTRIBUTING.md for details on the mock strategy and adding new tests.

Requirements

  • Python 3.10 -- PsychoPy does not yet support 3.11+
  • Vernier Go Direct Respiration Belt (GDX-RB) -- required for hardware experiments; display demos run without a belt

Quick start

Run a no-hardware display demo to verify PsychoPy is working:

python -m respyra.demos.demo_display

With a belt connected, run the full experiment:

respyra-task

See the full documentation for detailed installation, quickstart, and user guide.

Running the experiment

python -m respyra.scripts.breath_tracking_task
# or, after pip install:
respyra-task

Session flow

  1. Belt connection -- BLE with automatic USB fallback (connects before PsychoPy to avoid Windows COM conflicts)
  2. Participant info dialog -- enter participant ID and session number
  3. Range calibration (15 s) -- comfortable deep breaths to establish breathing range, with percentile-based outlier rejection and sensor saturation detection
  4. Trial loop (per condition x N reps):
    • Baseline (10 s) -- breathe naturally
    • Countdown (3 s) -- target dot blends from current position into the target waveform
    • Tracking (30 s) -- follow the sinusoidal target dot with breathing
    • Feedback -- mean absolute tracking error for the trial
  5. Data saved to data/ as CSV (one row per sample, flushed incrementally)

Experimental conditions

Conditions are defined in respyra/configs/breath_tracking.py using composable frequency segments:

Condition Pattern Feedback gain
slow_steady 3 cycles at 0.1 Hz (30 s) 1.0 (veridical)
mixed_rhythm 3 cycles at 0.1 Hz + 1 cycle at 0.3 Hz 1.0 (veridical)
perturbed_slow 3 cycles at 0.1 Hz (30 s) 1.5 (amplified trace)

The feedback gain perturbation multiplies the displayed breathing trace around the participant's center, similar to cursor rotation in visuomotor reaching studies. The target dot, tracking error, and color feedback remain based on the true (unperturbed) signal -- only the visual trace is distorted.

Visual feedback

The target dot changes color based on real-time tracking error:

  • Graded mode (default) -- continuous green (good) to yellow to red (poor) using HSV interpolation
  • Binary mode -- yellow/red threshold
  • Trinary mode -- yellow/orange/red with two thresholds

Post-session visualization

python -m respyra.utils.vis.plot_session data/sub-01_ses-001_2026-02-24.csv
# or, after pip install:
respyra-plot data/sub-01_ses-001_2026-02-24.csv

Generates a 6-panel summary figure saved as {csv_stem}_summary.png:

  1. Full session force trace with target overlay
  2. Signed tracking error per trial
  3. Per-trial mean absolute error (bar chart)
  4. Error distribution by condition (box plot)
  5. Baseline calibration stability across trials
  6. Summary statistics (MAE, RMSE, per-condition breakdown)

Project structure

respyra/
  core/             Reusable modules
    breath_belt.py    Non-blocking belt I/O (threaded reader + queue)
    display.py        PsychoPy window, SignalTrace waveform renderer
    data_logger.py    Incremental CSV logging with crash resilience
    events.py         Keyboard input helpers
    target_generator.py  Sinusoidal target waveform from segment definitions
    gdx/              Vernier gdx wrapper (from godirect-examples, not on PyPI)
  configs/          Experiment parameters (no magic numbers in scripts)
  scripts/          Runnable experiment sessions
  demos/            Standalone single-feature test scripts
  utils/vis/        Post-session visualization
docs/               Sphinx documentation source
media/              Stimulus assets and icons
data/               Session output (gitignored)

Demos

python -m respyra.demos.demo_belt_connection   # Test belt connectivity (terminal only)
python -m respyra.demos.demo_display           # PsychoPy display with synthetic data
python -m respyra.demos.demo_threaded_belt     # Threaded belt queue-draining pattern

Documentation

Full documentation is available at embodied-computation-group.github.io/respyra, including:

Why the Vernier belt?

The Vernier Go Direct Respiration Belt (GDX-RB) was chosen because it is inexpensive, well-documented, and available worldwide through educational science suppliers. It provides wireless (BLE) respiratory force measurement out of the box, making it accessible to researchers and teaching labs without specialized biomedical equipment budgets. While not a research-grade instrument, it offers a reliable and practical solution for respiratory tracking and interoception research at low cost. For applications requiring more sophisticated monitoring (e.g., dual-band respiratory inductance plethysmography or spirometry), respyra's modular sensor interface is designed to accommodate alternative hardware.

Platform notes

Windows BLE: The Vernier belt's BLE scanner (Bleak) requires COM in MTA mode on the main thread. PsychoPy sets COM to STA on import. The framework handles this by connecting the belt before importing PsychoPy.

Linux: Requires udev rules for USB access. See the installation guide.

macOS: Works with both BLE and USB out of the box.

Contributing

Contributions are welcome! See CONTRIBUTING.md for development setup, testing, linting, and pull request guidelines.

License

MIT

The respyra/core/gdx/ module is derived from VernierST/godirect-examples and is licensed under the BSD 3-Clause License.

Metadata

Release files for respyra 0.4.0

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

Source distribution (sdist)

Source distribution for respyra 0.4.0
File Size Uploaded
respyra-0.4.0.tar.gz 37.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for respyra 0.4.0
File Interpreter ABI Platform
respyra-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 37.4 MB

Release files / respyra-0.4.0.tar.gz

Download URL respyra-0.4.0.tar.gz
Size 37.3 MB
Tags Source
SHA-256 checksum
How to use checksums
125b54e51cd81e67444264bacfce33ef9563118f9cb337c64268836a4948f354
BLAKE2b-256 checksum
How to use checksums
abdfdf94df313b9cbd104b0e004ab0941c453366d58593bbcce4e3b197bbba19
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 25, 2026.

Transparency log

Release files / respyra-0.4.0-py3-none-any.whl

Download URL respyra-0.4.0-py3-none-any.whl
Size 71.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b1856a06d43a8b14802b60f26b9fad1ba0a7bff1acacd7a3c6e50093fc61c539
BLAKE2b-256 checksum
How to use checksums
df2ffdf8f49e4d9de49f9952d85663a4299509fad7e37b7e9f2f170c3f2b6e1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

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