def test_optflow_method_convergence(
    input_precip, optflow_method_name, motion_type, num_times, max_rel_rmse
):
    """
    Test the convergence to the actual solution of the optical flow method used.

    We measure the error in the retrieved field by using the
    Relative RMSE = Rel_RMSE = sqrt(Relative MSE)

        - Rel_RMSE = 0%: no error
        - Rel_RMSE = 100%: The retrieved motion field has an average error
          equal in magnitude to the motion field.

    Relative RMSE is computed only un a region surrounding the precipitation
    field, were we have enough information to retrieve the motion field.
    The precipitation region includes the precipitation pattern plus a margin
    of approximately 20 grid points.


    Parameters
    ----------

    input_precip: numpy array (lat, lon)
        Input precipitation field.

    optflow_method_name: str
        Optical flow method name

    motion_type : str
        The supported motion fields are:

            - linear_x: (u=2, v=0)
            - linear_y: (u=0, v=2)
    """
    if optflow_method_name == "lk":
        pytest.importorskip("cv2")

    ideal_motion, precip_obs = _create_observations(
        input_precip.copy(), motion_type, num_times=num_times
    )

    oflow_method = motion.get_method(optflow_method_name)

    if optflow_method_name == "vet":
        # By default, the maximum number of iteration in the VET minimization
        # is maxiter=100.
        # To increase the stability of the tests to we increase this value to
        # maxiter=150.
        retrieved_motion = oflow_method(
            precip_obs, verbose=False, options=dict(maxiter=150)
        )
    elif optflow_method_name == "proesmans":
        retrieved_motion = oflow_method(precip_obs)
    else:
        retrieved_motion = oflow_method(precip_obs, verbose=False)

    precip_data, _ = stp.utils.dB_transform(precip_obs.max(axis=0), inverse=True)
    precip_data.data[precip_data.mask] = 0

    precip_mask = (uniform_filter(precip_data, size=20) > 0.1) & ~precip_obs.mask.any(
        axis=0
    )

    # To evaluate the accuracy of the computed_motion vectors, we will use
    # a relative RMSE measure.
    # Relative MSE = < (expected_motion - computed_motion)^2 > / <expected_motion^2 >
    # Relative RMSE = sqrt(Relative MSE)

    mse = ((ideal_motion - retrieved_motion)[:, precip_mask] ** 2).mean()

    rel_mse = mse / (ideal_motion[:, precip_mask] ** 2).mean()
    rel_rmse = np.sqrt(rel_mse) * 100
    print(
        f"method:{optflow_method_name} ; "
        f"motion:{motion_type} ; times: {num_times} ; "
        f"rel_rmse:{rel_rmse:.2f}%"
    )
    assert rel_rmse < max_rel_rmse
Test the convergence to the actual solution of the optical flow method used.

We measure the error in the retrieved field by using the
Relative RMSE = Rel_RMSE = sqrt(Relative MSE)

- Rel_RMSE = 0%: no error
- Rel_RMSE = 100%: The retrieved motion field has an average error
equal in magnitude to the motion field.

Relative RMSE is computed only un a region surrounding the precipitation
field, were we have enough information to retrieve the motion field.
The precipitation region includes the precipitation pattern plus a margin
of approximately 20 grid points.


Parameters
----------

input_precip: numpy array (lat, lon)
Input precipitation field.

optflow_method_name: str
Optical flow method name

motion_type : str
The supported motion fields are:

- linear_x: (u=2, v=0)
- linear_y: (u=0, v=2)
pysteps/tests/test_motion.py