Ejemplo n.º 1
0
def test_neutral_losses_cosine_with_mass_shift(peaks, tolerance, masses,
                                               expected_matches):
    """Test neutral losses cosine on two spectra with mass shift."""
    builder = SpectrumBuilder()
    spectrum_1 = builder.with_mz(peaks[0][0]).with_intensities(
        peaks[0][1]).with_metadata(metadata={
            "precursor_mz": masses[0]
        }).build()
    spectrum_2 = builder.with_mz(peaks[1][0]).with_intensities(
        peaks[1][1]).with_metadata(metadata={
            "precursor_mz": masses[1]
        }).build()

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    if tolerance is None:
        neutral_losses_cosine = NeutralLossesCosine()
    else:
        neutral_losses_cosine = NeutralLossesCosine(tolerance=tolerance)

    score = neutral_losses_cosine.pair(norm_spectrum_1, norm_spectrum_2)
    expected_score = compute_expected_score(norm_spectrum_1, norm_spectrum_2,
                                            expected_matches)
    assert score["score"] == pytest.approx(
        expected_score, 0.0001), "Expected different cosine score."
    assert score["matches"] == len(
        expected_matches), "Expected differnt number of matching peaks."
Ejemplo n.º 2
0
def test_modified_cosine_order_of_input_spectrums():
    """Test modified cosine on two spectra in changing order."""
    spectrum_1 = Spectrum(mz=numpy.array([100, 150, 200, 300, 500, 510, 1100],
                                         dtype="float"),
                          intensities=numpy.array(
                              [700, 200, 100, 1000, 200, 5, 500],
                              dtype="float"),
                          metadata={"precursor_mz": 1000.0})

    spectrum_2 = Spectrum(
        mz=numpy.array([55, 105, 205, 304.5, 494.5, 515.5, 1045],
                       dtype="float"),
        intensities=numpy.array([700, 200, 100, 1000, 200, 5, 500],
                                dtype="float"),
        metadata={"precursor_mz": 1005.0})

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    modified_cosine = ModifiedCosine(tolerance=2.0)
    score_1_2, n_matches_1_2 = modified_cosine(norm_spectrum_1,
                                               norm_spectrum_2)
    score_2_1, n_matches_2_1 = modified_cosine(norm_spectrum_2,
                                               norm_spectrum_1)

    assert score_1_2 == score_2_1, "Expected that the order of the arguments would not matter."
    assert n_matches_1_2 == n_matches_2_1, "Expected that the order of the arguments would not matter."
Ejemplo n.º 3
0
def test_cosine_greedy_without_parameters():

    spectrum_1 = Spectrum(mz=numpy.array([100, 150, 200, 300, 500, 510, 1100], dtype="float"),
                          intensities=numpy.array([700, 200, 100, 1000, 200, 5, 500], dtype="float"))

    spectrum_2 = Spectrum(mz=numpy.array([100, 140, 190, 300, 490, 510, 1090], dtype="float"),
                          intensities=numpy.array([700, 200, 100, 1000, 200, 5, 500], dtype="float"))

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    cosine_greedy = CosineGreedyVectorial()
    score, n_matches = cosine_greedy(norm_spectrum_1, norm_spectrum_2)

    assert score == pytest.approx(0.81421, 0.0001), "Expected different cosine score."
    assert n_matches == 3
Ejemplo n.º 4
0
def library_match(spectra_list,
                  lib_mgf,
                  precursor_tol=1.0,
                  cosine=0.7,
                  n_peaks=3):
    """Reads a given library mgf file and matches the given spectra to the library spectra using normal cosine.
    Each test spectra is given the name of the library spectra match with the highest cosine score."""

    library = load_from_mgf(lib_mgf)

    # Apply filters to clean and enhance each spectrum
    library_spectra = []
    for spectrum in library:
        # spectrum = default_filters(spectrum)
        # Scale peak intensities to maximum of 1
        spectrum = normalize_intensities(spectrum)
        library_spectra.append(spectrum)

    scores = calculate_scores(references=library_spectra,
                              queries=spectra_list,
                              similarity_function=CosineHungarian())

    scores_list = []
    for score in scores:
        print(score)
        scores_list.append(score)

    scores_list.sort(reverse=True, key=lambda tuple: tuple[2])
