Rainbow#

import xarray as xr
from open_radar_data import DATASETS

import xradar as xd

Download#

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

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.

ds = xr.open_dataset(filename, group="sweep_0", engine="rainbow")
display(ds)
<xarray.Dataset> Size: 1MB
Dimensions:            (azimuth: 361, range: 400)
Coordinates:
  * azimuth            (azimuth) float64 3kB 0.5055 1.549 2.505 ... 358.5 359.5
    elevation          (azimuth) float64 3kB ...
    time               (azimuth) datetime64[ns] 3kB ...
  * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
    longitude          float64 8B ...
    latitude           float64 8B ...
    altitude           float64 8B ...
Data variables:
    DBZH               (azimuth, range) float64 1MB ...
    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.

ds.azimuth.sortby("time").plot(x="time")
[<matplotlib.lines.Line2D at 0x75ed067ca850>]
../_images/ccc42a9a9d1f10c2983a9277a5735f34f5157d599538a7e2b97379f2071e0737.png

Plot Range vs. Time#

We need to sort by time and specify the coordinate.

ds.DBZH.sortby("time").plot(y="time")
<matplotlib.collections.QuadMesh at 0x75ed066927b0>
../_images/98a51bdbc045ceceef2bd24ed54e59fa86838aad66cccd698499c92db93bd70c.png

Plot Range vs. Azimuth#

ds.DBZH.plot()
<matplotlib.collections.QuadMesh at 0x75ed065c2490>
../_images/84f67bd79325a24a8f6fed4826740f6e6dfe9b2e6894c7523813458b0b0459fa.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.

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_as_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: 'T_PathFileOrDataStore') -> 'bool'
 |      Backend open_dataset method used by Xarray in :py:func:`~xarray.open_dataset`.
 |
 |  open_datatree(
 |      self,
 |      filename_or_obj: 'T_PathFileOrDataStore',
 |      *,
 |      drop_variables: 'str | Iterable[str] | None' = None
 |  ) -> 'DataTree'
 |      Backend open_datatree method used by Xarray in :py:func:`~xarray.open_datatree`.
 |
 |      If implemented, set the class variable supports_groups to True.
 |
 |  open_groups_as_dict(
 |      self,
 |      filename_or_obj: 'T_PathFileOrDataStore',
 |      *,
 |      drop_variables: 'str | Iterable[str] | None' = None
 |  ) -> 'dict[str, Dataset]'
 |      Opens a dictionary mapping from group names to Datasets.
 |
 |      Called by :py:func:`~xarray.open_groups`.
 |      This function exists to provide a universal way to open all groups in a file,
 |      before applying any additional consistency checks or requirements necessary
 |      to create a `DataTree` object (typically done using :py:meth:`~xarray.DataTree.from_dict`).
 |
 |      If implemented, set the class variable supports_groups to True.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from xarray.backends.common.BackendEntrypoint:
 |
 |  __dict__
 |      dictionary for instance variables
 |
 |  __weakref__
 |      list of weak references to the object
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from xarray.backends.common.BackendEntrypoint:
 |
 |  supports_groups = False
ds = xr.open_dataset(filename, group="sweep_1", engine="rainbow", first_dim="time")
display(ds)
<xarray.Dataset> Size: 1MB
Dimensions:            (time: 361, range: 400)
Coordinates:
  * time               (time) datetime64[ns] 3kB 2013-05-10T00:00:19.01515150...
    azimuth            (time) float64 3kB ...
    elevation          (time) float64 3kB ...
  * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
    longitude          float64 8B ...
    latitude           float64 8B ...
    altitude           float64 8B ...
