예제 #1
0
def depolarization(zdr, rho):
    """Compute the depolarization ration.

    Compute the depolarization ration using differential
    reflectivity :math:`Z_{DR}` and crosscorrelation coefficient
    :math:`Rho_{HV}` of a radar sweep (:cite:`Kilambi2018`,
    :cite:`Melnikov2013`, :cite:`Ryzhkov2017`).

    Parameters
    ----------
    zdr : float or :class:`numpy:numpy.ndarray`
        differential reflectivity
    rho : float or :class:`numpy:numpy.ndarray`
        crosscorrelation coefficient

    Returns
    ------
    depolarization : :class:`numpy:numpy.ndarray`
        array of depolarization ratios with the same shape as input data,
        numpy broadcasting rules apply
    """
    zdr = trafo.idecibel(np.asanyarray(zdr))
    m = 2 * np.asanyarray(rho) * zdr**0.5

    return trafo.decibel((1 + zdr - m) / (1 + zdr + m))
예제 #2
0
파일: zr.py 프로젝트: tooowzh/wradlib
def _z_to_r_enhanced_mdfilt(z, mode='mirror'):
    """multidimensional version

    assuming the two last dimensions represent a 2-D image
    Uses :func:`scipy:scipy.ndimage.filters.generic_filter` to reduce the
    number of for-loops even more.
    """
    # get the shape of the input
    # dimy = z.shape[-2]
    # dimx = z.shape[-1]

    # calculate the decibel values from the input
    db = trafo.decibel(z)

    # set up our output arrays
    r = np.zeros(z.shape)
    size = list(z.shape)
    size[-2:] = [3, 3]
    size[:-2] = [1] * len(size[:-2])
    size = tuple(size)
    si = filters.generic_filter(db, z_to_r_esifilter, size=size, mode=mode)

    gt44 = db > 44.
    r[gt44] = z_to_r(z[gt44], a=77, b=1.9)
    si[gt44] = -1.
    # the same is true for values between 36.5 and 44 dBZ
    bt3644 = (db >= 36.5) & (db <= 44.)
    r[bt3644] = z_to_r(z[bt3644], a=200, b=1.6)
    si[bt3644] = -2.

    si1 = (si >= 0.)
    si2 = si1 & (si < 3.5)
    si3 = si1 & ~si2 & (si <= 7.5)
    si4 = si > 7.5

    r[si2] = z_to_r(z[si2], a=125, b=1.4)
    r[si3] = z_to_r(z[si3], a=200, b=1.6)
    r[si4] = z_to_r(z[si4], a=320, b=1.4)

    return r, si
