diff --git a/continuous_integration/environment-ci.yml b/continuous_integration/environment-ci.yml index 941c2135b9..629c63aa67 100644 --- a/continuous_integration/environment-ci.yml +++ b/continuous_integration/environment-ci.yml @@ -26,6 +26,7 @@ dependencies: - shapely - ruff - mda-xdrlib + - xradar>=0.5.0 - pip - pip: - cibuildwheel diff --git a/doc/environment.yml b/doc/environment.yml index bbcc740206..7f8ee4e387 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -35,6 +35,7 @@ dependencies: - pre_commit - cmweather - mda-xdrlib + - xradar>=0.5.0 - pip - pip: - pooch diff --git a/pyart/xradar/accessor.py b/pyart/xradar/accessor.py index 548f8c17f8..90b7c66c7c 100644 --- a/pyart/xradar/accessor.py +++ b/pyart/xradar/accessor.py @@ -12,6 +12,7 @@ from datatree.treenode import NodePath from xarray import DataArray, Dataset, concat from xarray.core import utils +from xradar.util import get_sweep_keys from ..config import get_metadata from ..core.transforms import ( @@ -271,7 +272,9 @@ class Xradar: def __init__(self, xradar, default_sweep="sweep_0", scan_type=None): self.xradar = xradar self.scan_type = scan_type or "ppi" - self.combined_sweeps = self._combine_sweeps(self.xradar) + self.sweep_group_names = get_sweep_keys(self.xradar) + self.nsweeps = len(self.sweep_group_names) + self.combined_sweeps = self._combine_sweeps() self.fields = self._find_fields(self.combined_sweeps) self.time = dict( data=(self.combined_sweeps.time - self.combined_sweeps.time.min()).astype( @@ -304,8 +307,7 @@ def __init__(self, xradar, default_sweep="sweep_0", scan_type=None): self.metadata = dict(**self.xradar.attrs) self.ngates = len(self.range["data"]) self.nrays = len(self.azimuth["data"]) - self.nsweeps = len(self.xradar.sweep_group_name) - self.instrument_parameters = dict(**self.xradar["radar_parameters"].attrs) + self.instrument_parameters = self.find_instrument_parameters() self.init_gate_x_y_z() self.init_gate_alt() @@ -351,6 +353,37 @@ def __getitem__(self: DataTree, key): # Iterators + def find_instrument_parameters(self): + # By default, check the radar_parameters first + if "radar_parameters" in list(self.xradar.children): + radar_param_dict = self.xradar["radar_parameters"].ds.to_dict(data="array") + instrument_parameters = radar_param_dict["data_vars"] + instrument_parameters.update(radar_param_dict["attrs"]) + + else: + instrument_parameters = {} + + # Check to see if the root dataset has this info + if len(self.xradar.ds) > 0: + root_param_dict = self.xradar.ds.to_dict(data="array") + instrument_parameters.update(root_param_dict["data_vars"]) + instrument_parameters.update(root_param_dict["attrs"]) + + if len(instrument_parameters.keys()) > 0: + for field in instrument_parameters.keys(): + field_dict = instrument_parameters[field] + if isinstance(field_dict, dict): + if "attrs" in field_dict: + for param in field_dict["attrs"]: + field_dict[param] = field_dict["attrs"][param] + del field_dict["attrs"] + + if "dims" in field_dict: + del field_dict["dims"] + instrument_parameters[field] = field_dict + + return instrument_parameters + def iter_start(self): """Return an iterator over the sweep start indices.""" return (s for s in self.sweep_start_ray_index["data"]) @@ -546,11 +579,11 @@ def init_gate_alt(self): data=np.mean(self.altitude["data"]) + self.gate_z["data"] ) - def _combine_sweeps(self, radar): + def _combine_sweeps(self): # Loop through and extract the different datasets ds_list = [] - for sweep in radar.sweep_group_name.values: - ds_list.append(radar[sweep].ds.drop_duplicates("azimuth")) + for sweep in self.sweep_group_names: + ds_list.append(self.xradar[sweep].ds.drop_duplicates("azimuth")) # Merge based on the sweep number merged = concat(ds_list, dim="sweep_number") diff --git a/tests/xradar/test_accessor.py b/tests/xradar/test_accessor.py index 1412eb9538..611ef4ad2d 100644 --- a/tests/xradar/test_accessor.py +++ b/tests/xradar/test_accessor.py @@ -19,6 +19,21 @@ def test_get_field(filename=filename): assert reflectivity.shape == (480, 996) +def test_instrument_parameters(filename=filename): + dtree = xd.io.open_cfradial1_datatree( + filename, + optional=False, + ) + radar = pyart.xradar.Xradar(dtree) + assert radar.instrument_parameters["instrument_name"] == "SPOLRVP8" + assert_allclose( + radar.instrument_parameters["latitude"]["data"], np.array(22.52669907) + ) + assert_allclose( + radar.instrument_parameters["longitude"]["data"], np.array(120.4335022) + ) + + def test_get_gate_x_y_z(filename=filename): dtree = xd.io.open_cfradial1_datatree( filename,