def get_membership_functions(filename): """Reads membership function parameters from wradlib-data file. Parameters ---------- filename : filename Filename of wradlib-data file Returns ------- msf : :class:`numpy:numpy.ndarray` Array of membership funcions with shape (hm-classes, observables, indep-ranges, 5) """ gzip = util.import_optional('gzip') with gzip.open(filename, 'rb') as f: nclass = int(f.readline().decode().split(':')[1].strip()) nobs = int(f.readline().decode().split(':')[1].strip()) with warnings.catch_warnings(): warnings.filterwarnings('ignore', category=UserWarning) data = np.genfromtxt(f, skip_header=10, autostrip=True, invalid_raise=False) data = np.reshape(data, (nobs, int(data.shape[0] / nobs), data.shape[1])) msf = np.reshape( data, (data.shape[0], nclass, int(data.shape[1] / nclass), data.shape[2])) msf = np.swapaxes(msf, 0, 1) return msf
def get_radolan_filehandle(fname): """Opens radolan file and returns file handle Parameters ---------- fname : string or file-like filename or file-like object Returns ------- f : object file handle """ ret = lambda obj: obj if isinstance(fname, str): gzip = util.import_optional("gzip") # open file handle try: with gzip.open(fname, "rb") as f: f.read(1) f.seek(0, 0) ret = gzip.open except IOError: with open(fname, "rb") as f: f.read(1) f.seek(0, 0) ret = open return ret(fname, "rb") else: return ret(fname)
def get_rb_header(fid): """Read Rainbow Header from filename, converts it to a dict and returns it Parameters ---------- fid : file handle File handle of Data File Returns ------- object : dictionary Rainbow File Contents """ # load the header lines, i.e. the XML part end_xml_marker = b"<!-- END XML -->" header = b"" line = b"" while not line.startswith(end_xml_marker): header += line[:-1] line = fid.readline() if len(line) == 0: raise IOError("WRADLIB: Rainbow Fileheader Corrupt") xmltodict = util.import_optional("xmltodict") return xmltodict.parse(header)
def get_radolan_filehandle(fname): """Opens radolan file and returns file handle Parameters ---------- fname : string filename Returns ------- f : object filehandle """ gzip = util.import_optional('gzip') # open file handle try: f = gzip.open(fname, 'rb') f.read(1) except IOError: f = open(fname, 'rb') f.read(1) # rewind file f.seek(0, 0) return f
def decompress(data): """Decompression of data Parameters ---------- data : string (from xml) data string containing compressed data. """ zlib = util.import_optional("zlib") return zlib.decompress(data)
def get_wradlib_data_file(file, file_or_filelike): datafile = util.get_wradlib_data_file(file) if file_or_filelike == "filelike": _open = open if datafile[-3:] == ".gz": gzip = util.import_optional("gzip") _open = gzip.open with _open(datafile, mode="r+b") as f: yield sio.BytesIO(f.read()) else: yield datafile
def unfold_phi(phidp, rho, width=5, copy=False): """Unfolds differential phase by adjusting values that exceeded maximum \ ambiguous range. Accepts arbitrarily dimensioned arrays, but THE LAST DIMENSION MUST BE THE RANGE. This is the fast Fortran-based implementation (RECOMMENDED). The algorithm is based on the paper of :cite:`Wang2009`. Parameters ---------- phidp : :class:`numpy:numpy.ndarray` array of shape (...,nr) with nr being the number of range bins rho : :class:`numpy:numpy.ndarray` array of same shape as ``phidp`` width : int Width of the analysis window copy : bool Leaves original ``phidp`` array unchanged if set to True (default: False) """ # Check whether fast Fortran implementation is available speedup = util.import_optional("wradlib.speedup") shape = phidp.shape assert rho.shape == shape, "rho and phidp must have the same shape." phidp = phidp.reshape((-1, shape[-1])) if copy: phidp = phidp.copy() rho = rho.reshape((-1, shape[-1])) gradphi = util.gradient_from_smoothed(phidp) beams, rs = phidp.shape # Compute the standard deviation within windows of 9 range bins stdarr = np.zeros(phidp.shape, dtype=np.float32) for r in range(rs - 9): stdarr[..., r] = np.std(phidp[..., r:r + 9], -1) phidp = speedup.f_unfold_phi( phidp=phidp.astype("f4"), rho=rho.astype("f4"), gradphi=gradphi.astype("f4"), stdarr=stdarr.astype("f4"), beams=beams, rs=rs, w=width, ) return phidp.reshape(shape)
def get_rb_blob_data(datastring, blobid): """ Read BLOB data from datastring and return it Parameters ---------- datastring : string Blob Description String blobid : int Number of requested blob Returns ------- data : string Content of blob """ xmltodict = util.import_optional("xmltodict") start = 0 search_string = '<BLOB blobid="{0}"'.format(blobid) start = datastring.find(search_string.encode(), start) if start == -1: raise EOFError("Blob ID {0} not found!".format(blobid)) end = datastring.find(b">", start) xmlstring = datastring[start:end + 1] # cheat the xml parser by making xml well-known xmldict = xmltodict.parse(xmlstring.decode() + "</BLOB>") cmpr = get_rb_blob_attribute(xmldict, "compression") size = int(get_rb_blob_attribute(xmldict, "size")) data = datastring[end + 2:end + 2 + size] # read blob data to string # decompress if necessary # the first 4 bytes are neglected for an unknown reason if cmpr == "qt": data = decompress(data[4:]) return data
def plot(self, ax=111, fig=None, proj=None, func='pcolormesh', cmap='viridis', center=False, add_colorbar=False, add_labels=False, **kwargs): """Plot Plan Position Indicator (PPI) or Range Height Indicator (RHI). The implementation of this plot routine is in cartesian axes and does all coordinate transforms using xarray machinery. This allows zooming into the data as well as making it easier to plot additional data (like gauge locations) without having to convert them to the radar's polar coordinate system. Using ``proj='cg'`` the plotting is done in a curvelinear grid axes. Additional data can be plotted in polar coordinates or cartesian coordinates depending which axes object is used. ``**kwargs`` may be used to try to influence the :func:`matplotlib.pyplot.pcolormesh`, :func:`matplotlib.pyplot.contour`, :func:`matplotlib.pyplot.contourf` and :func:`wradlib.georef.polar.spherical_to_proj` routines under the hood. Parameters ---------- proj : cartopy CRS | curvelinear grid dict | None cartopy CRS Coordinate Reference System describing projection If this parameter is not None, ``site`` must be set properly. Then the function will attempt to georeference the radar bins and display the PPI in the coordinate system defined by the projection string. fig : :class:`matplotlib:matplotlib.figure.Figure` If given, the PPI/RHI will be plotted into this figure object. Axes are created as needed. If None, a new figure object will be created or current figure will be used, depending on ``ax``. ax : :class:`matplotlib:matplotlib.axes.Axes` | matplotlib grid definition If matplotlib Axes object is given, the PPI will be plotted into this axes object. If matplotlib grid definition is given (nrows/ncols/plotnumber), axis are created in the specified place. Defaults to '111', only one subplot/axis. func : str Name of plotting function to be used under the hood. Defaults to 'pcolormesh'. 'contour' and 'contourf' can be selected too. cmap : str matplotlib colormap string Returns ------- pm : :class:`matplotlib:matplotlib.collections.QuadMesh` | \ :class:`matplotlib:matplotlib.contour.QuadContourSet` The result of the plotting function. Necessary, if you want to add a colorbar to the plot. Note ---- If ``proj`` contains a curvelinear grid dict, the ``cgax`` - curvelinear Axes (r-theta-grid) is returned. ``caax`` - Cartesian Axes (x-y-grid) and ``paax`` - parasite axes object for plotting polar data can be derived like this:: caax = cgax.parasites[0] paax = cgax.parasites[1] The function :func:`~wradlib.vis.create_cg` uses the Matplotlib AXISARTIST namespace `mpl_toolkits.axisartist`_. Here are some limitations to normal Matplotlib Axes. See `AxesGridToolkitUserGuide`_. Examples -------- See :ref:`/notebooks/visualisation/wradlib_plot_ppi_example.ipynb`, and :ref:`/notebooks/visualisation/wradlib_plot_curvelinear_grids.ipynb`. .. _mpl_toolkits.axisartist: https://matplotlib.org/mpl_toolkits/axes_grid/users/axisartist.html .. _AxesGridToolkitUserGuide: https://matplotlib.org/mpl_toolkits/axes_grid/users/index.html """ cg = False caax = None paax = None # fix for correct zorder of data and grid kwargs['zorder'] = kwargs.pop('zorder', 0) self.proj = proj # handle curvelinear grid properties if proj == 'cg' or isinstance(proj, collections.abc.Mapping): self.proj = None if self.sweep_mode == 'azimuth_surveillance': cg = {'rot': -450, 'scale': -1} else: cg = {'rot': 0, 'scale': 1} if isinstance(proj, collections.abc.Mapping): cg.update(proj) if isinstance(proj, osr.SpatialReference): raise TypeError( "WRADLIB: Currently GDAL OSR SRS are not supported") if isinstance(ax, axes.Axes): if cg: try: caax = ax.parasites[0] paax = ax.parasites[1] except AttributeError: raise TypeError( "WRADLIB: If `proj='cg'` `ax` need to be of type" " `mpl_toolkits.axisartist.SubplotHost`") else: # axes object is given if fig is None: if ax == 111: # create new figure if there is only one subplot fig = pl.figure() else: # assume current figure fig = pl.gcf() if cg: # create curvelinear axes ax, caax, paax = create_cg(fig=fig, subplot=ax, **cg) # this is in fact the outermost thick "ring" rdiff = self._obj.range[1] - self._obj.range[0] ax.axis["lon"] = ax.new_floating_axis( 1, (np.max(self._obj.bins) + rdiff / 2.)) ax.axis["lon"].major_ticklabels.set_visible(False) # and also set tickmarklength to zero for better presentation ax.axis["lon"].major_ticks.set_ticksize(0) else: ax = fig.add_subplot(ax, projection=self.proj) if cg: plax = paax infer_intervals = kwargs.pop('infer_intervals', False) xp, yp = 'rays', 'bins' else: plax = ax infer_intervals = kwargs.pop('infer_intervals', True) if self.sweep_mode == 'azimuth_surveillance': xp, yp = 'x', 'y' else: xp, yp = 'gr', 'z' # use cartopy, if available if hasattr(plax, 'projection'): cartopy = util.import_optional('cartopy') map_trans = cartopy.crs.AzimuthalEquidistant( central_longitude=self.site[0], central_latitude=self.site[1]) kwargs.update({'transform': map_trans}) # claim xarray plot function and create plot plotfunc = getattr(self._obj.plot, func) pm = plotfunc(x=xp, y=yp, ax=plax, cmap=cmap, center=center, add_colorbar=add_colorbar, add_labels=add_labels, infer_intervals=infer_intervals, **kwargs) # set cg grids and limits if cg: if self.sweep_mode == 'azimuth_surveillance': xlims = np.min(self._obj.x), np.max(self._obj.x) ylims = np.min(self._obj.y), np.max(self._obj.y) else: xlims = np.min(self._obj.gr), np.max(self._obj.gr) ylims = np.min(self._obj.z), np.max(self._obj.z) ax.set_ylim(ylims) ax.set_xlim(xlims) ax.grid(True) caax.grid(True) if self.sweep_mode == 'azimuth_surveillance': ax.set_aspect('equal', adjustable='box') # set ax as current pl.sca(ax) return pm
#!/usr/bin/env python # Copyright (c) 2011-2018, wradlib developers. # Distributed under the MIT License. See LICENSE.txt for more info. import unittest import sys import wradlib.vis as vis import wradlib.georef as georef import numpy as np import matplotlib.pyplot as pl from wradlib.util import import_optional from tempfile import NamedTemporaryFile cartopy = import_optional('cartopy') pl.interactive(True) # noqa class PolarPlotTest(unittest.TestCase): def setUp(self): img = np.zeros((360, 10), dtype=np.float32) img[2, 2] = 10 # isolated pixel img[5, 6:8] = 10 # line img[20, :] = 5 # spike img[60:120, 2:7] = 11 # precip field self.r = np.arange(0, 100000, 10000) self.az = np.arange(0, 360) self.el = np.arange(0, 90) self.th = np.zeros_like(self.az) self.az1 = np.ones_like(self.el) * 225 self.img = img self.proj = georef.create_osr("dwd-radolan")
#!/usr/bin/env python # Copyright (c) 2011-2020, wradlib developers. # Distributed under the MIT License. See LICENSE.txt for more info. import sys import tempfile import unittest import numpy as np import matplotlib.pyplot as pl pl.interactive(True) # noqa from wradlib import georef, util, vis cartopy = util.import_optional('cartopy') class PolarPlotTest(unittest.TestCase): def setUp(self): img = np.zeros((360, 10), dtype=np.float32) img[2, 2] = 10 # isolated pixel img[5, 6:8] = 10 # line img[20, :] = 5 # spike img[60:120, 2:7] = 11 # precip field self.r = np.arange(0, 100000, 10000) self.az = np.arange(0, 360) self.el = np.arange(0, 90) self.th = np.zeros_like(self.az) self.az1 = np.ones_like(self.el) * 225 self.img = img self.proj = georef.create_osr("dwd-radolan")
def test_import_optional(self): m = util.import_optional("math") np.testing.assert_equal(m.log10(100), 2.0) mod = util.import_optional("h8x") with pytest.raises(AttributeError): mod.test()
def test_import_optional(self): m = util.import_optional('math') np.testing.assert_equal(m.log10(100), 2.0) mod = util.import_optional('h8x') with self.assertRaises(AttributeError): mod.test()
import tempfile from distutils.version import LooseVersion import matplotlib as mpl import matplotlib.pyplot as pl import numpy as np import pytest from wradlib import georef, util, vis from . import requires_data pl.interactive(True) # noqa cartopy = util.import_optional("cartopy") class TestPolarPlot: img = np.zeros((360, 10), dtype=np.float32) img[2, 2] = 10 # isolated pixel img[5, 6:8] = 10 # line img[20, :] = 5 # spike img[60:120, 2:7] = 11 # precip field r = np.arange(0, 100000, 10000) az = np.arange(0, 360) el = np.arange(0, 90) th = np.zeros_like(az) az1 = np.ones_like(el) * 225 img = img proj = georef.create_osr("dwd-radolan")
#!/usr/bin/env python # Copyright (c) 2011-2018, wradlib developers. # Distributed under the MIT License. See LICENSE.txt for more info. import unittest import sys import wradlib.vis as vis import wradlib.georef as georef import wradlib.io as io import numpy as np import matplotlib.pyplot as pl from wradlib.util import import_optional from tempfile import NamedTemporaryFile cartopy = import_optional('cartopy') pl.interactive(True) # noqa class PolarPlotTest(unittest.TestCase): def setUp(self): img = np.zeros((360, 10), dtype=np.float32) img[2, 2] = 10 # isolated pixel img[5, 6:8] = 10 # line img[20, :] = 5 # spike img[60:120, 2:7] = 11 # precip field self.r = np.arange(0, 100000, 10000) self.az = np.arange(0, 360) self.el = np.arange(0, 90) self.th = np.zeros_like(self.az) self.az1 = np.ones_like(self.el) * 225 self.img = img
def test_import_optional(self): m = util.import_optional('math') np.testing.assert_equal(m.log10(100), 2.0) mod = util.import_optional('h8x') self.assertRaises(AttributeError, lambda: mod.test())