Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
precip_obs, _ = stp.utils.dB_transform(precip_obs, inverse=True)
precip_data = precip_obs.max(axis=0)
precip_data.data[precip_data.mask] = 0
precip_mask = ((uniform_filter(precip_data, size=20) > 0.1)
& ~precip_obs.mask.any(axis=0))
cmap = get_cmap('jet')
cmap.set_under('grey', alpha=0.25)
cmap.set_over('none')
# Compare retrieved motion field with the ideal one
plt.figure(figsize=(9, 4))
plt.subplot(1, 2, 1)
ax = plot_precip_field(precip_obs[0], title="Reference motion")
quiver(ideal_motion, step=25, ax=ax)
plt.subplot(1, 2, 2)
ax = plot_precip_field(precip_obs[0], title="Retrieved motion")
quiver(computed_motion, step=25, ax=ax)
# To evaluate the accuracy of the computed_motion vectors, we will use
# a relative RMSE measure.
# Relative MSE = < (expected_motion - computed_motion)^2 > /
# Relative RMSE = sqrt(Relative MSE)
mse = ((ideal_motion - computed_motion)[:, precip_mask] ** 2).mean()
rel_mse = mse / (ideal_motion[:, precip_mask] ** 2).mean()
plt.suptitle(f"{optflow_method_name} "
f"Relative RMSE: {np.sqrt(rel_mse) * 100:.2f}%")
# The path to an example BOM netcdf file
root_path = sp.rcparams.data_sources["bom"]["root_path"]
filename = os.path.join(
root_path, "prcp-cscn/2/2018/06/16/2_20180616_150000.prcp-cscn.nc"
)
###############################################################################
# pysteps original
# ~~~~~~~~~~~~~~~~
# Read data
R, __, metadata = sp.io.import_bom_rf3(filename)
metadata
# Visualization
sp.visualization.plot_precip_field(
R,
map=None,# "cartopy",
type="depth",
units="mm",
geodata=metadata,
drawlonlatlines=True,
)
###############################################################################
# pysteps using xarray
# ~~~~~~~~~~~~~~~~~~~~
# Read data
bom = xr.open_mfdataset(filename)
print(bom)
R_f = nowcast_method(
R[-3:, :, :],
V,
n_leadtimes,
n_cascade_levels=8,
R_thr=-10.0,
decomp_method="fft",
bandpass_filter_method="gaussian",
probmatching_method="mean",
)
# Back-transform to rain rate
R_f = transformation.dB_transform(R_f, threshold=-10.0, inverse=True)[0]
# Plot the S-PROG forecast
plot_precip_field(
R_f[-1, :, :],
geodata=metadata,
title="S-PROG (+ %i min)" % (n_leadtimes * timestep),
)
###############################################################################
# As we can see from the figure above, the forecast produced by S-PROG is a
# smooth field. In other words, the forecast variance is lower than the
# variance of the original observed field.
# However, certain applications demand that the forecast retain the same
# statistical properties of the observations. In such cases, the S-PROG
# forecasts are of limited use and a stochatic approach might be of more
# interest.
###############################################################################
# Stochastic nowcast with STEPS
fns = io.find_by_date(
date, root_path, path_fmt, fn_pattern, fn_ext, timestep, num_prev_files=2
)
# Read the data from the archive
importer = io.get_method(importer_name, "importer")
R, _, metadata = io.read_timeseries(fns, importer, **importer_kwargs)
# Convert to rain rate
R, metadata = conversion.to_rainrate(R, metadata)
# Upscale data to 2 km to limit memory usage
R, metadata = dimension.aggregate_fields_space(R, metadata, 2000)
# Plot the rainfall field
plot_precip_field(R[-1, :, :], geodata=metadata)
# Log-transform the data to unit of dBR, set the threshold to 0.1 mm/h,
# set the fill value to -15 dBR
R, metadata = transformation.dB_transform(R, metadata, threshold=0.1, zerovalue=-15.0)
# Set missing values with the fill value
R[~np.isfinite(R)] = -15.0
# Nicely print the metadata
pprint(metadata)
###############################################################################
# Deterministic nowcast with S-PROG
# ---------------------------------
#
# First, the motiong field is estimated using a local tracking approach based
timestep = rcparams.data_sources[data_source]["timestep"]
# Find the input files from the archive
fns = io.archive.find_by_date(
date, root_path, path_fmt, fn_pattern, fn_ext, timestep, num_prev_files=2
)
# Read the radar composites
importer = io.get_method(importer_name, "importer")
Z, _, metadata = io.read_timeseries(fns, importer, **importer_kwargs)
# Convert to rain rate using the finnish Z-R relationship
R, metadata = conversion.to_rainrate(Z, metadata, 223.0, 1.53)
# Plot the rainfall field
plot_precip_field(R[-1, :, :], geodata=metadata)
# Store the last frame for plotting it later later
R_ = R[-1, :, :].copy()
# Log-transform the data to unit of dBR, set the threshold to 0.1 mm/h,
# set the fill value to -15 dBR
R, metadata = transformation.dB_transform(R, metadata, threshold=0.1, zerovalue=-15.0)
# Nicely print the metadata
pprint(metadata)
###############################################################################
# Compute the nowcast
# -------------------
#
# The extrapolation nowcast is based on the estimation of the motion field,
del quality # Not used
reference_field = np.squeeze(reference_field) # Remove time dimension
###############################################################################
# Preprocess the data
# ~~~~~~~~~~~~~~~~~~~
# Convert to mm/h
reference_field, metadata = stp.utils.to_rainrate(reference_field, metadata)
# Mask invalid values
reference_field = np.ma.masked_invalid(reference_field)
# Plot the reference precipitation
plot_precip_field(reference_field, title="Reference field")
plt.show()
# Log-transform the data [dBR]
reference_field, metadata = stp.utils.dB_transform(reference_field,
metadata,
threshold=0.1,
zerovalue=-15.0)
print("Precip. pattern shape: " + str(reference_field.shape))
# This suppress nan conversion warnings in plot functions
reference_field.data[reference_field.mask] = np.nan
################################################################################
# Synthetic precipitation observations
###############################################################################
# Variational echo tracking (VET)
# -------------------------------
#
# This module implements the VET algorithm presented
# by Laroche and Zawadzki (1995) and used in the McGill Algorithm for
# Prediction by Lagrangian Extrapolation (MAPLE) described in
# Germann and Zawadzki (2002).
# The approach essentially consists of a global optimization routine that seeks
# at minimizing a cost function between the displaced and the reference image.
oflow_method = motion.get_method("VET")
V2 = oflow_method(R[-3:, :, :])
# Plot the motion field
plot_precip_field(R_, geodata=metadata, title="VET")
quiver(V2, geodata=metadata, step=25)
###############################################################################
# Dynamic and adaptive radar tracking of storms (DARTS)
# -----------------------------------------------------
#
# DARTS uses a spectral approach to optical flow that is based on the discrete
# Fourier transform (DFT) of a temporal sequence of radar fields.
# The level of truncation of the DFT coefficients controls the degree of
# smoothness of the estimated motion field, allowing for an efficient
# motion estimation. DARTS requires a longer sequence of radar fields for
# estimating the motion, here we are going to use all the available 10 fields.
oflow_method = motion.get_method("DARTS")
R[~np.isfinite(R)] = metadata["zerovalue"]
V3 = oflow_method(R) # needs longer training sequence
tight_layout()
###############################################################################
# As we can see from these two members of the ensemble, the stochastic forecast
# mantains the same variance as in the observed rainfall field.
# STEPS also includes a stochatic perturbation of the motion field in order
# to quantify the its uncertainty.
###############################################################################
# Finally, it is possible to derive probabilities from our ensemble forecast.
# Compute exceedence probabilities for a 0.5 mm/h threshold
P = excprob(R_f[:, -1, :, :], 0.5)
# Plot the field of probabilities
plot_precip_field(
P,
geodata=metadata,
drawlonlatlines=False,
type="prob",
units="mm/h",
probthr=0.5,
title="Exceedence probability (+ %i min)" % (n_leadtimes * timestep),
)
timestep=timestep,
decomp_method="fft",
bandpass_filter_method="gaussian",
noise_method="nonparametric",
vel_pert_method="bps",
mask_method="incremental",
seed=seed,
)
# Back-transform to rain rates
R_f = transformation.dB_transform(R_f, threshold=-10.0, inverse=True)[0]
# Plot the ensemble mean
R_f_mean = np.mean(R_f[:, -1, :, :], axis=0)
plot_precip_field(
R_f_mean,
geodata=metadata,
title="Ensemble mean (+ %i min)" % (n_leadtimes * timestep),
)
###############################################################################
# The mean of the ensemble displays similar properties as the S-PROG
# forecast seen above, although the degree of smoothing also depends on
# the ensemble size. In this sense, the S-PROG forecast can be seen as
# the mean of an ensemble of infinite size.
# Plot some of the realizations
fig = figure()
for i in range(4):
ax = fig.add_subplot(221 + i)
ax.set_title("Member %02d" % i)