Ejemplo n.º 5
0
def post_process_normal(spectrum_in: SpectrumType, min_peaks: int = 10) \
        -> Union[SpectrumType, None]:
    """Normal processing of spectra for Spec2Vec

    Parameters
    ----------
    spectrum_in:
        Input spectrum.
    min_peaks:
        Minimum number of peaks to pass the spectrum (otherwise -> None)
    """
    if spectrum_in is None:
        return None

    s = spectrum_in.clone()
    s = normalize_intensities(s)
    if any(np.isnan(s.peaks[1])):
        return None  # remove spectra that have all intensities 0
    s = select_by_mz(s, mz_from=0, mz_to=1000)
    s = require_minimum_number_of_peaks(s, n_required=min_peaks)
    s = reduce_to_number_of_peaks(s, n_required=min_peaks, ratio_desired=0.5)
    if s is None:
        return None
    # remove low peaks unless less than 10 peaks are left
    s_remove_low_peaks = select_by_relative_intensity(s, intensity_from=0.001)
    if len(s_remove_low_peaks.peaks) >= 10:
        s = s_remove_low_peaks
    # add losses to normally processed spectra
    s = add_losses(s, loss_mz_from=5.0, loss_mz_to=200.0)
    return s
Ejemplo n.º 6
0
def test_cosine_score_greedy_with_tolerance_0_2():
    spectrum_1 = Spectrum(mz=numpy.array([100, 150, 200, 300, 500, 510, 1100], dtype="float"),
                          intensities=numpy.array([700, 200, 100, 1000, 200, 5, 500], dtype="float"),
                          metadata=dict())

    spectrum_2 = Spectrum(mz=numpy.array([50, 100, 200, 299.5, 489.5, 510.5, 1040], dtype="float"),
                          intensities=numpy.array([700, 200, 100, 1000, 200, 5, 500], dtype="float"),
                          metadata=dict())

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    cosine_greedy = CosineGreedyVectorial(tolerance=0.2)
    score, n_matches = cosine_greedy(norm_spectrum_1, norm_spectrum_2)

    assert score == pytest.approx(0.081966, 0.0001), "Expected different cosine score."
    assert n_matches == 2
Ejemplo n.º 7
0
def test_normalize_intensities_empty_peaks():
    """Test running filter with empty peaks spectrum."""
    spectrum_in = SpectrumBuilder().build()

    spectrum = normalize_intensities(spectrum_in)

    assert spectrum == spectrum_in, "Spectrum should remain unchanged."
Ejemplo n.º 8
0
def test_cosine_score_greedy_with_tolerance_2_0():

    spectrum_1 = Spectrum(mz=numpy.array([100, 200, 299, 300, 301, 500, 510], dtype="float"),
                          intensities=numpy.array([10, 10, 500, 100, 200, 20, 100], dtype="float"),
                          metadata=dict())

    spectrum_2 = Spectrum(mz=numpy.array([100, 200, 300, 301, 500, 512], dtype="float"),
                          intensities=numpy.array([10, 10, 500, 100, 20, 100], dtype="float"),
                          metadata=dict())

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    cosine_greedy = CosineGreedyVectorial(tolerance=2.0)
    score, n_matches = cosine_greedy(norm_spectrum_1, norm_spectrum_2)

    assert score == pytest.approx(0.903412, 0.0001), "Expected different cosine score."
    assert n_matches == 6
Ejemplo n.º 9
0
 def apply_my_filters(s):
     s = default_filters(s)
     s = add_parent_mass(s)
     s = normalize_intensities(s)
     s = select_by_relative_intensity(s, intensity_from=0.0, intensity_to=1.0)
     s = select_by_mz(s, mz_from=0, mz_to=1000)
     s = require_minimum_number_of_peaks(s, n_required=5)
     return s
Ejemplo n.º 10
0
def test_modified_cosine_with_mass_shift_5():
    """Test modified cosine on two spectra with mass set shift."""
    spectrum_1 = Spectrum(mz=numpy.array([100, 150, 200, 300, 500, 510, 1100], dtype="float"),
                          intensities=numpy.array([700, 200, 100, 1000, 200, 5, 500], dtype="float"),
                          metadata={"precursor_mz": 1000.0})

    spectrum_2 = Spectrum(mz=numpy.array([55, 105, 205, 304.5, 494.5, 515.5, 1045], dtype="float"),
                          intensities=numpy.array([700, 200, 100, 1000, 200, 5, 500], dtype="float"),
                          metadata={"precursor_mz": 1005.0})

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    modified_cosine = ModifiedCosine()
    score = modified_cosine.pair(norm_spectrum_1, norm_spectrum_2)

    assert score["score"] == pytest.approx(0.081966, 0.0001), "Expected different cosine score."
    assert score["matches"] == 2, "Expected 2 matching peaks."
