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¶
Read polar data set¶
In [3]:
filename = wradlib.util.get_wradlib_data_file('misc/polar_R_tur.gz')
data = np.loadtxt(filename)
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
proj = wradlib.georef.epsg_to_osr(31467)
# 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_at_gages = polarneighbs.extract(data)
print( "Radar values at rain gauge #1: %r" % radar_at_gages[0].tolist())
print( "Radar values at rain gauge #2: %r" % radar_at_gages[1].tolist())
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 = fig.add_subplot(121)
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 = fig.add_subplot(122)
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
phidp_re, kdp_re = wradlib.dp.process_raw_phidp_vulpiani(phidp_raw, dr=dr)
# Plot results
fig = pl.figure(figsize=(12,8))
ax = fig.add_subplot(211)
pl.plot(kdp_true, "g-", label="True KDP")
pl.plot(kdp_re, "r-", label="Reconstructed KDP")
pl.grid()
lg = pl.legend()
ax = fig.add_subplot(212)
pl.plot(r, phidp_true, "b--", label="True PhiDP")
pl.plot(r, np.ma.masked_invalid(phidp_raw), "b-", label="Raw 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}