i7aof.io

Utilities for writing NetCDF and related I/O helpers. See i7aof.io for developer details.

i7aof.io.read_dataset(path, **kwargs) Dataset

Open a dataset with package defaults and normalize time metadata.

  • Ensures cftime decoding for robust non-standard calendars.

  • If both time and time_bnds are present, propagate the same units/calendar into time_bnds attributes (not encoding) so that both variables serialize consistently. This avoids placing units/calendar in encodings, which recent backends reject.

Any extra keyword arguments are passed through to xarray.open_dataset. By default, this function sets decode_times=CFDatetimeCoder(use_cftime=True) unless explicitly overridden, ensuring decoded CF-time coordinates backed by cftime objects for predictable behavior across calendars.

i7aof.io.write_netcdf(ds, filename, fillvalues=None, format=None, engine=None, progress_bar=False, has_fill_values=None)

Write an xarray.Dataset to a file with NetCDF4 fill values

Parameters:
  • ds (xarray.Dataset) – The dataset to save

  • filename (str) – The path for the NetCDF file to write

  • fillvalues (dict, optional) – A dictionary of fill values for different NetCDF types. Default is netCDF4.default_fillvals

  • format ({'NETCDF4', 'NETCDF4_CLASSIC', 'NETCDF3_64BIT', 'NETCDF3_CLASSIC'}, optional) – The NetCDF file format to use, the default is ‘NETCDF4’

  • engine ({'netcdf4', 'scipy', 'h5netcdf'}, optional) – The library to use for NetCDF output, the default is ‘netcdf4’

  • has_fill_values (bool | dict | callable, optional) –

    Controls whether to apply _FillValue per variable without scanning data:

    • bool: apply to all variables (True adds, False omits)

    • dict: mapping of var_name -> bool

    • callable: function (var_name, var: xarray.DataArray) -> bool

    If omitted (None), the function determines necessity by checking for NaNs using xarray’s lazy operations (var.isnull().any().compute()), which is safe for chunked datasets. For unchunked datasets, the scan may load data into memory; callers can avoid this by opening datasets with Dask chunks.