def _compute_kernel_anisotropic(params, cutoff=6.0):
    """Compute anisotropic Gaussian convolution kernel."""
    phi, sigma1, sigma2 = params

    phi_r = phi / 180.0 * np.pi
    rot_inv = np.array(
        [[np.cos(phi_r), np.sin(phi_r)], [-np.sin(phi_r), np.cos(phi_r)]]
    )

    bb_y1, bb_x1, bb_y2, bb_x2 = _compute_ellipse_bbox(phi, sigma1, sigma2, cutoff)

    x = np.arange(int(bb_x1), int(bb_x2) + 1).astype(float)
    if len(x) % 2 == 0:
        x = np.arange(int(bb_x1) - 1, int(bb_x2) + 1).astype(float)
    y = np.arange(int(bb_y1), int(bb_y2) + 1).astype(float)
    if len(y) % 2 == 0:
        y = np.arange(int(bb_y1) - 1, int(bb_y2) + 1).astype(float)

    x_grid, y_grid = np.meshgrid(x, y)
    xy_grid = np.vstack([x_grid.flatten(), y_grid.flatten()])
    xy_grid = np.dot(rot_inv, xy_grid)

    x2 = xy_grid[0, :] * xy_grid[0, :]
    y2 = xy_grid[1, :] * xy_grid[1, :]
    result = np.exp(-(x2 / sigma1**2 + y2 / sigma2**2))

    return np.reshape(result / np.sum(result), x_grid.shape)
Compute anisotropic Gaussian convolution kernel.
pysteps/nowcasts/linda.py