Ejemplo n.º 11
0
def test_neutral_losses_cosine_without_precursor_mz():
    """Test without precursor-m/z. Should raise assertion error."""
    mz = np.array([100, 150, 200], dtype="float")
    intensities = np.array([700, 200, 100], dtype="float")
    builder = SpectrumBuilder()
    spectrum_1 = builder.with_mz(mz).with_intensities(intensities).build()
    spectrum_2 = builder.with_mz(mz).with_intensities(intensities).build()

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    neutral_losses_cosine = NeutralLossesCosine()

    with pytest.raises(AssertionError) as msg:
        neutral_losses_cosine.pair(norm_spectrum_1, norm_spectrum_2)

    expected_message = "Precursor_mz missing. Apply 'add_precursor_mz' filter first."
    assert str(msg.value) == expected_message
Ejemplo n.º 12
0
def test_modified_cosine_with_mass_shift_5_tolerance_2():
    """Test modified cosine on two spectra with mass set shift and tolerance."""
    spectrum_1 = Spectrum(mz=numpy.array([100, 200, 299, 300, 301, 500, 510], dtype="float"),
                          intensities=numpy.array([10, 10, 500, 100, 200, 20, 100], dtype="float"),
                          metadata={"precursor_mz": 1000.0})

    spectrum_2 = Spectrum(mz=numpy.array([105, 205, 305, 306, 505, 517], dtype="float"),
                          intensities=numpy.array([10, 10, 500, 100, 20, 100], dtype="float"),
                          metadata={"precursor_mz": 1005})

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    modified_cosine = ModifiedCosine(tolerance=2.0)
    score = modified_cosine.pair(norm_spectrum_1, norm_spectrum_2)

    assert score["score"] == pytest.approx(0.96788, 0.0001), "Expected different modified cosine score."
    assert score["matches"] == 6, "Expected 6 matching peaks."
Ejemplo n.º 13
0
def test_modified_cosine_without_precursor_mz():
    """Test without precursor-m/z. Should raise assertion error."""
    spectrum_1 = Spectrum(mz=numpy.array([100, 150, 200, 300, 500, 510, 1100], dtype="float"),
                          intensities=numpy.array([700, 200, 100, 1000, 200, 5, 500], dtype="float"))

    spectrum_2 = Spectrum(mz=numpy.array([100, 140, 190, 300, 490, 510, 1090], dtype="float"),
                          intensities=numpy.array([700, 200, 100, 1000, 200, 5, 500], dtype="float"))

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    modified_cosine = ModifiedCosine()

    with pytest.raises(AssertionError) as msg:
        modified_cosine.pair(norm_spectrum_1, norm_spectrum_2)

    expected_message = "Precursor_mz missing. Apply 'add_precursor_mz' filter first."
    assert str(msg.value) == expected_message
Ejemplo n.º 14
0
def test_modified_cosine_with_mass_shift_5_no_matches_expected():
    """Test modified cosine on two spectra with no expected matches."""
    spectrum_1 = Spectrum(mz=numpy.array([100, 200, 300], dtype="float"),
                          intensities=numpy.array([10, 10, 500], dtype="float"),
                          metadata={"precursor_mz": 1000.0})

    spectrum_2 = Spectrum(mz=numpy.array([120, 220, 320], dtype="float"),
                          intensities=numpy.array([10, 10, 500], dtype="float"),
                          metadata={"precursor_mz": 1005})

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    modified_cosine = ModifiedCosine(tolerance=1.0)
    score = modified_cosine.pair(norm_spectrum_1, norm_spectrum_2)

    assert score["score"] == pytest.approx(0.0, 1e-5), "Expected different modified cosine score."
    assert score["matches"] == 0, "Expected 0 matching peaks."
Ejemplo n.º 15
0
def test_neutral_losses_cosine_precursor_mz_as_invalid_string():
    """Test neutral losses cosine on two spectra with precursor_mz given as string."""
    spectrum_1 = Spectrum(mz=np.array([100, 200, 300], dtype="float"),
                          intensities=np.array([10, 10, 500], dtype="float"),
                          metadata={"precursor_mz": 1000.0})

    spectrum_2 = Spectrum(mz=np.array([120, 220, 320], dtype="float"),
                          intensities=np.array([10, 10, 500], dtype="float"),
                          metadata={"precursor_mz": "mz 1005.0"})

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    neutral_losses_cosine = NeutralLossesCosine(tolerance=1.0)
    with pytest.raises(AssertionError) as msg:
        _ = neutral_losses_cosine.pair(norm_spectrum_1, norm_spectrum_2)

    expected_message = "Precursor_mz missing. Apply 'add_precursor_mz' filter first."
    assert str(msg.value) == expected_message
