Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
bff8667
started to change all functions to work with 4d data
Joep1999 Sep 11, 2025
62ab9c1
inbetween commit, things not working currently
Joep1999 Sep 12, 2025
099db2c
ensembles working, but blending does not look good
Joep1999 Sep 15, 2025
9c9154f
removed prints, mostly working
Joep1999 Sep 17, 2025
06c6483
fix: make sure means and stds of external nowcast cascade are used
RubenImhoff Sep 17, 2025
3cc1023
refactor: run black
RubenImhoff Sep 17, 2025
18a99da
fixing bug with probmatching
Joep1999 Sep 23, 2025
f74a60f
fixed small problem with means and stds
Joep1999 Sep 23, 2025
e6beb32
feat: first steps towards allowing noise development with external no…
RubenImhoff Sep 23, 2025
48942f3
Merge branch 'setup-ensemble-possbilities-with-external-nowcast' of h…
RubenImhoff Sep 23, 2025
ff71084
feat: allow adding noise to external nowcast blending
RubenImhoff Sep 23, 2025
31628c0
added support for copying multiple nowcasts and forecasts in case n_e…
Joep1999 Sep 23, 2025
a5e8ea3
concorporated changes ruben and small bugfix
Joep1999 Sep 23, 2025
f690fc7
fix: minor fixes to decomposition of external nowcast
RubenImhoff Sep 23, 2025
48a96f5
fix: minor fixes after merge
RubenImhoff Sep 23, 2025
3174d7a
fix: make sure slicing of means and stds goes well
RubenImhoff Sep 23, 2025
a5804a7
Merge remote-tracking branch 'upstream/master' into setup-ensemble-po…
Joep1999 Sep 24, 2025
a35461b
feat: add ensemble forecast gallery example
RubenImhoff Sep 26, 2025
c43fac9
added first test to check working of creating ensembles with determin…
Joep1999 Oct 9, 2025
7e04001
small fixes tests and blending
Joep1999 Oct 9, 2025
3b256e9
fixed a mistake in the small fixes
Joep1999 Oct 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 120 additions & 16 deletions examples/steps_blended_forecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@
n_leadtimes = len(leadtimes_min)
for n, leadtime in enumerate(leadtimes_min):
# Nowcast with blending into NWP
plt.subplot(n_leadtimes, 2, n * 2 + 1)
ax1 = plt.subplot(n_leadtimes, 2, n * 2 + 1)
plot_precip_field(
precip_forecast[0, int(leadtime / timestep) - 1, :, :],
geodata=radar_metadata,
Expand All @@ -204,37 +204,39 @@
colorscale="STEPS-NL",
colorbar=False,
)
ax1.axis("off")