예제 #3
0
def z_to_r_enhanced(z, polar=True, shower=True):
    """Calculates rainrates from radar reflectivities using the enhanced \
    three-part Z-R-relationship used by the DWD (as of 2009)

    To be used with polar representations so that one dimension is cyclical.
    i.e. z should be of shape (nazimuths, nbins) --> the first dimension
    is the cyclical one. For DWD DX-Data z's shape is (360,128).

    Neighborhood-means are taken only for available data via fast convolution
    sums.
    Refer to the RADOLAN final report or the RADOLAN System handbook for
    details on the calculations.
    Basically, for low reflectivities an index called the shower index is
    calculated as the mean of the differences along both axis in a neighborhood
    of 3x3 pixels.
    This means:

                        +------+-----------------+
                        |      | x-direction --> |
                        +------+-----+-----+-----+
                        | | y  |  1  |  2  |  3  |
                        | | l  +-----+-----+-----+
                        | | d  |  4  |  5  |  6  |
                        | | i  +-----+-----+-----+
                        | | r  |  7  |  8  |  9  |
                        +------+-----+-----+-----+

    If 5 is the pixel in question, it's shower index is calculated as:

    .. math::

        ( &|1-2| + |2-3| + |4-5| + |5-6| + |7-8| + |8-9| + \\\\
          &|1-4| + |4-7| + |2-5| + |5-8| + |3-6| + |6-9| ) / 12.

    then, the upper line of the sum would be diffx (DIFFerences in
    X-direction), the lower line would be diffy
    (DIFFerences in Y-direction) in the code below.

    Parameters
    ----------
    z : :class:`numpy:numpy.ndarray`
        Corresponds to reflectivity Z in mm**6/m**3
        ND-array, at least 2D
    polar : bool
        defaults to to True (polar data), False for cartesian data.
    shower : bool
        output shower index, defaults to True

    Returns
    -------
    r : :class:`numpy:numpy.ndarray`
        r  - array of shape z.shape - calculated rain rates
    si : :class:`numpy:numpy.ndarray`
        si - array of shape z.shape - calculated shower index
        for control purposes. May be omitted in later versions

    """
    z = np.asanyarray(z, dtype=np.float64)
    shape = z.shape
    z = z.reshape((-1,) + shape[-2:])
    if polar:
        z0 = np.concatenate([z[:, -1:, :], z, z[:, 0:1, :]], axis=-2)
        x_ymin, x_ymax = 2, -2
        y_ymin, y_ymax = 1, -1
        x_xmin, x_xmax = None, None
        y_xmin, y_xmax = 1, -1
    else:
        z0 = z.copy()
        x_ymin, x_ymax = 1, -1
        y_ymin, y_ymax = None, None
        x_xmin, x_xmax = None, None
        y_xmin, y_xmax = 1, -1
    z0 = trafo.decibel(z0)

    # create shower index using differences and convolution sum
    diffx = np.abs(np.diff(z0, n=1, axis=-1))
    diffy = np.abs(np.diff(z0, n=1, axis=-2))
    xkernel = np.ones((1, 3, 2))
    ykernel = np.ones((1, 2, 3))
    resx = signal.convolve(diffx, xkernel, mode="full", method="direct")[
        :, x_ymin:x_ymax, x_xmin:x_xmax
    ]
    resy = signal.convolve(diffy, ykernel, mode="full", method="direct")[
        :, y_ymin:y_ymax, y_xmin:y_xmax
    ]
    si = resx + resy

    # edge cases divide by 7, everything else divide by 12
    if polar:
        si[:, :, 0] /= 7.0
        si[:, :, -1] /= 7.0
        si[:, :, 1:-1] /= 12.0
    else:
        si[:, 1:-1, 1:-1] /= 12.0
        si[:, :, 0] /= 7
        si[:, :, -1] /= 7.0
        si[:, 0, :] /= 7
        si[:, -1, :] /= 7.0

    rr = np.zeros(z.shape)
    z0_ = z0[:, y_ymin:y_ymax, :]

    # get masks
    gt44 = z0_ > 44
    bt3644 = (z0_ >= 36.5) & (z0_ <= 44.0)
    si[bt3644] = -1.0
    si[gt44] = -1.0
    mn75h = (si > 7.5) & (si < 36.5)
    mn35 = (si > -1) & (si < 3.5)
    mn75l = (si >= 3.5) & (si <= 7.5)

    # calculate rainrates according DWD
    rr[mn75l] = z_to_r(z[mn75l], a=200.0, b=1.6)
    rr[mn75h] = z_to_r(z[mn75h], a=320.0, b=1.4)
    rr[mn35] = z_to_r(z[mn35], a=125.0, b=1.4)
    rr[gt44] = z_to_r(z[gt44], a=77.0, b=1.9)
    rr[bt3644] = z_to_r(z[bt3644], a=200.0, b=1.6)

    rr.shape = shape
    si.shape = shape

    if shower:
        return rr, si
    else:
        return rr
예제 #4
0
ranges = r
polargrid = np.meshgrid(ranges, azimuths)
lon, lat, alt = wradlib.georef.polar2lonlatalt_n(polargrid[0], polargrid[1], elevation, radar_location)

gk3 = wradlib.georef.epsg_to_osr(31467)
x, y = wradlib.georef.reproject(lon, lat, projection_target=gk3)
xgrid, ygrid = wradlib.georef.reproject(dpr_lon[latstart:latend], dpr_lat[latstart:latend], projection_target=gk3)

grid_xy = np.vstack((xgrid.ravel(), ygrid.ravel())).transpose()


xy=np.concatenate([x.ravel()[:,None],y.ravel()[:,None]], axis=1)
gridded = wradlib.comp.togrid(xy, grid_xy, ranges[-1], np.array([x.mean(), y.mean()]), R.ravel(), ipoli[0],nnearest=40,p=2)
gridded = np.ma.masked_invalid(gridded).reshape(xgrid.shape)

gridded = decibel(gridded)

R = decibel(R)