def test_normalize_intensities_empty_peaks():
    """Test running filter with empty peaks spectrum."""
    mz = numpy.array([], dtype='float')
    intensities = numpy.array([], dtype='float')
    spectrum_in = Spectrum(mz=mz, intensities=intensities)

    spectrum = normalize_intensities(spectrum_in)

    assert spectrum == spectrum_in, "Spectrum should remain unchanged."
Ejemplo n.º 17
0
def test_cosine_score_greedy_order_of_arguments():

    spectrum_1 = Spectrum(mz=numpy.array([100, 200, 299, 300, 301, 500, 510], dtype="float"),
                          intensities=numpy.array([10, 10, 500, 100, 200, 20, 100], dtype="float"),
                          metadata=dict())

    spectrum_2 = Spectrum(mz=numpy.array([100, 200, 300, 301, 500, 512], dtype="float"),
                          intensities=numpy.array([10, 10, 500, 100, 20, 100], dtype="float"),
                          metadata=dict())

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)

    cosine_greedy = CosineGreedyVectorial(tolerance=2.0)
    score_1_2, n_matches_1_2 = cosine_greedy(norm_spectrum_1, norm_spectrum_2)
    score_2_1, n_matches_2_1 = cosine_greedy(norm_spectrum_2, norm_spectrum_1)

    assert score_1_2 == score_2_1, "Expected that the order of the arguments would not matter."
    assert n_matches_1_2 == n_matches_2_1, "Expected that the order of the arguments would not matter."
Ejemplo n.º 18
0
 def apply_my_filters(s):
     """This is how a user would typically design his own pre- and post-
     processing pipeline."""
     s = default_filters(s)
     s = add_parent_mass(s)
     s = normalize_intensities(s)
     s = reduce_to_number_of_peaks(s, n_required=10, ratio_desired=0.5)
     s = select_by_mz(s, mz_from=0, mz_to=1000)
     s = add_losses(s, loss_mz_from=10.0, loss_mz_to=200.0)
     s = require_minimum_number_of_peaks(s, n_required=5)
     return s
Ejemplo n.º 19
0
def spectrum_processing(s):
    """This is how one would typically design a desired pre- and post-
    processing pipeline."""
    s = default_filters(s)
    s = add_precursor_mz(s)
    s = normalize_intensities(s)
    s = reduce_to_number_of_peaks(s, n_required=5, ratio_desired=0.5, n_max=500)
    s = select_by_mz(s, mz_from=0, mz_to=1000)
    s = add_losses(s, loss_mz_from=10.0, loss_mz_to=200.0)
    s = require_minimum_number_of_peaks(s, n_required=5)
    return s
Ejemplo n.º 20
0
def test_normalize_intensities():

    mz = numpy.array([10, 20, 30, 40], dtype='float')
    intensities = numpy.array([0, 1, 10, 100], dtype='float')
    spectrum_in = Spectrum(mz=mz, intensities=intensities)

    spectrum = normalize_intensities(spectrum_in)

    assert max(spectrum.peaks.intensities
               ) == 1.0, "Expected the spectrum to be scaled to 1.0."
    assert numpy.array_equal(spectrum.peaks.mz, mz), "Expected the spectrum's intensity locations along "\
                                                     "the mz-axis to be unaffected."
Ejemplo n.º 21
0
def test_normalize_intensities_all_zeros(caplog):
    """Test if non-sense intensities are handled correctly."""
    mz = numpy.array([10, 20, 30], dtype='float')
    intensities = numpy.array([0, 0, 0], dtype='float')
    spectrum_in = SpectrumBuilder().with_mz(mz).with_intensities(
        intensities).build()

    spectrum = normalize_intensities(spectrum_in)

    assert spectrum is None, "Expected spectrum to be set to None."
    msg = "Spectrum with all peak intensities <= 0 was set to None."
    assert msg in caplog.text, "Expected log message."
