91
91
92
92
import numpy as np
93
93
94
- # import xarray as xr
95
94
from matplotlib .pyplot import imread
96
95
97
96
from pysteps .decorators import postprocess_import
98
97
from pysteps .exceptions import DataModelError
99
98
from pysteps .exceptions import MissingOptionalDependency
99
+ from pysteps .utils import aggregate_fields
100
100
101
101
try :
102
102
import gdalconst
@@ -235,7 +235,7 @@ def _get_threshold_value(precip):
235
235
236
236
237
237
@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 ):
239
239
"""
240
240
Importer for NSSL's Multi-Radar/Multi-Sensor System
241
241
([MRMS](https://www.nssl.noaa.gov/projects/mrms/)) rainrate product
@@ -250,7 +250,13 @@ def import_mrms_grib(filename, extent=None, **kwargs):
250
250
by default to reduce the memory footprint. However, be aware that when this
251
251
array is passed to a pystep function, it may be converted to double
252
252
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.
254
260
255
261
Finally, if desired, the precipitation data can be extracted over a
256
262
sub region of the full domain using the `extent` keyword.
@@ -277,6 +283,11 @@ def import_mrms_grib(filename, extent=None, **kwargs):
277
283
By default (None), the entire domain is retrieved.
278
284
The extent can be in any form that can be converted to a flat array
279
285
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.
280
291
281
292
{extra_kwargs_doc}
282
293
@@ -304,6 +315,9 @@ def import_mrms_grib(filename, extent=None, **kwargs):
304
315
except OSError :
305
316
raise OSError (f"Error opening NCEP's MRMS file. " f"File Not Found: { filename } " )
306
317
318
+ if isinstance (window_size , int ):
319
+ window_size = (window_size , window_size )
320
+
307
321
if extent is not None :
308
322
extent = np .asarray (extent )
309
323
if (extent .ndim != 1 ) or (extent .size != 4 ):
@@ -334,6 +348,27 @@ def import_mrms_grib(filename, extent=None, **kwargs):
334
348
precip = grib_msg .values
335
349
no_data_mask = precip == - 3 # Missing values
336
350
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
+
337
372
lons , lats = np .meshgrid (lons , lats )
338
373
precip [no_data_mask ] = np .nan
339
374
@@ -359,8 +394,8 @@ def import_mrms_grib(filename, extent=None, **kwargs):
359
394
pr = pyproj .Proj (proj_params )
360
395
proj_def = " " .join ([f"+{ key } ={ value } " for key , value in proj_params .items ()])
361
396
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 ]
364
399
365
400
x1 , y1 = pr (ul_lon , lr_lat )
366
401
x2 , y2 = pr (lr_lon , ul_lat )
0 commit comments