import numpy as np


def score_spectrum(spec_real, spec_predict, ms2_ppm):
    index_left = np.searchsorted(spec_predict[:, 0], spec_real[:, 0] * (1. - ms2_ppm * 1e-6), side='left')
    index_right = np.searchsorted(spec_predict[:, 0], spec_real[:, 0] * (1. + ms2_ppm * 1e-6), side='right')

    intensity_sum = np.sum(spec_real[:, 1])
    if intensity_sum > 0:
        score = 0.
        for intensity_cur, i_start, i_end in zip(spec_real[:, 1], index_left, index_right):
            if i_end > i_start:
                p_pred = np.max(spec_predict[i_start:i_end, 1])
                score += p_pred * intensity_cur
        return score / intensity_sum
    else:
        return 0.


def score_spectrum_slow(spec_real, spec_predict, precursor_mass, ms2_ppm):
    product_ion_intensity = [x[1] for x in spec_real if x[0] <= precursor_mass - 0.5]
    product_ions_intensity_sum = sum(product_ion_intensity)
    cur_score = 0.
    if product_ions_intensity_sum > 0:
        for peak in spec_real:
            if peak[0] > precursor_mass - 0.5:
                continue
            mass_delta = peak[0] * ms2_ppm * 1e-6
            mass_min = peak[0] - mass_delta
            mass_max = peak[0] + mass_delta
            select_info = np.bitwise_and(spec_predict[:, 0] >= mass_min, spec_predict[:, 0] <= mass_max)
            select_peak = spec_predict[select_info, 1]
            if select_peak.any():
                p = np.max(select_peak)
                cur_score += peak[1] * p
            pass
        cur_score = cur_score / product_ions_intensity_sum
    return cur_score
