def cosine_score_hungarian(spec1, spec2, mass_shift, tol, min_intens=0):
    "Taking full care of weighted bipartite matching problem.\n\n    Use Hungarian algorithm (slow...)\n\n    Args:\n    --------\n    spec1: Spectrum peaks and intensities as numpy array.\n    spec2: Spectrum peaks and intensities as numpy array.\n    mass_shift: float\n        Difference in parent mass of both spectra to account for. Set to 'None'\n        when no shifting is desired --> back to normal cosine score.\n    tol: float\n        Tolerance value to define how far two peaks can be apart to still count as match.\n    min_intens: float\n        Minimum intensity (relative to max.intensity peak in spectrum). Peaks with lower\n        intensity will be ignored --> higher min_intens is faster, but less precise.\n    "
    if ((spec1.shape[0] == 0) or (spec2.shape[0] == 0)):
        return (0.0, [])
    spec1[:, 1] = (spec1[:, 1] / max(spec1[:, 1]))
    spec2[:, 1] = (spec2[:, 1] / max(spec2[:, 1]))
    spec1 = spec1[(spec1[:, 1] > min_intens), :]
    spec2 = spec2[(spec2[:, 1] > min_intens), :]
    zero_pairs = find_pairs_numba(spec1, spec2, tol, shift=0.0)
    if ((mass_shift is not None) and (mass_shift != 0.0)):
        nonzero_pairs = find_pairs_numba(spec1, spec2, tol, shift=mass_shift)
        matching_pairs = (zero_pairs + nonzero_pairs)
    else:
        matching_pairs = zero_pairs
    matching_pairs = sorted(matching_pairs, key=(lambda x: x[2]), reverse=True)
    used_matches = []
    list1 = list(set([x[0] for x in matching_pairs]))
    list2 = list(set([x[1] for x in matching_pairs]))
    matrix_size = (len(list1), len(list2))
    matrix = np.ones(matrix_size)
    if (len(matching_pairs) > 0):
        for m in matching_pairs:
            matrix[(list1.index(m[0]), list2.index(m[1]))] = (1 - m[2])
        (row_ind, col_ind) = linear_sum_assignment(matrix)
        score = (len(row_ind) - matrix[(row_ind, col_ind)].sum())
        used_matches = [(list1[x], list2[y]) for (x, y) in zip(row_ind, col_ind)]
        score = (score / max(np.sum((spec1[:, 1] ** 2)), np.sum((spec2[:, 1] ** 2))))
    else:
        score = 0.0
    return (score, used_matches)
Taking full care of weighted bipartite matching problem.

Use Hungarian algorithm (slow...)

Args:
--------
spec1: Spectrum peaks and intensities as numpy array.
spec2: Spectrum peaks and intensities as numpy array.
mass_shift: float
    Difference in parent mass of both spectra to account for. Set to 'None'
    when no shifting is desired --> back to normal cosine score.
tol: float
    Tolerance value to define how far two peaks can be apart to still count as match.
min_intens: float
    Minimum intensity (relative to max.intensity peak in spectrum). Peaks with lower
    intensity will be ignored --> higher min_intens is faster, but less precise.
def cosine_score_hungarian(spec1, spec2, mass_shift, tol, min_intens=0):
    "Taking full care of weighted bipartite matching problem.\n\n    Use Hungarian algorithm (slow...)\n\n    Args:\n    --------\n    spec1: Spectrum peaks and intensities as numpy array.\n    spec2: Spectrum peaks and intensities as numpy array.\n    mass_shift: float\n        Difference in parent mass of both spectra to account for. Set to 'None'\n        when no shifting is desired --> back to normal cosine score.\n    tol: float\n        Tolerance value to define how far two peaks can be apart to still count as match.\n    min_intens: float\n        Minimum intensity (relative to max.intensity peak in spectrum). Peaks with lower\n        intensity will be ignored --> higher min_intens is faster, but less precise.\n    "
    if ((spec1.shape[0] == 0) or (spec2.shape[0] == 0)):
        return (0.0, [])
    spec1[:, 1] = (spec1[:, 1] / max(spec1[:, 1]))
    spec2[:, 1] = (spec2[:, 1] / max(spec2[:, 1]))
    spec1 = spec1[(spec1[:, 1] > min_intens), :]
    spec2 = spec2[(spec2[:, 1] > min_intens), :]
    zero_pairs = find_pairs_numba(spec1, spec2, tol, shift=0.0)
    if ((mass_shift is not None) and (mass_shift != 0.0)):
        nonzero_pairs = find_pairs_numba(spec1, spec2, tol, shift=mass_shift)
        matching_pairs = (zero_pairs + nonzero_pairs)
    else:
        matching_pairs = zero_pairs
    matching_pairs = sorted(matching_pairs, key=(lambda x: x[2]), reverse=True)
    used_matches = []
    list1 = list(set([x[0] for x in matching_pairs]))
    list2 = list(set([x[1] for x in matching_pairs]))
    matrix_size = (len(list1), len(list2))
    matrix = np.ones(matrix_size)
    if (len(matching_pairs) > 0):
        for m in matching_pairs:
            matrix[(list1.index(m[0]), list2.index(m[1]))] = (1 - m[2])
        (row_ind, col_ind) = linear_sum_assignment(matrix)
        score = (len(row_ind) - matrix[(row_ind, col_ind)].sum())
        used_matches = [(list1[x], list2[y]) for (x, y) in zip(row_ind, col_ind)]
        score = (score / max(np.sum((spec1[:, 1] ** 2)), np.sum((spec2[:, 1] ** 2))))
    else:
        score = 0.0
    return (score, used_matches)