Ejemplo n.º 22
0
def test_neutral_losses_cosine_precursor_mz_as_string(caplog):
    """Test neutral losses cosine on two spectra with precursor_mz given as string."""
    spectrum_1 = Spectrum(mz=np.array([100, 200, 300], dtype="float"),
                          intensities=np.array([10, 10, 500], dtype="float"),
                          metadata={"precursor_mz": 1000.0},
                          metadata_harmonization=False)

    spectrum_2 = Spectrum(mz=np.array([120, 220, 320], dtype="float"),
                          intensities=np.array([10, 10, 500], dtype="float"),
                          metadata={"precursor_mz": "1005.0"},
                          metadata_harmonization=False)

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    neutral_losses_cosine = NeutralLossesCosine(tolerance=1.0)
    score = neutral_losses_cosine.pair(norm_spectrum_1, norm_spectrum_2)

    assert score["score"] == pytest.approx(
        0.0, 1e-5), "Expected different neutral losses cosine score."
    assert score["matches"] == 0, "Expected 0 matching peaks."
    expected_msg = "Precursor_mz must be of type int or float. Apply 'add_precursor_mz' filter first."
    assert expected_msg in caplog.text, "Expected different log message"
Ejemplo n.º 23
0
def test_normalize_intensities(mz, intensities):
    """Test if peak intensities are normalized correctly."""
    spectrum_in = SpectrumBuilder().with_mz(mz).with_intensities(
        intensities).build()

    spectrum = normalize_intensities(spectrum_in)

    assert max(spectrum.peaks.intensities
               ) == 1.0, "Expected the spectrum to be scaled to 1.0."
    assert numpy.array_equal(spectrum.peaks.intensities, intensities /
                             100), "Expected different intensities"
    assert numpy.array_equal(spectrum.peaks.mz,
                             mz), "Expected different peak mz."
def test_normalize_intensities():
    """Test if peak intensities are normalized correctly."""
    mz = numpy.array([10, 20, 30, 40], dtype='float')
    intensities = numpy.array([0, 1, 10, 100], dtype='float')
    spectrum_in = Spectrum(mz=mz, intensities=intensities)

    spectrum = normalize_intensities(spectrum_in)

    assert max(spectrum.peaks.intensities
               ) == 1.0, "Expected the spectrum to be scaled to 1.0."
    assert numpy.array_equal(spectrum.peaks.intensities, intensities /
                             100), "Expected different intensities"
    assert numpy.array_equal(spectrum.peaks.mz,
                             mz), "Expected different peak mz."
    def return_noise_filtered_spectrum(self, spectrum):
        # spectrum.plot()
        md = spectrum.metadata.copy()
        #        print("Number of peaks on entry:", len(spectrum.peaks))
        mzlist, intensitylist = self.filter_out_noisy_peaks(spectrum)
        mzlist = np.asarray(mzlist, dtype=float)
        intensitylist = np.asarray(intensitylist, dtype=float)
        spec = Spectrum(mzlist, intensitylist, md)
        spec = normalize_intensities(spec)
        #        print("number on exit", len(spec.peaks.mz))
        # spec.plot()
        return spec


#        print("Number of peaks on exit:", len(spectrum.peaks))
Ejemplo n.º 26
0
def test_neutral_losses_cosine_order_of_input_spectrums():
    """Test neutral losses cosine on two spectra in changing order."""
    spectrum_1 = Spectrum(mz=np.array([100, 150, 200, 300, 500, 510, 1100],
                                      dtype="float"),
                          intensities=np.array(
                              [700, 200, 100, 1000, 200, 5, 500],
                              dtype="float"),
                          metadata={"precursor_mz": 1000.0})

    spectrum_2 = Spectrum(
        mz=np.array([55, 105, 205, 304.5, 494.5, 515.5, 1045], dtype="float"),
        intensities=np.array([700, 200, 100, 1000, 200, 5, 500],
                             dtype="float"),
        metadata={"precursor_mz": 1005.0})

    norm_spectrum_1 = normalize_intensities(spectrum_1)
    norm_spectrum_2 = normalize_intensities(spectrum_2)
    neutral_losses_cosine = NeutralLossesCosine(tolerance=2.0)
    score_1_2 = neutral_losses_cosine.pair(norm_spectrum_1, norm_spectrum_2)
    score_2_1 = neutral_losses_cosine.pair(norm_spectrum_2, norm_spectrum_1)

    assert score_1_2["score"] == score_2_1[
        "score"], "Expected that the order of the arguments would not matter."
    assert score_1_2 == score_2_1, "Expected that the order of the arguments would not matter."
