diff --git a/wradlib/io/xarray.py b/wradlib/io/xarray.py index ad894141b..31d630024 100644 --- a/wradlib/io/xarray.py +++ b/wradlib/io/xarray.py @@ -51,7 +51,7 @@ {} """ -__all__ = ['XRadVol', 'CfRadial', 'OdimH5', 'VolTS', 'to_cfradial2', 'to_odim', +__all__ = ['XRadVol', 'CfRadial', 'OdimH5', 'OdimTS', 'to_cfradial2', 'to_odim', 'create_xarray_dataarray'] __doc__ = __doc__.format('\n '.join(__all__)) @@ -953,6 +953,34 @@ def georeference(self, sweeps=None): for swp in sweeps: self[swp] = self[swp].pipe(xarray.georeference_dataset) + def check_azimuth(self, sweeps=None): + """Check Azimuth values + + Parameter + --------- + sweeps : list + list with sweep keys to check azimuth's, defaults to all sweeps + """ + if sweeps is None: + sweeps = self + + for swp in sweeps: + self[swp] = self[swp].pipe(_check_azimuth) + + def check_time(self, sweeps=None): + """Check time values + + Parameter + --------- + sweeps : list + list with sweep keys to check time's, defaults to all sweeps + """ + if sweeps is None: + sweeps = self + + for swp in sweeps: + self[swp] = self[swp].pipe(_check_time) + class CfRadial(XRadVol): """ Class for xarray based retrieval of CfRadial data files @@ -1176,7 +1204,10 @@ def __init__(self, filename=None, flavour=None, **kwargs): raise ValueError("File list empty") for f in filename: - self.assign_data(f, flavour=flavour, **kwargs) + try: + self.assign_data(f, flavour=flavour, **kwargs) + except xr.MergeError as e: + raise xr.MergeError(f"WRADLIB: '{e}' while merging {f}") if 'cf' in kwargs.get('standard', 'cf-mandatory'): self.assign_root() @@ -1232,6 +1263,8 @@ def assign_data(self, filename, flavour=None, **kwargs): georef = kwargs.get('georef', False) standard = kwargs.get('standard', 'cf-mandatory') dim0 = kwargs.get('dim0', 'time') + chunks = kwargs.get('chunks', None) + compat = kwargs.get('compat', 'no_conflicts') # retrieve and assign global groups /how, /what, /where groups = ['how', 'what', 'where'] @@ -1250,7 +1283,8 @@ def assign_data(self, filename, flavour=None, **kwargs): # retrieve ds and assign datasetX how/what/where group attributes groups = [None, 'how', 'what', 'where'] ds, ds_how, ds_what, ds_where = _get_odim_groups(nch.nch[sweep], - groups) + groups, + chunks=chunks) ds_grps = {'how': ds_how, 'what': ds_what, 'where': ds_where} @@ -1330,7 +1364,8 @@ def assign_data(self, filename, flavour=None, **kwargs): self.sweep_angles.append(fixed_angle) else: dictkey = self.sweep_names[index] - self._sweeps[dictkey] = xr.merge([self._sweeps[dictkey], ds]) + self._sweeps[dictkey] = xr.merge([self._sweeps[dictkey], ds], + compat=compat) def assign_root(self): # retrieve and assign global groups /how, /what, /where @@ -1378,16 +1413,16 @@ def assign_root(self): self.root = root -class VolTS(XRadVol): +class OdimTS(XRadVol): """ Class for xarray based retrieval of volume timeseries data """ - def __init__(self, filename=None, flavour=None, **kwargs): + def __init__(self, filename=None, flavour='ODIM', **kwargs): """Initialize xarray structure from hdf5 data structure. Parameters ---------- - filename : str - Source data file name. + filename : list + List of source data file names. flavour : str Name of hdf5 flavour ('ODIM' or 'GAMIC'). Defaults to 'ODIM'. @@ -1417,32 +1452,44 @@ def __init__(self, filename=None, flavour=None, **kwargs): importing all available cfradial2 metadata (not fully implemented) """ - super(VolTS, self).__init__() + super(OdimTS, self).__init__() if not isinstance(filename, list): filename = [filename] + # keyword arguments + georef = kwargs.pop('georef', False) + # get first timeslot - # Todo: make usable also for CfRadial + root = [] vol = OdimH5(filename[0], flavour=flavour, dim0='azimuth', **kwargs) - self._root = vol.root + vol.check_azimuth() + vol.check_time() + root.append(vol.root) self._sweeps = vol._sweeps self._nch = [vol._nch] - - for swp in self: - self[swp] = self[swp].pipe(_check_azimuth).pipe(_check_time) - for f in filename[1:]: + v = OdimH5(f, flavour=flavour, dim0='azimuth', **kwargs) - self._root = xr.concat([self.root, v.root], dim='time', - data_vars='different') + v.check_azimuth() + v.check_time() self._nch.append(v._nch) - for swp in self._root.sweep_group_name.values: - self[swp] = xr.concat([self[swp], v[swp].pipe(_check_azimuth). - pipe(_check_time)], - dim='time', - data_vars='different', - coords='different') + root.append(v.root) + for swp in self: + s1 = set(v[swp].variables) + s2 = set(moments_mapping) + print(list(s1 & s2)) + try: + self[swp] = xr.concat([self[swp], v[swp]], + dim='time', + data_vars=list(s1 & s2), + coords='different') + except xr.MergeError as e: + raise xr.MergeError(f"WRADLIB: '{e}' while concatenating {swp} of {f}") + if georef: + self.georeference() + self._root = xr.concat(root, dim='time', + data_vars='different') def _check_time(ds): @@ -1782,8 +1829,10 @@ def _get_odim_group_moments(nch, sweep, moments=None, **kwargs): # fix dimensions dims = dmom.dims if dims[0] == dims[1]: - datas.update({name: (['dim_0', 'dim_1'], - dmom.rename({dims[0]: 'dim_0'}))}) + da = xr.DataArray(dmom.values, attrs=attrs) + if chunks is not None: + da = da.chunk(chunks) + datas.update({name: da}) else: datas.update({name: dmom.rename({dims[0]: 'dim_0', dims[1]: 'dim_1' diff --git a/wradlib/tests/test_io.py b/wradlib/tests/test_io.py index 0566af602..74d4453f4 100644 --- a/wradlib/tests/test_io.py +++ b/wradlib/tests/test_io.py @@ -1223,7 +1223,7 @@ def test_read_odim_multi(self): files = 'hdf5/71*.h5' files = '%s/%s' % (util.get_wradlib_data_path(), files) files = glob.glob(files) - io.xarray.VolTS(files) + io.xarray.OdimTS(files) class DemTest(unittest.TestCase):