Source code for xradar.transform.cfradial

#!/usr/bin/env python
# Copyright (c) 2024, openradar developers.
# Distributed under the MIT License. See LICENSE for more info.
"""
Transform CF-Radial
===================

This module provides the utilities to convert between CfRadial1 and
CfRadial2 formats, following WMO guidelines for radar data processing.

.. autosummary::
   :nosignatures:
   :toctree: generated/

    {}

to_cfradial1
------------
Convert a `xarray.DataTree` object to CfRadial1 format. The output is
an `xarray.Dataset` following the CfRadial1 standard, which can be used
for radar data visualization and further processing.

Parameters:
    - dtree: xarray.DataTree
        Radar xarray object to convert.
    - filename: str (optional)
        Output file name for the CfRadial1 dataset.
    - calibs: bool (default: True)
        Whether to include calibration parameters.

Returns:
    - dataset: xarray.Dataset
        Converted dataset in CfRadial1 format.

to_cfradial2
------------
Convert a `xarray.Dataset` object to CfRadial2 format by mapping the
structure back into a `xarray.DataTree`.

Parameters:
    - ds: xarray.Dataset
        CfRadial1 dataset to convert.
    - kwargs: dict
        Additional keyword arguments for controlling the conversion, such
        as specifying sweeps or metadata inclusion.

Returns:
    - dtree: xarray.DataTree
        Converted data tree in CfRadial2 format.

"""

__all__ = [
    "to_cfradial2",
    "to_cfradial1",
]

__doc__ = __doc__.format("\n   ".join(__all__))

from importlib.metadata import version

from xarray import DataTree

from ..io.backends.cfradial1 import (
    _get_radar_calibration,
    _get_required_root_dataset,
    _get_subgroup,
    _get_sweep_groups,
)
from ..io.backends.common import _attach_sweep_groups
from ..io.export.cfradial1 import (
    _calib_mapper,
    _variable_mapper,
)
from ..model import (
    georeferencing_correction_subgroup,
    radar_parameters_subgroup,
)


# to_cfradial1 function implementation
[docs] def to_cfradial1(dtree=None, calibs=True): """ Convert a radar xarray.DataTree to the CFRadial1 format and save it to a file. Ensure that the resulting dataset is well-formed and does not include specified extraneous variables. Parameters ---------- dtree: xarray.DataTree Radar xarray.DataTree object. calibs: Bool, optional Whether to include calibration parameters. """ # Generate the initial ds_cf using the existing mapping functions dataset = _variable_mapper(dtree) # Handle calibration parameters if calibs: if "radar_calibration" in dtree: calib_params = dtree["radar_calibration"].to_dataset() calibs = _calib_mapper(calib_params) dataset.update(calibs) # Add additional parameters if they exist in dtree if "radar_parameters" in dtree: radar_params = dtree["radar_parameters"].to_dataset().reset_coords() dataset.update(radar_params) if "georeferencing_correction" in dtree: radar_georef = dtree["georeferencing_correction"].to_dataset().reset_coords() dataset.update(radar_georef) # Ensure that the data type of sweep_mode and similar variables matches if "sweep_mode" in dataset.variables: dataset["sweep_mode"] = dataset["sweep_mode"].astype("S") # Update global attributes dataset.attrs = dtree.attrs dataset.attrs["Conventions"] = "Cf/Radial" dataset.attrs["version"] = "1.2" xradar_version = version("xradar") dataset.attrs["history"] += f": xradar v{xradar_version} CfRadial1 export" return dataset
# to_cfradial2 function implementation
[docs] def to_cfradial2(ds, **kwargs): """Convert a CfRadial1 Dataset to CfRadial2 DataTree.""" first_dim = kwargs.pop("first_dim", "auto") optional = kwargs.pop("optional", True) kwargs.pop("site_coords", True) sweep = kwargs.pop("sweep", None) # Create DataTree root node with required data root_data = _get_required_root_dataset(ds, optional=optional) dtree = DataTree(dataset=root_data, name="root") # Attach additional root metadata groups as child nodes radar_parameters = _get_subgroup(ds, radar_parameters_subgroup) if radar_parameters: dtree["radar_parameters"] = DataTree(radar_parameters, name="radar_parameters") calib = _get_radar_calibration(ds) if calib: dtree["radar_calibration"] = DataTree(calib, name="radar_calibration") georeferencing = _get_subgroup(ds, georeferencing_correction_subgroup) if georeferencing: dtree["georeferencing_correction"] = DataTree( georeferencing, name="georeferencing_correction" ) # Attach sweep child nodes sweep_groups = list( _get_sweep_groups( ds, sweep=sweep, first_dim=first_dim, optional=optional, site_coords=True, ).values() ) dtree = _attach_sweep_groups(dtree, sweep_groups) return dtree