Data variables:
    DBZH               (time, range) float64 1MB ...
    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.

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:`xarray.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_as_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: xarray.DataTree
        DataTree
dtree = xd.io.open_rainbow_datatree(filename, sweep="sweep_8")
display(dtree)
<xarray.DataTree>
Group: /
│   Dimensions:              (sweep: 1)
│   Coordinates:
│       latitude             float64 8B ...
│       longitude            float64 8B ...
│       altitude             float64 8B ...
│   Dimensions without coordinates: sweep
│   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'
│       sweep_group_name     (sweep) int64 8B 8
│       sweep_fixed_angle    (sweep) float64 8B 12.2
│   Attributes:
│       Conventions:      None
│       instrument_name:  None
│       version:          None
│       title:            None
│       institution:      None
│       references:       None
│       source:           None
│       history:          None
│       comment:          im/exported using xradar
└── Group: /sweep_0
        Dimensions:            (azimuth: 361, range: 400)
        Coordinates:
          * azimuth            (azimuth) float64 3kB 0.5 1.544 2.51 ... 358.5 359.5
            elevation          (azimuth) float64 3kB ...
            time               (azimuth) datetime64[ns] 3kB 2013-05-10T00:02:03.10606...
          * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
        Data variables:
            DBZH               (azimuth, range) float64 1MB ...
            sweep_mode         <U20 80B ...
            sweep_number       int64 8B ...
            prt_mode           <U7 28B ...
            follow_mode        <U7 28B ...
            sweep_fixed_angle  float64 8B ...

Plot Sweep Range vs. Time#

dtree["sweep_0"].ds.DBZH.sortby("time").plot(y="time")
<matplotlib.collections.QuadMesh at 0x75ecfc9b6c10>
../_images/60da3e4ef4ba6fdf7b1794508cfa36448a7db4b5e0bc06dd2d0d13bcdd5425c0.png

Plot Sweep Range vs. Azimuth#

dtree["sweep_0"].ds.DBZH.plot()
<matplotlib.collections.QuadMesh at 0x75ecfc8ac550>
../_images/0b294e6814c343eecf55b73b4793a2652bdc40c21b27ac5bd1db914a6acb3ee8.png
dtree = xd.io.open_rainbow_datatree(filename, sweep="sweep_8")
display(dtree)
<xarray.DataTree>
Group: /
│   Dimensions:              (sweep: 1)
│   Coordinates:
│       latitude             float64 8B ...
│       longitude            float64 8B ...
│       altitude             float64 8B ...
│   Dimensions without coordinates: sweep
│   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'
│       sweep_group_name     (sweep) int64 8B 8
│       sweep_fixed_angle    (sweep) float64 8B 12.2
│   Attributes:
│       Conventions:      None
│       instrument_name:  None
│       version:          None
│       title:            None
│       institution:      None
│       references:       None
│       source:           None
│       history:          None
│       comment:          im/exported using xradar
└── Group: /sweep_0
        Dimensions:            (azimuth: 361, range: 400)
        Coordinates:
          * azimuth            (azimuth) float64 3kB 0.5 1.544 2.51 ... 358.5 359.5
            elevation          (azimuth) float64 3kB ...
            time               (azimuth) datetime64[ns] 3kB 2013-05-10T00:02:03.10606...
          * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
        Data variables:
            DBZH               (azimuth, range) float64 1MB ...
            sweep_mode         <U20 80B ...
            sweep_number       int64 8B ...
            prt_mode           <U7 28B ...
            follow_mode        <U7 28B ...
            sweep_fixed_angle  float64 8B ...
dtree = xd.io.open_rainbow_datatree(filename, sweep=[0, 1, 8])
display(dtree)
<xarray.DataTree>
Group: /
│   Dimensions:              (sweep: 3)
│   Coordinates:
│       latitude             float64 8B ...
│       longitude            float64 8B ...
│       altitude             float64 8B ...
│   Dimensions without coordinates: sweep
│   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'
│       sweep_group_name     (sweep) int64 24B 1 2 9
│       sweep_fixed_angle    (sweep) float64 24B 1.4 2.4 14.8
│   Attributes:
│       Conventions:      None
│       instrument_name:  None
│       version:          None
│       title:            None
│       institution:      None
│       references:       None
│       source:           None
│       history:          None
│       comment:          im/exported using xradar
├── Group: /sweep_0
│       Dimensions:            (azimuth: 361, range: 400)
│       Coordinates:
│         * azimuth            (azimuth) float64 3kB 0.5055 1.549 2.516 ... 358.5 359.5
│           elevation          (azimuth) float64 3kB ...
│           time               (azimuth) datetime64[ns] 3kB 2013-05-10T00:00:25.62121...
│         * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
│       Data variables:
│           DBZH               (azimuth, range) float64 1MB ...
│           sweep_mode         <U20 80B ...
│           sweep_number       int64 8B ...
│           prt_mode           <U7 28B ...
│           follow_mode        <U7 28B ...
│           sweep_fixed_angle  float64 8B ...
├── Group: /sweep_1
│       Dimensions:            (azimuth: 361, range: 400)
│       Coordinates:
│         * azimuth            (azimuth) float64 3kB 0.511 1.505 2.505 ... 358.5 359.5
│           elevation          (azimuth) float64 3kB ...
│           time               (azimuth) datetime64[ns] 3kB 2013-05-10T00:00:36.65151...
│         * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
│       Data variables:
│           DBZH               (azimuth, range) float64 1MB ...
│           sweep_mode         <U20 80B ...
│           sweep_number       int64 8B ...
│           prt_mode           <U7 28B ...
│           follow_mode        <U7 28B ...
│           sweep_fixed_angle  float64 8B ...
└── Group: /sweep_2
        Dimensions:            (azimuth: 361, range: 400)
        Coordinates:
          * azimuth            (azimuth) float64 3kB 0.522 1.516 2.51 ... 358.5 359.5
            elevation          (azimuth) float64 3kB ...
            time               (azimuth) datetime64[ns] 3kB 2013-05-10T00:02:14.19696...
          * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
        Data variables:
            DBZH               (azimuth, range) float64 1MB ...
            sweep_mode         <U20 80B ...
            sweep_number       int64 8B ...
            prt_mode           <U7 28B ...
            follow_mode        <U7 28B ...
            sweep_fixed_angle  float64 8B ...
dtree = xd.io.open_rainbow_datatree(filename, sweep=["sweep_1", "sweep_2", "sweep_8"])
display(dtree)
<xarray.DataTree>
Group: /
│   Dimensions:              (sweep: 3)
│   Coordinates:
│       latitude             float64 8B ...
│       longitude            float64 8B ...
│       altitude             float64 8B ...
│   Dimensions without coordinates: sweep
│   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'
│       sweep_group_name     (sweep) int64 24B 1 2 8
│       sweep_fixed_angle    (sweep) float64 24B 1.4 2.4 12.2
│   Attributes:
│       Conventions:      None
│       instrument_name:  None
│       version:          None
│       title:            None
│       institution:      None
│       references:       None
│       source:           None
│       history:          None
│       comment:          im/exported using xradar
├── Group: /sweep_0
│       Dimensions:            (azimuth: 361, range: 400)
│       Coordinates:
│         * azimuth            (azimuth) float64 3kB 0.5055 1.549 2.516 ... 358.5 359.5
│           elevation          (azimuth) float64 3kB ...
│           time               (azimuth) datetime64[ns] 3kB 2013-05-10T00:00:25.62121...
│         * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
│       Data variables:
│           DBZH               (azimuth, range) float64 1MB ...
│           sweep_mode         <U20 80B ...
│           sweep_number       int64 8B ...
│           prt_mode           <U7 28B ...
│           follow_mode        <U7 28B ...
│           sweep_fixed_angle  float64 8B ...
├── Group: /sweep_1
│       Dimensions:            (azimuth: 361, range: 400)
│       Coordinates:
│         * azimuth            (azimuth) float64 3kB 0.511 1.505 2.505 ... 358.5 359.5
│           elevation          (azimuth) float64 3kB ...
│           time               (azimuth) datetime64[ns] 3kB 2013-05-10T00:00:36.65151...
│         * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
│       Data variables:
│           DBZH               (azimuth, range) float64 1MB ...
│           sweep_mode         <U20 80B ...
│           sweep_number       int64 8B ...
│           prt_mode           <U7 28B ...
│           follow_mode        <U7 28B ...
│           sweep_fixed_angle  float64 8B ...
└── Group: /sweep_2
        Dimensions:            (azimuth: 361, range: 400)
        Coordinates:
          * azimuth            (azimuth) float64 3kB 0.5 1.544 2.51 ... 358.5 359.5
            elevation          (azimuth) float64 3kB ...
            time               (azimuth) datetime64[ns] 3kB 2013-05-10T00:02:03.10606...
          * range              (range) float32 2kB 125.0 375.0 ... 9.962e+04 9.988e+04
        Data variables:
            DBZH               (azimuth, range) float64 1MB ...
            sweep_mode         <U20 80B ...
            sweep_number       int64 8B ...
            prt_mode           <U7 28B ...
            follow_mode        <U7 28B ...
            sweep_fixed_angle  float64 8B ...