Exemplo n.º 1
0
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)
Exemplo n.º 2
0
def unfold_phi_naive(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 slow Python-based implementation (NOT 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)

    """
    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)

    # phi_corr = np.zeros(phidp.shape)
    for beam in range(beams):

        if np.all(phidp[beam] == 0):
            continue

        # step 1: determine location where meaningful PhiDP profile begins
        for j in range(0, rs - width):
            if (np.sum(stdarr[beam, j:j + width] < 5) == width) and \
                    (np.sum(rho[beam, j:j + 5] > 0.9) == width):
                break

        ref = np.mean(phidp[beam, j:j + width])
        for k in range(j + width, rs):
            if np.sum(stdarr[beam, k - width:k] < 5) and \
                    np.logical_and(gradphi[beam, k] > -5,
                                   gradphi[beam, k] < 20):
                ref += gradphi[beam, k] * 0.5
                if phidp[beam, k] - ref < -80:
                    if phidp[beam, k] < 0:
                        phidp[beam, k] += 360
            elif phidp[beam, k] - ref < -80:
                if phidp[beam, k] < 0:
                    phidp[beam, k] += 360
    return phidp
Exemplo n.º 3
0
 def test_gradient_from_smoothed(self):
     x = np.arange(10).reshape((2, 5)).astype("f4")**2
     result = util.gradient_from_smoothed(x)
     shouldbe = np.array([[1.0, 2.0, 1.5, 0.0, 0.0],
                          [11.0, 12.0, 6.5, 0.0, 0.0]])
     np.testing.assert_allclose(result, shouldbe)
Exemplo n.º 4
0
 def test_gradient_from_smoothed(self):
     x = np.arange(10).reshape((2, 5)).astype("f4") ** 2
     result = util.gradient_from_smoothed(x)
     shouldbe = np.array([[1., 11., 2., 1.5, 0., 0.],
                          [1., 11., 12., 6.5, 0., 0.]])
     np.testing.assert_allclose(result, shouldbe)