# Raw NWP forecast
plt.subplot(n_leadtimes, 2, n * 2 + 2)
plot_precip_field(
ax2 = plot_precip_field(
nwp_precip_mmh[0, int(leadtime / timestep) - 1, :, :],
geodata=nwp_metadata,
title=f"NWP +{leadtime} min",
axis="off",
colorscale="STEPS-NL",
colorbar=False,
)
ax2.axis("off")

plt.tight_layout()
plt.show()


###############################################################################
# It is also possible to blend a deterministic external nowcast (e.g. a pre-
# made nowcast or a deterministic AI-based nowcast) with NWP using the STEPS
# algorithm. In that case, we add a `precip_nowcast` to `blending.steps.forecast`.
# By providing an external nowcast, the STEPS blending method will omit the
# autoregression and advection step for the extrapolation cascade and use the
# existing external nowcast instead (which will thus be decomposed into
# multiplicative cascades!). The weights determination and possible post-
# processings steps will remain the same.
# It is also possible to blend a deterministic or probabilistic external nowcast
# (e.g. a pre-made nowcast or a deterministic AI-based nowcast) with NWP using
# the STEPS algorithm. In that case, we add a `precip_nowcast` to
# `blending.steps.forecast`. By providing an external nowcast, the STEPS blending
# method will omit the autoregression and advection step for the extrapolation
# cascade and use the existing external nowcast instead (which will thus be
# decomposed into multiplicative cascades!). The weights determination and
# possible post-processings steps will remain the same.
#
# Start with creating an external nowcast
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# We go for a simple advection-only nowcast for the example, but this setup can
# be replaced with any external deterministic nowcast.
# be replaced with any external deterministic or probabilistic nowcast.
extrapolate = nowcasts.get_method("extrapolation")
radar_precip_to_advect = radar_precip.copy()
radar_metadata_to_advect = radar_metadata.copy()
Expand All @@ -258,8 +260,8 @@


################################################################################
# Blend the external nowcast with NWP
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Blend the external nowcast with NWP - deterministic mode
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

precip_forecast = blending.steps.forecast(
precip=radar_precip,
Expand Down Expand Up @@ -311,7 +313,7 @@
idx = int(leadtime / timestep) - 1

# Blended nowcast
plt.subplot(n_leadtimes, 3, n * 3 + 1)
ax1 = plt.subplot(n_leadtimes, 3, n * 3 + 1)
plot_precip_field(
precip_forecast[0, idx, :, :],
geodata=radar_metadata,
Expand All @@ -320,9 +322,10 @@
colorscale="STEPS-NL",
colorbar=False,
)
ax1.axis("off")

# Raw extrapolated nowcast
plt.subplot(n_leadtimes, 3, n * 3 + 2)
ax2 = plt.subplot(n_leadtimes, 3, n * 3 + 2)
plot_precip_field(
fc_lagrangian_extrapolation_mmh[idx, :, :],
geodata=radar_metadata,
Expand All @@ -331,17 +334,118 @@
colorscale="STEPS-NL",
colorbar=False,
)
ax2.axis("off")

# Raw NWP forecast
plt.subplot(n_leadtimes, 3, n * 3 + 3)
plot_precip_field(
ax3 = plot_precip_field(
nwp_precip_mmh[0, idx, :, :],
geodata=nwp_metadata,
title=f"NWP +{leadtime} min",
axis="off",
colorscale="STEPS-NL",
colorbar=False,
)
ax3.axis("off")


################################################################################
# Blend the external nowcast with NWP - ensemble mode
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

precip_forecast = blending.steps.forecast(
precip=radar_precip,
precip_nowcast=fc_lagrangian_extrapolation,
precip_models=nwp_precip,
velocity=velocity_radar,
velocity_models=velocity_nwp,
timesteps=18,
timestep=timestep,
issuetime=date_radar,
n_ens_members=5,
precip_thr=radar_metadata["threshold"],
kmperpixel=radar_metadata["xpixelsize"] / 1000.0,
noise_stddev_adj="auto",
vel_pert_method=None,
nowcasting_method="external_nowcast",
noise_method="nonparametric",
probmatching_method="cdf",
mask_method="incremental",
weights_method="bps",
)

# Transform the data back into mm/h
precip_forecast, _ = converter(precip_forecast, radar_metadata)
radar_precip_mmh, _ = converter(radar_precip, radar_metadata)
fc_lagrangian_extrapolation_mmh, _ = converter(
fc_lagrangian_extrapolation, radar_metadata_to_advect
)
nwp_precipfc_lagrangian_extrapolation_mmh_mmh, _ = converter(nwp_precip, nwp_metadata)


################################################################################
# Visualize the output
# ~~~~~~~~~~~~~~~~~~~~

fig = plt.figure(figsize=(5, 12))

leadtimes_min = [30, 60, 90, 120, 150, 180]
n_leadtimes = len(leadtimes_min)

for n, leadtime in enumerate(leadtimes_min):
idx = int(leadtime / timestep) - 1

# Blended nowcast member 1
ax1 = plt.subplot(n_leadtimes, 4, n * 4 + 1)
plot_precip_field(
precip_forecast[0, idx, :, :],
geodata=radar_metadata,
title="Blend Mem. 1",
axis="off",
colorscale="STEPS-NL",
colorbar=False,
)
ax1.axis("off")

# Blended nowcast member 5
ax2 = plt.subplot(n_leadtimes, 4, n * 4 + 2)
plot_precip_field(
precip_forecast[4, idx, :, :],
geodata=radar_metadata,
title="Blend Mem. 5",
axis="off",
colorscale="STEPS-NL",
colorbar=False,
)
ax2.axis("off")

# Raw extrapolated nowcast
ax3 = plt.subplot(n_leadtimes, 4, n * 4 + 3)
plot_precip_field(
fc_lagrangian_extrapolation_mmh[0, idx, :, :],
geodata=radar_metadata,
title=f"NWC + {leadtime} min",
axis="off",
colorscale="STEPS-NL",
colorbar=False,
)
ax3.axis("off")

# Raw NWP forecast
ax4 = plt.subplot(n_leadtimes, 4, n * 4 + 4)
plot_precip_field(
nwp_precip_mmh[0, idx, :, :],
geodata=nwp_metadata,
title=f"NWP + {leadtime} min",
axis="off",
colorscale="STEPS-NL",
colorbar=False,
)
ax4.axis("off")

plt.show()

print("Done.")


################################################################################
Expand Down
Loading