neuropose/README.md

120 lines
4.9 KiB
Markdown

# NeuroPose (rewrite)
Ground-up rewrite of the prior NeuroPose internal prototype. The repository
is private while the IRB data-handling policy is being authored; this README
is aimed at contributors working on the rewrite, not external users.
## Layout
```text
neuropose/
├── .github/workflows/ # CI: ruff + pyright + pytest (ci.yml), mkdocs (docs.yml)
├── src/neuropose/
│ ├── __init__.py # version only
│ ├── config.py # pydantic-settings Settings class
│ ├── io.py # prediction schema, load/save helpers
│ ├── estimator.py # per-video MeTRAbs worker
│ ├── interfacer.py # filesystem-polling daemon
│ ├── visualize.py # per-frame 2D + 3D overlay rendering
│ ├── cli.py # typer app (watch | process | analyze)
│ ├── _model.py # MeTRAbs download + SHA-256 verify + load
│ └── analyzer/ # post-processing subpackage
│ ├── dtw.py # FastDTW helpers
│ └── features.py # normalization, padding, joint angles, stats
├── tests/
│ ├── conftest.py # env isolation, synthetic video, fake model
│ ├── unit/ # fast, no model download
│ └── integration/ # marked @slow, downloads the real MeTRAbs model
├── docs/ # mkdocs-material site (mkdocs.yml at repo root)
├── scripts/download_model.py # pre-warm the model cache
├── pyproject.toml # hatchling build, dev group (PEP 735)
├── Dockerfile # CPU image, non-root, /data volume
├── CHANGELOG.md # Keep a Changelog format
├── RESEARCH.md # DTW methodology + MeTRAbs self-hosting R&D log
├── AUTHORS.md
├── CITATION.cff
└── LICENSE # MIT
```
## Architecture
Three stages, one module each:
- **`estimator`** — per-video worker. Streams frames from an input video via
OpenCV, runs MeTRAbs on each frame, and returns a validated
`VideoPredictions` (per-frame `boxes`, `poses3d`, `poses2d` plus a
`VideoMetadata` envelope with frame count, fps, and resolution). Pure
library — no filesystem semantics.
- **`interfacer`** — filesystem-polling daemon. Watches the configured input
directory for new job subdirectories, dispatches each to an `Estimator`,
and persists job state (`status.json`) across crashes and restarts. Single
instance enforced via `fcntl.flock`. Owns the input → output → failed
directory lifecycle.
- **`analyzer`** — post-processing subpackage. FastDTW-based motion
comparison (`dtw_all`, `dtw_per_joint`, `dtw_relation`) and joint-angle /
feature-statistics helpers. Pure functions operating on `VideoPredictions`.
Heavy dependencies (fastdtw, scipy) are lazy-imported so
`import neuropose.analyzer` works without the `analysis` extra.
Configuration is centralized in `src/neuropose/config.py` (a
pydantic-settings `Settings` class). The runtime data directory defaults to
`$XDG_DATA_HOME/neuropose/jobs/` and never lives inside the repository.
## Development setup
Requires Python 3.11 and [`uv`](https://github.com/astral-sh/uv).
```bash
git clone https://git.levineuwirth.org/neuwirth/neuropose.git
cd neuropose
uv sync --group dev
```
`uv sync --group dev` creates `.venv/` automatically and installs the
runtime stack (pydantic, typer, OpenCV, TensorFlow, matplotlib) plus the
full dev toolchain (pytest, ruff, pyright, pre-commit, mkdocs-material,
fastdtw, scipy). First sync downloads ~600 MB of TensorFlow; subsequent
runs hit the uv cache.
Install the pre-commit hooks:
```bash
uv run pre-commit install
```
### Running tests
```bash
uv run pytest # unit tests only (default)
uv run pytest --runslow # unit + integration; downloads ~2 GB MeTRAbs model
uv run pytest -m "not slow" # explicitly exclude slow tests
```
Integration tests live under `tests/integration/` and are gated behind
`@pytest.mark.slow` plus a custom `--runslow` flag implemented in
`tests/conftest.py`. Without the flag, slow tests are skipped at collection
time. The first `--runslow` run downloads the pinned MeTRAbs tarball
(~2 GB) into a session-scoped temp cache; subsequent tests in the same run
reuse it.
### Lint and type-check
```bash
uv run ruff check .
uv run ruff format .
uv run pyright
```
CI runs lint, typecheck, and test as three parallel jobs on every push and
PR to `main` — see `.github/workflows/ci.yml`.
### Docs
```bash
uv run mkdocs serve # live-reload preview at http://127.0.0.1:8000
uv run mkdocs build --strict # same check CI runs
```
The API reference pages under `docs/api/` are auto-generated from source
docstrings via mkdocstrings, so they cannot drift out of sync.