Source code for swarmpal.io._cdf_interface

from __future__ import annotations

import logging

import pycdfpp
from viresclient._data_handling import FileReader
from xarray import Dataset

logger = logging.getLogger(__name__)


[docs] def cdf_to_xarray_viresclient( cdf_file, ): """Using viresclient FileReader""" with open(cdf_file, "rb") as f: with FileReader(f) as fr: return fr.as_xarray_dataset()
[docs] def cdf_to_xarray(cdf_file): """Using pycdfpp""" cdf = pycdfpp.load(str(cdf_file)) timevars = ("Timestamp",) # NB hardcoded for now, but should be made flexible ds = Dataset() # Add all the variables for varname, data in cdf.items(): timevar = timevars[0] num_dims = len(data.shape) cdf_type = data.type dim_names = [timevar] + [f"{varname}_dim_{i}" for i in range(1, num_dims)] if str(cdf_type).endswith("CDF_EPOCH"): ds[varname] = dim_names, pycdfpp.to_datetime64(data) else: ds[varname] = dim_names, data attrs = {} for _, attr in dict(data.attributes).items(): attrs[attr.name] = attr.value ds[varname].attrs = attrs # Add global attributes for attr_name, attr_value in cdf.attributes.items(): _attr_value = attr_value[0] if len(attr_value) == 1 else list(attr_value) ds.attrs[attr_name] = _attr_value return ds
[docs] def xarray_to_cdf(ds, file_name): cdf = pycdfpp.CDF() # Global attributes for attr_name, attr_value in ds.attrs.items(): _attr_value = [attr_value] if not isinstance(attr_value, list) else attr_value try: cdf.add_attribute(attr_name, _attr_value) except Exception as e: logger.warning(f"Error adding attribute {attr_name}: {e}") # # Coordinates # for var_name, var_data in ds.coords.items(): # cdf.add_variable(var_name, var_data.values, compression=pycdfpp.CompressionType.gzip_compression) # for attr_name, attr_value in var_data.attrs.items(): # cdf[var_name].add_attribute(attr_name, attr_value) # Only add Timestamp coordinate (typically the only coordinate in the dataset) # Fix Timestamp to CDF_EPOCH to match source data cdf.add_variable( "Timestamp", ds["Timestamp"].values, pycdfpp.DataType.CDF_EPOCH, compression=pycdfpp.CompressionType.gzip_compression, ) # Data variables for var_name, var_data in ds.data_vars.items(): _var_data = var_data.astype("str") if var_name == "Spacecraft" else var_data try: cdf.add_variable( var_name, _var_data.values, compression=pycdfpp.CompressionType.gzip_compression, ) for attr_name, attr_value in _var_data.attrs.items(): cdf[var_name].add_attribute(attr_name, attr_value) except Exception as e: logger.warning(f"Error adding variable {var_name}: {e}") pycdfpp.save(cdf, file_name)