xradar is in an early stage of development, please report any issues here!

Rainbow#

[1]:
import os
import xarray as xr
import xradar as xd
from open_radar_data import DATASETS

Download#

Fetching Rainbow radar data file from open-radar-data repository.

[2]:
filename = DATASETS.fetch("2013051000000600dBZ.vol")
Downloading file '2013051000000600dBZ.vol' from 'https://github.com/openradar/open-radar-data/raw/main/data/2013051000000600dBZ.vol' to '/home/docs/.cache/open-radar-data'.

xr.open_dataset#

Making use of the xarray rainbow backend. We also need to provide the group. Note, that we are using CfRadial2 group access pattern.

[3]:
ds = xr.open_dataset(filename, group="sweep_0", engine="rainbow")
display(ds)
<xarray.Dataset> Size: 588kB
Dimensions:            (azimuth: 361, range: 400)
Coordinates:
    elevation          (azimuth) float64 3kB ...
  * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
    time               (azimuth) datetime64[ns] 3kB ...
    longitude          float64 8B ...
    latitude           float64 8B ...
    altitude           float64 8B ...
  * azimuth            (azimuth) float64 3kB 0.5055 1.549 2.505 ... 358.5 359.5
Data variables:
    DBZH               (azimuth, range) float32 578kB ...
    sweep_mode         <U20 80B ...
    sweep_number       int64 8B ...
    prt_mode           <U7 28B ...
    follow_mode        <U7 28B ...
    sweep_fixed_angle  float64 8B ...

Plot Time vs. Azimuth#

We need to sort by time and specify the coordinate.

[4]:
ds.azimuth.sortby("time").plot(x="time")
[4]:
[<matplotlib.lines.Line2D at 0x7f2cb0c1fc10>]
../_images/notebooks_Rainbow_7_1.png

Plot Range vs. Time#

We need to sort by time and specify the coordinate.

[5]:
ds.DBZH.sortby("time").plot(y="time")
[5]:
<matplotlib.collections.QuadMesh at 0x7f2ca8876750>
../_images/notebooks_Rainbow_9_1.png

Plot Range vs. Azimuth#

[6]:
ds.DBZH.plot()
[6]:
<matplotlib.collections.QuadMesh at 0x7f2ca894f150>
../_images/notebooks_Rainbow_11_1.png

backend_kwargs#

Beside first_dim there are several additional backend_kwargs for the rainbow backend, which handle different aspects of angle alignment. This comes into play, when azimuth and/or elevation arrays are not evenly spacend and other issues.

[7]:
help(xd.io.RainbowBackendEntrypoint)
Help on class RainbowBackendEntrypoint in module xradar.io.backends.rainbow:

