eoio.writers.zarr.writer module#

eoio.writers.zarr.writer - Zarr writer

Wraps to_zarr with the parts eoio needs on top of it: attribute encoding (handled by BaseWriter), explicit chunking, and appending along a dimension as a first-class operation rather than something the caller assembles.

Unlike the netCDF writer, there are no compression defaults to add - zarr compresses by default, and does it well (a 200k-element float array occupies about 2 kB rather than 800 kB). Pass encoding to change or disable that.

A DataTree is written as zarr groups, one per node. xarray implements neither append_dim nor group for a tree, so ZarrWriter.can_write() refuses a tree combined with either - at the first write rather than the second, since a first append is an ordinary write and would otherwise succeed.

Appending is a mutation#

An append is not a fresh write that happens to extend an array: it changes an artifact that already exists, so what is already in the store has to be reconciled with what is arriving. Two things follow, and both are handled here rather than left to the caller.

Coordinates. to_zarr extends a dimension unconditionally, so re-running a write that partly succeeded appends the same time steps a second time. Nothing downstream can tell the duplicates apart, and the artifact is usually permanent, so on_overlap governs it explicitly and defaults to refusing.

Attributes. Zarr replaces a group’s attributes wholesale on every write, so an append would otherwise leave the store carrying only the last-appended object’s metadata - and with update_history on by default, a stack’s history would record the most recent append instead of accumulating. Appends therefore merge into what the store already holds instead of overwriting it.

class eoio.writers.zarr.writer.ZarrWriter(write_params: Dict[str, Any] | None = None)[source]#

Bases: BaseWriter

Write a Dataset or DataTree to a Zarr store.

all_write_params: Dict[str, str] = {'append_dim': 'dimension name to append along, or None (not supported for a DataTree)', 'chunks': 'mapping of dimension name to chunk size, or None to leave chunking alone', 'consolidated': 'True/False', 'create_parents': 'True/False', 'encode_attrs': 'True/False', 'encoding': 'per-variable encoding dict, or None. Ignored when appending', 'group': 'group path within the store, or None for the root (not supported for a DataTree)', 'mode': 'w/w-/a/a-/r+', 'on_nonconformance': 'warn/error/ignore', 'on_overlap': 'error/skip/allow - what to do when appending coordinates the store already has', 'update_history': 'True/False', 'zarr_format': '2/3, or None for the zarr default'}#
can_write(obj: Any) → WriteCapability[source]#

Report whether this writer can express obj with its current parameters.

Parameters:

obj – Candidate object.

Returns:

Capability, with a reason when the answer is no.

default_write_params: Dict[str, Any] = {'append_dim': None, 'chunks': None, 'consolidated': True, 'create_parents': True, 'encode_attrs': True, 'encoding': None, 'group': None, 'mode': 'w', 'on_nonconformance': 'warn', 'on_overlap': 'error', 'update_history': True, 'zarr_format': None}#
static get_extension() → str[source]#

Return the filename extension this writer produces, including the dot.

Used to name outputs when the caller gives a directory rather than a full path (see write_multi).

name: str = 'zarr'#

Name this writer is registered under. Concrete writers must set this.

write_dataset(obj: Dataset | DataTree, path: Path) → None[source]#

Write the object to a Zarr store.

Parameters:
  • obj – Dataset or DataTree, already encoded by the base class.

  • path – Destination store path.

Raises:

ImportError – If the optional zarr package is not installed.