Skip to content

Commit 2595491

Browse files
authored
Merge pull request #142 from wilhelm-lab/release/0.7.4
release/0.7.4
2 parents 040d3c5 + 878a94c commit 2595491

25 files changed

+1453
-481
lines changed

.cookietemple.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ full_name: Victor Giurcoiu
1515
email: victor.giurcoiu@tum.de
1616
project_name: spectrum_fundamentals
1717
project_short_description: Fundamentals public repo
18-
version: 0.7.3
18+
version: 0.7.4
1919
license: MIT

.github/release-drafter.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
name-template: "0.7.3 🌈" # <<COOKIETEMPLE_FORCE_BUMP>>
2-
tag-template: 0.7.3 # <<COOKIETEMPLE_FORCE_BUMP>>
1+
name-template: "0.7.4 " # <<COOKIETEMPLE_FORCE_BUMP>>
2+
tag-template: 0.7.4 # <<COOKIETEMPLE_FORCE_BUMP>>
33
exclude-labels:
44
- "skip-changelog"
55

.github/workflows/run_tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ jobs:
119119
if: always() && matrix.session == 'tests' && matrix.os == 'ubuntu-latest'
120120
uses: actions/upload-artifact@v4
121121
with:
122+
include-hidden-files: "true"
122123
name: coverage-data
123124
path: ".coverage.*"
124125

cookietemple.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.7.3
2+
current_version = 0.7.4
33

44
[bumpversion_files_whitelisted]
55
init_file = spectrum_fundamentals/__init__.py

docs/_key_contributors.rst

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,21 @@
22

33
Current developers
44

5-
* `Mario Picciani <https://github.com/picciama>`_: lead developer since 2022, maintainer
6-
* `Mostafa Kalhor <https://github.com/mostafakalhor>`_: developer, crosslinking
7-
* `Wassim Gabriel <https://github.com/WassimG>`_: developer, PTMs, neutral losses, GUI
8-
* `Arne van den Berg <https://github.com/arne-vdb>`_: developer, diverse contributions
9-
* `Victor-George Giurcoiu <https://github.com/victorgiurcoiu>`_: developer, diverse contributions
10-
* `Ludwig Lautenbacher <https://github.com/LLautenbacher>`_: developer, Koina, GUI
11-
* `Armin Soleymaniniya <https://github.com/arminsl>`_: developer, GUI
12-
* `Ayla Schröder <https://github.com/ayla-s>`_: developer, pickedGroupFDR
13-
* Zixuan Xiao: developer, GUI
14-
15-
Previous developers
16-
17-
* `Matthew The <https://github.com/MatthewThe>`_: developer, percolator
18-
* `Omar Shouman <https://github.com/omsh>`_: developer, diverse contributions
19-
* Firas Hamood: developer, diverse contributions
20-
* Cecilia Jensen: developer, diverse contributions
21-
* Julian Mueller: developer, diverse contributions
5+
* `Arne van den Berg <https://github.com/arne-vdb>`_
6+
* `Wassim Gabriel <https://github.com/WassimG>`_
7+
* `Victor-George Giurcoiu <https://github.com/victorgiurcoiu>`_
8+
* `Firas Hamood <https://github.com/fhamood>`_
9+
* `Cecilia Jensen`_
10+
* `Mostafa Kalhor <https://github.com/mostafakalhor>`_
11+
* `Ludwig Lautenbacher <https://github.com/LLautenbacher>`_
12+
* `Julian Mueller <https://github.com/jmueller95>`_
13+
* `Mario Picciani <https://github.com/picciama>`_
14+
* `Ayla Schröder <https://github.com/ayla-s>`_
15+
* `Omar Shouman <https://github.com/omsh>`_
16+
* `Armin Soleymaniniya <https://github.com/arminsl>`_
17+
* `Matthew The <https://github.com/MatthewThe>`_
18+
* `Zixuan Xiao <https://github.com/zix-xiao>`_
2219