# ON RADOLAN GRID
proj_stereo = wrl.georef.create_osr("dwd-radolan")
proj_wgs = osr.SpatialReference()
proj_wgs.ImportFromEPSG(4326)

box_x, box_y = wradlib.georef.reproject(lon, lat, projection_target=proj_stereo , projection_source=proj_wgs)
gpm_x, gpm_y = wradlib.georef.reproject(dpr_lon[latstart:latend], dpr_lat[latstart:latend], projection_target=proj_stereo , projection_source=proj_wgs)

#Todo IM PLOT VERWENDEN !!!!!!!

# Plot
# ----
예제 #5
0
                ############################################## INTERLOLATION RX

                #mask2 = ~np.isnan(rwdata2)

                result2 = wrl.ipol.interpolate(xy,
                                               grid_gpm_xy,
                                               rwdata2.reshape(900 * 900, 1),
                                               wrl.ipol.Idw,
                                               nnearest=8)

                result2 = np.ma.masked_invalid(result2)

                rrr2 = result2.reshape(gpm_x.shape)

                rrr2 = decibel(rrr2)
                rwdata2 = decibel(rwdata2)

                ## Interpolation of the binary Grid

                res_bin = wrl.ipol.interpolate(xy,
                                               grid_gpm_xy,
                                               rn.reshape(900 * 900, 1),
                                               wrl.ipol.Idw,
                                               nnearest=25)
                res_bin = res_bin.reshape(gpm_x.shape)

                res_bin[res_bin != 0] = 1  # Randkorrektur

                rand_y_unten = -4658.6447242655722
                rand_y_oben = -3759.6447242655722
예제 #6
0
        xy = np.vstack((x.ravel(), y.ravel())).transpose()

        mask = ~np.isnan(rwdata)

        result = wrl.ipol.interpolate(xy,
                                      grid_gpm_xy,
                                      rwdata.reshape(900 * 900, 1),
                                      wrl.ipol.Idw,
                                      nnearest=4)

        result = np.ma.masked_invalid(result)

        rrr = result.reshape(gpm_x.shape)

        rrr = decibel(rrr)
        rwdata = decibel(rwdata)

        ## Interpolation of the binary Grid
        ## ------------------------------

        res_bin = wrl.ipol.interpolate(xy,
                                       grid_gpm_xy,
                                       rn.reshape(900 * 900, 1),
                                       wrl.ipol.Idw,
                                       nnearest=4)
        res_bin = res_bin.reshape(gpm_x.shape)

        res_bin[res_bin != 0] = 1  # Randkorrektur

        rand_y_unten = -4658.6447242655722
예제 #7
0
 def test_decibel(self):
     self.assertTrue(np.allclose(trafo.decibel(self.lin), self.dec))
예제 #8
0
grid_xy = np.vstack((dpr_lon.ravel(), dpr_lat.ravel())).transpose()

xy = np.concatenate([lon.ravel()[:, None], lat.ravel()[:, None]], axis=1)

gridded = wradlib.comp.togrid(xy,
                              grid_xy,
                              ranges[-1],
                              np.array([lon.mean(), lat.mean()]),
                              R.ravel(),
                              ipoli[0],
                              nnearest=40,
                              p=2)
gridded = np.ma.masked_invalid(gridded).reshape(dpr_lon.shape)
gridded[np.where(rr > radius)] = np.nan

R = decibel(R)
gridded = decibel(gridded)

fig = plt.figure(figsize=(14, 12))
fig.suptitle('BoXPol vs DPR ' + ZP + ' Rho_th: ' + str(rho_th))

###################
ax1 = fig.add_subplot(221, aspect='auto')
plt.pcolormesh(dpr_lon,
               dpr_lat,
               np.ma.masked_invalid(pp),
               vmin=0,
               vmax=40,
               cmap=my_cmap())

plt.colorbar()
예제 #9
0
        gk3 = wradlib.georef.epsg_to_osr(31467)

        grid_gpm_xy = np.vstack((gpm_x.ravel(), gpm_y.ravel())).transpose()

        xy = np.vstack((x.ravel(), y.ravel())).transpose()

        mask = ~np.isnan(rwdata)

        result = wrl.ipol.interpolate(xy, grid_gpm_xy, rwdata.reshape(900*900,1), wrl.ipol.Idw, nnearest=4)

        result = np.ma.masked_invalid(result)

        rrr = result.reshape(gpm_x.shape)

        rrr = decibel(rrr)
        rwdata = decibel(rwdata)


        ## Interpolation of the binary Grid
        ## ------------------------------

        res_bin = wrl.ipol.interpolate(xy, grid_gpm_xy, rn.reshape(900*900,1), wrl.ipol.Idw, nnearest=4)
        res_bin = res_bin.reshape(gpm_x.shape)

        res_bin[res_bin!=0]= 1 # Randkorrektur

        rand_y_unten = -4658.6447242655722
        rand_y_oben = -3759.6447242655722
        rand_x_rechts = 375.5378330781441
