Skip to main content

birm: Bayesian Impulse-Response Modeling

pypi CI coverage docstring coverage DOI

About

This package implements a Bayesian Impulse-Response Model (BIRM) for athletic performance. The default prior structure is physiologically informed and resolves inference issues common in the literature, and the model allows for multivariate inputs and outputs so that parameters can be informed by multiple metrics of performance adjusted for their external influencers.

Usage

Installation

Install from PyPI:

pip install birm

Preparing data

The Panel is the model-ready dataset used by birm to align loads, metrics and exogenous predictors. Build a Panel from a single long-form table:

import pandas as pd
from birm import Panel

df = pd.DataFrame(
    {
        "date": ["2025-01-03", "2025-01-03", "2025-01-04", "2025-01-06"],
        "metric": ["w", "hrv", "hrv", "speed"],
        "value": [210.0, 64.0, 61.0, 4.71],
    }
)

panel = Panel.from_long(df, date="date", metric="metric", value="value", load="w").standardize()
panel.T  # 4 days on the shared daily grid
panel.densest()  # 'hrv' has the most observations

See the docs for more ways to build the Panel from your data.

Specifying a model

An IRModel is the declarative spec of the shared-stock impulse-response model. You define it by picking a fitness × fatigue core and attach one Metric per response series, then fit it with .fit(panel).

from birm import IRModel, Load, Metric

model = IRModel(
    load=Load("w"),  # training-load driver w_t
    fitness="banister",
    fatigue="banister",  # selects the impulse-response core R_t
    metrics=(
        Metric("hrv", exog=("w",), ar1=True),  # HRV-suppression beta + slow drift u
        Metric("speed", exog=("temp", "indoor")),  # heat + treadmill adjustments
    ),
)
idata = model.fit(panel, sampler=dict(draws=1000, tune=2000, seed=0))

idata is an ArviZ InferenceData. Summarize parameters, check convergence, or pull the shared impulse-response stock R_t:

import arviz as az

az.summary(idata, var_names=["k_F", "k_G", "tau_F", "tau_G"], ci_prob=0.95)  # mean, 95% CI, r_hat
az.plot_trace(idata, var_names=["k_F", "tau_F"])  # convergence diagnostics

R = idata.posterior["R"]  # (chain, draw, T) latent stock
R_mean = R.mean(("chain", "draw"))  # posterior-mean trajectory
idata.to_netcdf("fit.nc")  # cache for later reuse

See the docs for the full model reference.

For Developers

Setup

uv sync  # install package + dev dependencies into .venv

Development workflow

All changes should be made on a branch and merged to main via pull request. All changes require accompanying unit tests in tests/ and documentation in docs/.

git checkout -b feat/my-feature   # or fix/, docs/, refactor/, etc.

# ...you make your changes, and then

make format      # auto-fix formatting and lint violations
make check       # lint, type-check, and verify docstring coverage
make test        # run tests with coverage (90% minimum)
make docs-serve  # preview docs locally at http://127.0.0.1:8000

git push -u origin feat/my-feature
# open a pull request on GitHub

CI runs make check and make test automatically on every push and pull request. A PR cannot be merged if CI fails.

What triggers what

Action CI checks Docs deployed Package published
Push to any branch / open PR ✓
Merge to main ✓ ✓
Push a v* tag ✓

Docs-only change (e.g. fix a typo in docs/ or a docstring): open a PR and merge to main. Docs redeploy automatically, no tag needed.

Code-only change (e.g. bug fix): merge to main, then tag when ready to publish (see below). Docs will also redeploy on merge, reflecting any updated docstrings.

Publishing a new package version

  1. Bump the version in pyproject.toml:
    # choose one:
    make bump-patch   # 0.1.0 → 0.1.1  (bug fixes)
    make bump-minor   # 0.1.0 → 0.2.0  (new features)
    make bump-major   # 0.1.0 → 1.0.0  (breaking changes)
    
  2. Commit, tag, and push:
    git add pyproject.toml
    git commit -m "chore: bump version to v0.x.x"
    git tag v0.x.x
    git push && git push --tags
    

Pushing the tag triggers the publish workflow, which runs the test suite and publishes the package to PyPI. Check that the release appeared:

Metadata

Release files for birm 0.1.1

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

Source distribution (sdist)

Source distribution for birm 0.1.1
File Size Uploaded Provenance Actions
birm-0.1.1.tar.gz 23.3 kB Without provenance Details for birm-0.1.1.tar.gz

Built distribution (wheel)

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

Total release size: 50.7 kB

Release files / birm-0.1.1.tar.gz

Download URL birm-0.1.1.tar.gz
Size 23.3 kB
Tags Source
SHA-256 checksum
How to use checksums
5d0fc39bc10cd8de91e6eef39a6561ad52da78449f7c2f1083f7c917b6576e7c
BLAKE2b-256 checksum
How to use checksums
f07f0656f59127e0cfe5e13c7ce180f8c9e33cf5e1a2d78b546870cb16ce7401
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / birm-0.1.1-py3-none-any.whl

Download URL birm-0.1.1-py3-none-any.whl
Size 27.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4f323d2edec043a4a9996266a245db5e6684ff2589bb15a8e48ae756129937bb
BLAKE2b-256 checksum
How to use checksums
0ee8d8ddde4f9ae6e35c0d308269cfbd9e19873897952e2059fb55ab9749876f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for birm 0.1.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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