def METHOD_NAME(
    sim, mean_vol, eig_vols, lambdas=None, noise_var=0, batch_size=512
):
    """
    Calculate coordinates using Wiener filter
    :param sim: A simulation object containing the images whose coordinates we want.
    :param mean_vol: The mean volume of the source as Volume instance.
    :param eig_vols: The eigenvolumes of the source as Volume instance.
    :param lambdas: The eigenvalues in a K-by-K diagonal matrix (default `eye(K)`).
    :param noise_var: The variance of the noise in the images (default 0).
    :param batch_size: The size of the batches in which to compute the coordinates (default 512).
    :return: A K-by-`src.n` array of coordinates corresponding to the Wiener filter coordinates of each image in sim.
    The coordinates are obtained by the formula
        alpha_s = eig_vols^T H_s ( y_s - P_s mean_vol ) ,
    where P_s is the forward image mapping and y_s is the sth image,
        H_s = Sigma * P_s^T ( P_s Sigma P_s^T + noise_var I )^(-1) ,
    and Sigma is the covariance matrix eig_vols * lambdas * eig_vols^T.
    Note that when noise_var is zero, this reduces to the projecting y_s onto the span of P_s eig_vols.
    # TODO: Find a better place for this functionality other than in utils
    """
    if not isinstance(mean_vol, Volume):
        logger.debug(
            "src_wiener_coords mean_vol should be a Volume instance. Attempt correction."
        )
        if len(mean_vol.shape) == 4 and mean_vol.shape[3] != 1:
            msg = (
                f"Cannot naively convert {mean_vol.shape} to Volume instance."
                "Please change calling code."
            )
            logger.error(msg)
            raise RuntimeError(msg)
        mean_vol = Volume(mean_vol)
    if not isinstance(eig_vols, Volume):
        logger.debug(
            "src_wiener_coords eig_vols should be a Volume instance. Correcting for now."
        )
        eig_vols = Volume(eig_vols)
    if not sim.dtype == mean_vol.dtype == eig_vols.dtype:
        logger.warning(
            "Inconsistent types in src_wiener_coords"
            f" sim {sim.dtype},"
            f" mean_vol {mean_vol.dtype},"
            f" eig_vols {eig_vols.dtype}"
        )
    k = eig_vols.n_vols
    if lambdas is None:
        lambdas = np.eye(k)
    coords = np.zeros((k, sim.n))
    covar_noise = noise_var * np.eye(k)
    for i in range(0, sim.n, batch_size):
        ims = sim.images[i : i + batch_size]
        batch_n = ims.shape[0]
        ims -= sim.vol_forward(mean_vol, i, batch_n)
        Qs, Rs = qr_vols_forward(sim, i, batch_n, eig_vols, k)
        Q_vecs = mat_to_vec(Qs)
        # RCOPT
        ims = np.moveaxis(ims.asnumpy(), 0, 2)
        im_vecs = mat_to_vec(ims)
        for j in range(batch_n):
            im_coords = Q_vecs[:, :, j].T @ im_vecs[:, j]
            covar_im = (Rs[:, :, j] @ lambdas @ Rs[:, :, j].T) + covar_noise
            xx = solve(covar_im, im_coords)
            im_coords = lambdas @ Rs[:, :, j].T @ xx
            coords[:, i + j] = im_coords
    return coords