Skip to content

sleap-io v0.9.2

Latest

Choose a tag to compare

@gitttt-1234 gitttt-1234 released this 24 Jul 23:31
80bbcd9

sleap-io v0.9.2 Release Notes

Summary

sleap-io v0.9.2 is a focused patch release that fixes a major I/O scalability bug in multi-camera RecordingSession storage. Previously, an entire session — calibration, camera↔video mapping, and every frame group's inline 3D points — was serialized as one JSON string in sessions_json. On a real 3-camera, 108,000-frame project that string reached 524 MB, 78.6% of which was 3D point text, and HDF5 variable-length strings can't be read back past roughly a 0.45 GB ceiling in JS/WASM — making such files effectively unreadable in browser-based tooling. The bulk numeric data now lives in a dedicated columnar /session_data HDF5 group, dropping sessions_json to single-digit MB on that project.

The SLP format advances 2.7 → 2.8 — format 2.8 adds the /session_data group. It's additive and read-on-group-presence: pre-2.8 files load unchanged, and files with no camera sessions stay at format ≤2.7.

Highlights:

  • Columnar RecordingSession storage (#546) — moves per-frame 3D point data out of sessions_json into a chunked, gzip-compressed /session_data HDF5 group, referenced by row range (mirroring how 2D /points are referenced from /instances). Fully backward compatible; no public API changes. A real 108k-frame project's sessions_json shrinks from 524 MB to single-digit MB.
  • h5wasm identity/category link interop fix (#548)read_identity_links and read_category_links now accept the flat-2D + field_names table encoding that sleap-io.js (via h5wasm) writes, matching every other structured-table reader. Only affects cross-language interop with sleap-io.js-written files.
  • Storage Representation Matrix docs (#549)docs/formats/slp.md gains a reference table of every on-disk data structure's representation, introducing format version, and read/write support at format 2.8.

Installation / Upgrade

# One-off CLI usage (no installation needed)
uvx sleap-io@0.9.2 show labels.slp

# Install as CLI tool (new install)
uv tool install "sleap-io[all]"

# Upgrade existing CLI tool installation
uv tool upgrade sleap-io

# Add to project (new dependency)
uv add "sleap-io[all]"

# Upgrade existing project dependency
uv lock --upgrade-package sleap-io && uv sync

See installation docs for more options.


Improvements

Columnar RecordingSession storage: 3D points move out of sessions_json (#546)

RecordingSession (multi-camera calibration) was serialized as a single JSON string per session in the sessions_json HDF5 dataset — calibration, the camcorder_to_video_idx_map, and every frame group with its inline 3D points, all as text. On a real 3-camera, 108,000-frame project that string reached 524 MB, of which 412.7 MB (78.6%) was 3D point text. HDF5 variable-length strings can't be read back past roughly a 0.45 GB ceiling in JS/WASM, so such files were effectively unreadable in browser-based tooling (the coordinated sleap-io.js port).

The unbounded per-frame numeric payload now lives in a dedicated columnar /session_data HDF5 group, referenced by row range from a slim sessions_json — the same pattern already used for how 2D /points are referenced from /instances:

  • sessions_json (slim): calibration + camcorder_to_video_idx_map + session metadata + an fg_start/fg_end range into session_data/frame_groups.
  • /session_data/frame_groups(frame_idx, ig_start, ig_end)
  • /session_data/instance_groups(identity_idx, score, instance_3d_score, pts3d_start/end, pts3d_predicted, member_start/end)
  • /session_data/instance_group_members(camera, lf, inst), the columnarized camcorder_to_lf_and_inst_idx_map
  • /session_data/points_3d (N,3) / pred_points_3d (N,4 = xyz+score) — chunked, gzip-compressed float matrices; NaN rows denote missing keypoints
  • /session_data/frame_group_meta / instance_group_meta — optional per-row JSON blobs for lossless typed metadata

On the reported dataset, sessions_json drops from 524 MB to single-digit MB.

Format version: 2.7 → 2.8, bumped only when a session actually has frame groups; session-free/single-view files stay at ≤2.7 and are byte-identical to before.

Compatibility: Fully backward and forward compatible. The reader dispatches on /session_data presence and still parses legacy inline frame_group_dicts from ≤2.7 files. An older (<2.8) reader opening a 2.8 file loads calibration from the slim sessions_json and silently ignores /session_data — no corruption, just absent 3D data. No public API changes: labels.sessions[...].frame_groups[...].instance_groups[...].points works identically; this is purely an on-disk representation change.

Handled consistently across eager I/O (incremental per-session append, bounded peak memory), lazy I/O (raw passthrough — also fixes a prior bug where lazy re-save could silently drop frame groups/3D data), and streaming/remote reads (chunked datasets over fsspec range reads, removing the vlen-string ceiling for large remote files).


Fixes

Read h5wasm flat-2D identity/category links (#548)

read_identity_links and read_category_links read /identity/links and /categories/links via direct structured field access only, with no fallback. h5wasm — the HDF5 layer sleap-io.js writes through — can't create true HDF5 compound datasets, so it stores every structured table as a flat 2-D f8 array plus a field_names attribute, the same convention already handled for points/pred_points/instances/frames, and for /session_data in #546. These two per-detection link readers were the one place not yet wired through the shared flat-2D conversion helper, so a links table written by sleap-io.js raised on read in Python.

Both readers now route through the existing shared conversion helper, which rebuilds a structured array when a field_names attribute is present and passes a genuine compound dataset through unchanged. Only cross-language interop is affected — files written by sleap-io.js (h5wasm) that are read back by Python sleap-io. Plain Python-written .slp/.pkg.slp files are read identically before and after this fix. Closes #547.


Documentation

  • New Storage Representation Matrix section in docs/formats/slp.md cataloging, for every on-disk data structure at format 2.8, its storage representation (compound, columnar group, EAV, plain matrix, ragged CSR, string, JSON, or attribute), the format version that introduced it, and read/write support — complementing the existing Version History and browser-compatibility sections.
  • Documents the write/read asymmetry: Python always writes a single native representation per structure, while compound-kind readers additionally accept the sleap-io.js h5wasm flat-2D + field_names encoding for browser interop.

Changelog

  • #546: feat(io): Columnar RecordingSession storage: move 3D points out of sessions_json (SLP 2.8)
  • #548: fix(io): read h5wasm flat-2D identity/category links (coordinated sleap-io.js port)
  • #549: docs(slp): add Storage Representation Matrix (format 2.8)

Full Changelog: v0.9.1...v0.9.2