def initialize_nonparam_2d_fft_filter(field, **kwargs):
    """
    Takes one ore more 2d input fields and produces one non-parametric, global
    and anisotropic fourier filter.

    Parameters
    ----------
    field: array-like
        Two- or three-dimensional array containing one or more input fields.
        All values are required to be finite. If more than one field are passed,
        the average fourier filter is returned. It assumes that fields are stacked
        by the first axis: [nr_fields, y, x].

    Other Parameters
    ----------------
    win_fun: {'hann', 'tukey', None}
        Optional tapering function to be applied to the input field, generated with
        :py:func:`pysteps.utils.tapering.compute_window_function`
        (default 'tukey').
    donorm: bool
        Option to normalize the real and imaginary parts.
        Default: False
    rm_rdisc: bool
        Whether or not to remove the rain/no-rain disconituity (default True).
        It assumes no-rain pixels are assigned with lowest value.
    fft_method: str or tuple
        A string or a (function,kwargs) tuple defining the FFT method to use
        (see "FFT methods" in :py:func:`pysteps.utils.interface.get_method`).
        Defaults to "numpy".

    Returns
    -------
    out: dict
        A dictionary containing the keys field and input_shape. The first is a
        two-dimensional array of shape (m, int(n/2)+1) that defines the filter.
        The second one is the shape of the input field for the filter.

        It can be passed to
        :py:func:`pysteps.noise.fftgenerators.generate_noise_2d_fft_filter`.
    """
    if len(field.shape) < 2 or len(field.shape) > 3:
        raise ValueError("the input is not two- or three-dimensional array")
    if np.any(~np.isfinite(field)):
        raise ValueError(
            "field contains non-finite values, this typically happens when the input\n"
            + "precipitation field provided to pysteps contains (mostly)zero values.\n"
            + "To prevent this error please call pysteps.utils.check_norain first,\n"
            + "using the same win_fun as used in this method (tukey by default)\n"
            + "and then only call this method if that check fails."
        )

    # defaults
    win_fun = kwargs.get("win_fun", "tukey")
    donorm = kwargs.get("donorm", False)
    rm_rdisc = kwargs.get("rm_rdisc", True)
    use_full_fft = kwargs.get("use_full_fft", False)
    fft = kwargs.get("fft_method", "numpy")
    if type(fft) == str:
        fft_shape = field.shape if len(field.shape) == 2 else field.shape[1:]
        fft = utils.get_method(fft, shape=fft_shape)

    field = field.copy()

    # remove rain/no-rain discontinuity
    if rm_rdisc:
        field[field > field.min()] -= field[field > field.min()].min() - field.min()

    # dims
    if len(field.shape) == 2:
        field = field[None, :, :]
    nr_fields = field.shape[0]
    field_shape = field.shape[1:]
    if use_full_fft:
        fft_shape = (field.shape[1], field.shape[2])
    else:
        fft_shape = (field.shape[1], int(field.shape[2] / 2) + 1)

    # make sure non-rainy pixels are set to zero
    field -= field.min(axis=(1, 2))[:, None, None]

    if win_fun is not None:
        tapering = utils.tapering.compute_window_function(
            field_shape[0], field_shape[1], win_fun
        )
    else:
        tapering = np.ones(field_shape)

    F = np.zeros(fft_shape, dtype=complex)
    for i in range(nr_fields):
        if use_full_fft:
            F += fft.fft2(field[i, :, :] * tapering)
        else:
            F += fft.rfft2(field[i, :, :] * tapering)
    F /= nr_fields

    # normalize the real and imaginary parts
    if donorm:
        if np.std(F.imag) > 0:
            F.imag = (F.imag - np.mean(F.imag)) / np.std(F.imag)
        if np.std(F.real) > 0:
            F.real = (F.real - np.mean(F.real)) / np.std(F.real)

    return {
        "field": np.abs(F),
        "input_shape": field.shape[1:],
        "use_full_fft": use_full_fft,
    }
Takes one ore more 2d input fields and produces one non-parametric, global
and anisotropic fourier filter.

Parameters
----------
field: array-like
Two- or three-dimensional array containing one or more input fields.
All values are required to be finite. If more than one field are passed,
the average fourier filter is returned. It assumes that fields are stacked
by the first axis: [nr_fields, y, x].

Other Parameters
----------------
win_fun: {'hann', 'tukey', None}
Optional tapering function to be applied to the input field, generated with
:py:func:`pysteps.utils.tapering.compute_window_function`
(default 'tukey').
donorm: bool
Option to normalize the real and imaginary parts.
Default: False
rm_rdisc: bool
Whether or not to remove the rain/no-rain disconituity (default True).
It assumes no-rain pixels are assigned with lowest value.
fft_method: str or tuple
A string or a (function,kwargs) tuple defining the FFT method to use
(see "FFT methods" in :py:func:`pysteps.utils.interface.get_method`).
Defaults to "numpy".

Returns
-------
out: dict
A dictionary containing the keys field and input_shape. The first is a
two-dimensional array of shape (m, int(n/2)+1) that defines the filter.
The second one is the shape of the input field for the filter.

It can be passed to
:py:func:`pysteps.noise.fftgenerators.generate_noise_2d_fft_filter`.
pysteps/noise/fftgenerators.py