In [1]:

# flake8: noqa


# Routine verification measures for radar-based precipitation estimates¶

In [2]:

import wradlib
import os
import numpy as np
import matplotlib.pyplot as pl
import warnings
warnings.filterwarnings('ignore')
try:
get_ipython().magic("matplotlib inline")
except:
pl.ion()

/home/travis/miniconda/envs/wradlib/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from float to np.floating is deprecated. In future, it will be treated as np.float64 == np.dtype(float).type.
from ._conv import register_converters as _register_converters


## Extract bin values from a polar radar data set at rain gage locations¶

In [3]:

filename = wradlib.util.get_wradlib_data_file('misc/polar_R_tur.gz')


### Define site coordinates (lon/lat) and polar coordinate system¶

In [4]:

r = np.arange(1,129)
az = np.linspace(0,360,361)[0:-1]
sitecoords = (9.7839, 48.5861)


### Make up two rain gauge locations (say we want to work in Gaus Krueger zone 3)¶

In [5]:

# Define the projection via epsg-code
# Coordinates of the rain gages in Gauss-Krueger 3 coordinates
x, y = np.array([3557880, 3557890]), np.array([5383379, 5383375])


### Now extract the radar values at those bins that are closest to our rain gauges¶

For this purppose, we use the PolarNeighbours class from wraldib’s verify module. Here, we extract the 9 nearest bins…

In [6]:

polarneighbs = wradlib.verify.PolarNeighbours(r, az, sitecoords, proj, x, y, nnear=9)

Radar values at rain gauge #1: [0.01, 0.01, 0.02, 0.02, 0.01, 0.01, 0.02, 0.01, 0.05]
Radar values at rain gauge #2: [0.15, 0.2, 0.06, 0.06, 0.26, 0.69, 0.03, 0.05, 0.09]


### Retrieve the bin coordinates (all of them or those at the rain gauges)¶

In [7]:

binx, biny = polarneighbs.get_bincoords()
binx_nn, biny_nn = polarneighbs.get_bincoords_at_points()


### Plot the entire radar domain and zoom into the surrounding of the rain gauge locations¶

In [8]:

fig = pl.figure(figsize=(12,12))
ax.plot(binx, biny, 'r+')
ax.plot(binx_nn, biny_nn, 'b+', markersize=10)
ax.plot(x, y, 'bo')
ax.axis('tight')
ax.set_aspect("equal")
pl.title("Full view")
ax.plot(binx, biny, 'r+')
ax.plot(binx_nn, biny_nn, 'b+', markersize=10)
ax.plot(x, y, 'bo')
pl.xlim(binx_nn.min()-5, binx_nn.max()+5)
pl.ylim(biny_nn.min()-7, biny_nn.max()+8)
ax.set_aspect("equal")
txt = pl.title("Zoom into rain gauge locations")
pl.tight_layout()


## Create a verification report¶

In this example, we make up a true Kdp profile and verify our reconstructed Kdp.

### Create synthetic data and reconstruct KDP¶

In [9]:

# Synthetic truth
dr = 0.5
r = np.arange(0, 100, dr)
kdp_true = np.sin(0.3*r)
kdp_true[kdp_true<0] = 0.
phidp_true = np.cumsum(kdp_true)*2*dr
# Synthetic observation of PhiDP with a random noise and gaps
phidp_raw = phidp_true + np.random.uniform(-2, 2, len(phidp_true))
gaps = np.random.uniform(0, len(r), 20).astype("int")
phidp_raw[gaps] = np.nan

# Reconstruct PhiDP and KDP

# Plot results
fig = pl.figure(figsize=(12,8))
pl.plot(kdp_true, "g-", label="True KDP")
pl.plot(kdp_re, "r-", label="Reconstructed KDP")
pl.grid()
lg = pl.legend()

pl.plot(r, phidp_true, "b--", label="True PhiDP")
pl.plot(r, phidp_re, "g-", label="Reconstructed PhiDP")
pl.grid()
lg = pl.legend(loc="lower right")
txt = pl.xlabel("Range (km)")


### Create verification report¶

In [10]:

metrics = wradlib.verify.ErrorMetrics(kdp_true, kdp_re)
metrics.pprint()
ax = pl.subplot(111, aspect=1.)
ax.plot(metrics.obs, metrics.est, "bo")
ax.plot([-1, 2], [-1, 2], "k--")
pl.xlim(-0.3, 1.1)
pl.ylim(-0.3, 1.1)
xlabel = ax.set_xlabel("True KDP (deg/km)")
ylabel = ax.set_ylabel("Reconstructed KDP (deg/km)")

{'corr': 0.93,
'mas': 0.11,
'meanerr': -0.0,
'mse': 0.02,
'nash': 0.87,
'pbias': -0.0,
'r2': 0.86,
'ratio': nan,
'rmse': 0.14,
'spearman': 0.89,
'sse': 4.23}