예제 #10
0
 def test_decibel(self):
     self.assertTrue(np.allclose(trafo.decibel(self.lin), self.dec))
예제 #11
0
 def test_decibel(self):
     assert np.allclose(trafo.decibel(self.lin), self.dec)
예제 #12
0
                result = np.ma.masked_invalid(result)

                rrr = result.reshape(gpm_x.shape)

                ############################################## INTERLOLATION RX

                #mask2 = ~np.isnan(rwdata2)

                result2 = wrl.ipol.interpolate(xy, grid_gpm_xy, rwdata2.reshape(900*900,1), wrl.ipol.Idw, nnearest=8)

                result2 = np.ma.masked_invalid(result2)

                rrr2 = result2.reshape(gpm_x.shape)

                rrr2 = decibel(rrr2)
                rwdata2 = decibel(rwdata2)


                ## Interpolation of the binary Grid

                res_bin = wrl.ipol.interpolate(xy, grid_gpm_xy, rn.reshape(900*900,1), wrl.ipol.Idw, nnearest=25)
                res_bin = res_bin.reshape(gpm_x.shape)

                res_bin[res_bin != 0] = 1  # Randkorrektur

                rand_y_unten = -4658.6447242655722
                rand_y_oben = -3759.6447242655722
                rand_x_rechts = 375.5378330781441

예제 #13
0
파일: zr.py 프로젝트: tooowzh/wradlib
def _z_to_r_enhanced(z):
    """Calculates rainrates from radar reflectivities using the enhanced \
    three-part Z-R-relationship used by the DWD (as of 2009).

    This function does the actual calculations without any padding.
    Neighborhood-means are taken only for available data, reducing the number
    of elements used near the edges of the array.
    Refer to the RADOLAN final report or the RADOLAN System handbook for
    details on the calculations.
    Basically, for low reflectivities an index called the shower index is
    calculated as the mean of the differences along both axis in a neighborhood
    of 3x3 pixels.
    This means:
           x-direction -->
    y |    +---+---+---+
    | |    | 1 | 2 | 3 |
    d v    +---+---+---+
    i      | 4 | 5 | 6 |
    r      +---+---+---+
    e      | 7 | 8 | 9 |
    c      +---+---+---+
    t
    i      if 5 is the pixel in question, its shower index is calculated as
    o      ( |1-2| + |2-3| + |4-5| + |5-6| + |7-8| + |8-9| +
    n      + |1-4| + |4-7| + |2-5| + |5-8| + |3-6| + |6-9| ) / 12.
           then, the upper line of the sum would be diffx (DIFFerences in
           X-direction), the lower line would be diffy
           (DIFFerences in Y-direction) in the code below.
    """
    # get the shape of the input
    dimy = z.shape[0]
    dimx = z.shape[1]

    # calculate the decibel values from the input
    db = trafo.decibel(z)

    # set up our output arrays
    r = np.zeros(z.shape)
    si = np.zeros(z.shape)

    # calculate difference fields in x and y direction
    #  mainly for performance reasons, so that we can use numpy's efficient
    #  array operations and avoid calculating a difference more than once
    diffx = np.abs(db[:, :-1] - db[:, 1:])
    diffy = np.abs(db[:-1, :] - db[1:, :])

    # if the reflectivity is larger than 44dBZ, then there is no need to
    # calculate the shower index
    gt44 = np.where(db > 44.)
    r[gt44] = z_to_r(z[gt44], a=77., b=1.9)
    # the same is true for values between 36.5 and 44 dBZ
    bt3644 = np.where(np.logical_and(db >= 36.5, db <= 44.))
    r[bt3644] = z_to_r(z[bt3644], a=200., b=1.6)

    # now iterate over the array and look for the remaining values
    # TODO : this could be a starting point for further optimization, if we
    #        iterated only over the remaining pixels instead of all
    for i in range(dimy):
        for j in range(dimx):
            # if the reflectivity is too high, we coped with it already
            # so we can skip that one
            if db[i, j] >= 36.5:
                # just set the shower index to some impossible value so that
                # we know that there was no calculation done here
                si[i, j] = -1
                # continue with the next iteration
                continue
            else:
                # calculate the bounds of the region where we have to consider
                # the respective difference
                xmin = max(0, j - 1)
                xmax = min(dimx, j + 1)
                ymin = max(0, i - 1)
                ymax = min(dimy, i + 1)
                # in fact python is quite forgiving with upper indices
                # ours might go one index too far, so don't try to port this
                # to another programming language straigt away!
                diffxcut = diffx[ymin:ymax + 1, xmin:xmax]
                diffycut = diffy[ymin:ymax, xmin:xmax + 1]
                # calculate the mean for the current pixel
                mn = (np.sum(diffxcut) + np.sum(diffycut)) / \
                     (diffxcut.size + diffycut.size)
                # apply the three different Z/R relations
                if mn < 3.5:
                    r[i, j] = z_to_r(z[i, j], a=125., b=1.4)
                elif mn <= 7.5:
                    r[i, j] = z_to_r(z[i, j], a=200., b=1.6)
                else:
                    r[i, j] = z_to_r(z[i, j], a=320., b=1.4)
                # save the shower index
                si[i, j] = mn
    # return the results
    return r, si
