Skip to content

Commit a9e4cc8

Browse files
authored
Revert some changes from #255 (#271)
* Re-add option to upscale mrms data * Remove references to xarray
1 parent 8a65727 commit a9e4cc8

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

pysteps/io/importers.py

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,12 @@
9191

9292
import numpy as np
9393

94-
# import xarray as xr
9594
from matplotlib.pyplot import imread
9695

9796
from pysteps.decorators import postprocess_import
9897
from pysteps.exceptions import DataModelError
9998
from pysteps.exceptions import MissingOptionalDependency
99+
from pysteps.utils import aggregate_fields
100100

101101
try:
102102
import gdalconst
@@ -235,7 +235,7 @@ def _get_threshold_value(precip):
235235

236236

237237
@postprocess_import(dtype="float32")
238-
def import_mrms_grib(filename, extent=None, **kwargs):
238+
def import_mrms_grib(filename, extent=None, window_size=4, **kwargs):
239239
"""
240240
Importer for NSSL's Multi-Radar/Multi-Sensor System
241241
([MRMS](https://www.nssl.noaa.gov/projects/mrms/)) rainrate product
@@ -250,7 +250,13 @@ def import_mrms_grib(filename, extent=None, **kwargs):
250250
by default to reduce the memory footprint. However, be aware that when this
251251
array is passed to a pystep function, it may be converted to double
252252
precision, doubling the memory footprint.
253-
To change the precision of the data, use the *dtype* keyword.
253+
To change the precision of the data, use the ``dtype`` keyword.
254+
255+
Also, by default, the original data is downscaled by 4
256+
(resulting in a ~4 km grid spacing).
257+
In case that the original grid spacing is needed, use ``window_size=1``.
258+
But be aware that a single composite in double precipitation will
259+
require 186 Mb of memory.
254260
255261
Finally, if desired, the precipitation data can be extracted over a
256262
sub region of the full domain using the `extent` keyword.
@@ -277,6 +283,11 @@ def import_mrms_grib(filename, extent=None, **kwargs):
277283
By default (None), the entire domain is retrieved.
278284
The extent can be in any form that can be converted to a flat array
279285
of 4 elements array (e.g., lists or tuples).
286+
window_size: array_like or int
287+
Array containing down-sampling integer factor along each axis.
288+
If an integer value is given, the same block shape is used for all the
289+
image dimensions.
290+
Default: window_size=4.
280291
281292
{extra_kwargs_doc}
282293
@@ -304,6 +315,9 @@ def import_mrms_grib(filename, extent=None, **kwargs):
304315
except OSError:
305316
raise OSError(f"Error opening NCEP's MRMS file. " f"File Not Found: {filename}")
306317

318+
if isinstance(window_size, int):
319+
window_size = (window_size, window_size)
320+
307321
if extent is not None:
308322
extent = np.asarray(extent)
309323
if (extent.ndim != 1) or (extent.size != 4):
@@ -334,6 +348,27 @@ def import_mrms_grib(filename, extent=None, **kwargs):
334348
precip = grib_msg.values
335349
no_data_mask = precip == -3 # Missing values
336350

351+
# Create a function with default arguments for aggregate_fields
352+
block_reduce = partial(aggregate_fields, method="mean", trim=True)
353+
354+
if window_size != (1, 1):
355+
# Downscale data
356+
lats = block_reduce(lats, window_size[0])
357+
lons = block_reduce(lons, window_size[1])
358+
359+
# Update the limits
360+
ul_lat, lr_lat = lats[0], lats[-1] # Lat from North to south!
361+
ul_lon, lr_lon = lons[0], lons[-1]
362+
363+
precip[no_data_mask] = 0 # block_reduce does not handle nan values
364+
precip = block_reduce(precip, window_size, axis=(0, 1))
365+
366+
# Consider that if a single invalid observation is located in the block,
367+
# then mark that value as invalid.
368+
no_data_mask = block_reduce(
369+
no_data_mask.astype("int"), window_size, axis=(0, 1)
370+
).astype(bool)
371+
337372
lons, lats = np.meshgrid(lons, lats)
338373
precip[no_data_mask] = np.nan
339374

@@ -359,8 +394,8 @@ def import_mrms_grib(filename, extent=None, **kwargs):
359394
pr = pyproj.Proj(proj_params)
360395
proj_def = " ".join([f"+{key}={value} " for key, value in proj_params.items()])
361396

362-
xsize = grib_msg["iDirectionIncrementInDegrees"]
363-
ysize = grib_msg["jDirectionIncrementInDegrees"]
397+
xsize = grib_msg["iDirectionIncrementInDegrees"] * window_size[0]
398+
ysize = grib_msg["jDirectionIncrementInDegrees"] * window_size[1]
364399

365400
x1, y1 = pr(ul_lon, lr_lat)
366401
x2, y2 = pr(lr_lon, ul_lat)

pysteps/tests/helpers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ def get_precipitation_fields(
101101
102102
Returns
103103
-------
104-
data_array : xr.DataArray
104+
reference_field : array
105+
metadata : dict
105106
"""
106107

107108
if source == "bom":

pysteps/utils/reprojection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def reproject_grids(src_array, dst_array, metadata_src, metadata_dst):
3535
precipitation fields. These precipitation fields will be reprojected.
3636
dst_array: array-like
3737
Array containing a precipitation field or a time series of precipitation
38-
fields. The xarray src_array will be reprojected to the domain of
38+
fields. The src_array will be reprojected to the domain of
3939
dst_array.
4040
metadata_src: dict
4141
Metadata dictionary containing the projection, x- and ypixelsize, x1 and

0 commit comments

Comments
 (0)