2320
Other roles
2421

25-
* `Mathias Wilhelm <https://github.com/mwilhelm42>`_: advisor and PI of wilhelmlab
22+
* `Mathias Wilhelm <https://github.com/mwilhelm42>`_ advisor and PI of wilhelmlab

docs/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@
5252
# the built documents.
5353
#
5454
# The short X.Y version.
55-
version = "0.7.3"
55+
version = "0.7.4"
5656
# The full version, including alpha/beta/rc tags.
57-
release = "0.7.3"
57+
release = "0.7.4"
5858

5959
# The language for content autogenerated by Sphinx. Refer to documentation
6060
# for a list of supported languages.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "spectrum_fundamentals"
3-
version = "0.7.3" # <<COOKIETEMPLE_FORCE_BUMP>>
3+
version = "0.7.4" # <<COOKIETEMPLE_FORCE_BUMP>>
44
description = "Fundamental functions, annotation pipeline and constants for oktoberfest"
55
authors = ["Wilhelmlab at Technical University of Munich"]
66
license = "MIT"

spectrum_fundamentals/__init__.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
"""Spectrum Fundamentals."""
22

3-
__author__ = "Mario Picciani"
4-
__email__ = "mario.picciani@tum.de"
5-
__version__ = "0.7.3"
3+
from datetime import datetime
4+
5+
__author__ = """The Oktoberfest development team (Wilhelmlab at Technical University of Munich)"""
6+
__copyright__ = f"Copyright {datetime.now():%Y}, Wilhelmlab at Technical University of Munich"
7+
__license__ = "MIT"
8+
__version__ = "0.7.4"
69

710
import logging
811
import logging.handlers

spectrum_fundamentals/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
@click.command()
8-
@click.version_option(version="0.7.3", message=click.style("spectrum_fundamentals Version: 0.7.3"))
8+
@click.version_option(version="0.7.4", message=click.style("spectrum_fundamentals Version: 0.7.4"))
99
def main() -> None:
1010
"""spectrum_fundamentals."""
1111

