Skip to main content

CFT Zarr Custom Codecs

Custom codecs for Zarr v3 optimized for CFT (Cryo-Fluorescence Tomography) data storage.

Codecs

This package provides custom Zarr v3 codecs:

  • cft_zarr.jpeg_compressor: JPEG compressor for RGB images (BytesBytesCodec - supports incremental updates)
  • cft_zarr.shift12jls_compressor: JPEG-LS compressor for 12-bit fluorescent data (BytesBytesCodec - supports incremental updates)
  • cft_zarr.jpeg: JPEG codec for RGB images (ArrayBytesCodec)
  • cft_zarr.shift12jls: JPEG-LS codec for 12-bit fluorescent data (ArrayBytesCodec)
  • cft_zarr.jls16: JPEG-LS codec for uint16 data without shifting; can also store scaled uint32 stack sums
  • cft_zarr.jpegxl: JPEG XL codec (ArrayBytesCodec)

Installation

pip install cft-zarr

JPEG-LS backend

The three JPEG-LS codecs use cftimg_native (the Rust cftimg-native wheel, 0.4.1 or newer: jpegls-rs encoder, faster, decodes in parallel) when it is importable and fall back to imagecodecs (CharLS) otherwise. Both backends write byte-identical chunks (a SPIFF-wrapped 16-bit JPEG-LS stream, as imagecodecs.jpegls_encode writes it; imagecodecs before 2026.1.14 wrote the RGB code 10 instead of grayscale 8 in the SPIFF color space byte, which decoders ignore) and decode each other's output. Set CFT_ZARR_JPEGLS_BACKEND=imagecodecs to force the fallback.

Usage

Reading Zarr Files

Important: You must import cft_zarr before opening Zarr files that use these codecs. This registers the codecs with Zarr.

import cft_zarr  # This registers the codecs
import zarr

# Now you can open Zarr files that use custom codecs
arr = zarr.open('rgb.zarr', mode='r')

Using with napari

When opening Zarr files in napari, cft_zarr can be auto-registered via the napari plugin system (installed in the same environment as napari). If you still have trouble, import cft_zarr first:

import cft_zarr  # Register codecs before opening files
import napari

# Now napari can read Zarr files with custom codecs
viewer = napari.Viewer()
viewer.open('path/to/file.zarr')  # Will work with custom codecs

Or in a Python script before launching napari:

import cft_zarr  # Must import before opening Zarr files
import napari

viewer = napari.Viewer()
viewer.open('rgb.zarr')
napari.run()

Creating Zarr Arrays with Custom Codecs

import cft_zarr
from cft_zarr import JPEGCompressor, JLS16Codec, Shift12JLSCompressor
import zarr

# Create RGB array with JPEG compression
rgb_array = zarr.create(
    shape=(100, 512, 512, 3),
    chunks=(4, 512, 512, 3),
    dtype='uint8',
    compressors=[JPEGCompressor(level=85)]
)

# Create fluorescent array with Shift12JLS compression
fl_array = zarr.create(
    shape=(100, 512, 512),
    chunks=(4, 512, 512),
    dtype='uint16',
    compressors=[Shift12JLSCompressor()]
)

# Create a uint16 fluorescent array with direct JPEG-LS compression
jls16_array = zarr.create(
    shape=(100, 512, 512),
    chunks=(4, 512, 512),
    dtype='uint16',
    serializer=JLS16Codec(),
    compressors=[]
)

# Store 32x 12-bit stack sums as uint32 with scale=2.
# The encoded stream stores round(value / 2) as uint16 JPEG-LS and decodes
# back to value * 2, giving at most +/-1 count error from the scaling step.
stack32_array = zarr.create(
    shape=(100, 512, 512),
    chunks=(4, 512, 512),
    dtype='uint32',
    serializer=JLS16Codec(scale=2),
    compressors=[]
)

Decode concurrency

The cft_zarr.jpeg and cft_zarr.shift12jls array codecs decode chunks on a shared worker pool instead of blocking Zarr's IO event loop. The pool starts threads on demand, with one worker per available logical CPU, shared across RGB and fluorescence arrays. Python 3.13+ uses the process-aware CPU count; Python 3.11–3.12 uses the system CPU count. If the count is unavailable, the pool uses one worker. No extra dependency or configuration is required. Codec metadata, pixel values and encoding are unchanged.

Each worker still decodes a complete physical chunk. Decoded-chunk caching in the viewer remains important for adjacent slices. Cancelling a read can cancel queued work; a native decode already running finishes before its worker is reused. Active native calls cannot be interrupted. The concurrency cap bounds simultaneous decodes, not total dataset or viewer cache memory.

Metadata

Release files for cft-zarr 0.1.3

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

Source distribution (sdist)

Source distribution for cft-zarr 0.1.3
File Size Uploaded Provenance Actions
cft_zarr-0.1.3.tar.gz 37.9 kB Without provenance Details for cft_zarr-0.1.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cft-zarr 0.1.3
File Interpreter ABI Platform Actions
cft_zarr-0.1.3-py3-none-any.whl Python 3 none any Details for cft_zarr-0.1.3-py3-none-any.whl

Total release size: 85.3 kB

Release files / cft_zarr-0.1.3.tar.gz

Download URL cft_zarr-0.1.3.tar.gz
Size 37.9 kB
Tags Source
SHA-256 checksum
How to use checksums
445a79964e2d9b20af90329e1e7774498d739b828206488fb4f1ee0917292bef
BLAKE2b-256 checksum
How to use checksums
9896918c628e06ff8a8a55de2d9fff5502c044f124abf7fbd9a125cae4147aab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.2.1 CPython/3.14.3 Darwin/27.0.0

Release files / cft_zarr-0.1.3-py3-none-any.whl

Download URL cft_zarr-0.1.3-py3-none-any.whl
Size 47.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b1943c15adc0a05e2920448e093f0f8dfcdc93ca350cc262288bc757cbd46584
BLAKE2b-256 checksum
How to use checksums
41fc2b10b4012c7601ccb084335858f1eccec912b0b674d018691163830424c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.2.1 CPython/3.14.3 Darwin/27.0.0

Security for cft-zarr 0.1.3

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