xarray_safeguards
xarray_safeguards
Fearless (chunked) lossy compression with xarray-safeguards
Lossy compression can be scary as valuable information or features of the data may be lost.
By using Safeguards to guarantee
your safety requirements, lossy compression can be applied safely and
without fear.
Overview
This package provides functionality to use safeguards with (chunked)
xarray.DataArrays and cross-chunk boundary conditions.
Since applying safeguards to chunked data by yourself is very difficult and
error-prone, this package handles all of the complexity for you with a simple
and safe API.
In particular, xarray-safeguards provides the
produce_data_array_correction
function to produce a correction such that certain properties of the original
data are preserved after compression, which can be stored in the same or a
different dataset (or file).
This correction can be applied to the decompressed data using the
apply_data_array_correction function or the
.safeguarded accessor on datasets.
This package also provides the .safeguards
accessor on correction or corrected data arrays to inspect the safeguards that
were applied.
By applying the corrections produced by produce_data_array_correction, data
that was compressed with badly-behaving lossy compressors can be safely used,
at the cost of potentially less efficient compression, and lossy compression
can be applied without fear.
Example
You can produce and apply the corrections to uphold an absolute error bound of \(eb_{abs} = 0.1\) for an already-compressed data array as follows:
import numpy as np
import xarray as xr
from xarray_safeguards import apply_data_array_correction, produce_data_array_correction
# some (chunked) n-dimensional data array
da = xr.DataArray(np.linspace(-10, 10, 21), name="da").chunk(10)
# lossy-compressed approximation of the data, here all zeros
da_approximation = xr.DataArray(np.zeros_like(da.values), name="da").chunk(10)
da_correction = produce_data_array_correction(
data=da,
approximation=da_approximation,
# guarantee an absolute error bound of 0.1:
# |x - x'| <= 0.1
safeguards=[dict(kind="eb", type="abs", eb=0.1)],
)
## (a) manual correction ##
da_corrected = apply_data_array_correction(da_approximation, da_correction)
np.testing.assert_allclose(da_corrected.values, da.values, rtol=0, atol=0.1)
## (b) automatic correction with xarray accessors ##
# combine the lossy approximation and the correction into one dataset
# e.g. by loading them from different files using `xarray.open_mfdataset`
ds = xr.Dataset({
da_approximation.name: da_approximation,
da_correction.name: da_correction,
})
# access the safeguarded dataset that applies all corrections
ds_safeguarded: xr.Dataset = ds.safeguarded
np.testing.assert_allclose(ds_safeguarded["da"].values, da.values, rtol=0, atol=0.1)
Please refer to the
compression_safeguards.SafeguardKind
for an enumeration of all supported safeguards.
- API Reference
Classes:
-
DatasetSafeguardedAccessor–An extension for an
xarray.Datasetthat provides the -
DataArraySafeguardsAccessor–An extension for an
xarray.DataArraythat provides
Functions:
-
produce_data_array_correction–Produce the correction required to make the
approximationdata array satisfy thesafeguardsrelative to thedataarray. -
apply_data_array_correction–Apply the
correctionto theapproximationarray to satisfy the safeguards for which thecorrectionwas produced.
DataValue
module-attribute
Parameter value type that includes scalar numbers and data arrays thereof.
- API Reference xarray_safeguards produce_data_array_correction
produce_data_array_correction
produce_data_array_correction(
data: DataArray,
approximation: DataArray,
*,
safeguards: Collection[dict[str, JSON] | Safeguard],
late_bound: Mapping[str, DataValue] = MappingProxyType(
dict()
),
check_chunks_first: bool = True,
allow_unsafe_safeguards_override: bool = False,
) -> DataArray
Produce the correction required to make the approximation data array satisfy the safeguards relative to the data array.
The data array may be chunked1 and the approximation array must use the
same chunking. Importantly, the data array must contain the complete data,
i.e. not just a sub-chunk of the data, so that non-pointwise safeguards are
correctly applied.
If the the data array is chunked, the correction is produced lazily,
otherwise it is computed eagerly.
The data array must have a name and the approximation array must use the
same name.
-
At the moment, only chunking with
daskis supported. ↩
| Parameters: |
|
|---|
| Returns: |
|
|---|
| Raises: |
|
|---|
apply_data_array_correction
Apply the correction to the approximation array to satisfy the safeguards for which the correction was produced.
The approximation must be bitwise equivalent to the approximation that
was used to produce the correction.
The approximation array may be chunked1 and the correction array must
use the same chunking, though this chunking may differ from the one that
was used to produce the correction.
If the the approximation array is chunked, the correction is applied lazily,
otherwise it its application is computed eagerly.
-
Any chunking supported by
xarrayis supported, including but not limited todask, please see https://docs.xarray.dev/en/stable/internals/chunked-arrays.html. ↩
| Parameters: |
|---|
| Returns: |
|
|---|
| Raises: |
|
|---|
DatasetSafeguardedAccessor
An extension for an xarray.Dataset that provides the
.safeguarded property that applies safeguards corrections in the dataset
to their respective variables.
The safeguarded variables must be bitwise equivalent to the variables for which their corrections were originally produced.
For instance, for a dataset ds that contains both a variable ds.foo and
its correction, you can access the corrected variable using
ds.safeguarded.foo.
| Raises: |
|
|---|
DataArraySafeguardsAccessor
An extension for an xarray.DataArray that provides
the .safeguards property that exposes the collection of
Safeguards for
a safeguards correction or corrected array.
| Raises: |
|
|---|