Skip to main content

Aind.Behavior.VrForaging.Packaging

CI License ruff uv

Parses raw AIND VR-foraging behavioral sessions into analysis-ready parquet tables and an NWB file.

Architecture

A session is loaded once (via contraqctor), then a set of independent processors fan out over it. Each processor owns one output and knows how to express it in two targets:

raw session dir
      │
      ▼
  Dataset  ◄── aind_behavior_vr_foraging.data_contract.dataset(path)
      │
      ▼
  create_processors(dataset)          # picks processor variants by dataset version
      │   [SessionMetadata, PositionAndVelocity, SiteTable, Licks, Sniffing,
      │    SoftwareEvents, Events]
      │
      ├─► proc.compute()  ──► pandas DataFrame  ──► one <name>.parquet   (process_session)
      │                        (provenance stamped into df.attrs / parquet schema)
      │
      └─► proc.nwbize(nwb) ──► populates an NWBFile ──► .nwb.zarr (NwbSession)
  • Processor — every processor subclasses AbstractProcessor, implementing _compute() and (optionally) nwbize(). compute() wraps _compute() and stamps provenance (packaging_version, data_contract_version, dataset_version, processor) into the DataFrame's attrs.
  • DataFrame — the common in-memory representation. One row per unit of the output (e.g. one site-table row = one site).
  • Parquet — pipeline.session.process_session() calls compute() on each processor and writes a parquet per processor, promoting df.attrs to first-class parquet metadata (readable from DuckDB, Polars, R arrow, Spark, …).
  • NWB — NwbSession builds a single NWBFile from AIND metadata, then calls each processor's nwbize() to fill it, and writes NWB-Zarr.

Version dispatch is automatic: datasets with schema version < 0.6.0 receive legacy processor variants.

Examples

Get a sites table

Install straight from GitHub with uv:

# into a uv project
uv add "git+https://github.com/AllenNeuralDynamics/Aind.Behavior.VrForaging.Packaging.git"

# or into the current environment
uv pip install "git+https://github.com/AllenNeuralDynamics/Aind.Behavior.VrForaging.Packaging.git"

Then load a session and compute the sites table (one row per site):

from aind_behavior_vr_foraging.data_contract import dataset
from aind_behavior_vr_foraging_packaging.pipeline.session import resolve_site_table_processor

ds = dataset("path/to/session")  # load the raw session
sites_df = resolve_site_table_processor(ds).compute()

sites_df.to_parquet("sites.parquet")  # optional: persist to disk
print(f"{len(sites_df)} sites, {sites_df['has_reward'].sum()} rewarded")

resolve_site_table_processor automatically picks the current or legacy variant based on the dataset's schema version. To produce every table at once, use process_session(ds, "output_dir") instead — it writes sites.parquet, position_velocity.parquet, and the rest, and returns them keyed by name.

Exporting a dataset collection

Install the CLI with uv:

uv tool install aind-behavior-vr-foraging-packaging

Then run the export pipeline across a folder of raw session directories (--input-dir must contain one subdirectory per session):

vr-foraging-packaging batch --input-dir /data/raw --output-dir /data/export

--output-dir receives the results:

/data/export/
├── session.parquet          # session catalogue (one row per session)
├── sites.parquet            # aggregated sites table (all sessions)
└── sessions/
    └── <session_id>/
        ├── sites.parquet
        ├── position_velocity.parquet
        └── ...

Subcommands

Command What --input-dir is What it does
session one raw session directory Export that session's tables (and optionally NWB)
batch a folder of raw session directories Export every session, then aggregate
aggregate a sessions/ tree from an earlier run Rebuild the experiment-level tables only

Swap batch for session or aggregate in the command above to run those. Run vr-foraging-packaging <command> --help for that command's full flag reference, or see the Getting Started guide for common flag combinations.

Want to try the latest main without installing? uvx runs it straight from GitHub — since the command name differs from the package name, pass the source via --from:

uvx --from "git+https://github.com/AllenNeuralDynamics/Aind.Behavior.VrForaging.Packaging.git" \
    vr-foraging-packaging batch --input-dir /data/raw --output-dir /data/export

Documentation

The full documentation site is built with Zensical.

Preview locally:

uv sync --group docs
uv run zensical serve

Build a static copy:

uv run zensical build --clean
# output → site/

The site deploys automatically to GitHub Pages on every push to main as part of the main CI workflow.

Contributors

Contributions to this repository are welcome! However, please ensure that your code adheres to the recommended DevOps practices below:

Linting

We use ruff as our primary linting tool.

Type checking

We use ty for static type checking. Run uv run ty check from the root of the repository.

Testing

Attempt to add tests when new features are added. To run the currently available tests, run uv run pytest from the root of the repository.

Integration tests

Integration tests run the parser end-to-end against real datasets stored in a public S3 bucket. They are gated by a pytest marker so they don't run by default.

Run locally:

uv run pytest -m integration

The first run downloads datasets (~100 MB per dataset) to tests/integration/.cache/. Subsequent runs reuse the cache when the S3 ETag matches. The cache directory is gitignored.

Trigger on a PR:

Integration tests do not run on every PR. To run them for a specific PR, add the run-integration label via the GitHub UI (open the PR, click Labels in the right-hand sidebar, and select run-integration) or with:

gh pr edit <PR_NUMBER> --add-label run-integration

The integration job runs automatically on push to main and on release: published. A release cannot ship without the integration suite passing.

Adding a dataset:

Add an entry to tests/integration/datasets.yml. The manifest schema and full field documentation are in tests/integration/model.py (Pydantic model). The rationale field is required and is printed alongside any test failure to make triage fast.

Lock files

We use uv to manage our lock files and therefore encourage everyone to use uv as a package manager as well.

Release files for aind-behavior-vr-foraging-packaging 0.21.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 aind-behavior-vr-foraging-packaging 0.21.0
File Size Uploaded
aind_behavior_vr_foraging_packaging-0.21.0.tar.gz 339.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aind-behavior-vr-foraging-packaging 0.21.0
File Interpreter ABI Platform
aind_behavior_vr_foraging_packaging-0.21.0-py3-none-any.whl Python 3 none any Details

Total release size: 397.6 kB

Release files / aind_behavior_vr_foraging_packaging-0.21.0.tar.gz

Download URL aind_behavior_vr_foraging_packaging-0.21.0.tar.gz
Size 339.5 kB
Tags Source
SHA-256 checksum
How to use checksums
73a80805860c79360554d7be0974a852acc0454fe445211967c8e05d6064e3e1
BLAKE2b-256 checksum
How to use checksums
05c26b82489f4b0984b0f12664ab29cb7c7b0e3cf275f6bf32de3b715be221ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","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 / aind_behavior_vr_foraging_packaging-0.21.0-py3-none-any.whl

Download URL aind_behavior_vr_foraging_packaging-0.21.0-py3-none-any.whl
Size 58.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
694f19dbbf660f585d24342869970229c611bb02ea5c926a5c77bb7f842f5812
BLAKE2b-256 checksum
How to use checksums
38a966c39f0ed0e9ce5a307b020f2a5435887b00ace753d5e5bab62aa5e39e34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","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 history Release notifications | RSS feed

0.23.0

2 release files

0.22.0

2 release files

This release

0.21.0 This release

2 release files

0.20.0

2 release files

0.0.19

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

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