class RainbowBackendEntrypoint(xarray.backends.common.BackendEntrypoint)
 |  Xarray BackendEntrypoint for Rainbow5 data.
 |
 |  Method resolution order:
 |      RainbowBackendEntrypoint
 |      xarray.backends.common.BackendEntrypoint
 |      builtins.object
 |
 |  Methods defined here:
 |
 |  open_dataset(self, filename_or_obj, *, mask_and_scale=True, decode_times=True, concat_characters=True, decode_coords=True, drop_variables=None, use_cftime=None, decode_timedelta=None, group=None, reindex_angle=False, first_dim='auto', site_coords=True)
 |      Backend open_dataset method used by Xarray in :py:func:`~xarray.open_dataset`.
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |
 |  __annotations__ = {}
 |
 |  description = 'Open Rainbow5 files in Xarray'
 |
 |  open_dataset_parameters = ('filename_or_obj', 'mask_and_scale', 'decod...
 |
 |  url = 'https://xradar.rtfd.io/latest/io.html#rainbow-data-i-o'
 |
 |  ----------------------------------------------------------------------
 |  Methods inherited from xarray.backends.common.BackendEntrypoint:
 |
 |  __repr__(self) -> 'str'
 |      Return repr(self).
 |
 |  guess_can_open(self, filename_or_obj: 'str | os.PathLike[Any] | BufferedIOBase | AbstractDataStore') -> 'bool'
 |      Backend open_dataset method used by Xarray in :py:func:`~xarray.open_dataset`.
 |
 |  open_datatree(self, filename_or_obj: 'str | os.PathLike[Any] | BufferedIOBase | AbstractDataStore', **kwargs: 'Any') -> 'DataTree'
 |      Backend open_datatree method used by Xarray in :py:func:`~xarray.open_datatree`.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from xarray.backends.common.BackendEntrypoint:
 |
 |  __dict__
 |      dictionary for instance variables
 |
 |  __weakref__
 |      list of weak references to the object

[8]:
ds = xr.open_dataset(filename, group="sweep_1", engine="rainbow", first_dim="time")
display(ds)
<xarray.Dataset> Size: 588kB
Dimensions:            (time: 361, range: 400)
Coordinates:
    elevation          (time) float64 3kB ...
  * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
  * time               (time) datetime64[ns] 3kB 2013-05-10T00:00:19.01515150...
    longitude          float64 8B ...
    latitude           float64 8B ...
    altitude           float64 8B ...
    azimuth            (time) float64 3kB ...
Data variables:
    DBZH               (time, range) float32 578kB ...
    sweep_mode         <U20 80B ...
    sweep_number       int64 8B ...
    prt_mode           <U7 28B ...
    follow_mode        <U7 28B ...
    sweep_fixed_angle  float64 8B ...

open_odim_datatree#

The same works analoguous with the datatree loader. But additionally we can provide a sweep string, number or list.

[9]:
help(xd.io.open_rainbow_datatree)
Help on function open_rainbow_datatree in module xradar.io.backends.rainbow:

open_rainbow_datatree(filename_or_obj, **kwargs)
    Open ODIM_H5 dataset as :py:class:`datatree.DataTree`.

    Parameters
    ----------
    filename_or_obj : str, Path, file-like or DataStore
        Strings and Path objects are interpreted as a path to a local or remote
        radar file

    Keyword Arguments
    -----------------
    sweep : int, list of int, optional
        Sweep number(s) to extract, default to first sweep. If None, all sweeps are
        extracted into a list.
    first_dim : str
        Can be ``time`` or ``auto`` first dimension. If set to ``auto``,
        first dimension will be either ``azimuth`` or ``elevation`` depending on
        type of sweep. Defaults to ``auto``.
    reindex_angle : bool or dict
        Defaults to False, no reindexing. Given dict should contain the kwargs to
        reindex_angle. Only invoked if `decode_coord=True`.
    fix_second_angle : bool
        If True, fixes erroneous second angle data. Defaults to ``False``.
    site_coords : bool
        Attach radar site-coordinates to Dataset, defaults to ``True``.
    kwargs : dict
        Additional kwargs are fed to :py:func:`xarray.open_dataset`.

    Returns
    -------
    dtree: datatree.DataTree
        DataTree

[10]:
dtree = xd.io.open_rainbow_datatree(filename, sweep="sweep_8")
display(dtree)
<xarray.DatasetView> Size: 232B
Dimensions:              ()
Data variables:
    volume_number        int64 8B 0
    platform_type        <U5 20B 'fixed'
    instrument_type      <U5 20B 'radar'
    time_coverage_start  <U20 80B '2013-05-10T00:01:55Z'
    time_coverage_end    <U20 80B '2013-05-10T00:02:05Z'
    longitude            float64 8B 6.38
    altitude             float64 8B 116.7
    latitude             float64 8B 50.86
Attributes:
    Conventions:      None
    instrument_name:  None
    version:          None
    title:            None
    institution:      None
    references:       None
    source:           None
    history:          None
    comment:          im/exported using xradar

Plot Sweep Range vs. Time#

[11]:
dtree["sweep_0"].ds.DBZH.sortby("time").plot(y="time")
[11]:
<matplotlib.collections.QuadMesh at 0x7f2ca6c23b10>
../_images/notebooks_Rainbow_19_1.png

Plot Sweep Range vs. Azimuth#

[12]:
dtree["sweep_0"].ds.DBZH.plot()
[12]:
<matplotlib.collections.QuadMesh at 0x7f2cb09df910>
../_images/notebooks_Rainbow_21_1.png
[13]:
dtree = xd.io.open_rainbow_datatree(filename, sweep="sweep_8")
display(dtree)
<xarray.DatasetView> Size: 232B
Dimensions:              ()
Data variables:
    volume_number        int64 8B 0
    platform_type        <U5 20B 'fixed'
    instrument_type      <U5 20B 'radar'
    time_coverage_start  <U20 80B '2013-05-10T00:01:55Z'
    time_coverage_end    <U20 80B '2013-05-10T00:02:05Z'
    longitude            float64 8B 6.38
    altitude             float64 8B 116.7
    latitude             float64 8B 50.86
Attributes:
    Conventions:      None
    instrument_name:  None
    version:          None
    title:            None
    institution:      None
    references:       None
    source:           None
    history:          None
    comment:          im/exported using xradar
[14]:
dtree = xd.io.open_rainbow_datatree(filename, sweep=[0, 1, 8])
display(dtree)
<xarray.DatasetView> Size: 232B
Dimensions:              ()
Data variables:
    volume_number        int64 8B 0
    platform_type        <U5 20B 'fixed'
    instrument_type      <U5 20B 'radar'
    time_coverage_start  <U20 80B '2013-05-10T00:00:19Z'
    time_coverage_end    <U20 80B '2013-05-10T00:02:19Z'
    longitude            float64 8B 6.38
    altitude             float64 8B 116.7
    latitude             float64 8B 50.86
Attributes:
    Conventions:      None
    instrument_name:  None
    version:          None
    title:            None
    institution:      None
    references:       None
    source:           None
    history:          None
    comment:          im/exported using xradar
[15]:
dtree = xd.io.open_rainbow_datatree(filename, sweep=["sweep_1", "sweep_2", "sweep_8"])
display(dtree)
<xarray.DatasetView> Size: 232B
Dimensions:              ()
Data variables:
    volume_number        int64 8B 0
    platform_type        <U5 20B 'fixed'
    instrument_type      <U5 20B 'radar'
    time_coverage_start  <U20 80B '2013-05-10T00:00:19Z'
    time_coverage_end    <U20 80B '2013-05-10T00:02:05Z'
    longitude            float64 8B 6.38
    altitude             float64 8B 116.7
    latitude             float64 8B 50.86
Attributes:
    Conventions:      None
    instrument_name:  None
    version:          None
    title:            None
    institution:      None
    references:       None
    source:           None
    history:          None
    comment:          im/exported using xradar