spectrum_fundamentals/annotation/annotation.py

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def match_peaks(
1717
tmt_n_term: int,
1818
unmod_sequence: str,
1919
charge: int,
20-
) -> List[Dict[str, Union[str, int, float]]]:
20+
) -> Tuple[List[Dict[str, Union[str, int, float]]], int]:
2121
"""
2222
Matching experimental peaks with theoretical fragment ions.
2323
@@ -36,6 +36,7 @@ def match_peaks(
3636
temp_list = []
3737
next_start_peak = 0
3838
matched_peak = False
39+
count_annotated_nl = 0
3940
fragment_no: float
4041
for fragment in fragments_meta_data:
4142
min_mass = fragment["min_mass"]
@@ -56,27 +57,32 @@ def match_peaks(
5657
if (
5758
not (fragment["ion_type"][0] == "b" and fragment_no == 1)
5859
or (unmod_sequence[0] == "R" or unmod_sequence[0] == "H" or unmod_sequence[0] == "K")
59-
and (tmt_n_term == 1)
60+
or (tmt_n_term == 2)
6061
):
61-
row_list.append(
62-
{
63-
"ion_type": fragment["ion_type"],
64-
"no": fragment_no,
65-
"charge": fragment["charge"],
66-
"exp_mass": peak_mass,
67-
"theoretical_mass": fragment["mass"],
68-
"intensity": peak_intensity,
69-
}
70-
)
71-
if peak_intensity > max_intensity:
72-
max_intensity = float(peak_intensity)
62+
# For now only counting neutral loss peaks this can change with different models later
63+
if fragment["neutral_loss"] == "":
64+
row_list.append(
65+
{
66+
"ion_type": fragment["ion_type"],
67+
"no": fragment_no,
68+
"charge": fragment["charge"],
69+
"exp_mass": peak_mass,
70+
"theoretical_mass": fragment["mass"],
71+
"intensity": peak_intensity,
72+
}
73+
)
74+
if peak_intensity > max_intensity:
75+
max_intensity = float(peak_intensity)
76+
else:
77+
count_annotated_nl += 1
78+
7379
matched_peak = True
7480
next_start_peak = start_peak
7581
start_peak += 1
7682
for row in row_list:
7783
row["intensity"] = float(row["intensity"]) / max_intensity
7884
temp_list.append(row)
79-
return temp_list
85+
return temp_list, count_annotated_nl
8086

8187

8288
def handle_multiple_matches(
@@ -123,6 +129,7 @@ def annotate_spectra(
123129
unit_mass_tolerance: Optional[str] = None,
124130
custom_mods: Optional[Dict[str, float]] = None,
125131
fragmentation_method: str = "HCD",
132+
annotate_neutral_loss: Optional[bool] = False,
126133
) -> pd.DataFrame:
127134
"""
128135
Annotate a set of spectra.
@@ -143,6 +150,7 @@ def annotate_spectra(
143150
:param unit_mass_tolerance: unit for the mass tolerance (da or ppm)
144151
:param fragmentation_method: fragmentation method that was used
145152
:param custom_mods: mapping of custom UNIMOD string identifiers ('[UNIMOD:xyz]') to their mass
153+
:param annotate_neutral_loss: flag to indicate whether to annotate neutral losses or not
146154
:return: a Pandas DataFrame containing the annotated spectra with meta data
147155
"""
148156
raw_file_annotations = []
@@ -155,14 +163,22 @@ def annotate_spectra(
155163
unit_mass_tolerance,
156164
fragmentation_method=fragmentation_method,
157165
custom_mods=custom_mods,
166+
annotate_neutral_losses=annotate_neutral_loss,
158167
)
159168
if not results:
160169
continue
161170
raw_file_annotations.append(results)
162171
results_df = pd.DataFrame(raw_file_annotations)
163172

164173
if "CROSSLINKER_TYPE" not in index_columns:
165-
results_df.columns = ["INTENSITIES", "MZ", "CALCULATED_MASS", "removed_peaks"]
174+
results_df.columns = [
175+
"INTENSITIES",
176+
"MZ",
177+
"CALCULATED_MASS",
178+
"removed_peaks",
179+
"ANNOTATED_NL_COUNT",
180+
"EXPECTED_NL_COUNT",
181+
]
166182
else:
167183
results_df.columns = [
168184
"INTENSITIES_A",
@@ -347,9 +363,10 @@ def parallel_annotate(
347363
unit_mass_tolerance: Optional[str] = None,
348364
custom_mods: Optional[Dict[str, float]] = None,
349365
fragmentation_method: str = "HCD",
366+
annotate_neutral_losses: Optional[bool] = False,
350367
) -> Optional[
351368
Union[
352-
Tuple[np.ndarray, np.ndarray, float, int],
369+
Tuple[np.ndarray, np.ndarray, float, int, int, int],
353370
Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, float, float, int, int],
354371
]
355372
]:
@@ -369,6 +386,7 @@ def parallel_annotate(
369386
:param unit_mass_tolerance: unit for the mass tolerance (da or ppm)
370387
:param custom_mods: mapping of custom UNIMOD string identifiers ('[UNIMOD:xyz]') to their mass
371388
:param fragmentation_method: fragmentation method that was used
389+
:param annotate_neutral_losses: flag to indicate whether to annotate neutral losses or not
372390
:return: a tuple containing intensity values (np.ndarray), masses (np.ndarray), calculated mass (float),
373391
and any removed peaks (List[str])
374392
"""
@@ -383,6 +401,7 @@ def parallel_annotate(
383401
unit_mass_tolerance,
384402
fragmentation_method=fragmentation_method,
385403
custom_mods=custom_mods,
404+
add_neutral_losses=annotate_neutral_losses,
386405
)
387406

388407
if (spectrum[index_columns["PEPTIDE_LENGTH_A"]] > 30) or (spectrum[index_columns["PEPTIDE_LENGTH_B"]] > 30):
@@ -399,6 +418,7 @@ def _annotate_linear_spectrum(
399418
unit_mass_tolerance: Optional[str],
400419
custom_mods: Optional[Dict[str, float]] = None,
401420
fragmentation_method: str = "HCD",
421+
add_neutral_losses: Optional[bool] = False,
402422
):
403423
"""
404424
Annotate a linear peptide spectrum.
@@ -409,21 +429,24 @@ def _annotate_linear_spectrum(
409429
:param unit_mass_tolerance: Unit for the mass tolerance (da or ppm)
410430
:param custom_mods: mapping of custom UNIMOD string identifiers ('[UNIMOD:xyz]') to their mass
411431
:param fragmentation_method: fragmentation method that was used
432+
:param add_neutral_losses: flag to indicate whether to annotate neutral losses or not
412433
:return: Annotated spectrum
413434
"""
414435
mod_seq_column = "MODIFIED_SEQUENCE"
415436
if "MODIFIED_SEQUENCE_MSA" in index_columns:
416437
mod_seq_column = "MODIFIED_SEQUENCE_MSA"
417-
fragments_meta_data, tmt_n_term, unmod_sequence, calc_mass = initialize_peaks(
438+
439+
fragments_meta_data, tmt_n_term, unmod_sequence, calc_mass, expected_nl = initialize_peaks(
418440
sequence=spectrum[index_columns[mod_seq_column]],
419441
mass_analyzer=spectrum[index_columns["MASS_ANALYZER"]],
420442
charge=spectrum[index_columns["PRECURSOR_CHARGE"]],
421443
mass_tolerance=mass_tolerance,
422444
unit_mass_tolerance=unit_mass_tolerance,
423445
fragmentation_method=fragmentation_method,
424446
custom_mods=custom_mods,
447+
add_neutral_losses=add_neutral_losses,
425448
)
426-
matched_peaks = match_peaks(
449+
matched_peaks, count_annotated_nl = match_peaks(
427450
fragments_meta_data,
428451
spectrum[index_columns["INTENSITIES"]],
429452
spectrum[index_columns["MZ"]],
@@ -439,13 +462,13 @@ def _annotate_linear_spectrum(
439462
if len(matched_peaks) == 0:
440463
intensity = np.full(vec_length, 0.0)
441464
mass = np.full(vec_length, 0.0)
442-
return intensity, mass, calc_mass, 0
465+
return intensity, mass, calc_mass, 0, 0, 0
443466

444467
matched_peaks, removed_peaks = handle_multiple_matches(matched_peaks)
445468
intensities, mass = generate_annotation_matrix(
446469
matched_peaks, unmod_sequence, spectrum[index_columns["PRECURSOR_CHARGE"]], fragmentation_method
447470
)
448-
return intensities, mass, calc_mass, removed_peaks
471+
return intensities, mass, calc_mass, removed_peaks, count_annotated_nl, expected_nl
449472

450473

451474
def _annotate_crosslinked_spectrum(
@@ -493,7 +516,7 @@ def _xl_annotation_workflow(seq_id: str, non_cl_xl: bool):
493516
array_size = 348
494517
inputs.append(custom_mods)
495518
fragments_meta_data, tmt_n_term, unmod_sequence, calc_mass = initialize_peaks_xl(*inputs)
496-
matched_peaks = match_peaks(
519+
matched_peaks, annotated_nl = match_peaks(
497520
fragments_meta_data,
498521
np.array(spectrum[index_columns["INTENSITIES"]]),
499522
np.array(spectrum[index_columns["MZ"]]), # Convert to numpy array

0 commit comments

Comments
 (0)