Dask
Pyramid.write runs on a local thread pool. To use Dask instead, for example on a distributed cluster, call as_datatree() to get a lazy DataTree and write it with to_zarr.
A lazy source
Open air_temperature with one Dask chunk per year:
import xarray as xr
import xproj # noqa: F401
ds = xr.tutorial.open_dataset("air_temperature", chunks={"time": 730}).drop_encoding()
ds = ds.proj.assign_crs(spatial_ref="EPSG:4326")
ds.air
<xarray.DataArray 'air' (time: 2920, lat: 25, lon: 53)> Size: 31MB
dask.array<open_dataset-air, shape=(2920, 25, 53), dtype=float64, chunksize=(730, 25, 53), chunktype=numpy.ndarray>
Coordinates:
* time (time) datetime64[ns] 23kB 2013-01-01 ... 2014-12-31T18:00:00
* lat (lat) float32 100B 75.0 72.5 70.0 67.5 ... 22.5 20.0 17.5 15.0
* lon (lon) float32 212B 200.0 202.5 205.0 ... 325.0 327.5 330.0
* spatial_ref int64 8B 0
Indexes:
spatial_ref CRSIndex (crs=EPSG:4326)
Attributes: (11)Write with Dask
Plan the pyramid as usual. as_datatree() returns every level as a lazy DataTree, and pyramid.encoding holds the recommended chunks and shards. The shards are sized to divide evenly into the Dask chunks, so no rechunking is needed:
from topozarr import create_pyramid
pyramid = create_pyramid(ds, levels=2, x_dim="lon", y_dim="lat")
lazy = pyramid.as_datatree()
lazy.to_zarr("air-dask.zarr", zarr_format=3, consolidated=False, mode="w", encoding=pyramid.encoding)
lazy
<xarray.DataTree>
Group: /
│ Attributes: (9)
├── Group: /0
│ Dimensions: (time: 2920, lat: 25, lon: 53)
│ Coordinates:
│ * time (time) datetime64[ns] 23kB 2013-01-01 ... 2014-12-31T18:00:00
│ * lat (lat) float32 100B 75.0 72.5 70.0 67.5 ... 22.5 20.0 17.5 15.0
│ * lon (lon) float32 212B 200.0 202.5 205.0 ... 325.0 327.5 330.0
│ * spatial_ref int64 8B 0
│ Data variables:
│ air (time, lat, lon) float64 31MB dask.array<chunksize=(730, 25, 53), meta=np.ndarray>
│ Indexes:
│ spatial_ref CRSIndex (crs=EPSG:4326)
│ Attributes: (8)
└── Group: /1
Dimensions: (time: 2920, lat: 12, lon: 26)
Coordinates:
* time (time) datetime64[ns] 23kB 2013-01-01 ... 2014-12-31T18:00:00
* lat (lat) float32 48B 73.75 68.75 63.75 58.75 ... 28.75 23.75 18.75
* lon (lon) float32 104B 201.2 206.2 211.2 ... 316.2 321.2 326.2
spatial_ref int64 8B 0
Data variables:
air (time, lat, lon) float64 7MB dask.array<chunksize=(730, 12, 26), meta=np.ndarray>
Attributes: (8)To run on a cluster, start a dask.distributed.Client before calling to_zarr.