Skip to main content
pbzarr

pbzarr

pbzarr stores per-base genomic data (read depths, methylation, boolean masks, and other per-position values) in Zarr v3. It builds on the recent work in the Python array ecosystem: Zarr, Xarray, and Dask. pbzarr has a Rust and Python API for reading and writing pbz stores, and since a pbz store is just a Zarr store, anything that reads Zarr can read pbzarr.

A store holds one or more tracks. A track is usually a single quantitative signal or metric measured across the whole genome, one value per base. pbzarr keeps that idea but generalizes it: a track is an N-dimensional array indexed by genomic position along its first axis. A 1D track is the familiar one-value-per-base signal; add a second axis and you store many values per base, which is what makes it natural to keep multiple metrics or a whole cohort of samples in a single track.

A few things you get from this:

  • Many values per base live in one array, so Zarr compresses the redundancy across that second axis, not just the runs within a single column.
  • Analysis stays vectorized. Sums, means, and masks run across the whole array at once instead of looping over separate files in Python.
  • Xarray and Dask work directly on the store, so there's no separate conversion step before you can label, slice, or parallelize.

pbzarr can be thought of as the spiritual successor of d4. d4 improved on bigWig with compression, better throughput, multi-track files, and a cleaner API. pbzarr pushes on all of those, mostly by leaning on the work behind Zarr, Xarray, and Dask rather than reinventing it.

For now pbzarr imports from existing formats (d4 and bigWig) rather than generating signal itself, but it does so fast, and once the data is in a pbz store the analysis speedups and disk savings make the conversion worth it. This is all still in active development, so expect rough edges and changes.

Quickstart (Python)

The fastest way to build a store is straight from a d4 or bigWig file. The contig names and lengths are read from the source header, and the dtype is set by the format (d4 is int32, bigWig is float32), so there is nothing else to declare:

import pbzarr

# Single sample: a 1D scalar track.
store = pbzarr.PbzStore.from_d4("sample.pbz", "sample.d4", track="depth")

# A cohort: pass {label: path}. The keys become the column labels, in order,
# and the result is a 2D (position, sample) track. Every source must map to
# the same reference; a mismatched contig set raises.
store = pbzarr.PbzStore.from_d4(
    "cohort.pbz",
    {"A": "A.d4", "B": "B.d4", "C": "C.d4"},
    track="depth",
    column_dim="sample",
)

# bigWig is the same call, into a float32 track.
store = pbzarr.PbzStore.from_bigwig("signal.pbz", "sample.bw", track="signal")

Or build the store by hand when you need full control over the layout:

import numpy as np
import zarr

store = pbzarr.PbzStore.create(
    "out.pbz",
    contigs=["chr1", "chr2"],
    contig_lengths=[248_956_422, 242_193_529],
    coordinate_space="GRCh38",
)

# A 1D scalar track and a 2D cohort track.
store.create_track("mask", dtype="bool")
store.create_track("depth", dtype="int32", columns=["A", "B", "C"], column_dim="sample")

# Bulk-import the cohort track from d4 (PyO3 -> Rust). Use import_bigwig for bigWig.
store.import_d4("depth", sources=[("A.d4", "A"), ("B.d4", "B"), ("C.d4", "C")])

# Or write arbitrary numpy data through zarr-python directly.
g = zarr.open_group("out.pbz", mode="r+")
g["chr1/mask"][:] = np.random.rand(248_956_422) > 0.5

Read with xarray

store = pbzarr.PbzStore("out.pbz")
store.tracks                                       # ['depth', 'mask']
store.region("chr1:1000-2000", track="depth")      # xr.DataArray
store.region("chr1:1000-2000", track="depth", column="A")  # one sample

# Or open the whole store as an xarray DataTree via the .pbz accessor:
dt = pbzarr.open("out.pbz")
dt.pbz.region("chr1:1000-2000", track="depth")

The .pbz accessor on xr.DataTree is registered when you import pbzarr. Regions use 0-based, half-open coordinates, so chr1:1000-2000 is [1000, 2000).

Note: Python PbzStore.create / create_track consolidate metadata after each call. Stores written by the Rust crate do not consolidate yet, so pbzarr.open(...) emits a benign RuntimeWarning for those; run zarr.consolidate_metadata(path) once to silence it.

Format at a glance

  • Layout: contig-major Zarr v3 store with <contig>/<track> arrays. Position is the first axis; an optional column dim (default name "column", often overridden to "sample") is the second.
  • Tracks: 1D for scalar values (e.g., masks), 2D for cohort values (e.g., per-sample depths). Rank-faithful on disk.
  • Coordinates: 0-based, half-open.
  • Compression: Blosc(zstd-5, byte-shuffle) on every data array.
  • Coord arrays: cohort tracks write per-contig 1D string arrays at <contig>/<column_dim> listing the column labels; xarray promotes them to coordinates automatically.

For the full design see docs/DESIGN.md.

Links

Development note

The per-base Zarr format that pbzarr standardizes was first prototyped by hand in clam, where the initial concepts (the contig-major layout, cohort-shaped tracks, and the zarr/ndarray I/O path) were fleshed out before AI tooling was introduced. pbzarr lifts those concepts into a dedicated, spec-driven library.

From that point, development of pbzarr was heavily assisted by Claude (Anthropic), accelerating the library implementation, d4 import, tests, and documentation. The architecture, domain knowledge, and direction remain the author's own; Claude was used as an accelerant, not an author.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pbzarr-0.5.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.8 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

pbzarr-0.5.1-cp311-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (6.8 MB view details)

Uploaded CPython 3.11+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file pbzarr-0.5.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pbzarr-0.5.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 019bd28dd3459c302d03a0140fed620a9c4753292dd596ca0724e6cc794f8a4b
MD5 c50b339299e43afe33e73b70b5b4fa62
BLAKE2b-256 ce7f474dcbd0cc80adf9f6be5e184604fabcc92f856d69655ecead870572ec86

See more details on using hashes here.

Provenance

The following attestation bundles were made for pbzarr-0.5.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on pbzarr/pbzarr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pbzarr-0.5.1-cp311-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for pbzarr-0.5.1-cp311-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 b9e25f1683670da81c9fa56cb2907b538a42fabfbe8ed8f4aebadaf04678b309
MD5 b6f6830cbdfa15d2df5cde0054ed155e
BLAKE2b-256 8fae1a5e803fe13154757494760ec2fbc975fd0e7aa19b6a93342bae1bb0af7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pbzarr-0.5.1-cp311-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: release.yml on pbzarr/pbzarr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.5.1 This release

2 files

0.5.0

2 files

0.3.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 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