예제 #14
0
파일: zr.py 프로젝트: tooowzh/wradlib
def _z_to_r_enhanced_mdcorr(z, xmode='reflect', ymode='wrap'):
    """multidimensional version

    assuming the two last dimensions represent a 2-D image
    Uses :func:`scipy:scipy.ndimage.filters.correlate` to reduce the number of
    for-loops even more.
    """
    # get the shape of the input
    # dimy = z.shape[-2]
    # dimx = z.shape[-1]

    # calculate the decibel values from the input
    db = trafo.decibel(z)
    # calculate the shower differences by 1-d correlation with a differencing
    # kernel
    db_diffx = np.abs(
        filters.correlate1d(db, [1, -1], axis=-1, mode=xmode, origin=-1))
    db_diffy = np.abs(
        filters.correlate1d(db, [1, -1], axis=-2, mode=ymode, origin=-1))
    diffxmode = 'wrap' if xmode == 'wrap' else 'constant'
    diffymode = 'wrap' if ymode == 'wrap' else 'constant'
    diffx_sum1 = filters.correlate1d(db_diffx, [1, 1, 1],
                                     axis=-2,
                                     mode=diffymode)
    diffxsum = filters.correlate1d(diffx_sum1, [1, 1, 0],
                                   axis=-1,
                                   mode=diffxmode)
    diffy_sum1 = filters.correlate1d(db_diffy, [1, 1, 1],
                                     axis=-1,
                                     mode=diffxmode)
    diffysum = filters.correlate1d(diffy_sum1, [1, 1, 0],
                                   axis=-2,
                                   mode=diffymode)

    divider = np.ones(db.shape) * 12.
    if xmode != 'wrap':
        divider[..., [0, -1]] = np.rint(
            (divider[..., [0, -1]] + 1) / 1.618) - 1
    if ymode != 'wrap':
        divider[..., [0, -1], :] = np.rint(
            (divider[..., [0, -1], :] + 1) / 1.618) - 1

    # the shower index is the sum of the x- and y-differences
    si = (diffxsum + diffysum) / divider

    # set up our rainfall output array
    r = np.zeros(z.shape)

    gt44 = db > 44.
    r[gt44] = z_to_r(z[gt44], a=77, b=1.9)
    si[gt44] = -1.
    # the same is true for values between 36.5 and 44 dBZ
    bt3644 = (db >= 36.5) & (db <= 44.)
    r[bt3644] = z_to_r(z[bt3644], a=200, b=1.6)
    si[bt3644] = -2.

    si1 = (si >= 0.)
    si2 = si1 & (si < 3.5)
    si3 = si1 & ~si2 & (si <= 7.5)
    si4 = si > 7.5

    r[si2] = z_to_r(z[si2], a=125, b=1.4)
    r[si3] = z_to_r(z[si3], a=200, b=1.6)
    r[si4] = z_to_r(z[si4], a=320, b=1.4)

    return r, si