Ejemplo n.º 27
0
def post_process(s):
    s = normalize_intensities(s)
    s = select_by_mz(s, mz_from=0, mz_to=1000)
    s = require_minimum_number_of_peaks(s, n_required=10)
    try:
        s = reduce_to_number_of_peaks(s, n_required=10, ratio_desired=0.5)
    except:
        pass
    if s is None:
        return None
    s_remove_low_peaks = select_by_relative_intensity(s, intensity_from=0.001)
    if len(s_remove_low_peaks.peaks) >= 10:
        s = s_remove_low_peaks

    s = add_losses(s, loss_mz_from=5.0, loss_mz_to=200.0)
    return s
Ejemplo n.º 28
0
def test_normalize_intensities_losses_present(mz, intensities, metadata,
                                              expected_losses):
    """Test if also losses (if present) are normalized correctly."""
    spectrum_in = SpectrumBuilder().with_mz(mz).with_intensities(
        intensities).with_metadata(metadata).build()

    spectrum = add_losses(spectrum_in)
    spectrum = normalize_intensities(spectrum)

    assert max(spectrum.peaks.intensities
               ) == 1.0, "Expected the spectrum to be scaled to 1.0."
    assert numpy.array_equal(spectrum.peaks.intensities, intensities /
                             100), "Expected different intensities"
    assert max(spectrum.losses.intensities
               ) == 1.0, "Expected the losses to be scaled to 1.0."
    assert numpy.all(spectrum.losses.intensities ==
                     expected_losses), "Expected different loss intensities"
Ejemplo n.º 29
0
def post_process_md(spectrum_in: SpectrumType,
                    low_int_cutoff: float = 0.05,
                    min_peaks: int = 10,
                    max_peaks: int = 30) -> Union[SpectrumType, None]:
    """Processing of spectra that are used for mass difference extraction

    Parameters
    ----------
    spectrum_in:
        Input spectrum.
    low_int_cutoff:
        Lower intensity cutoff for the peaks selected for MD
    min_peaks:
        Minimum number of peaks to pass the spectrum (otherwise -> None)
    max_peaks:
        Maximum number of peaks allowed in the spectrum (ranked on intensity)
    """
    if spectrum_in is None:
        return None

    s = spectrum_in.clone()
    # remove precurzor_mz from spectra so neutral losses don't end up in MDs
    s = remove_precursor_mz_peak(s)
    s = normalize_intensities(s)
    if any(np.isnan(s.peaks[1])):
        return None  # remove spectra that have all intensities 0
    s = select_by_mz(s, mz_from=0, mz_to=1000)
    s = require_minimum_number_of_peaks(s, n_required=min_peaks)
    s = reduce_to_number_of_peaks(s, n_required=min_peaks, ratio_desired=0.5)
    if s is None:
        return None
    # remove low peaks unless less than 10 peaks are left
    s_remove_low_peaks = select_by_relative_intensity(s, intensity_from=0.001)
    if len(s_remove_low_peaks.peaks) >= 10:
        s = s_remove_low_peaks
    # do an additional removal step with a different intensity cutoff
    s_second_peak_removal = select_by_relative_intensity(
        s, intensity_from=low_int_cutoff)
    if len(s_second_peak_removal.peaks) >= 10:
        s = s_second_peak_removal

    # reduce to top30 peaks
    s = reduce_to_number_of_peaks(s, n_required=min_peaks, n_max=max_peaks)
    return s
def test_normalize_intensities_losses_present():
    """Test if also losses (if present) are normalized correctly."""
    mz = numpy.array([10, 20, 30, 40], dtype='float')
    intensities = numpy.array([0, 1, 10, 100], dtype='float')
    spectrum_in = Spectrum(mz=mz,
                           intensities=intensities,
                           metadata={"precursor_mz": 45.0})

    spectrum = add_losses(spectrum_in)
    spectrum = normalize_intensities(spectrum)
    expected_loss_intensities = numpy.array([1., 0.1, 0.01, 0.], dtype='float')

    assert max(spectrum.peaks.intensities
               ) == 1.0, "Expected the spectrum to be scaled to 1.0."
    assert numpy.array_equal(spectrum.peaks.intensities, intensities /
                             100), "Expected different intensities"
    assert max(spectrum.losses.intensities
               ) == 1.0, "Expected the losses to be scaled to 1.0."
    assert numpy.all(spectrum.losses.intensities == expected_loss_intensities
                     ), "Expected different loss intensities"