9191
9292import numpy as np
9393
94- # import xarray as xr
9594from matplotlib .pyplot import imread
9695
9796from pysteps .decorators import postprocess_import
9897from pysteps .exceptions import DataModelError
9998from pysteps .exceptions import MissingOptionalDependency
99+ from pysteps .utils import aggregate_fields
100100
101101try :
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 )
0 commit comments