Skip to content

Commit ed76516

Browse files
authored
Improve documentation of rainfarm downscaling (#292)
1 parent 33d80d4 commit ed76516

File tree

3 files changed

+58
-46
lines changed

3 files changed

+58
-46
lines changed

examples/rainfarm_downscale.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,15 @@
5757
# -----------------
5858
#
5959
# To test our downscaling method, we first need to upscale the original field to
60-
# a lower resolution. We are going to use an upscaling factor of 16 x.
60+
# a lower resolution. This is only for demo purposes, as we need to artificially
61+
# create a lower resolution field to apply our downscaling method.
62+
# We are going to use a factor of 16 x.
6163

62-
upscaling_factor = 16
63-
upscale_to = metadata["xpixelsize"] * upscaling_factor # upscaling factor : 16 x
64-
precip_lr, metadata_lr = aggregate_fields_space(precip, metadata, upscale_to)
64+
scale_factor = 16
65+
upscaled_resolution = (
66+
metadata["xpixelsize"] * scale_factor
67+
) # upscaled resolution : 16 km
68+
precip_lr, metadata_lr = aggregate_fields_space(precip, metadata, upscaled_resolution)
6569

6670
# Plot the upscaled rainfall field
6771
plt.figure()
@@ -81,33 +85,29 @@
8185
# Per realization, generate a stochastically downscaled precipitation field
8286
# and plot it.
8387
# The first time, the spectral slope alpha needs to be estimated. To illustrate
84-
# the sensitity of this parameter, we are going to plot some realizations with
88+
# the sensitivity of this parameter, we are going to plot some realizations with
8589
# half or double the estimated slope.
8690
alpha = None
8791
for n in range(num_realizations):
8892

8993
# Spectral slope estimated from the upscaled field
9094
precip_hr, alpha = rainfarm.downscale(
91-
precip_lr, alpha=alpha, ds_factor=upscaling_factor, return_alpha=True
95+
precip_lr, ds_factor=scale_factor, alpha=alpha, return_alpha=True
9296
)
9397
plt.subplot(num_realizations, 3, n * 3 + 2)
9498
plot_precip_field(precip_hr, geodata=metadata, axis="off", colorbar=False)
9599
if n == 0:
96100
plt.title(f"alpha={alpha:.1f}")
97101

98102
# Half the estimated slope
99-
precip_hr = rainfarm.downscale(
100-
precip_lr, alpha=alpha * 0.5, ds_factor=upscaling_factor
101-
)
103+
precip_hr = rainfarm.downscale(precip_lr, ds_factor=scale_factor, alpha=alpha * 0.5)
102104
plt.subplot(num_realizations, 3, n * 3 + 1)
103105
plot_precip_field(precip_hr, geodata=metadata, axis="off", colorbar=False)
104106
if n == 0:
105107
plt.title(f"alpha={alpha * 0.5:.1f}")
106108

107109
# Double the estimated slope
108-
precip_hr = rainfarm.downscale(
109-
precip_lr, alpha=alpha * 2, ds_factor=upscaling_factor
110-
)
110+
precip_hr = rainfarm.downscale(precip_lr, ds_factor=scale_factor, alpha=alpha * 2)
111111
plt.subplot(num_realizations, 3, n * 3 + 3)
112112
plot_precip_field(precip_hr, geodata=metadata, axis="off", colorbar=False)
113113
if n == 0:

pysteps/downscaling/rainfarm.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
Implementation of the RainFARM stochastic downscaling method as described in
77
:cite:`Rebora2006`.
88
9+
RainFARM is a downscaling algorithm for rainfall fields developed by Rebora et
10+
al. (2006). The method can represent the realistic small-scale variability of the
11+
downscaled precipitation field by means of Gaussian random fields.
12+
13+
914
.. autosummary::
1015
:toctree: ../generated/
1116
@@ -39,38 +44,35 @@ def _balanced_spatial_average(x, k):
3944
return convolve(x, k) / convolve(ones, k)
4045

4146

42-
def downscale(precip, alpha=None, ds_factor=16, threshold=None, return_alpha=False):
47+
def downscale(precip, ds_factor, alpha=None, threshold=None, return_alpha=False):
4348
"""
44-
Downscale a rainfall field by a given factor.
49+
Downscale a rainfall field by increasing its spatial resolution by
50+
a positive integer factor.
4551
4652
Parameters
4753
----------
48-
49-
precip: array_like
50-
Array of shape (m,n) containing the input field.
54+
precip: array-like
55+
Array of shape (m, n) containing the input field.
5156
The input is expected to contain rain rate values.
52-
57+
All values are required to be finite.
5358
alpha: float, optional
54-
Spectral slope. If none, the slope is estimated from
59+
Spectral slope. If None, the slope is estimated from
5560
the input array.
56-
57-
ds_factor: int, optional
58-
Downscaling factor.
59-
61+
ds_factor: positive int
62+
Downscaling factor, it specifies by how many times
63+
to increase the initial grid resolution.
6064
threshold: float, optional
6165
Set all values lower than the threshold to zero.
62-
6366
return_alpha: bool, optional
64-
Whether to return the estimated spectral slope `alpha`.
65-
67+
Whether to return the estimated spectral slope ``alpha``.
6668
6769
Returns
6870
-------
69-
r: array_like
70-
Array of shape (m*ds_factor,n*ds_factor) containing
71+
r: array-like
72+
Array of shape (m * ds_factor, n * ds_factor) containing
7173
the downscaled field.
7274
alpha: float
73-
Returned only when `return_alpha=True`.
75+
Returned only when ``return_alpha=True``.
7476
7577
Notes
7678
-----

pysteps/tests/test_downscaling_rainfarm.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,35 @@
77
from pysteps.utils import aggregate_fields_space, square_domain
88

99

10-
# load and preprocess input field
11-
precip, metadata = get_precipitation_fields(
12-
num_prev_files=0, num_next_files=0, return_raw=False, metadata=True
13-
)
14-
precip = precip.filled()
15-
precip, metadata = square_domain(precip, metadata, "crop")
10+
@pytest.fixture(scope="module")
11+
def data():
12+
precip, metadata = get_precipitation_fields(
13+
num_prev_files=0, num_next_files=0, return_raw=False, metadata=True
14+
)
15+
precip = precip.filled()
16+
precip, metadata = square_domain(precip, metadata, "crop")
17+
return precip, metadata
1618

1719

1820
rainfarm_arg_names = ("alpha", "ds_factor", "threshold", "return_alpha")
19-
20-
2121
rainfarm_arg_values = [(1.0, 1, 0, False), (1, 2, 0, False), (1, 4, 0, False)]
2222

2323

2424
@pytest.mark.parametrize(rainfarm_arg_names, rainfarm_arg_values)
25-
def test_rainfarm_shape(alpha, ds_factor, threshold, return_alpha):
26-
"""Test that the output of rainfarm is consistent with the downscalnig factor."""
27-
25+
def test_rainfarm_shape(data, alpha, ds_factor, threshold, return_alpha):
26+
"""Test that the output of rainfarm is consistent with the downscaling factor."""
27+
precip, metadata = data
2828
window = metadata["xpixelsize"] * ds_factor
2929
precip_lr, __ = aggregate_fields_space(precip, metadata, window)
3030

3131
rainfarm = downscaling.get_method("rainfarm")
32-
33-
precip_hr = rainfarm(precip_lr, alpha, ds_factor, threshold, return_alpha)
32+
precip_hr = rainfarm(
33+
precip_lr,
34+
alpha=alpha,
35+
ds_factor=ds_factor,
36+
threshold=threshold,
37+
return_alpha=return_alpha,
38+
)
3439

3540
assert precip_hr.ndim == precip.ndim
3641
assert precip_hr.shape[0] == precip.shape[0]
@@ -41,15 +46,20 @@ def test_rainfarm_shape(alpha, ds_factor, threshold, return_alpha):
4146

4247

4348
@pytest.mark.parametrize(rainfarm_arg_names, rainfarm_arg_values)
44-
def test_rainfarm_alpha(alpha, ds_factor, threshold, return_alpha):
49+
def test_rainfarm_alpha(data, alpha, ds_factor, threshold, return_alpha):
4550
"""Test that rainfarm computes and returns alpha."""
46-
51+
precip, metadata = data
4752
window = metadata["xpixelsize"] * ds_factor
4853
precip_lr, __ = aggregate_fields_space(precip, metadata, window)
4954

5055
rainfarm = downscaling.get_method("rainfarm")
51-
52-
precip_hr = rainfarm(precip_lr, alpha, ds_factor, threshold, return_alpha)
56+
precip_hr = rainfarm(
57+
precip_lr,
58+
alpha=alpha,
59+
ds_factor=ds_factor,
60+
threshold=threshold,
61+
return_alpha=return_alpha,
62+
)
5363

5464
assert len(precip_hr) == 2
5565
if alpha is None:

0 commit comments

Comments
 (0)