diff --git a/alphabase/constants/aa.py b/alphabase/constants/aa.py index 7c0c266b..a93db1e3 100644 --- a/alphabase/constants/aa.py +++ b/alphabase/constants/aa.py @@ -1,5 +1,4 @@ import os -import typing import numpy as np import pandas as pd @@ -29,7 +28,7 @@ AA_Composition: dict = {} -def replace_atoms(atom_replace_dict: typing.Dict): +def replace_atoms(atom_replace_dict: dict): for aa, row in aa_formula.iterrows(): formula = row["formula"] atom_comp = dict(parse_formula(formula)) @@ -81,7 +80,7 @@ def reset_AA_Composition(): reset_AA_Composition() -def reset_AA_atoms(atom_replace_dict: typing.Dict = {}): +def reset_AA_atoms(atom_replace_dict: dict = {}): reset_elements() replace_atoms(atom_replace_dict) reset_AA_mass() diff --git a/alphabase/constants/atom.py b/alphabase/constants/atom.py index 32bdc406..9edb399a 100644 --- a/alphabase/constants/atom.py +++ b/alphabase/constants/atom.py @@ -1,6 +1,5 @@ import os import re -import typing from collections import defaultdict import numpy as np @@ -102,7 +101,7 @@ def truncate_isotope(isotopes: np.ndarray, mono_idx: int) -> tuple: MASS_NH3: int = None -def update_atom_infos(new_atom_info: typing.Dict): +def update_atom_infos(new_atom_info: dict): """Update the atom information in CHEM_INFO_DICT. Args: diff --git a/alphabase/constants/isotope.py b/alphabase/constants/isotope.py index 270dcfb9..405b9e90 100644 --- a/alphabase/constants/isotope.py +++ b/alphabase/constants/isotope.py @@ -19,7 +19,7 @@ def abundance_convolution( mono1: int, d2: np.ndarray, mono2: int, -) -> typing.Tuple[np.ndarray, int]: +) -> tuple[np.ndarray, int]: """ If we have two isotope distributions, we can convolute them into one distribution. @@ -60,7 +60,7 @@ def one_element_dist( n: int, chem_isotope_dist: NumbaTypedDict, chem_mono_idx: NumbaTypedDict, -) -> typing.Tuple[np.ndarray, int]: +) -> tuple[np.ndarray, int]: """ Calculate the isotope distribution for an element and its numbers. @@ -101,7 +101,7 @@ def one_element_dist( ) -def formula_dist(formula: typing.Union[list, str]) -> typing.Tuple[np.ndarray, int]: +def formula_dist(formula: typing.Union[list, str]) -> tuple[np.ndarray, int]: """ Generate the isotope distribution and the mono index for a given formula (as a list, e.g. `[('H', 2), ('C', 2), ('O', 1)]`). @@ -210,8 +210,8 @@ def __init__( def calc_formula_distribution( self, - formula: typing.List[typing.Tuple[str, int]], - ) -> typing.Tuple[np.ndarray, int]: + formula: list[tuple[str, int]], + ) -> tuple[np.ndarray, int]: """Calculate isotope abundance distribution for a given formula Parameters diff --git a/alphabase/constants/modification.py b/alphabase/constants/modification.py index 63b14e08..a3a6fb5d 100644 --- a/alphabase/constants/modification.py +++ b/alphabase/constants/modification.py @@ -1,5 +1,5 @@ import os -from typing import List, Union +from typing import Union import numpy as np import pandas as pd @@ -184,7 +184,7 @@ def load_mod_df( def calc_modification_mass( - nAA: int, mod_names: List[str], mod_sites: List[int] + nAA: int, mod_names: list[str], mod_sites: list[int] ) -> np.ndarray: """ Calculate modification masses for the given peptide length (`nAA`), @@ -221,7 +221,7 @@ def calc_modification_mass( def calc_mod_masses_for_same_len_seqs( - nAA: int, mod_names_list: List[List[str]], mod_sites_list: List[List[int]] + nAA: int, mod_names_list: list[list[str]], mod_sites_list: list[list[int]] ) -> np.ndarray: """ Calculate modification masses for the given peptides with same peptide length (`nAA`). @@ -258,7 +258,7 @@ def calc_mod_masses_for_same_len_seqs( return masses -def calc_modification_mass_sum(mod_names: List[str]) -> float: +def calc_modification_mass_sum(mod_names: list[str]) -> float: """ Calculate summed mass of the given modification without knowing the sites and peptide length. @@ -314,8 +314,8 @@ def _calc_modloss_with_importance( def calc_modloss_mass_with_importance( nAA: int, - mod_names: List, - mod_sites: List, + mod_names: list, + mod_sites: list, for_nterm_frag: bool, ) -> np.ndarray: """ @@ -390,8 +390,8 @@ def _calc_modloss(mod_losses: np.ndarray) -> np.ndarray: def calc_modloss_mass( nAA: int, - mod_names: List, - mod_sites: List, + mod_names: list, + mod_sites: list, for_nterm_frag: bool, ) -> np.ndarray: """ @@ -463,7 +463,7 @@ def _check_mass_sanity( composition_mass = calc_mass_from_formula(composition) if not np.allclose(composition_mass, MOD_MASS[mod_name], atol=1e-5): raise ValueError( - f"Modification mass of {mod_name} is inconsistent with the composition formula: {composition}, df version {MOD_DF.loc[mod_name,['composition']]}" + f"Modification mass of {mod_name} is inconsistent with the composition formula: {composition}, df version {MOD_DF.loc[mod_name, ['composition']]}" f" calculated_mass={composition_mass}, mod_mass={MOD_MASS[mod_name]}" ) diff --git a/alphabase/peptide/fragment.py b/alphabase/peptide/fragment.py index d0c3e0ab..29ee8b7d 100644 --- a/alphabase/peptide/fragment.py +++ b/alphabase/peptide/fragment.py @@ -1,6 +1,6 @@ import warnings from dataclasses import dataclass, field -from typing import Dict, List, Tuple, Union +from typing import Union import numpy as np import pandas as pd @@ -316,7 +316,7 @@ def parse_all_frag_type_representation(): parse_all_frag_type_representation() -def sort_charged_frag_types(charged_frag_types: List[str]) -> List[str]: +def sort_charged_frag_types(charged_frag_types: list[str]) -> list[str]: """charged frag types are sorted by (no-loss, loss) and then alphabetically""" has_loss = [ f.replace(FRAGMENT_CHARGE_SEPARATOR, "").count("_") > 0 @@ -328,8 +328,8 @@ def sort_charged_frag_types(charged_frag_types: List[str]) -> List[str]: def get_charged_frag_types( - frag_types: List[str], max_frag_charge: int = 2 -) -> List[str]: + frag_types: list[str], max_frag_charge: int = 2 +) -> list[str]: """ Calculate the combination of fragment types and charge states. Returns a sorted list of charged fragment types. @@ -364,8 +364,8 @@ def get_charged_frag_types( def filter_valid_charged_frag_types( - charged_frag_types: List[str], -) -> List[str]: + charged_frag_types: list[str], +) -> list[str]: """ Filters a list of charged fragment types and returns only the valid ones. A valid charged fragment type must: @@ -397,7 +397,7 @@ def filter_valid_charged_frag_types( return valid_types -def parse_charged_frag_type(charged_frag_type: str) -> Tuple[str, int]: +def parse_charged_frag_type(charged_frag_type: str) -> tuple[str, int]: """ Oppsite to `get_charged_frag_types`. @@ -440,8 +440,8 @@ def parse_charged_frag_type(charged_frag_type: str) -> Tuple[str, int]: def init_zero_fragment_dataframe( - peplen_array: np.ndarray, charged_frag_types: List[str], dtype=PEAK_MZ_DTYPE -) -> Tuple[pd.DataFrame, np.ndarray, np.ndarray]: + peplen_array: np.ndarray, charged_frag_types: list[str], dtype=PEAK_MZ_DTYPE +) -> tuple[pd.DataFrame, np.ndarray, np.ndarray]: """Initialize a zero dataframe based on peptide length (nAA) array (peplen_array) and charge_frag_types (column number). The row number of returned dataframe is np.sum(peplen_array-1). @@ -487,7 +487,7 @@ def init_fragment_dataframe_from_other( def init_fragment_by_precursor_dataframe( precursor_df, - charged_frag_types: List[str], + charged_frag_types: list[str], *, reference_fragment_df: pd.DataFrame = None, dtype: np.dtype = PEAK_MZ_DTYPE, @@ -572,8 +572,8 @@ def update_sliced_fragment_dataframe( fragment_df: pd.DataFrame, fragment_df_vals: np.ndarray, values: np.ndarray, - frag_start_end_list: List[Tuple[int, int]], - charged_frag_types: List[str] = None, + frag_start_end_list: list[tuple[int, int]], + charged_frag_types: list[str] = None, ): """ Set the values of the slices `frag_start_end_list=[(start,end),(start,end),...]` @@ -616,8 +616,8 @@ def update_sliced_fragment_dataframe( def get_sliced_fragment_dataframe( fragment_df: pd.DataFrame, - frag_start_end_list: Union[List, np.ndarray], - charged_frag_types: List = None, + frag_start_end_list: Union[list, np.ndarray], + charged_frag_types: list = None, ) -> pd.DataFrame: """ Get the sliced fragment_df from `frag_start_end_list=[(start,end),(start,end),...]`. @@ -653,10 +653,10 @@ def get_sliced_fragment_dataframe( def concat_precursor_fragment_dataframes( - precursor_df_list: List[pd.DataFrame], - fragment_df_list: List[pd.DataFrame], + precursor_df_list: list[pd.DataFrame], + fragment_df_list: list[pd.DataFrame], *other_fragment_df_lists, -) -> Tuple[pd.DataFrame, ...]: +) -> tuple[pd.DataFrame, ...]: """ Since fragment_df is indexed by precursor_df, when we concatenate multiple fragment_df, the indexed positions will change for in precursor_dfs, @@ -914,7 +914,7 @@ def parse_fragment( top_k: int, intensities: np.ndarray, number_of_fragment_types: int, -) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: """ Parse fragments to get fragment numbers, fragment positions and not top k excluded indices in one hit faster than doing each operation individually, and makes the most of the operations that are done in parallel. @@ -979,8 +979,8 @@ def flatten_fragments( min_fragment_intensity: float = -1, keep_top_k_fragments: int = 1000, custom_columns: list = ["type", "number", "position", "charge", "loss_type"], - custom_df: Dict[str, pd.DataFrame] = {}, -) -> Tuple[pd.DataFrame, pd.DataFrame]: + custom_df: dict[str, pd.DataFrame] = {}, +) -> tuple[pd.DataFrame, pd.DataFrame]: """ Converts the tabular fragment format consisting of the `fragment_mz_df` and the `fragment_intensity_df` @@ -1168,10 +1168,10 @@ def compress_fragment_indices(frag_idx): def remove_unused_fragments( precursor_df: pd.DataFrame, - fragment_df_list: Tuple[pd.DataFrame, ...], + fragment_df_list: tuple[pd.DataFrame, ...], frag_start_col: str = "frag_start_idx", frag_stop_col: str = "frag_stop_idx", -) -> Tuple[pd.DataFrame, Tuple[pd.DataFrame, ...]]: +) -> tuple[pd.DataFrame, tuple[pd.DataFrame, ...]]: """Removes unused fragments of removed precursors, reannotates the `frag_start_col` and `frag_stop_col` @@ -1220,7 +1220,7 @@ def remove_unused_fragments( def create_fragment_mz_dataframe_by_sort_precursor( precursor_df: pd.DataFrame, - charged_frag_types: List, + charged_frag_types: list, batch_size: int = 500000, dtype: np.dtype = PEAK_MZ_DTYPE, ) -> pd.DataFrame: @@ -1277,7 +1277,7 @@ def create_fragment_mz_dataframe_by_sort_precursor( def create_fragment_mz_dataframe( precursor_df: pd.DataFrame, - charged_frag_types: List, + charged_frag_types: list, *, reference_fragment_df: pd.DataFrame = None, inplace_in_reference: bool = False, diff --git a/alphabase/peptide/mass_calc.py b/alphabase/peptide/mass_calc.py index 5a9e3da1..2a1d2c89 100644 --- a/alphabase/peptide/mass_calc.py +++ b/alphabase/peptide/mass_calc.py @@ -1,5 +1,3 @@ -from typing import List, Tuple - import numpy as np from alphabase.constants.aa import ( @@ -17,7 +15,7 @@ def calc_diff_modification_mass( - pep_len: int, mass_diffs: List[float], mass_diff_sites: List[int] + pep_len: int, mass_diffs: list[float], mass_diff_sites: list[int] ) -> np.ndarray: """ For open-search, we may also get modification @@ -52,7 +50,7 @@ def calc_diff_modification_mass( def calc_mod_diff_masses_for_same_len_seqs( - nAA: int, aa_mass_diffs_list: List[List[float]], mod_sites_list: List[List[int]] + nAA: int, aa_mass_diffs_list: list[list[float]], mod_sites_list: list[list[int]] ) -> np.ndarray: """ Calculate diff modification masses for the given peptide length (`nAA`), @@ -96,11 +94,11 @@ def calc_mod_diff_masses_for_same_len_seqs( def calc_b_y_and_peptide_mass( sequence: str, - mod_names: List[str], - mod_sites: List[int], - aa_mass_diffs: List[float] = None, - aa_mass_diff_sites: List[int] = None, -) -> Tuple[np.ndarray, np.ndarray, float]: + mod_names: list[str], + mod_sites: list[int], + aa_mass_diffs: list[float] = None, + aa_mass_diff_sites: list[int] = None, +) -> tuple[np.ndarray, np.ndarray, float]: """ It is highly recommend to use `calc_b_y_and_peptide_masses_for_same_len_seqs` @@ -124,7 +122,7 @@ def calc_b_y_and_peptide_mass( def calc_peptide_masses_for_same_len_seqs( - sequences: np.ndarray, mod_list: List[str], mod_diff_list: List[str] = None + sequences: np.ndarray, mod_list: list[str], mod_diff_list: list[str] = None ) -> np.ndarray: """ Calculate peptide masses for peptide sequences with same lengths. @@ -171,11 +169,11 @@ def calc_peptide_masses_for_same_len_seqs( def calc_b_y_and_peptide_masses_for_same_len_seqs( sequences: np.ndarray, - mod_list: List[List[str]], - site_list: List[List[int]], - mod_diff_list: List[List[float]] = None, - mod_diff_site_list: List[List[int]] = None, -) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: + mod_list: list[list[str]], + site_list: list[list[int]], + mod_diff_list: list[list[float]] = None, + mod_diff_site_list: list[list[int]] = None, +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: """ Calculate b/y fragment masses and peptide masses for peptide sequences with same lengths. diff --git a/alphabase/pg_reader/pg_reader.py b/alphabase/pg_reader/pg_reader.py index ba56088f..452ea09c 100644 --- a/alphabase/pg_reader/pg_reader.py +++ b/alphabase/pg_reader/pg_reader.py @@ -2,9 +2,10 @@ import re import warnings +from collections.abc import Iterable from copy import deepcopy from pathlib import Path -from typing import Any, Dict, Iterable, Optional, Type, Union +from typing import Any, Optional, Union import pandas as pd @@ -93,7 +94,7 @@ def __init__( self.measurement_regex = self._get_measurement_regex(regex=measurement_regex) - def add_column_mapping(self, column_mapping: Dict) -> None: + def add_column_mapping(self, column_mapping: dict) -> None: """Add additional column mappings for the search engine.""" self.column_mapping = {**self.column_mapping, **column_mapping} @@ -273,10 +274,10 @@ class PGReaderProvider: def __init__(self): """Initialize PGReaderProvider.""" - self.reader_dict: dict[str, Type[PGReaderBase]] = {} + self.reader_dict: dict[str, type[PGReaderBase]] = {} def register_reader( - self, reader_type: str, reader_class: Type[PGReaderBase] + self, reader_type: str, reader_class: type[PGReaderBase] ) -> None: """Register a reader by reader_type.""" self.reader_dict[reader_type.lower()] = reader_class diff --git a/alphabase/psm_reader/alphapept_reader.py b/alphabase/psm_reader/alphapept_reader.py index d978bb7c..5ca57ff5 100644 --- a/alphabase/psm_reader/alphapept_reader.py +++ b/alphabase/psm_reader/alphapept_reader.py @@ -1,7 +1,6 @@ """Reader for AlphaPept's .ms_data.hdf files.""" from pathlib import Path -from typing import Tuple import h5py import numpy as np @@ -17,7 +16,7 @@ _SEPARATOR = ModificationKeys.SEPARATOR -def parse_ap(precursor: str) -> Tuple[str, str, str, str, int]: +def parse_ap(precursor: str) -> tuple[str, str, str, str, int]: """Parser to parse peptide strings.""" items = precursor.split("_") decoy = 1 if len(items) == 3 else 0 # noqa: PLR2004 magic value diff --git a/alphabase/psm_reader/dia_psm_reader.py b/alphabase/psm_reader/dia_psm_reader.py index 3e6e8bae..660d78ea 100644 --- a/alphabase/psm_reader/dia_psm_reader.py +++ b/alphabase/psm_reader/dia_psm_reader.py @@ -1,6 +1,6 @@ """Readers for Spectronaut's output library and reports, Swath data and DIANN data.""" -from typing import List, Optional +from typing import Optional import numpy as np import pandas as pd @@ -49,7 +49,7 @@ def __init__( # noqa: PLR0913, D417 # too many arguments in function definition *, column_mapping: Optional[dict] = None, modification_mapping: Optional[dict] = None, - mod_seq_columns: Optional[List[str]] = None, + mod_seq_columns: Optional[list[str]] = None, fdr: float = 0.01, keep_decoy: bool = False, rt_unit: Optional[str] = None, diff --git a/alphabase/psm_reader/keys.py b/alphabase/psm_reader/keys.py index 2635d0bc..46419697 100644 --- a/alphabase/psm_reader/keys.py +++ b/alphabase/psm_reader/keys.py @@ -1,6 +1,6 @@ """Constants for accessing the columns of a PSM dataframe.""" -from typing import Any, List, NoReturn +from typing import Any, NoReturn class ConstantsClass(type): @@ -10,7 +10,7 @@ def __setattr__(cls, name: Any, value: Any) -> NoReturn: # noqa: ANN401 """Raise an error when trying to set an attribute.""" raise TypeError("Constants class cannot be modified") - def get_values(cls) -> List[str]: + def get_values(cls) -> list[str]: """Get all user-defined string values of the class.""" return [ value diff --git a/alphabase/psm_reader/maxquant_reader.py b/alphabase/psm_reader/maxquant_reader.py index f0199b99..a27f63b9 100644 --- a/alphabase/psm_reader/maxquant_reader.py +++ b/alphabase/psm_reader/maxquant_reader.py @@ -2,7 +2,7 @@ import warnings from abc import ABC -from typing import List, Optional +from typing import Optional import numpy as np import pandas as pd @@ -134,7 +134,7 @@ def __init__( # noqa: PLR0913 # too many arguments in function definition, miss *, column_mapping: Optional[dict] = None, modification_mapping: Optional[dict] = None, - mod_seq_columns: Optional[List[str]] = None, + mod_seq_columns: Optional[list[str]] = None, fdr: float = 0.01, keep_decoy: bool = False, rt_unit: Optional[str] = None, @@ -198,7 +198,7 @@ def __init__( # noqa: PLR0913, D417 # too many arguments in function definition *, column_mapping: Optional[dict] = None, modification_mapping: Optional[dict] = None, - mod_seq_columns: Optional[List[str]] = None, + mod_seq_columns: Optional[list[str]] = None, fdr: float = 0.01, keep_decoy: bool = False, rt_unit: Optional[str] = None, diff --git a/alphabase/psm_reader/modification_mapper.py b/alphabase/psm_reader/modification_mapper.py index 55526f6b..6d6b4935 100644 --- a/alphabase/psm_reader/modification_mapper.py +++ b/alphabase/psm_reader/modification_mapper.py @@ -2,7 +2,7 @@ import copy from collections import defaultdict -from typing import Dict, Optional +from typing import Optional from alphabase.constants.modification import ModificationKeys from alphabase.psm_reader.utils import MOD_TO_UNIMOD_DICT, get_extended_modifications @@ -13,9 +13,9 @@ class ModificationMapper: def __init__( self, - custom_modification_mapping: Optional[Dict[str, str]], + custom_modification_mapping: Optional[dict[str, str]], *, - reader_yaml: Dict, + reader_yaml: dict, mapping_type: str, add_unimod_to_mod_mapping: bool, ): @@ -87,7 +87,7 @@ def add_modification_mapping(self, custom_modification_mapping: dict) -> None: ) def set_modification_mapping( - self, modification_mapping: Optional[Dict] = None + self, modification_mapping: Optional[dict] = None ) -> None: """Set the modification mapping for the search engine. @@ -149,7 +149,7 @@ def _str_mods_to_lists(self) -> None: if isinstance(val, str): self.modification_mapping[mod] = [val] - def _get_reversed_mod_mapping(self) -> Dict[str, str]: + def _get_reversed_mod_mapping(self) -> dict[str, str]: """Create a reverse mapping from the modification format used by the search engine to the AlphaBase format.""" rev_mod_mapping = {} for mod_alphabase_format, mod_other_format in self.modification_mapping.items(): diff --git a/alphabase/psm_reader/msfragger_reader.py b/alphabase/psm_reader/msfragger_reader.py index 032efe83..4f4c464c 100644 --- a/alphabase/psm_reader/msfragger_reader.py +++ b/alphabase/psm_reader/msfragger_reader.py @@ -1,7 +1,7 @@ """MSFragger reader.""" import warnings -from typing import Dict, List, Optional, Tuple +from typing import Optional import numpy as np import pandas as pd @@ -18,7 +18,7 @@ ) -def _is_all_fragger_decoy(proteins: List[str]) -> bool: +def _is_all_fragger_decoy(proteins: list[str]) -> bool: """Check if all proteins are MSFragger decoy entries. Parameters @@ -37,7 +37,7 @@ def _is_all_fragger_decoy(proteins: List[str]) -> bool: ) -def _extract_position(entry: str) -> Tuple[int, str]: +def _extract_position(entry: str) -> tuple[int, str]: """Extract leading position digits from modification entry. Parameters @@ -80,7 +80,7 @@ def _extract_mass_shift(entry: str) -> float: ) -def _parse_lookup_key(lookup_key: str, entry: str) -> Tuple[str, float]: +def _parse_lookup_key(lookup_key: str, entry: str) -> tuple[str, float]: """Parse lookup key into amino acid and mass shift. Parameters @@ -111,9 +111,9 @@ class MSFraggerModificationTranslator: def __init__( self, - mass_mapped_mods: List[str], + mass_mapped_mods: list[str], mod_mass_tol: float, - rev_mod_mapping: Dict[str, str], + rev_mod_mapping: dict[str, str], ): """Initialize MSFragger modification translator. @@ -161,7 +161,7 @@ def translate(self, psm_df: pd.DataFrame) -> pd.DataFrame: return psm_df - def _parse_assigned_modifications(self, assigned_mods: str) -> Tuple[str, str]: + def _parse_assigned_modifications(self, assigned_mods: str) -> tuple[str, str]: """Parse MSFragger Assigned Modifications string. Parameters @@ -196,7 +196,7 @@ def _parse_assigned_modifications(self, assigned_mods: str) -> Tuple[str, str]: sites ) - def _parse_single_modification(self, entry: str) -> Tuple[str, str]: + def _parse_single_modification(self, entry: str) -> tuple[str, str]: """Parse a single modification entry.""" if entry.startswith(MsFraggerTokens.N_TERM): return self._resolve_terminal_mod(entry, "Any_N-term"), "0" @@ -287,10 +287,10 @@ def _match_mod_by_mass( def _get_mods_from_masses( # noqa: PLR0912, C901 too many branches, too complex TODO: refactor sequence: str, - msf_aa_mods: List[str], - mass_mapped_mods: List[str], + msf_aa_mods: list[str], + mass_mapped_mods: list[str], mod_mass_tol: float, -) -> Tuple[str, str, str, str]: +) -> tuple[str, str, str, str]: mods = [] mod_sites = [] aa_mass_diffs = [] diff --git a/alphabase/psm_reader/pfind_reader.py b/alphabase/psm_reader/pfind_reader.py index 3c773b2a..2c795cf3 100644 --- a/alphabase/psm_reader/pfind_reader.py +++ b/alphabase/psm_reader/pfind_reader.py @@ -1,6 +1,6 @@ """pFind reader.""" -from typing import Optional, Tuple, Union +from typing import Optional, Union import numpy as np import pandas as pd @@ -91,7 +91,7 @@ def translate_pFind_mod(mod_str: str) -> Union[str, NAType]: # noqa: N802 name return ModificationKeys.SEPARATOR.join(ret_mods) -def get_pFind_mods(pfind_mod_str: str) -> Tuple[str, str]: # noqa: N802 name `get_pFind_mods` should be lowercase TODO: used by peptdeep +def get_pFind_mods(pfind_mod_str: str) -> tuple[str, str]: # noqa: N802 name `get_pFind_mods` should be lowercase TODO: used by peptdeep """Parse pFind modification string.""" pfind_mod_str = pfind_mod_str.strip(ModificationKeys.SEPARATOR) if not pfind_mod_str: diff --git a/alphabase/psm_reader/psm_reader.py b/alphabase/psm_reader/psm_reader.py index 271fdc71..2331c564 100644 --- a/alphabase/psm_reader/psm_reader.py +++ b/alphabase/psm_reader/psm_reader.py @@ -5,7 +5,7 @@ import warnings from abc import ABC from pathlib import Path -from typing import Dict, List, Optional, Set, Type, Union +from typing import Optional, Union import pandas as pd @@ -48,7 +48,7 @@ def __init__( # noqa: PLR0913 # too many arguments fdr: float = 0.01, keep_decoy: bool = False, rt_unit: Optional[str] = None, - mod_seq_columns: Optional[List[str]] = None, + mod_seq_columns: Optional[list[str]] = None, **kwargs, ): """The Base class for all PSMReaders. @@ -182,11 +182,11 @@ def psm_df(self) -> pd.DataFrame: return self._psm_df @property - def modification_mapping(self) -> Dict: + def modification_mapping(self) -> dict: """Get the modification mapping dictionary.""" return self._modification_mapper.modification_mapping - def add_modification_mapping(self, modification_mapping: Dict) -> None: + def add_modification_mapping(self, modification_mapping: dict) -> None: """Append additional modification mappings for the search engine. See ModificationMapper.add_modification_mapping for more details. @@ -194,7 +194,7 @@ def add_modification_mapping(self, modification_mapping: Dict) -> None: self._modification_mapper.add_modification_mapping(modification_mapping) def set_modification_mapping( - self, modification_mapping: Optional[Dict] = None + self, modification_mapping: Optional[dict] = None ) -> None: """Set the modification mapping for the search engine. @@ -202,17 +202,17 @@ def set_modification_mapping( """ self._modification_mapper.set_modification_mapping(modification_mapping) - def add_column_mapping(self, column_mapping: Dict) -> None: + def add_column_mapping(self, column_mapping: dict) -> None: """Add additional column mappings for the search engine.""" self.column_mapping = {**self.column_mapping, **column_mapping} - def load(self, _file: Union[List[str], str]) -> pd.DataFrame: + def load(self, _file: Union[list[str], str]) -> pd.DataFrame: """Import a single file or multiple files.""" if isinstance(_file, list): return self.import_files(_file) return self.import_file(_file) - def import_files(self, file_list: List[str]) -> pd.DataFrame: + def import_files(self, file_list: list[str]) -> pd.DataFrame: """Import multiple files.""" df_list = [self.import_file(file) for file in file_list] self._psm_df = pd.concat(df_list, ignore_index=True) @@ -280,7 +280,7 @@ def _load_file(self, filename: Union[str, Path, io.StringIO]) -> pd.DataFrame: def _get_actual_column( self, - column_list: List[str], + column_list: list[str], df: pd.DataFrame, ) -> Optional[str]: """Get the first column from `column_list` that is a column of `df`.""" @@ -430,7 +430,7 @@ def _normalize_rt(self) -> None: def filter_psm_by_modifications( self, - include_mod_set: Optional[Set] = None, + include_mod_set: Optional[set] = None, ) -> None: """Only keeps peptides with modifications in `include_mod_list`.""" if include_mod_set is None: @@ -457,7 +457,7 @@ def __init__(self): self.reader_dict = {} def register_reader( - self, reader_type: str, reader_class: Type[PSMReaderBase] + self, reader_type: str, reader_class: type[PSMReaderBase] ) -> None: """Register a reader by reader_type.""" self.reader_dict[reader_type.lower()] = reader_class diff --git a/alphabase/psm_reader/sage_reader.py b/alphabase/psm_reader/sage_reader.py index 7ed527a5..67eab2c6 100644 --- a/alphabase/psm_reader/sage_reader.py +++ b/alphabase/psm_reader/sage_reader.py @@ -4,8 +4,9 @@ import multiprocessing as mp import re from abc import ABC +from collections.abc import Generator from functools import partial -from typing import Generator, List, Optional, Tuple +from typing import Optional import numpy as np import pandas as pd @@ -113,7 +114,7 @@ def translate(self, psm_df: pd.DataFrame) -> pd.DataFrame: def _annotate_from_custom_translation( self, discovered_modifications_df: pd.DataFrame, translation_df: pd.DataFrame - ) -> Tuple[pd.DataFrame, pd.DataFrame]: + ) -> tuple[pd.DataFrame, pd.DataFrame]: """Annotate modifications from custom translation df, if provided. Discovered modifications are first matched using the custom translation dataframe. @@ -236,7 +237,7 @@ def _discover_modifications(psm_df: pd.DataFrame) -> pd.DataFrame: def _match_modified_sequence( sequence: str, -) -> List[Tuple[str, str, bool, bool, float]]: +) -> list[tuple[str, str, bool, bool, float]]: """Get all matches with the amino acid location. P[-100.0]EPTIDE -> [('[-100.0]', 'P', False, False, -100.0)] @@ -333,7 +334,7 @@ def _lookup_modification( def _translate_modifications( sequence: str, mod_translation_df: pd.DataFrame -) -> Tuple[Optional[str], Optional[str]]: +) -> tuple[Optional[str], Optional[str]]: """Translate modifications in the sequence to alphabase style modifications. Parameters diff --git a/alphabase/psm_reader/utils.py b/alphabase/psm_reader/utils.py index 6c92432e..e841ba1e 100644 --- a/alphabase/psm_reader/utils.py +++ b/alphabase/psm_reader/utils.py @@ -1,6 +1,6 @@ """Utility functions for PSM readers.""" -from typing import Dict, List, Tuple, Union +from typing import Union import pandas as pd from pandas._libs.missing import NAType @@ -19,8 +19,8 @@ def translate_modifications( - mod_str: str, mod_dict: Dict -) -> Tuple[Union[str, NAType], List[str]]: + mod_str: str, mod_dict: dict +) -> tuple[Union[str, NAType], list[str]]: """Translate modifications of `mod_str` to the AlphaBase format mapped by mod_dict. Parameters @@ -84,7 +84,7 @@ def keep_modifications(mod_str: str, mod_set: set) -> Union[str, NAType]: return mod_str -def get_extended_modifications(mod_list: List[str]) -> List[str]: +def get_extended_modifications(mod_list: list[str]) -> list[str]: """Get an extended set of modifications from a list of modifications. Extend bracket types of modifications and strip off underscore, e.g. @@ -113,7 +113,7 @@ def get_extended_modifications(mod_list: List[str]) -> List[str]: return sorted(list(mod_set)) -def get_column_mapping_for_df(column_mapping: dict, df: pd.DataFrame) -> Dict[str, str]: +def get_column_mapping_for_df(column_mapping: dict, df: pd.DataFrame) -> dict[str, str]: """Determine the mapping of AlphaBase columns to the columns in the given DataFrame. For each AlphaBase column name, check if the corresponding search engine-specific diff --git a/alphabase/smiles/adding_smiles.py b/alphabase/smiles/adding_smiles.py index a5971c4e..6767b411 100644 --- a/alphabase/smiles/adding_smiles.py +++ b/alphabase/smiles/adding_smiles.py @@ -19,7 +19,7 @@ """ import os -from typing import Dict, Literal +from typing import Literal import pandas as pd @@ -37,8 +37,8 @@ def process_modifications( - mods_dict: Dict[str, str], mod_type: Literal["ptm", "n_term", "c_term"] = "ptm" -) -> Dict[str, Dict[str, str]]: + mods_dict: dict[str, str], mod_type: Literal["ptm", "n_term", "c_term"] = "ptm" +) -> dict[str, dict[str, str]]: """ Process various types of modifications (PTM, N-term, C-term) with a unified approach. diff --git a/alphabase/smiles/peptide.py b/alphabase/smiles/peptide.py index 297eb41a..e0cf0878 100644 --- a/alphabase/smiles/peptide.py +++ b/alphabase/smiles/peptide.py @@ -88,7 +88,7 @@ def _get_terminal_mods(self, mods: dict) -> tuple: (n_term_mod, c_term_mod) """ n_term_mod = mods.get(0) - c_term_mod = mods.get(-1, None) + c_term_mod = mods.get(-1) return n_term_mod, c_term_mod def _get_amino_acid_smiles(self, aa: str, mod_idx: int, mods: dict) -> str: diff --git a/alphabase/smiles/smiles.py b/alphabase/smiles/smiles.py index 52f95a10..24091367 100644 --- a/alphabase/smiles/smiles.py +++ b/alphabase/smiles/smiles.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional +from typing import Optional import pandas as pd @@ -144,7 +144,7 @@ def __init__(self): self._ptm_dict = None @property - def aa_smiles(self) -> Dict[str, str]: + def aa_smiles(self) -> dict[str, str]: """ Dictionary of amino acid SMILES. @@ -162,7 +162,7 @@ def aa_smiles(self) -> Dict[str, str]: return self._aa_smiles @property - def aa_mols(self) -> Dict[str, Chem.Mol]: + def aa_mols(self) -> dict[str, Chem.Mol]: """ Dictionary of amino acid RDKit molecules. @@ -178,7 +178,7 @@ def aa_mols(self) -> Dict[str, Chem.Mol]: return self._aa_mols @property - def n_term_modifications(self) -> Dict[str, str]: + def n_term_modifications(self) -> dict[str, str]: """ Dictionary of N-terminal modifications. @@ -194,7 +194,7 @@ def n_term_modifications(self) -> Dict[str, str]: return self._n_term_modifications @property - def c_term_modifications(self) -> Dict[str, str]: + def c_term_modifications(self) -> dict[str, str]: """ Dictionary of C-terminal modifications. @@ -210,7 +210,7 @@ def c_term_modifications(self) -> Dict[str, str]: return self._c_term_modifications @property - def ptm_dict(self) -> Dict[str, str]: + def ptm_dict(self) -> dict[str, str]: """ Dictionary of post-translational modifications (PTMs). @@ -228,7 +228,7 @@ def ptm_dict(self) -> Dict[str, str]: } return self._ptm_dict - def _get_modifications(self, *terms: str) -> Dict[str, str]: + def _get_modifications(self, *terms: str) -> dict[str, str]: """ Helper method to get modifications based on specific terms. diff --git a/alphabase/spectral_library/annotate.py b/alphabase/spectral_library/annotate.py index 169905a6..69d9e394 100644 --- a/alphabase/spectral_library/annotate.py +++ b/alphabase/spectral_library/annotate.py @@ -1,6 +1,6 @@ """Module for annotating spectral libraries with raw mass spectrometry data.""" -from typing import List, Tuple, Union +from typing import Union import numpy as np import pandas as pd @@ -329,7 +329,7 @@ def annotate_spectrum( # noqa: PLR0913 def _build_theoretical_flatlib( - template: SpecLibFlat, charged_frag_types: List[str] + template: SpecLibFlat, charged_frag_types: list[str] ) -> SpecLibFlat: """Generate a flat spectral library containing theoretical fragments.""" theoretical_flat = SpecLibFlat( @@ -360,7 +360,7 @@ def _build_theoretical_flatlib( def add_dense_lib( - flatlib: SpecLibFlat, charged_frag_types: Union[List[str], Tuple[str, ...]] + flatlib: SpecLibFlat, charged_frag_types: Union[list[str], tuple[str, ...]] ) -> SpecLibFlat: """Add dense format to the flatlib object. diff --git a/alphabase/spectral_library/base.py b/alphabase/spectral_library/base.py index 6b781f4d..1cb5e786 100644 --- a/alphabase/spectral_library/base.py +++ b/alphabase/spectral_library/base.py @@ -84,7 +84,7 @@ def __init__( # ['b_z1','b_z2','y_z1','y_modloss_z1', ...]; # 'b_z1': 'b' is the fragment type and # 'z1' is the charge state z=1. - charged_frag_types: typing.List[str] = ["b_z1", "b_z2", "y_z1", "y_z2"], + charged_frag_types: list[str] = ["b_z1", "b_z2", "y_z1", "y_z2"], precursor_mz_min: float = 400, precursor_mz_max: float = 6000, decoy: str = None, @@ -194,7 +194,7 @@ def copy(self): def append( self, other: "SpecLibBase", - dfs_to_append: typing.List[str] = [ + dfs_to_append: list[str] = [ "_precursor_df", "_fragment_df", "_fragment_intensity_df", diff --git a/alphabase/spectral_library/peaks_reader.py b/alphabase/spectral_library/peaks_reader.py index eb71d4cb..76e533b5 100644 --- a/alphabase/spectral_library/peaks_reader.py +++ b/alphabase/spectral_library/peaks_reader.py @@ -7,7 +7,7 @@ import re import warnings -from typing import List, Optional, Set, Tuple +from typing import Optional import numpy as np import pandas as pd @@ -56,7 +56,7 @@ def _parse_fragment_annotation( annotation: str, -) -> Optional[Tuple[str, int, int, str]]: +) -> Optional[tuple[str, int, int, str]]: """Parse a PEAKS fragment annotation into its components. Parameters @@ -88,14 +88,14 @@ class PeaksModificationTranslator: precursor for removal. """ - def __init__(self, mass_mapped_mods: List[str], mod_mass_tol: float): + def __init__(self, mass_mapped_mods: list[str], mod_mass_tol: float): """Store the candidate alphabase mod names and the mass tolerance (Da).""" self._mass_mapped_mods = mass_mapped_mods self._mod_mass_tol = mod_mass_tol def translate( self, sequences: np.ndarray, mod_strings: np.ndarray - ) -> Tuple[list, list]: + ) -> tuple[list, list]: """Translate PEAKS ``Modifications`` cells to alphabase mods and mod_sites. Parameters @@ -116,7 +116,7 @@ def translate( """ cache = {} - unknown_mods: Set[str] = set() + unknown_mods: set[str] = set() mods_list = [] sites_list = [] for sequence, mod_str in zip(sequences, mod_strings): @@ -138,7 +138,7 @@ def translate( def _parse_cell( self, sequence: str, mod_str: str - ) -> Tuple[Optional[str], Optional[str], Set[str]]: + ) -> tuple[Optional[str], Optional[str], set[str]]: """Parse a single PEAKS ``Modifications`` cell. Positions are 0-based indices into the backbone sequence; a mod whose name @@ -166,7 +166,7 @@ def _parse_cell( mods = [] sites = [] - unknown: Set[str] = set() + unknown: set[str] = set() for raw_entry in mod_str.split(";"): entry = raw_entry.strip() if not entry: @@ -272,12 +272,12 @@ class PeaksLibraryReader(LibraryReaderBase): def __init__( # noqa: PLR0913 many arguments self, - charged_frag_types: Optional[List[str]] = None, + charged_frag_types: Optional[list[str]] = None, column_mapping: Optional[dict] = None, modification_mapping: Optional[dict] = None, fdr: float = 0.01, fixed_C57: bool = False, # noqa: N803, FBT001, FBT002 - mod_seq_columns: Optional[List[str]] = None, + mod_seq_columns: Optional[list[str]] = None, rt_unit: Optional[str] = None, precursor_mz_min: float = 400, precursor_mz_max: float = 2000, diff --git a/alphabase/spectral_library/reader.py b/alphabase/spectral_library/reader.py index b224d4da..0b680a98 100644 --- a/alphabase/spectral_library/reader.py +++ b/alphabase/spectral_library/reader.py @@ -2,7 +2,7 @@ import io from pathlib import Path -from typing import List, Optional, Union +from typing import Optional, Union import numpy as np import pandas as pd @@ -24,7 +24,7 @@ class LibraryReaderBase(ModifiedSequenceReader, SpecLibBase): def __init__( # noqa: PLR0913 many arguments in function definition self, - charged_frag_types: List[str] = [ + charged_frag_types: list[str] = [ "b_z1", "b_z2", "y_z1", @@ -38,7 +38,7 @@ def __init__( # noqa: PLR0913 many arguments in function definition modification_mapping: Optional[dict] = None, fdr: float = 0.01, fixed_C57: bool = False, # noqa: FBT001, FBT002, N803 TODO: make this *,fixed_c57 (breaking) - mod_seq_columns: Optional[List[str]] = None, + mod_seq_columns: Optional[list[str]] = None, rt_unit: Optional[str] = None, # library reader-specific: precursor_mz_min: float = 400, diff --git a/alphabase/spectral_library/translate.py b/alphabase/spectral_library/translate.py index 4e3ff66a..948c0944 100644 --- a/alphabase/spectral_library/translate.py +++ b/alphabase/spectral_library/translate.py @@ -1,5 +1,4 @@ import multiprocessing as mp -import typing import numpy as np import pandas as pd @@ -13,7 +12,7 @@ # @numba.njit #(cannot use numba for pd.Series) def create_modified_sequence( - seq_mods_sites: typing.Tuple, # must be ('sequence','mods','mod_sites') + seq_mods_sites: tuple, # must be ('sequence','mods','mod_sites') translate_mod_dict: dict = None, mod_sep="[]", nterm="_", diff --git a/alphabase/spectral_library/translate_diann.py b/alphabase/spectral_library/translate_diann.py index 7de4ca36..756e825f 100644 --- a/alphabase/spectral_library/translate_diann.py +++ b/alphabase/spectral_library/translate_diann.py @@ -5,7 +5,7 @@ preparation for a larger refactor of the library-export code. """ -from typing import List, Optional, Union +from typing import Optional, Union import pandas as pd import tqdm @@ -123,7 +123,7 @@ class DiannParquetCols(metaclass=ConstantsClass): def _get_first_present_column( precursor_df: pd.DataFrame, - candidates: List[str], + candidates: list[str], default: Union[str, float, None] = None, ) -> Union[pd.Series, str, float, None]: """Return the first present candidate column of `precursor_df`, else `default`.""" diff --git a/alphabase/spectral_library/validate.py b/alphabase/spectral_library/validate.py index 3396d577..cf7ccf55 100644 --- a/alphabase/spectral_library/validate.py +++ b/alphabase/spectral_library/validate.py @@ -1,4 +1,4 @@ -from typing import List, Union +from typing import Union import numpy as np import pandas as pd @@ -165,7 +165,7 @@ def __call__(self, df: pd.DataFrame): class Schema: - def __init__(self, name: str, properties: List[Column]): + def __init__(self, name: str, properties: list[Column]): """ Schema for validating dataframes diff --git a/alphabase/tools/data_downloader.py b/alphabase/tools/data_downloader.py index 6b36b417..21daed76 100644 --- a/alphabase/tools/data_downloader.py +++ b/alphabase/tools/data_downloader.py @@ -204,9 +204,12 @@ def _download_file( """ try: if max_size_kb: - with urlopen( - self._encoded_url, context=_create_ssl_context() - ) as response, open(self._output_path, "wb") as out_file: + with ( + urlopen( + self._encoded_url, context=_create_ssl_context() + ) as response, + open(self._output_path, "wb") as out_file, + ): out_file.write(response.read(max_size_kb * 1024)) print(f"Truncating file to max. {max_size_kb} bytes ..") @@ -214,9 +217,12 @@ def _download_file( self._truncate_file(self._output_path) else: - with urlopen( - self._encoded_url, context=_create_ssl_context() - ) as response, open(self._output_path, "wb") as out_file: + with ( + urlopen( + self._encoded_url, context=_create_ssl_context() + ) as response, + open(self._output_path, "wb") as out_file, + ): total_size = int(response.headers.get("Content-Length", -1)) progress = Progress() block_num = 0 diff --git a/docs/nbs/library_from_fasta.ipynb b/docs/nbs/library_from_fasta.ipynb index d4e2cfd5..22059595 100644 --- a/docs/nbs/library_from_fasta.ipynb +++ b/docs/nbs/library_from_fasta.ipynb @@ -39,19 +39,11 @@ "metadata": {}, "outputs": [], "source": [ - "prot1 = 'MABCDESTKAFGHIJKLMNOPQRAFGHIJK'\n", - "prot2 = 'AFGHIJKLMNOPQR'\n", + "prot1 = \"MABCDESTKAFGHIJKLMNOPQRAFGHIJK\"\n", + "prot2 = \"AFGHIJKLMNOPQR\"\n", "protein_dict = {\n", - " 'xx': {\n", - " 'protein_id': 'xx',\n", - " 'gene_name': '',\n", - " 'sequence': prot1\n", - " },\n", - " 'yy': {\n", - " 'protein_id': 'yy',\n", - " 'gene_name': 'gene',\n", - " 'sequence': prot2\n", - " }\n", + " \"xx\": {\"protein_id\": \"xx\", \"gene_name\": \"\", \"sequence\": prot1},\n", + " \"yy\": {\"protein_id\": \"yy\", \"gene_name\": \"gene\", \"sequence\": prot2},\n", "}" ] }, @@ -261,9 +253,11 @@ ], "source": [ "fasta_lib = SpecLibFasta(\n", - " ['b_z1','y_z1'], I_to_L=False, decoy='pseudo_reverse',\n", - " var_mods=['Acetyl@Protein_N-term', 'Oxidation@M'],\n", - " fix_mods=['Carbamidomethyl@C'],\n", + " [\"b_z1\", \"y_z1\"],\n", + " I_to_L=False,\n", + " decoy=\"pseudo_reverse\",\n", + " var_mods=[\"Acetyl@Protein_N-term\", \"Oxidation@M\"],\n", + " fix_mods=[\"Carbamidomethyl@C\"],\n", ")\n", "# fasta_lib.get_peptides_from_fasta(fasta_files)\n", "fasta_lib.get_peptides_from_protein_dict(protein_dict)\n", @@ -920,7 +914,7 @@ ], "source": [ "fasta_lib.add_modifications()\n", - "fasta_lib.precursor_df[['sequence','mods','mod_sites']]" + "fasta_lib.precursor_df[[\"sequence\", \"mods\", \"mod_sites\"]]" ] }, { @@ -1167,9 +1161,13 @@ ], "source": [ "from alphabase.protein.fasta import append_special_modifications\n", + "\n", "fasta_lib._precursor_df = append_special_modifications(\n", - " fasta_lib.precursor_df, ['Phospho@S','Phospho@T'],\n", - " min_mod_num=0, max_mod_num=1, max_peptidoform_num=100\n", + " fasta_lib.precursor_df,\n", + " [\"Phospho@S\", \"Phospho@T\"],\n", + " min_mod_num=0,\n", + " max_mod_num=1,\n", + " max_peptidoform_num=100,\n", ")\n", "fasta_lib.precursor_df" ] @@ -1429,11 +1427,13 @@ } ], "source": [ - "fasta_lib.add_peptide_labeling({\n", - " '': [], # not labelled for reference\n", - " '0': ['Dimethyl@Any_N-term','Dimethyl@K'],\n", - " '8': ['Dimethyl:2H(6)13C(2)@Any_N-term','Dimethyl:2H(6)13C(2)@K'],\n", - "})\n", + "fasta_lib.add_peptide_labeling(\n", + " {\n", + " \"\": [], # not labelled for reference\n", + " \"0\": [\"Dimethyl@Any_N-term\", \"Dimethyl@K\"],\n", + " \"8\": [\"Dimethyl:2H(6)13C(2)@Any_N-term\", \"Dimethyl:2H(6)13C(2)@K\"],\n", + " }\n", + ")\n", "fasta_lib.precursor_df" ] }, @@ -1589,7 +1589,7 @@ ], "source": [ "fasta_lib.add_charge()\n", - "fasta_lib.precursor_df[['sequence','mods','mod_sites','charge']]" + "fasta_lib.precursor_df[[\"sequence\", \"mods\", \"mod_sites\", \"charge\"]]" ] }, { @@ -1783,7 +1783,10 @@ "source": [ "fasta_lib.calc_precursor_mz()\n", "fasta_lib.calc_precursor_isotope()\n", - "fasta_lib.precursor_df[['precursor_mz']+[col for col in fasta_lib.precursor_df.columns if col.startswith('i_')]]" + "fasta_lib.precursor_df[\n", + " [\"precursor_mz\"]\n", + " + [col for col in fasta_lib.precursor_df.columns if col.startswith(\"i_\")]\n", + "]" ] }, { @@ -2032,7 +2035,7 @@ } ], "source": [ - "fasta_lib.precursor_df[['frag_start_idx','frag_stop_idx']]" + "fasta_lib.precursor_df[[\"frag_start_idx\", \"frag_stop_idx\"]]" ] }, { @@ -2123,8 +2126,8 @@ } ], "source": [ - "start, end = fasta_lib.precursor_df[['frag_start_idx','frag_stop_idx']].values[1]\n", - "fasta_lib.fragment_mz_df.iloc[start:end,:]" + "start, end = fasta_lib.precursor_df[[\"frag_start_idx\", \"frag_stop_idx\"]].values[1]\n", + "fasta_lib.fragment_mz_df.iloc[start:end, :]" ] }, { diff --git a/docs/nbs/library_reader.ipynb b/docs/nbs/library_reader.ipynb index 499d5375..ccb6c1fa 100644 --- a/docs/nbs/library_reader.ipynb +++ b/docs/nbs/library_reader.ipynb @@ -183,8 +183,10 @@ } ], "source": [ - "from alphabase.spectral_library.reader import SWATHLibraryReader\n", "from io import StringIO\n", + "\n", + "from alphabase.spectral_library.reader import SWATHLibraryReader\n", + "\n", "tsv_str = \"\"\"PrecursorCharge\tModifiedPeptide\tStrippedPeptide\tiRT\tLabeledPeptide\tPrecursorMz\tFragmentLossType\tFragmentNumber\tFragmentType\tFragmentCharge\tFragmentMz\tRelativeIntensity\tIonMobility\n", "2\t_DPLAVDK_\tDPLAVDK\t-15.0871\t_DPLAVDK_\t379.2081611\tnoloss\t3\tb\t1\t326.1710473\t14.37029\t0.9\n", "2\t_DPLAVDK_\tDPLAVDK\t-15.0871\t_DPLAVDK_\t379.2081611\tnoloss\t3\ty\t1\t361.2081611\t37.7585\t0.9\n", @@ -237,7 +239,17 @@ "\n", "reader = SWATHLibraryReader()\n", "psm_df = reader.import_file(StringIO(tsv_str))\n", - "for col in ['sequence','charge','rt','rt_norm','mods','mod_sites','nAA','frag_start_idx','frag_stop_idx']:\n", + "for col in [\n", + " \"sequence\",\n", + " \"charge\",\n", + " \"rt\",\n", + " \"rt_norm\",\n", + " \"mods\",\n", + " \"mod_sites\",\n", + " \"nAA\",\n", + " \"frag_start_idx\",\n", + " \"frag_stop_idx\",\n", + "]:\n", " assert col in psm_df.columns\n", "reader.psm_df" ] @@ -1601,9 +1613,19 @@ "\n", "reader = SWATHLibraryReader()\n", "psm_df = reader.import_file(StringIO(tsv_str))\n", - "for col in ['sequence','charge','rt','rt_norm','mods','mod_sites','nAA','frag_start_idx','frag_stop_idx']:\n", + "for col in [\n", + " \"sequence\",\n", + " \"charge\",\n", + " \"rt\",\n", + " \"rt_norm\",\n", + " \"mods\",\n", + " \"mod_sites\",\n", + " \"nAA\",\n", + " \"frag_start_idx\",\n", + " \"frag_stop_idx\",\n", + "]:\n", " assert col in psm_df.columns\n", - "assert 'raw_name' in psm_df.columns\n", + "assert \"raw_name\" in psm_df.columns\n", "psm_df" ] }, diff --git a/docs/nbs/peptide_smiles.ipynb b/docs/nbs/peptide_smiles.ipynb index 5429a876..9db8dbf4 100644 --- a/docs/nbs/peptide_smiles.ipynb +++ b/docs/nbs/peptide_smiles.ipynb @@ -24,14 +24,11 @@ "source": [ "import numpy as np\n", "from rdkit import Chem\n", - "from rdkit.Chem import Descriptors, Draw\n", - "from rdkit.Chem import rdCoordGen\n", - "from rdkit.Chem import rdFingerprintGenerator\n", - "from rdkit.Chem import MACCSkeys\n", + "from rdkit.Chem import Descriptors, Draw, MACCSkeys, rdCoordGen, rdFingerprintGenerator\n", "from rdkit.Chem.AtomPairs import Pairs\n", "\n", - "from alphabase.peptide.precursor import get_mod_seq_formula\n", "from alphabase.constants.atom import CHEM_MONO_MASS, MASS_H2O\n", + "from alphabase.peptide.precursor import get_mod_seq_formula\n", "from alphabase.smiles.peptide import PeptideSmilesEncoder\n", "\n", "# Initialize the encoder\n", @@ -88,6 +85,7 @@ " print(f\"SMILES: {smiles}\")\n", " print(f\"Exact Mass: {Descriptors.ExactMolWt(mol) - MASS_H2O:.4f}\")\n", "\n", + "\n", "sequence = \"QMNPHIR\"\n", "smiles = encoder.peptide_to_smiles(sequence)\n", "\n", @@ -95,7 +93,9 @@ "visualize_peptide(smiles, \"Peptide without modifications\")\n", "\n", "# Verify mass\n", - "expected_mass = np.sum([CHEM_MONO_MASS[elem] * n for elem, n in get_mod_seq_formula(sequence, \"\")])\n", + "expected_mass = np.sum(\n", + " [CHEM_MONO_MASS[elem] * n for elem, n in get_mod_seq_formula(sequence, \"\")]\n", + ")\n", "actual_mass = Descriptors.ExactMolWt(Chem.MolFromSmiles(smiles)) - MASS_H2O\n", "print(f\"Expected mass: {expected_mass:.4f}\")\n", "print(f\"Mass difference: {abs(actual_mass - expected_mass):.4f}\")" @@ -157,7 +157,9 @@ "visualize_peptide(smiles, \"Peptide with modifications\")\n", "\n", "# Verify mass\n", - "expected_mass = np.sum([CHEM_MONO_MASS[elem] * n for elem, n in get_mod_seq_formula(sequence, mods)])\n", + "expected_mass = np.sum(\n", + " [CHEM_MONO_MASS[elem] * n for elem, n in get_mod_seq_formula(sequence, mods)]\n", + ")\n", "actual_mass = Descriptors.ExactMolWt(Chem.MolFromSmiles(smiles)) - MASS_H2O\n", "print(f\"Expected mass: {expected_mass:.4f}\")\n", "print(f\"Mass difference: {abs(actual_mass - expected_mass):.4f}\")" @@ -219,7 +221,9 @@ "visualize_peptide(smiles, \"Peptide with N-terminal modification\")\n", "\n", "# Verify mass\n", - "expected_mass = np.sum([CHEM_MONO_MASS[elem] * n for elem, n in get_mod_seq_formula(sequence, mods)])\n", + "expected_mass = np.sum(\n", + " [CHEM_MONO_MASS[elem] * n for elem, n in get_mod_seq_formula(sequence, mods)]\n", + ")\n", "actual_mass = Descriptors.ExactMolWt(Chem.MolFromSmiles(smiles)) - MASS_H2O\n", "print(f\"Expected mass: {expected_mass:.4f}\")\n", "print(f\"Mass difference: {abs(actual_mass - expected_mass):.4f}\")" @@ -281,7 +285,9 @@ "visualize_peptide(smiles, \"Peptide with C-terminal modification\")\n", "\n", "# Verify mass\n", - "expected_mass = np.sum([CHEM_MONO_MASS[elem] * n for elem, n in get_mod_seq_formula(sequence, mods)])\n", + "expected_mass = np.sum(\n", + " [CHEM_MONO_MASS[elem] * n for elem, n in get_mod_seq_formula(sequence, mods)]\n", + ")\n", "actual_mass = Descriptors.ExactMolWt(Chem.MolFromSmiles(smiles)) - MASS_H2O\n", "print(f\"Expected mass: {expected_mass:.4f}\")\n", "print(f\"Mass difference: {abs(actual_mass - expected_mass):.4f}\")" @@ -343,7 +349,9 @@ "visualize_peptide(smiles, \"Peptide with multiple modifications\")\n", "\n", "# Verify mass\n", - "expected_mass = np.sum([CHEM_MONO_MASS[elem] * n for elem, n in get_mod_seq_formula(sequence, mods)])\n", + "expected_mass = np.sum(\n", + " [CHEM_MONO_MASS[elem] * n for elem, n in get_mod_seq_formula(sequence, mods)]\n", + ")\n", "actual_mass = Descriptors.ExactMolWt(Chem.MolFromSmiles(smiles)) - MASS_H2O\n", "print(f\"Expected mass: {expected_mass:.4f}\")\n", "print(f\"Mass difference: {abs(actual_mass - expected_mass):.4f}\")" @@ -377,10 +385,10 @@ } ], "source": [ - "def get_fingerprint(mol, fp_type='morgan', **kwargs):\n", + "def get_fingerprint(mol, fp_type=\"morgan\", **kwargs):\n", " \"\"\"\n", " Generate molecular fingerprints for an RDKit mol object.\n", - " \n", + "\n", " Parameters\n", " ----------\n", " mol : rdkit.Chem.Mol\n", @@ -390,34 +398,34 @@ " Default is 'morgan'.\n", " **kwargs : dict\n", " Additional keyword arguments for specific fingerprint parameters.\n", - " \n", + "\n", " Returns\n", " -------\n", " list\n", " Fingerprint bit vector.\n", " \"\"\"\n", - " if fp_type == 'morgan':\n", - " radius = kwargs.get('radius', 2)\n", - " nBits = kwargs.get('nBits', 2048)\n", - " mfpgen = rdFingerprintGenerator.GetMorganGenerator(radius=radius,fpSize=nBits)\n", + " if fp_type == \"morgan\":\n", + " radius = kwargs.get(\"radius\", 2)\n", + " nBits = kwargs.get(\"nBits\", 2048)\n", + " mfpgen = rdFingerprintGenerator.GetMorganGenerator(radius=radius, fpSize=nBits)\n", " fp = mfpgen.GetFingerprint(mol)\n", - " \n", - " elif fp_type == 'topological':\n", - " minPath = kwargs.get('minPath', 1)\n", - " maxPath = kwargs.get('maxPath', 7)\n", - " fpSize = kwargs.get('fpSize', 2048)\n", + "\n", + " elif fp_type == \"topological\":\n", + " minPath = kwargs.get(\"minPath\", 1)\n", + " maxPath = kwargs.get(\"maxPath\", 7)\n", + " fpSize = kwargs.get(\"fpSize\", 2048)\n", " fp = Chem.RDKFingerprint(mol, minPath=minPath, maxPath=maxPath, fpSize=fpSize)\n", - " \n", - " elif fp_type == 'maccs':\n", + "\n", + " elif fp_type == \"maccs\":\n", " fp = MACCSkeys.GenMACCSKeys(mol)\n", - " \n", - " elif fp_type == 'atompair':\n", - " nBits = kwargs.get('nBits', 2048)\n", + "\n", + " elif fp_type == \"atompair\":\n", + " nBits = kwargs.get(\"nBits\", 2048)\n", " fp = Pairs.GetAtomPairFingerprintAsBitVect(mol, nBits=nBits)\n", - " \n", + "\n", " else:\n", " raise ValueError(f\"Unknown fingerprint type: {fp_type}\")\n", - " \n", + "\n", " return fp.ToList()\n", "\n", "\n", @@ -426,7 +434,7 @@ "mod_sites = \"0;2;5\"\n", "\n", "smiles = encoder.peptide_to_smiles(sequence, mods, mod_sites)\n", - "np.array(get_fingerprint(Chem.MolFromSmiles(smiles), fp_type='topological')).shape" + "np.array(get_fingerprint(Chem.MolFromSmiles(smiles), fp_type=\"topological\")).shape" ] }, { @@ -561,7 +569,14 @@ ], "source": [ "for atom in mol.GetAtoms():\n", - " print(atom.GetSymbol(), atom.GetIdx(), atom.GetDegree(), atom.GetTotalNumHs(), atom.GetFormalCharge(), atom.GetIsAromatic())" + " print(\n", + " atom.GetSymbol(),\n", + " atom.GetIdx(),\n", + " atom.GetDegree(),\n", + " atom.GetTotalNumHs(),\n", + " atom.GetFormalCharge(),\n", + " atom.GetIsAromatic(),\n", + " )" ] } ], diff --git a/docs/nbs/psm_readers.ipynb b/docs/nbs/psm_readers.ipynb index 8a9458df..00d33bdf 100644 --- a/docs/nbs/psm_readers.ipynb +++ b/docs/nbs/psm_readers.ipynb @@ -1,1283 +1,1281 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# PSM readers" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "hide-cell" - ] - }, - "outputs": [], - "source": [ - "%reload_ext autoreload\n", - "%autoreload 2" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# Helper packages\n", - "import io\n", - "from copy import copy\n", - "import numpy as np\n", - "import pandas as pd \n", - "\n", - "# alphabase\n", - "from alphabase.psm_reader import psm_reader_provider, psm_reader_yaml" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Background \n", - "\n", - "The `alphabase.psm_reader` module provides a unifying interface to read PSM tables from different search engines and file formats. It is designed to be easy to use, and to provide a consistent output format in the form of `pandas.DataFrame`s, regardless of the input file format.\n", - "\n", - "### Introduction to peptide spectrum matches (PSMs)\n", - "\n", - "Peptide spectrum matches (PSMs) are the primary output of proteomics search engines. In a PSM table, each row typically represents a single peptide-spectrum-match, i.e. a peptide sequence that the proteomics search engine identified to be compatible with an observed mass spectrum in a given sample. PSM tables contain information about both 1) the *peptide sequence*, 2) the *spectrum*, as well as 3) the *score* assigned to the PSM by the search engine. \n", - "\n", - "A minimal PSM table could look something like this:\n", - "\n", - "| sample_id | peptide | confidence_score | scan_id |\n", - "|-------------|---------|-------| -------|\n", - "| 1 | PEPTIDE | 0.99 | 1234 |\n", - "\n", - "In this example, the search engine identified the peptide **PEPTIDE** as a match to the spectrum 1234 sample with `ID 1`, and assigned a confidence score of `0.99` to this match. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Search engine outputs\n", - "\n", - "In reality, PSM tables are significantly more complex than this, as they contain additional information on both the spectrum (e.g. the sample run, detector type, precursor intensities, ...), the peptide (e.g. the protein it belongs to, the modifications it carries), and the peptide search (quality control measures). This additional information can be extremely useful for downstream analyses, but also makes PSM tables more difficult to work with, as the exact names may differ between search engines, versions, and file formats. \n", - "\n", - "#### Unifying properties \n", - "\n", - "Alphabase aligns the column names to a unified vocabulary, as defined in the `alphabase.psm_reader.psm_reader_yaml` mapping. We can explore this standardization, that facilitates cross-engine comparisons. Note that some search engines use version-dependent names for the same property (indicated by lists) and alphabase can deal with this ambiguity. To support both Bruker and Thermo data, we did not use `Scan Number` in the output dataframe but `spec_idx` (starts with 0). `spec_idx = scan_num - 1` in thermo data. " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "tags": [ - "skip-execution" - ] - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Mapping of PSM columns to alphabase unified columns
alphabase (unified name)raw_namechargertmobilityproteinssequencescoreuniprot_idsgenesccsfdrscan_numdecoyprecursor_mzquery_idmodified_sequenceintensityrt_stoprt_startpeptide_fdrmodsfragment_intensityfragment_mzfragment_typefragment_chargefragment_seriesfragment_loss_typescannrspec_idxprotein_fdr
alphadiarunchargert_observedmobilityproteinssequencescoreuniprot_idsgenesccsfdrnannannannannanintensityrt_stoprt_startnanmodsnannannannannannannannannan
alphapeptraw_namechargertmobilitynannanscorenannannanq_valuescan_nodecoymzquery_idxnannannannannannannannannannannannannanraw_idxnan
diannRunPrecursor.ChargeRT['IM', 'IonMobility']Protein.NamesStripped.SequenceCScoreProtein.IdsGenesCCSQ.ValueMS2.ScannannannannannanRT.StopRT.Startnannannannannannannannannannannan
library_reader_baseReferenceRunPrecursorCharge['RT', 'iRT', 'Tr_recalibrated', 'RetentionTime', 'NormalizedRetentionTime']['Mobility', 'IonMobility', 'PrecursorIonMobility']['ProteinId', 'ProteinID', 'ProteinName', 'Protein Name']['PeptideSequence', 'StrippedPeptide']nan['UniProtIds', 'UniProtID', 'UniprotId']['GeneName', 'Genes', 'Gene']CCSnannannanPrecursorMznan['ModifiedPeptideSequence', 'ModifiedPeptide']nannannannannan['LibraryIntensity', 'RelativeIntensity', 'RelativeFragmentIntensity', 'RelativeFragmentIonIntensity']['ProductMz']['FragmentType', 'FragmentIonType', 'ProductType', 'ProductIonType']['FragmentCharge', 'FragmentIonCharge', 'ProductCharge', 'ProductIonCharge']['FragmentSeriesNumber', 'FragmentNumber']['FragmentLossType', 'FragmentIonLossType', 'ProductLossType', 'ProductIonLossType']nannannan
maxquantRaw fileChargeRetention time['Mobility', 'IonMobility', 'K0', '1/K0']ProteinsSequenceScorenan['Gene Names', 'Gene names']CCSnan['Scan number', 'MS/MS scan number', 'MS/MS Scan Number', 'Scan index']Reversem/znannanIntensitynannannannannannannannannannannannannan
msfragger_pepxmlraw_nameassumed_chargeretention_time_secion_mobilityproteinpeptideexpectnannannannanstart_scannannanspectrumnannannannannannannannannannannannannannannan
pfindraw_nameChargeRTnanProteinsSequenceFinal_ScoreProteinsnannanQ-valueScan_No['Target/Decoy', 'Targe/Decoy']nanFile_Namenannannannannannannannannannannannannannannan
sagefilenamechargertmobilityproteinsstripped_peptidesage_discriminant_scorenannannanspectrum_qnanis_decoynannanpeptidenannannanpeptide_qnannannannannannannanscannrnanprotein_q
spectronautReferenceRunPrecursorCharge['RT', 'iRT', 'Tr_recalibrated', 'RetentionTime', 'NormalizedRetentionTime']['Mobility', 'IonMobility', 'PrecursorIonMobility']['Protein Name', 'ProteinId', 'ProteinID', 'ProteinName', 'ProteinGroup', 'ProteinGroups']['StrippedPeptide', 'PeptideSequence']nan['UniProtIds', 'UniProtID', 'UniprotId']['Genes', 'Gene', 'GeneName', 'GeneNames']CCSnannannanPrecursorMznannannannannannannannannannannannannannannannan
spectronaut_reportR.FileNamecharge['EG.ApexRT', 'EG.MeanApexRT']['FG.ApexIonMobility']['PG.ProteinNames', 'PG.ProteinGroups']nannanPG.UniProtIdsPG.Genesnannannannannannannannannannannannannannannannannannannannannan
Missing0.0000000.0000000.0000000.1000000.1000000.2000000.3000000.4000000.4000000.5000000.5000000.5000000.6000000.6000000.7000000.8000000.8000000.8000000.8000000.9000000.9000000.9000000.9000000.9000000.9000000.9000000.9000000.9000000.9000000.900000
\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Generate a dataframe that maps the report-specific column names to the unified column names based on alphabase mapping\n", - "psm_column_mapping = (\n", - " pd.DataFrame.from_dict({\n", - " mapping.get(\"reader_type\", \"psm\"): mapping.get(\"column_mapping\", {}) for k, mapping in psm_reader_yaml.items() if k != \"modification_mappings\"\n", - " })\n", - " .T\n", - " .rename_axis(columns=\"alphabase (unified name)\")\n", - " )\n", - "\n", - "# Order by importance (number of search engines with corresponding column)\n", - "columns_ordered = psm_column_mapping.isna().mean(axis=0).sort_values(ascending=True)\n", - "psm_column_mapping = (\n", - " psm_column_mapping.loc[:, columns_ordered.index]\n", - " .sort_index(axis=0)\n", - " .dropna(how=\"all\", axis=1)\n", - ")\n", - "\n", - "# Compute summary\n", - "summary = (\n", - " psm_column_mapping\n", - " .agg([lambda x: x.isna().mean()])\n", - ")\n", - "\n", - "\n", - "\n", - "## Visualize the mapping of PSM columns to alphabase unified columns\n", - "# Stylize with pandas CSS class \n", - "headers = {\n", - " 'selector': 'th',#'th:not(.index_name)',\n", - " 'props': 'background-color: #18456d; color: white;'\n", - "}\n", - "cell_hover = { # for row hover use instead of \n", - " 'selector': 'td:hover',\n", - " 'props': [('background-color', '#ffffb3')]\n", - "}\n", - "index_names = {\n", - " 'selector': '.index_name',\n", - " 'props': 'font-style: italic; font-weight:bold; position: sticky'\n", - "}\n", - "\n", - "summary_row = {\"selector\": \"tbody tr:last-child\", \"props\": [(\"background-color\", \"#efefef\"), (\"font-weight\", \"bold\")]}\n", - "\n", - "caption = {\n", - " \"selector\": \"caption\",\n", - " \"props\": \"caption-side: top; font-style: italic; font-size: 12pt; text-align:left; margin-bottom: 10pt;\"\n", - "}\n", - "\n", - "# Visualize\n", - "psm_column_mapping_stylized = (\n", - " psm_column_mapping\n", - " .style\n", - "\n", - " .concat(\n", - " summary\n", - " .style\n", - " .relabel_index([\"Missing\"])\n", - " .bar(color='#cccccc', vmin=0, vmax=1)\n", - " )\n", - " .set_caption(\"Mapping of PSM columns to alphabase unified columns\")\n", - " .set_table_styles(\n", - " [headers, cell_hover, index_names, summary_row, caption]\n", - " )\n", - "\n", - ")\n", - "\n", - "psm_column_mapping_stylized" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Unifying peptide modifications \n", - "\n", - "Alphabase further unifies representations of peptide modifications between the different search engines to the community-driven unimod format.\n", - "\n", - "E.g. the MaxQuant-internal representations of phosphorylated serines are mapped to the unimod representation:\n", - "\n", - "| alphabase/UniMod | MaxQuant |\n", - "|------------------|----------|\n", - "| Phospho@S | S(Phospho (S)), S(Phospho (ST)), S(Phospho (STY)), S(Phospho (STYDH)), S(ph), pS |\n", - "\n", - "See `alphabase.psm_reader.psm_reader_yaml[\"modification_mappings\"]` for all mappings as parsed dictionaries and `alphabase.constants.const_files.psm_reader_yaml` for the underlying file." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Code | Read and parse PSM tables\n", - "\n", - "The alphabase `psm_reader` module enables users to parse proteomics PSM reports to a dataframe for most common search engines with a single line of code via its `alphabase.psm_reader.psm_reader_provider` factory. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Available readers \n", - "\n", - "`alphabase.psm_reader.psm_reader_provider` has registered some basic reader classes. A list of implemented readers can be accessed via its `reader_dict` property: " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Registered readers in alphabase:\n", - "\t- alphadia\n", - "\t- alphadia_parquet\n", - "\t- alphapept\n", - "\t- diann\n", - "\t- maxquant\n", - "\t- msfragger\n", - "\t- msfragger_pepxml\n", - "\t- msfragger_psm_tsv\n", - "\t- openswath\n", - "\t- pfind\n", - "\t- pfind3\n", - "\t- sage_parquet\n", - "\t- sage_tsv\n", - "\t- speclib_tsv\n", - "\t- spectronaut\n", - "\t- spectronaut_report\n", - "\t- swath\n" - ] - } - ], - "source": [ - "all_registered_readers = psm_reader_provider.reader_dict.keys()\n", - "\n", - "# Display all registered readers\n", - "sep = \"\\n\\t- \"\n", - "print(\"Registered readers in alphabase:\", sep.join(sorted(all_registered_readers)), sep=sep)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Interact with the reader provider" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Example 1 - MaxQuant\n", - "\n", - "We demonstrate how to interact with PSM tables via alphabase based on a minimal example output of the MaxQuant search engine. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, let's provide some minimal input, which is the header of a real MaxQuant report" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Raw fileScan numberScan indexSequenceLengthMissed cleavagesModificationsModified sequenceOxidation (M) ProbabilitiesOxidation (M) Score diffs...All sequencesAll modified sequencesReporter PIFReporter fractionidProtein group IDsPeptide IDMod. peptide IDEvidence IDOxidation (M) site IDs
020190402_QX1_SeVW_MA_HeLa_500ng_LC118135873979AAAAAAAAAPAAAATAPTTAATTAATAAQ290Unmodified_(Acetyl (Protein_N-term))AAAAAAAAM(Oxidation ...NaNNaN...AAAAAAAAAPAAAATAPTTAATTAATAAQ;FHRGPPDKDDMVSVTQ..._AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_FHRGPPDKDDMVS...NaNNaN01443000NaN
120190402_QX1_SeVW_MA_HeLa_500ng_LC118139174010AAAAAAAAAAPAAAATAPTTAATTAATAAQ290Unmodified_AAAAAAAAAPAAAATAPTTAATTAATAAQ_NaNNaN...AAAAAAAAAPAAAATAPTTAATTAATAAQ;SELKQEAMQSEQLQSV..._AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_SELKQEAM(Oxid...NaNNaN11443001NaN
220190402_QX1_SeVW_MA_HeLa_500ng_LC1110730798306AAAAAAAGDSDSWDADAFSVEDPVRK261Acetyl (Protein_N-term)_(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSV...NaNNaN...AAAAAAAGDSDSWDADAFSVEDPVRK;PSRQESELMWQWVDQRSDG..._(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSV...NaNNaN2625112NaN
\n", - "

3 rows × 61 columns

\n", - "
" - ], - "text/plain": [ - " Raw file Scan number Scan index \\\n", - "0 20190402_QX1_SeVW_MA_HeLa_500ng_LC11 81358 73979 \n", - "1 20190402_QX1_SeVW_MA_HeLa_500ng_LC11 81391 74010 \n", - "2 20190402_QX1_SeVW_MA_HeLa_500ng_LC11 107307 98306 \n", - "\n", - " Sequence Length Missed cleavages \\\n", - "0 AAAAAAAAAPAAAATAPTTAATTAATAAQ 29 0 \n", - "1 AAAAAAAAAAPAAAATAPTTAATTAATAAQ 29 0 \n", - "2 AAAAAAAGDSDSWDADAFSVEDPVRK 26 1 \n", - "\n", - " Modifications Modified sequence \\\n", - "0 Unmodified _(Acetyl (Protein_N-term))AAAAAAAAM(Oxidation ... \n", - "1 Unmodified _AAAAAAAAAPAAAATAPTTAATTAATAAQ_ \n", - "2 Acetyl (Protein_N-term) _(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSV... \n", - "\n", - " Oxidation (M) Probabilities Oxidation (M) Score diffs ... \\\n", - "0 NaN NaN ... \n", - "1 NaN NaN ... \n", - "2 NaN NaN ... \n", - "\n", - " All sequences \\\n", - "0 AAAAAAAAAPAAAATAPTTAATTAATAAQ;FHRGPPDKDDMVSVTQ... \n", - "1 AAAAAAAAAPAAAATAPTTAATTAATAAQ;SELKQEAMQSEQLQSV... \n", - "2 AAAAAAAGDSDSWDADAFSVEDPVRK;PSRQESELMWQWVDQRSDG... \n", - "\n", - " All modified sequences Reporter PIF \\\n", - "0 _AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_FHRGPPDKDDMVS... NaN \n", - "1 _AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_SELKQEAM(Oxid... NaN \n", - "2 _(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSV... NaN \n", - "\n", - " Reporter fraction id Protein group IDs Peptide ID Mod. peptide ID \\\n", - "0 NaN 0 1443 0 0 \n", - "1 NaN 1 1443 0 0 \n", - "2 NaN 2 625 1 1 \n", - "\n", - " Evidence ID Oxidation (M) site IDs \n", - "0 0 NaN \n", - "1 1 NaN \n", - "2 2 NaN \n", - "\n", - "[3 rows x 61 columns]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "maxquant_example = io.StringIO(\n", - "'''Raw file\tScan number\tScan index\tSequence\tLength\tMissed cleavages\tModifications\tModified sequence\tOxidation (M) Probabilities\tOxidation (M) Score diffs\tAcetyl (Protein_N-term)\tOxidation (M)\tProteins\tCharge\tFragmentation\tMass analyzer\tType\tScan event number\tIsotope index\tm/z\tMass\tMass error [ppm]\tMass error [Da]\tSimple mass error [ppm]\tRetention time\tPEP\tScore\tDelta score\tScore diff\tLocalization prob\tCombinatorics\tPIF\tFraction of total spectrum\tBase peak fraction\tPrecursor full scan number\tPrecursor Intensity\tPrecursor apex fraction\tPrecursor apex offset\tPrecursor apex offset time\tMatches\tIntensities\tMass deviations [Da]\tMass deviations [ppm]\tMasses\tNumber of matches\tIntensity coverage\tPeak coverage\tNeutral loss level\tETD identification type\tReverse\tAll scores\tAll sequences\tAll modified sequences\tReporter PIF\tReporter fraction\tid\tProtein group IDs\tPeptide ID\tMod. peptide ID\tEvidence ID\tOxidation (M) site IDs\n", - "20190402_QX1_SeVW_MA_HeLa_500ng_LC11\t81358\t73979\tAAAAAAAAAPAAAATAPTTAATTAATAAQ\t29\t0\tUnmodified\t_(Acetyl (Protein_N-term))AAAAAAAAM(Oxidation (M))PAAAATAPTTAATTAATAAQ_\t\t\t0\t0\tsp|P37108|SRP14_HUMAN\t3\tHCD\tFTMS\tMULTI-MSMS\t13\t1\t790.07495\t2367.203\t0.35311\t0.00027898\t-0.061634807\t70.261\t0.012774\t41.423\t36.666\tNaN\tNaN\t1\t0\t0\t0\t81345\t10653955\t0.0338597821787898\t-11\t0.139877319335938\ty1;y2;y3;y4;y11;y1-NH3;y2-NH3;a2;b2;b3;b4;b5;b6;b7;b8;b9;b11;b12;b6(2+);b8(2+);b13(2+);b18(2+)\t2000000;2000000;300000;400000;200000;1000000;400000;300000;600000;1000000;2000000;3000000;3000000;3000000;3000000;2000000;600000;500000;1000000;2000000;300000;200000\t5.2861228709844E-06;-6.86980268369553E-05;-0.00238178789771837;0.000624715964988809;-0.0145624692099773;-0.000143471782706683;-0.000609501446461991;-0.000524972720768346;0.00010190530804266;5.8620815195809E-05;0.000229901232955854;-0.000108750048696038;-0.000229593152369034;0.00183148682538103;0.00276641182404092;0.000193118923334623;0.00200988580445483;0.000102216846016745;5.86208151389656E-05;0.000229901232955854;-0.00104559184393338;0.00525030008475369\t0.0359413365445091;-0.314964433555295;-8.23711898839045;1.60102421155213;-14.8975999917227;-1.10320467763838;-3.03102462870716;-4.56152475051625;0.712219104095465;0.273777366204575;0.806231096969562;-0.305312183824154;-0.537399178230218;3.67572664689217;4.85930954169285;0.301587577451224;2.48616190909398;0.116225745519871;0.273777365939099;0.806231096969562;-2.19774169175011;7.53961026980589\t147.076413378177;218.113601150127;289.153028027798;390.197699998035;977.50437775671;130.050013034583;201.087592852046;115.087114392821;143.081402136892;214.118559209185;285.155501716567;356.192954155649;427.230188786552;498.265241494374;569.301420357176;640.341107437877;808.429168310795;879.468189767554;214.118559209185;285.155501716567;475.757386711244;696.362265007215\t22\t0.262893575628735\t0.0826446280991736\tNone\tUnknown\t\t41.4230894199432;4.75668724862449;3.9515580701967\tAAAAAAAAAPAAAATAPTTAATTAATAAQ;FHRGPPDKDDMVSVTQILQGK;PVTLWITVTHMQADEVSVWR\t_AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_FHRGPPDKDDMVSVTQILQGK_;_PVTLWITVTHMQADEVSVWR_\t\t\t0\t1443\t0\t0\t0\t\n", - "20190402_QX1_SeVW_MA_HeLa_500ng_LC11\t81391\t74010\tAAAAAAAAAAPAAAATAPTTAATTAATAAQ\t29\t0\tUnmodified\t_AAAAAAAAAPAAAATAPTTAATTAATAAQ_\t\t\t0\t0\tsp|P37108|SRP14_HUMAN\t2\tHCD\tFTMS\tMULTI-MSMS\t14\t0\t1184.6088\t2367.203\t0.037108\t4.3959E-05\t1.7026696\t70.287\t7.1474E-09\t118.21\t100.52\tNaN\tNaN\t1\t0\t0\t0\t81377\t9347701\t0.166790347889974\t-10\t0.12664794921875\ty1;y2;y3;y4;y5;y9;y12;y13;y14;y20;y13-H2O;y20-H2O;y1-NH3;y20-NH3;b3;b4;b5;b6;b7;b8;b9;b11;b12;b13;b14;b15;b16;b19;b15-H2O;b16-H2O\t500000;600000;200000;400000;200000;100000;200000;1000000;200000;300000;200000;100000;100000;70000;300000;900000;2000000;3000000;5000000;8000000;6000000;600000;800000;600000;200000;300000;200000;300000;300000;1000000\t-0.000194444760495571;0.000149986878682284;0.000774202587820128;-0.0002445094036716;0.000374520568641401;-0.00694293246522193;-0.0109837291331587;-0.0037745820627606;-0.000945546471939451;0.00152326440706929;0.00506054832726477;0.00996886361417637;6.25847393393997E-05;-0.024881067836759;-3.11821549132674E-05;-0.000183099230639527;0.000161332473453513;0.000265434980121881;0.000747070697229901;0.000975534518261156;0.00101513939785036;0.00651913000274362;0.0058584595163893;0.00579536744021425;0.00131097834105276;-0.0131378531671089;0.00472955218901916;-0.00161006322559842;-0.00201443239325272;0.0227149399370319\t-1.32206444236914;0.687655553213019;2.6775131607882;-0.626628140021726;0.811995006209331;-8.6203492854282;-10.1838066275079;-3.21078702288986;-0.758483069159249;0.881072738747222;4.37168212373889;5.82682888353564;0.481236695337485;-14.5343986203644;-0.145630261806375;-0.642102166533079;0.452935954800214;0.621293379181583;1.49934012872483;1.71355878380837;1.58531240493271;8.06399202403175;6.6614096214532;6.09718023739784;1.28333378040908;-11.7030234519348;3.96235146626144;-1.07856912288932;-1.82370619437775;19.3220953109188\t147.07661310906;218.113382465221;289.149872037312;390.198569223404;461.235063981231;805.411965958065;1078.54847749073;1175.59403219566;1246.62831694787;1728.87474561429;1157.57463237897;1710.85573532879;130.049806978061;1711.87460084504;214.118649012155;285.155914717031;356.192684073126;427.22969375842;498.266325910503;569.303211234482;640.340285417402;808.424659066597;879.462433524883;950.49961040476;1021.54120858166;1122.60333588727;1193.62258226971;1492.77704268533;1104.58164778019;1175.59403219566\t30\t0.474003002083763\t0.167630057803468\tNone\tUnknown\t\t118.209976573419;17.6937689289157;17.2534171481793\tAAAAAAAAAPAAAATAPTTAATTAATAAQ;SELKQEAMQSEQLQSVLYLK;VGSSVPSKASELVVMGDHDAARR\t_AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_SELKQEAM(Oxidation (M))QSEQLQSVLYLK_;_VGSSVPSKASELVVMGDHDAARR_\t\t\t1\t1443\t0\t0\t1\t\n", - "20190402_QX1_SeVW_MA_HeLa_500ng_LC11\t107307\t98306\tAAAAAAAGDSDSWDADAFSVEDPVRK\t26\t1\tAcetyl (Protein_N-term)\t_(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSVEDPVRK_\t\t\t1\t0\tsp|O75822|EIF3J_HUMAN\t3\tHCD\tFTMS\tMULTI-MSMS\t10\t2\t879.06841\t2634.1834\t-0.93926\t-0.00082567\t-3.2012471\t90.978\t2.1945E-12\t148.95\t141.24\tNaN\tNaN\t1\t0\t0\t0\t107297\t10193939\t0.267970762043589\t-8\t0.10211181640625\ty1;y2;y4;y5;y6;y7;y8;y9;y10;y11;y12;y13;y14;y15;y17;y18;y19;y20;y21;y23;y21-H2O;y1-NH3;y19-NH3;y14(2+);y16(2+);y22(2+);a2;b2;b3;b4;b5;b6;b7\t300000;200000;3000000;600000;1000000;500000;2000000;1000000;1000000;1000000;90000;1000000;400000;900000;1000000;400000;3000000;2000000;1000000;400000;100000;200000;200000;80000;100000;200000;200000;2000000;5000000;5000000;5000000;2000000;300000\t1.34859050149316E-07;-6.05140996867704E-06;2.27812602133781E-05;0.00128986659160546;-0.00934536073077652;0.000941953783126337;-0.00160424237344614;-0.00239257341399934;-0.00111053968612396;-0.00331340710044969;0.00330702864630439;0.000963683996815234;0.00596290290945944;-0.00662057038289277;-0.0117122701335575;0.00777853472800416;0.0021841542961738;0.000144322111736983;-0.00087403893667215;0.0197121595674616;-0.021204007680808;-0.000308954599830713;-0.026636719419912;-0.0137790992353075;0.00596067266928912;-0.0077053835773313;9.11402199221811E-06;-0.000142539300128419;-0.000251999832926231;1.90791054137662E-05;-0.00236430185879044;-9.54583337602344E-05;-0.000556959493223985\t0.000916705048437201;-0.0199575598103408;0.0456231928690862;2.09952637717462;-12.5708704058425;1.11808305811426;-1.72590731777249;-2.22239181008062;-0.967696370445928;-2.62418809422166;2.47964286628144;0.665205752892023;3.64753748704453;-3.84510115530963;-6.08782672045773;3.81508105974837;1.04209904973991;0.0666012719936656;-0.390545453668809;8.28224925531311;-9.55133250134922;-2.37499239179248;-12.8127653858411;-16.846761946123;6.48662354975264;-6.67117082062383;0.0580151981289049;-0.770098855873447;-0.983876895688683;0.0583162347158579;-5.93738717724506;-0.203431522818505;-1.03087538746314\t147.112804035741;303.21392125011;499.33507018564;614.360746132308;743.413974455831;842.472101057517;929.506675663573;1076.57587791081;1147.61170966489;1262.6408555643;1333.67134891635;1448.700635293;1634.77494902759;1721.81956091078;1923.88362405243;2038.89107627957;2095.9181343836;2166.95728800359;2237.99542015244;2380.04906152953;2220.00518543488;130.0865640237;2078.92040615582;817.907873297785;918.917619246831;1155.02717356753;157.097144992378;185.0922112678;256.129434516133;327.166277224995;398.205774393759;469.240619338034;540.278194626993\t33\t0.574496146107112\t0.14410480349345\tNone\tUnknown\t\t148.951235201399;7.71201258444522;7.36039532447559\tAAAAAAAGDSDSWDADAFSVEDPVRK;PSRQESELMWQWVDQRSDGER;HTLTSFWNFKAGCEEKCYSNR\t_(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSVEDPVRK_;_PSRQESELM(Oxidation (M))WQWVDQRSDGER_;_HTLTSFWNFKAGCEEKCYSNR_\t\t\t2\t625\t1\t1\t2\t'''\n", - ")\n", - "\n", - "# Parse with pandas for visualization purposes\n", - "pd.read_csv(copy(maxquant_example), sep=\"\\t\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Then use the `psm_reader_provider.get_reader` method to get the maxquant-report reader. Use the `import_file` method to read the file, which is directly returned as a pandas DataFrame. " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/lucas-diedrich/mamba/envs/alphabase/lib/python3.12/site-packages/alphabase/psm_reader/psm_reader.py:318: UserWarning: Unknown modifications: {'_(Acetyl (Protein_N-term))'}. Precursors with unknown modifications will be removed.\n", - " warnings.warn(\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
sequencechargertscan_numraw_nameprecursor_mzscoreproteinsdecoyspec_idxmodsmod_sitesnAArt_norm
0AAAAAAAAAAPAAAATAPTTAATTAATAAQ270.2878139120190402_QX1_SeVW_MA_HeLa_500ng_LC111184.6088118.21sp|P37108|SRP14_HUMAN081390300.772571
\n", - "
" - ], - "text/plain": [ - " sequence charge rt scan_num \\\n", - "0 AAAAAAAAAAPAAAATAPTTAATTAATAAQ 2 70.287 81391 \n", - "\n", - " raw_name precursor_mz score \\\n", - "0 20190402_QX1_SeVW_MA_HeLa_500ng_LC11 1184.6088 118.21 \n", - "\n", - " proteins decoy spec_idx mods mod_sites nAA rt_norm \n", - "0 sp|P37108|SRP14_HUMAN 0 81390 30 0.772571 " - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "maxquant_reader = psm_reader_provider.get_reader('maxquant')\n", - "\n", - "# Import the file or a bytestream\n", - "maxquant_report = maxquant_reader.import_file(maxquant_example)\n", - "\n", - "# The parsed PSM is also stored in the reader class as `psm_df` attribute\n", - "# maxquant_report = maxquant_reader.psm_df\n", - "\n", - "maxquant_report" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Example 2 - Set custom arguments \n", - "\n", - "One can also customize the reader by setting specific arguments. For example, one can set more stringent `fdr` filters (default: $fdr=0.01$). We showcase this on the example of a DIANN PSM report table." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
File.NameRunProtein.GroupProtein.IdsProtein.NamesGenesPG.QuantityPG.NormalisedPG.MaxLFQGenes.Quantity...Decoy.EvidenceDecoy.CScoreFragment.Quant.RawFragment.Quant.CorrectedFragment.CorrelationsMS2.ScanIMiIMPredicted.IMPredicted.iIM
0F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_...20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp...Q9UH36Q9UH36NaNSRRD3296.493428.893428.893296.49...1.236910.0000341212.01;2178.03;1390.01;1020.01;714.008;778.008;1212.01;1351.73;887.591;432.92;216.728;732.751;0.956668;0.757581;0.670497;0.592489;0.47072;0....300531.197081.193281.194531.19469
1F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_...20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp...Q9UH36Q9UH36NaNSRRD2365.002334.052334.052365.00...0.286330.0000021209.02;1210.02;1414.02;1051.01;236.003;130.002;1209.02;1109.89;732.154;735.384;0;46.0967;0.919244;0.937624;0.436748;0.639369;0.296736;0...300291.195001.193281.193811.19339
2F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_...20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp...Q9UH36Q9UH36NaNSRRD1664.511635.461635.471664.51...1.927530.000028744.01;1708.02;1630.02;1475.02;0;533.006;322.907;808.594;577.15;536.033;0;533.006;0.760181;0.764072;0.542005;0.415779;0;0.913438;300051.194091.193281.193231.19308
\n", - "

3 rows × 52 columns

\n", - "
" - ], - "text/plain": [ - " File.Name \\\n", - "0 F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_... \n", - "1 F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_... \n", - "2 F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_... \n", - "\n", - " Run Protein.Group \\\n", - "0 20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp... Q9UH36 \n", - "1 20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp... Q9UH36 \n", - "2 20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp... Q9UH36 \n", - "\n", - " Protein.Ids Protein.Names Genes PG.Quantity PG.Normalised PG.MaxLFQ \\\n", - "0 Q9UH36 NaN SRRD 3296.49 3428.89 3428.89 \n", - "1 Q9UH36 NaN SRRD 2365.00 2334.05 2334.05 \n", - "2 Q9UH36 NaN SRRD 1664.51 1635.46 1635.47 \n", - "\n", - " Genes.Quantity ... Decoy.Evidence Decoy.CScore \\\n", - "0 3296.49 ... 1.23691 0.000034 \n", - "1 2365.00 ... 0.28633 0.000002 \n", - "2 1664.51 ... 1.92753 0.000028 \n", - "\n", - " Fragment.Quant.Raw \\\n", - "0 1212.01;2178.03;1390.01;1020.01;714.008;778.008; \n", - "1 1209.02;1210.02;1414.02;1051.01;236.003;130.002; \n", - "2 744.01;1708.02;1630.02;1475.02;0;533.006; \n", - "\n", - " Fragment.Quant.Corrected \\\n", - "0 1212.01;1351.73;887.591;432.92;216.728;732.751; \n", - "1 1209.02;1109.89;732.154;735.384;0;46.0967; \n", - "2 322.907;808.594;577.15;536.033;0;533.006; \n", - "\n", - " Fragment.Correlations MS2.Scan IM \\\n", - "0 0.956668;0.757581;0.670497;0.592489;0.47072;0.... 30053 1.19708 \n", - "1 0.919244;0.937624;0.436748;0.639369;0.296736;0... 30029 1.19500 \n", - "2 0.760181;0.764072;0.542005;0.415779;0;0.913438; 30005 1.19409 \n", - "\n", - " iIM Predicted.IM Predicted.iIM \n", - "0 1.19328 1.19453 1.19469 \n", - "1 1.19328 1.19381 1.19339 \n", - "2 1.19328 1.19323 1.19308 \n", - "\n", - "[3 rows x 52 columns]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "diann_tsv_example = io.StringIO(r'''File.Name\tRun\tProtein.Group\tProtein.Ids\tProtein.Names\tGenes\tPG.Quantity\tPG.Normalised\tPG.MaxLFQ\tGenes.Quantity\tGenes.Normalised\tGenes.MaxLFQ\tGenes.MaxLFQ.Unique\tModified.Sequence\tStripped.Sequence\tPrecursor.Id\tPrecursor.Charge\tQ.Value\tGlobal.Q.Value\tProtein.Q.Value\tPG.Q.Value\tGlobal.PG.Q.Value\tGG.Q.Value\tTranslated.Q.Value\tProteotypic\tPrecursor.Quantity\tPrecursor.Normalised\tPrecursor.Translated\tQuantity.Quality\tRT\tRT.Start\tRT.Stop\tiRT\tPredicted.RT\tPredicted.iRT\tLib.Q.Value\tMs1.Profile.Corr\tMs1.Area\tEvidence\tSpectrum.Similarity\tMass.Evidence\tCScore\tDecoy.Evidence\tDecoy.CScore\tFragment.Quant.Raw\tFragment.Quant.Corrected\tFragment.Correlations\tMS2.Scan\tIM\tiIM\tPredicted.IM\tPredicted.iIM\n", - "F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-A2_1_22636.d\t20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-A2_1_22636\tQ9UH36\tQ9UH36\t\tSRRD\t3296.49\t3428.89\t3428.89\t3296.49\t3428.89\t3428.89\t3428.89\t(UniMod:1)AAAAAAALESWQAAAPR\tAAAAAAALESWQAAAPR\t(UniMod:1)AAAAAAALESWQAAAPR2\t2\t3.99074e-05\t1.96448e-05\t0.000159821\t0.000159821\t0.000146135\t0.000161212\t0\t1\t3296.49\t3428.89\t3296.49\t0.852479\t19.9208\t19.8731\t19.9685\t123.9\t19.8266\t128.292\t0\t0.960106\t5308.05\t1.96902\t0.683134\t0.362287\t0.999997\t1.23691\t3.43242e-05\t1212.01;2178.03;1390.01;1020.01;714.008;778.008;\t1212.01;1351.73;887.591;432.92;216.728;732.751;\t0.956668;0.757581;0.670497;0.592489;0.47072;0.855203;\t30053\t1.19708\t1.19328\t1.19453\t1.19469\n", - "F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-A8_1_22642.d\t20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-A8_1_22642\tQ9UH36\tQ9UH36\t\tSRRD\t2365\t2334.05\t2334.05\t2365\t2334.05\t2334.05\t2334.05\t(UniMod:1)AAAAAAALESWQAAAPR\tAAAAAAALESWQAAAPR\t(UniMod:1)AAAAAAALESWQAAAPR2\t2\t0.000184434\t1.96448e-05\t0.000596659\t0.000596659\t0.000146135\t0.000604961\t0\t1\t2365\t2334.05\t2365\t0.922581\t19.905\t19.8573\t19.9527\t123.9\t19.782\t128.535\t0\t0.940191\t4594.04\t1.31068\t0.758988\t0\t0.995505\t0.28633\t2.12584e-06\t1209.02;1210.02;1414.02;1051.01;236.003;130.002;\t1209.02;1109.89;732.154;735.384;0;46.0967;\t0.919244;0.937624;0.436748;0.639369;0.296736;0.647924;\t30029\t1.195\t1.19328\t1.19381\t1.19339\n", - "F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-B2_1_22648.d\t20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-B2_1_22648\tQ9UH36\tQ9UH36\t\tSRRD\t1664.51\t1635.46\t1635.47\t1664.51\t1635.46\t1635.47\t1635.47\t(UniMod:1)AAAAAAALESWQAAAPR\tAAAAAAALESWQAAAPR\t(UniMod:1)AAAAAAALESWQAAAPR2\t2\t0.000185123\t1.96448e-05\t0.000307409\t0.000307409\t0.000146135\t0.000311332\t0\t1\t1664.51\t1635.46\t1664.51\t0.811147\t19.8893\t19.8416\t19.937\t123.9\t19.7567\t128.896\t0\t0.458773\t6614.06\t1.7503\t0.491071\t0.00111683\t0.997286\t1.92753\t2.80543e-05\t744.01;1708.02;1630.02;1475.02;0;533.006;\t322.907;808.594;577.15;536.033;0;533.006;\t0.760181;0.764072;0.542005;0.415779;0;0.913438;\t30005\t1.19409\t1.19328\t1.19323\t1.19308\n", - "''')\n", - "\n", - "pd.read_csv(copy(diann_tsv_example), sep=\"\\t\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "By passing the more stringent `fdr` filter ($fdr_{\\text{stringent}} = 10^{-4}$) in the second function call, two precursors with an fdr of $\\sim0.0002$ are removed from the resulting table" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of observations (Standard filter): 3\n", - "Number of observations (Stringent filter): 1\n" - ] - } - ], - "source": [ - "# Read PSM reports with one liners\n", - "diann_psm_standard = psm_reader_provider.get_reader('diann').import_file(copy(diann_tsv_example))\n", - "diann_psm_custom_fdr = psm_reader_provider.get_reader('diann', fdr=1e-4).import_file(copy(diann_tsv_example))\n", - "\n", - "print(\"Number of observations (Standard filter):\", len(diann_psm_standard))\n", - "print(\"Number of observations (Stringent filter):\", len(diann_psm_custom_fdr))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion\n", - "\n", - "Overall, this tutorial \n", - "\n", - "- Explained how `alphabase` maps different search engine outputs to a unified format\n", - "- Provides examples on how to read PSM tables from different search engines\n", - "- Gives an overview over the available and implemented readers" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.9" - } + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# PSM readers" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [ + "hide-cell" + ] + }, + "outputs": [], + "source": [ + "%reload_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Helper packages\n", + "import io\n", + "from copy import copy\n", + "\n", + "import pandas as pd\n", + "\n", + "# alphabase\n", + "from alphabase.psm_reader import psm_reader_provider, psm_reader_yaml" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Background \n", + "\n", + "The `alphabase.psm_reader` module provides a unifying interface to read PSM tables from different search engines and file formats. It is designed to be easy to use, and to provide a consistent output format in the form of `pandas.DataFrame`s, regardless of the input file format.\n", + "\n", + "### Introduction to peptide spectrum matches (PSMs)\n", + "\n", + "Peptide spectrum matches (PSMs) are the primary output of proteomics search engines. In a PSM table, each row typically represents a single peptide-spectrum-match, i.e. a peptide sequence that the proteomics search engine identified to be compatible with an observed mass spectrum in a given sample. PSM tables contain information about both 1) the *peptide sequence*, 2) the *spectrum*, as well as 3) the *score* assigned to the PSM by the search engine. \n", + "\n", + "A minimal PSM table could look something like this:\n", + "\n", + "| sample_id | peptide | confidence_score | scan_id |\n", + "|-------------|---------|-------| -------|\n", + "| 1 | PEPTIDE | 0.99 | 1234 |\n", + "\n", + "In this example, the search engine identified the peptide **PEPTIDE** as a match to the spectrum 1234 sample with `ID 1`, and assigned a confidence score of `0.99` to this match. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Search engine outputs\n", + "\n", + "In reality, PSM tables are significantly more complex than this, as they contain additional information on both the spectrum (e.g. the sample run, detector type, precursor intensities, ...), the peptide (e.g. the protein it belongs to, the modifications it carries), and the peptide search (quality control measures). This additional information can be extremely useful for downstream analyses, but also makes PSM tables more difficult to work with, as the exact names may differ between search engines, versions, and file formats. \n", + "\n", + "#### Unifying properties \n", + "\n", + "Alphabase aligns the column names to a unified vocabulary, as defined in the `alphabase.psm_reader.psm_reader_yaml` mapping. We can explore this standardization, that facilitates cross-engine comparisons. Note that some search engines use version-dependent names for the same property (indicated by lists) and alphabase can deal with this ambiguity. To support both Bruker and Thermo data, we did not use `Scan Number` in the output dataframe but `spec_idx` (starts with 0). `spec_idx = scan_num - 1` in thermo data. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "skip-execution" + ] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Mapping of PSM columns to alphabase unified columns
alphabase (unified name)raw_namechargertmobilityproteinssequencescoreuniprot_idsgenesccsfdrscan_numdecoyprecursor_mzquery_idmodified_sequenceintensityrt_stoprt_startpeptide_fdrmodsfragment_intensityfragment_mzfragment_typefragment_chargefragment_seriesfragment_loss_typescannrspec_idxprotein_fdr
alphadiarunchargert_observedmobilityproteinssequencescoreuniprot_idsgenesccsfdrnannannannannanintensityrt_stoprt_startnanmodsnannannannannannannannannan
alphapeptraw_namechargertmobilitynannanscorenannannanq_valuescan_nodecoymzquery_idxnannannannannannannannannannannannannanraw_idxnan
diannRunPrecursor.ChargeRT['IM', 'IonMobility']Protein.NamesStripped.SequenceCScoreProtein.IdsGenesCCSQ.ValueMS2.ScannannannannannanRT.StopRT.Startnannannannannannannannannannannan
library_reader_baseReferenceRunPrecursorCharge['RT', 'iRT', 'Tr_recalibrated', 'RetentionTime', 'NormalizedRetentionTime']['Mobility', 'IonMobility', 'PrecursorIonMobility']['ProteinId', 'ProteinID', 'ProteinName', 'Protein Name']['PeptideSequence', 'StrippedPeptide']nan['UniProtIds', 'UniProtID', 'UniprotId']['GeneName', 'Genes', 'Gene']CCSnannannanPrecursorMznan['ModifiedPeptideSequence', 'ModifiedPeptide']nannannannannan['LibraryIntensity', 'RelativeIntensity', 'RelativeFragmentIntensity', 'RelativeFragmentIonIntensity']['ProductMz']['FragmentType', 'FragmentIonType', 'ProductType', 'ProductIonType']['FragmentCharge', 'FragmentIonCharge', 'ProductCharge', 'ProductIonCharge']['FragmentSeriesNumber', 'FragmentNumber']['FragmentLossType', 'FragmentIonLossType', 'ProductLossType', 'ProductIonLossType']nannannan
maxquantRaw fileChargeRetention time['Mobility', 'IonMobility', 'K0', '1/K0']ProteinsSequenceScorenan['Gene Names', 'Gene names']CCSnan['Scan number', 'MS/MS scan number', 'MS/MS Scan Number', 'Scan index']Reversem/znannanIntensitynannannannannannannannannannannannannan
msfragger_pepxmlraw_nameassumed_chargeretention_time_secion_mobilityproteinpeptideexpectnannannannanstart_scannannanspectrumnannannannannannannannannannannannannannannan
pfindraw_nameChargeRTnanProteinsSequenceFinal_ScoreProteinsnannanQ-valueScan_No['Target/Decoy', 'Targe/Decoy']nanFile_Namenannannannannannannannannannannannannannannan
sagefilenamechargertmobilityproteinsstripped_peptidesage_discriminant_scorenannannanspectrum_qnanis_decoynannanpeptidenannannanpeptide_qnannannannannannannanscannrnanprotein_q
spectronautReferenceRunPrecursorCharge['RT', 'iRT', 'Tr_recalibrated', 'RetentionTime', 'NormalizedRetentionTime']['Mobility', 'IonMobility', 'PrecursorIonMobility']['Protein Name', 'ProteinId', 'ProteinID', 'ProteinName', 'ProteinGroup', 'ProteinGroups']['StrippedPeptide', 'PeptideSequence']nan['UniProtIds', 'UniProtID', 'UniprotId']['Genes', 'Gene', 'GeneName', 'GeneNames']CCSnannannanPrecursorMznannannannannannannannannannannannannannannannan
spectronaut_reportR.FileNamecharge['EG.ApexRT', 'EG.MeanApexRT']['FG.ApexIonMobility']['PG.ProteinNames', 'PG.ProteinGroups']nannanPG.UniProtIdsPG.Genesnannannannannannannannannannannannannannannannannannannannannan
Missing0.0000000.0000000.0000000.1000000.1000000.2000000.3000000.4000000.4000000.5000000.5000000.5000000.6000000.6000000.7000000.8000000.8000000.8000000.8000000.9000000.9000000.9000000.9000000.9000000.9000000.9000000.9000000.9000000.9000000.900000
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Generate a dataframe that maps the report-specific column names to the unified column names based on alphabase mapping\n", + "psm_column_mapping = pd.DataFrame.from_dict(\n", + " {\n", + " mapping.get(\"reader_type\", \"psm\"): mapping.get(\"column_mapping\", {})\n", + " for k, mapping in psm_reader_yaml.items()\n", + " if k != \"modification_mappings\"\n", + " }\n", + ").T.rename_axis(columns=\"alphabase (unified name)\")\n", + "\n", + "# Order by importance (number of search engines with corresponding column)\n", + "columns_ordered = psm_column_mapping.isna().mean(axis=0).sort_values(ascending=True)\n", + "psm_column_mapping = (\n", + " psm_column_mapping.loc[:, columns_ordered.index]\n", + " .sort_index(axis=0)\n", + " .dropna(how=\"all\", axis=1)\n", + ")\n", + "\n", + "# Compute summary\n", + "summary = psm_column_mapping.agg([lambda x: x.isna().mean()])\n", + "\n", + "\n", + "## Visualize the mapping of PSM columns to alphabase unified columns\n", + "# Stylize with pandas CSS class\n", + "headers = {\n", + " \"selector\": \"th\", #'th:not(.index_name)',\n", + " \"props\": \"background-color: #18456d; color: white;\",\n", + "}\n", + "cell_hover = { # for row hover use instead of \n", + " \"selector\": \"td:hover\",\n", + " \"props\": [(\"background-color\", \"#ffffb3\")],\n", + "}\n", + "index_names = {\n", + " \"selector\": \".index_name\",\n", + " \"props\": \"font-style: italic; font-weight:bold; position: sticky\",\n", + "}\n", + "\n", + "summary_row = {\n", + " \"selector\": \"tbody tr:last-child\",\n", + " \"props\": [(\"background-color\", \"#efefef\"), (\"font-weight\", \"bold\")],\n", + "}\n", + "\n", + "caption = {\n", + " \"selector\": \"caption\",\n", + " \"props\": \"caption-side: top; font-style: italic; font-size: 12pt; text-align:left; margin-bottom: 10pt;\",\n", + "}\n", + "\n", + "# Visualize\n", + "psm_column_mapping_stylized = (\n", + " psm_column_mapping.style.concat(\n", + " summary.style.relabel_index([\"Missing\"]).bar(color=\"#cccccc\", vmin=0, vmax=1)\n", + " )\n", + " .set_caption(\"Mapping of PSM columns to alphabase unified columns\")\n", + " .set_table_styles([headers, cell_hover, index_names, summary_row, caption])\n", + ")\n", + "\n", + "psm_column_mapping_stylized" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Unifying peptide modifications \n", + "\n", + "Alphabase further unifies representations of peptide modifications between the different search engines to the community-driven unimod format.\n", + "\n", + "E.g. the MaxQuant-internal representations of phosphorylated serines are mapped to the unimod representation:\n", + "\n", + "| alphabase/UniMod | MaxQuant |\n", + "|------------------|----------|\n", + "| Phospho@S | S(Phospho (S)), S(Phospho (ST)), S(Phospho (STY)), S(Phospho (STYDH)), S(ph), pS |\n", + "\n", + "See `alphabase.psm_reader.psm_reader_yaml[\"modification_mappings\"]` for all mappings as parsed dictionaries and `alphabase.constants.const_files.psm_reader_yaml` for the underlying file." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code | Read and parse PSM tables\n", + "\n", + "The alphabase `psm_reader` module enables users to parse proteomics PSM reports to a dataframe for most common search engines with a single line of code via its `alphabase.psm_reader.psm_reader_provider` factory. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Available readers \n", + "\n", + "`alphabase.psm_reader.psm_reader_provider` has registered some basic reader classes. A list of implemented readers can be accessed via its `reader_dict` property: " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Registered readers in alphabase:\n", + "\t- alphadia\n", + "\t- alphadia_parquet\n", + "\t- alphapept\n", + "\t- diann\n", + "\t- maxquant\n", + "\t- msfragger\n", + "\t- msfragger_pepxml\n", + "\t- msfragger_psm_tsv\n", + "\t- openswath\n", + "\t- pfind\n", + "\t- pfind3\n", + "\t- sage_parquet\n", + "\t- sage_tsv\n", + "\t- speclib_tsv\n", + "\t- spectronaut\n", + "\t- spectronaut_report\n", + "\t- swath\n" + ] + } + ], + "source": [ + "all_registered_readers = psm_reader_provider.reader_dict.keys()\n", + "\n", + "# Display all registered readers\n", + "sep = \"\\n\\t- \"\n", + "print(\n", + " \"Registered readers in alphabase:\",\n", + " sep.join(sorted(all_registered_readers)),\n", + " sep=sep,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Interact with the reader provider" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Example 1 - MaxQuant\n", + "\n", + "We demonstrate how to interact with PSM tables via alphabase based on a minimal example output of the MaxQuant search engine. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, let's provide some minimal input, which is the header of a real MaxQuant report" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Raw fileScan numberScan indexSequenceLengthMissed cleavagesModificationsModified sequenceOxidation (M) ProbabilitiesOxidation (M) Score diffs...All sequencesAll modified sequencesReporter PIFReporter fractionidProtein group IDsPeptide IDMod. peptide IDEvidence IDOxidation (M) site IDs
020190402_QX1_SeVW_MA_HeLa_500ng_LC118135873979AAAAAAAAAPAAAATAPTTAATTAATAAQ290Unmodified_(Acetyl (Protein_N-term))AAAAAAAAM(Oxidation ...NaNNaN...AAAAAAAAAPAAAATAPTTAATTAATAAQ;FHRGPPDKDDMVSVTQ..._AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_FHRGPPDKDDMVS...NaNNaN01443000NaN
120190402_QX1_SeVW_MA_HeLa_500ng_LC118139174010AAAAAAAAAAPAAAATAPTTAATTAATAAQ290Unmodified_AAAAAAAAAPAAAATAPTTAATTAATAAQ_NaNNaN...AAAAAAAAAPAAAATAPTTAATTAATAAQ;SELKQEAMQSEQLQSV..._AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_SELKQEAM(Oxid...NaNNaN11443001NaN
220190402_QX1_SeVW_MA_HeLa_500ng_LC1110730798306AAAAAAAGDSDSWDADAFSVEDPVRK261Acetyl (Protein_N-term)_(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSV...NaNNaN...AAAAAAAGDSDSWDADAFSVEDPVRK;PSRQESELMWQWVDQRSDG..._(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSV...NaNNaN2625112NaN
\n", + "

3 rows × 61 columns

\n", + "
" + ], + "text/plain": [ + " Raw file Scan number Scan index \\\n", + "0 20190402_QX1_SeVW_MA_HeLa_500ng_LC11 81358 73979 \n", + "1 20190402_QX1_SeVW_MA_HeLa_500ng_LC11 81391 74010 \n", + "2 20190402_QX1_SeVW_MA_HeLa_500ng_LC11 107307 98306 \n", + "\n", + " Sequence Length Missed cleavages \\\n", + "0 AAAAAAAAAPAAAATAPTTAATTAATAAQ 29 0 \n", + "1 AAAAAAAAAAPAAAATAPTTAATTAATAAQ 29 0 \n", + "2 AAAAAAAGDSDSWDADAFSVEDPVRK 26 1 \n", + "\n", + " Modifications Modified sequence \\\n", + "0 Unmodified _(Acetyl (Protein_N-term))AAAAAAAAM(Oxidation ... \n", + "1 Unmodified _AAAAAAAAAPAAAATAPTTAATTAATAAQ_ \n", + "2 Acetyl (Protein_N-term) _(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSV... \n", + "\n", + " Oxidation (M) Probabilities Oxidation (M) Score diffs ... \\\n", + "0 NaN NaN ... \n", + "1 NaN NaN ... \n", + "2 NaN NaN ... \n", + "\n", + " All sequences \\\n", + "0 AAAAAAAAAPAAAATAPTTAATTAATAAQ;FHRGPPDKDDMVSVTQ... \n", + "1 AAAAAAAAAPAAAATAPTTAATTAATAAQ;SELKQEAMQSEQLQSV... \n", + "2 AAAAAAAGDSDSWDADAFSVEDPVRK;PSRQESELMWQWVDQRSDG... \n", + "\n", + " All modified sequences Reporter PIF \\\n", + "0 _AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_FHRGPPDKDDMVS... NaN \n", + "1 _AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_SELKQEAM(Oxid... NaN \n", + "2 _(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSV... NaN \n", + "\n", + " Reporter fraction id Protein group IDs Peptide ID Mod. peptide ID \\\n", + "0 NaN 0 1443 0 0 \n", + "1 NaN 1 1443 0 0 \n", + "2 NaN 2 625 1 1 \n", + "\n", + " Evidence ID Oxidation (M) site IDs \n", + "0 0 NaN \n", + "1 1 NaN \n", + "2 2 NaN \n", + "\n", + "[3 rows x 61 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "maxquant_example = io.StringIO(\n", + " \"\"\"Raw file\tScan number\tScan index\tSequence\tLength\tMissed cleavages\tModifications\tModified sequence\tOxidation (M) Probabilities\tOxidation (M) Score diffs\tAcetyl (Protein_N-term)\tOxidation (M)\tProteins\tCharge\tFragmentation\tMass analyzer\tType\tScan event number\tIsotope index\tm/z\tMass\tMass error [ppm]\tMass error [Da]\tSimple mass error [ppm]\tRetention time\tPEP\tScore\tDelta score\tScore diff\tLocalization prob\tCombinatorics\tPIF\tFraction of total spectrum\tBase peak fraction\tPrecursor full scan number\tPrecursor Intensity\tPrecursor apex fraction\tPrecursor apex offset\tPrecursor apex offset time\tMatches\tIntensities\tMass deviations [Da]\tMass deviations [ppm]\tMasses\tNumber of matches\tIntensity coverage\tPeak coverage\tNeutral loss level\tETD identification type\tReverse\tAll scores\tAll sequences\tAll modified sequences\tReporter PIF\tReporter fraction\tid\tProtein group IDs\tPeptide ID\tMod. peptide ID\tEvidence ID\tOxidation (M) site IDs\n", + "20190402_QX1_SeVW_MA_HeLa_500ng_LC11\t81358\t73979\tAAAAAAAAAPAAAATAPTTAATTAATAAQ\t29\t0\tUnmodified\t_(Acetyl (Protein_N-term))AAAAAAAAM(Oxidation (M))PAAAATAPTTAATTAATAAQ_\t\t\t0\t0\tsp|P37108|SRP14_HUMAN\t3\tHCD\tFTMS\tMULTI-MSMS\t13\t1\t790.07495\t2367.203\t0.35311\t0.00027898\t-0.061634807\t70.261\t0.012774\t41.423\t36.666\tNaN\tNaN\t1\t0\t0\t0\t81345\t10653955\t0.0338597821787898\t-11\t0.139877319335938\ty1;y2;y3;y4;y11;y1-NH3;y2-NH3;a2;b2;b3;b4;b5;b6;b7;b8;b9;b11;b12;b6(2+);b8(2+);b13(2+);b18(2+)\t2000000;2000000;300000;400000;200000;1000000;400000;300000;600000;1000000;2000000;3000000;3000000;3000000;3000000;2000000;600000;500000;1000000;2000000;300000;200000\t5.2861228709844E-06;-6.86980268369553E-05;-0.00238178789771837;0.000624715964988809;-0.0145624692099773;-0.000143471782706683;-0.000609501446461991;-0.000524972720768346;0.00010190530804266;5.8620815195809E-05;0.000229901232955854;-0.000108750048696038;-0.000229593152369034;0.00183148682538103;0.00276641182404092;0.000193118923334623;0.00200988580445483;0.000102216846016745;5.86208151389656E-05;0.000229901232955854;-0.00104559184393338;0.00525030008475369\t0.0359413365445091;-0.314964433555295;-8.23711898839045;1.60102421155213;-14.8975999917227;-1.10320467763838;-3.03102462870716;-4.56152475051625;0.712219104095465;0.273777366204575;0.806231096969562;-0.305312183824154;-0.537399178230218;3.67572664689217;4.85930954169285;0.301587577451224;2.48616190909398;0.116225745519871;0.273777365939099;0.806231096969562;-2.19774169175011;7.53961026980589\t147.076413378177;218.113601150127;289.153028027798;390.197699998035;977.50437775671;130.050013034583;201.087592852046;115.087114392821;143.081402136892;214.118559209185;285.155501716567;356.192954155649;427.230188786552;498.265241494374;569.301420357176;640.341107437877;808.429168310795;879.468189767554;214.118559209185;285.155501716567;475.757386711244;696.362265007215\t22\t0.262893575628735\t0.0826446280991736\tNone\tUnknown\t\t41.4230894199432;4.75668724862449;3.9515580701967\tAAAAAAAAAPAAAATAPTTAATTAATAAQ;FHRGPPDKDDMVSVTQILQGK;PVTLWITVTHMQADEVSVWR\t_AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_FHRGPPDKDDMVSVTQILQGK_;_PVTLWITVTHMQADEVSVWR_\t\t\t0\t1443\t0\t0\t0\t\n", + "20190402_QX1_SeVW_MA_HeLa_500ng_LC11\t81391\t74010\tAAAAAAAAAAPAAAATAPTTAATTAATAAQ\t29\t0\tUnmodified\t_AAAAAAAAAPAAAATAPTTAATTAATAAQ_\t\t\t0\t0\tsp|P37108|SRP14_HUMAN\t2\tHCD\tFTMS\tMULTI-MSMS\t14\t0\t1184.6088\t2367.203\t0.037108\t4.3959E-05\t1.7026696\t70.287\t7.1474E-09\t118.21\t100.52\tNaN\tNaN\t1\t0\t0\t0\t81377\t9347701\t0.166790347889974\t-10\t0.12664794921875\ty1;y2;y3;y4;y5;y9;y12;y13;y14;y20;y13-H2O;y20-H2O;y1-NH3;y20-NH3;b3;b4;b5;b6;b7;b8;b9;b11;b12;b13;b14;b15;b16;b19;b15-H2O;b16-H2O\t500000;600000;200000;400000;200000;100000;200000;1000000;200000;300000;200000;100000;100000;70000;300000;900000;2000000;3000000;5000000;8000000;6000000;600000;800000;600000;200000;300000;200000;300000;300000;1000000\t-0.000194444760495571;0.000149986878682284;0.000774202587820128;-0.0002445094036716;0.000374520568641401;-0.00694293246522193;-0.0109837291331587;-0.0037745820627606;-0.000945546471939451;0.00152326440706929;0.00506054832726477;0.00996886361417637;6.25847393393997E-05;-0.024881067836759;-3.11821549132674E-05;-0.000183099230639527;0.000161332473453513;0.000265434980121881;0.000747070697229901;0.000975534518261156;0.00101513939785036;0.00651913000274362;0.0058584595163893;0.00579536744021425;0.00131097834105276;-0.0131378531671089;0.00472955218901916;-0.00161006322559842;-0.00201443239325272;0.0227149399370319\t-1.32206444236914;0.687655553213019;2.6775131607882;-0.626628140021726;0.811995006209331;-8.6203492854282;-10.1838066275079;-3.21078702288986;-0.758483069159249;0.881072738747222;4.37168212373889;5.82682888353564;0.481236695337485;-14.5343986203644;-0.145630261806375;-0.642102166533079;0.452935954800214;0.621293379181583;1.49934012872483;1.71355878380837;1.58531240493271;8.06399202403175;6.6614096214532;6.09718023739784;1.28333378040908;-11.7030234519348;3.96235146626144;-1.07856912288932;-1.82370619437775;19.3220953109188\t147.07661310906;218.113382465221;289.149872037312;390.198569223404;461.235063981231;805.411965958065;1078.54847749073;1175.59403219566;1246.62831694787;1728.87474561429;1157.57463237897;1710.85573532879;130.049806978061;1711.87460084504;214.118649012155;285.155914717031;356.192684073126;427.22969375842;498.266325910503;569.303211234482;640.340285417402;808.424659066597;879.462433524883;950.49961040476;1021.54120858166;1122.60333588727;1193.62258226971;1492.77704268533;1104.58164778019;1175.59403219566\t30\t0.474003002083763\t0.167630057803468\tNone\tUnknown\t\t118.209976573419;17.6937689289157;17.2534171481793\tAAAAAAAAAPAAAATAPTTAATTAATAAQ;SELKQEAMQSEQLQSVLYLK;VGSSVPSKASELVVMGDHDAARR\t_AAAAAAAAAPAAAATAPTTAATTAATAAQ_;_SELKQEAM(Oxidation (M))QSEQLQSVLYLK_;_VGSSVPSKASELVVMGDHDAARR_\t\t\t1\t1443\t0\t0\t1\t\n", + "20190402_QX1_SeVW_MA_HeLa_500ng_LC11\t107307\t98306\tAAAAAAAGDSDSWDADAFSVEDPVRK\t26\t1\tAcetyl (Protein_N-term)\t_(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSVEDPVRK_\t\t\t1\t0\tsp|O75822|EIF3J_HUMAN\t3\tHCD\tFTMS\tMULTI-MSMS\t10\t2\t879.06841\t2634.1834\t-0.93926\t-0.00082567\t-3.2012471\t90.978\t2.1945E-12\t148.95\t141.24\tNaN\tNaN\t1\t0\t0\t0\t107297\t10193939\t0.267970762043589\t-8\t0.10211181640625\ty1;y2;y4;y5;y6;y7;y8;y9;y10;y11;y12;y13;y14;y15;y17;y18;y19;y20;y21;y23;y21-H2O;y1-NH3;y19-NH3;y14(2+);y16(2+);y22(2+);a2;b2;b3;b4;b5;b6;b7\t300000;200000;3000000;600000;1000000;500000;2000000;1000000;1000000;1000000;90000;1000000;400000;900000;1000000;400000;3000000;2000000;1000000;400000;100000;200000;200000;80000;100000;200000;200000;2000000;5000000;5000000;5000000;2000000;300000\t1.34859050149316E-07;-6.05140996867704E-06;2.27812602133781E-05;0.00128986659160546;-0.00934536073077652;0.000941953783126337;-0.00160424237344614;-0.00239257341399934;-0.00111053968612396;-0.00331340710044969;0.00330702864630439;0.000963683996815234;0.00596290290945944;-0.00662057038289277;-0.0117122701335575;0.00777853472800416;0.0021841542961738;0.000144322111736983;-0.00087403893667215;0.0197121595674616;-0.021204007680808;-0.000308954599830713;-0.026636719419912;-0.0137790992353075;0.00596067266928912;-0.0077053835773313;9.11402199221811E-06;-0.000142539300128419;-0.000251999832926231;1.90791054137662E-05;-0.00236430185879044;-9.54583337602344E-05;-0.000556959493223985\t0.000916705048437201;-0.0199575598103408;0.0456231928690862;2.09952637717462;-12.5708704058425;1.11808305811426;-1.72590731777249;-2.22239181008062;-0.967696370445928;-2.62418809422166;2.47964286628144;0.665205752892023;3.64753748704453;-3.84510115530963;-6.08782672045773;3.81508105974837;1.04209904973991;0.0666012719936656;-0.390545453668809;8.28224925531311;-9.55133250134922;-2.37499239179248;-12.8127653858411;-16.846761946123;6.48662354975264;-6.67117082062383;0.0580151981289049;-0.770098855873447;-0.983876895688683;0.0583162347158579;-5.93738717724506;-0.203431522818505;-1.03087538746314\t147.112804035741;303.21392125011;499.33507018564;614.360746132308;743.413974455831;842.472101057517;929.506675663573;1076.57587791081;1147.61170966489;1262.6408555643;1333.67134891635;1448.700635293;1634.77494902759;1721.81956091078;1923.88362405243;2038.89107627957;2095.9181343836;2166.95728800359;2237.99542015244;2380.04906152953;2220.00518543488;130.0865640237;2078.92040615582;817.907873297785;918.917619246831;1155.02717356753;157.097144992378;185.0922112678;256.129434516133;327.166277224995;398.205774393759;469.240619338034;540.278194626993\t33\t0.574496146107112\t0.14410480349345\tNone\tUnknown\t\t148.951235201399;7.71201258444522;7.36039532447559\tAAAAAAAGDSDSWDADAFSVEDPVRK;PSRQESELMWQWVDQRSDGER;HTLTSFWNFKAGCEEKCYSNR\t_(Acetyl (Protein_N-term))AAAAAAAGDSDSWDADAFSVEDPVRK_;_PSRQESELM(Oxidation (M))WQWVDQRSDGER_;_HTLTSFWNFKAGCEEKCYSNR_\t\t\t2\t625\t1\t1\t2\t\"\"\"\n", + ")\n", + "\n", + "# Parse with pandas for visualization purposes\n", + "pd.read_csv(copy(maxquant_example), sep=\"\\t\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then use the `psm_reader_provider.get_reader` method to get the maxquant-report reader. Use the `import_file` method to read the file, which is directly returned as a pandas DataFrame. " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/lucas-diedrich/mamba/envs/alphabase/lib/python3.12/site-packages/alphabase/psm_reader/psm_reader.py:318: UserWarning: Unknown modifications: {'_(Acetyl (Protein_N-term))'}. Precursors with unknown modifications will be removed.\n", + " warnings.warn(\n" + ] }, - "nbformat": 4, - "nbformat_minor": 4 + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
sequencechargertscan_numraw_nameprecursor_mzscoreproteinsdecoyspec_idxmodsmod_sitesnAArt_norm
0AAAAAAAAAAPAAAATAPTTAATTAATAAQ270.2878139120190402_QX1_SeVW_MA_HeLa_500ng_LC111184.6088118.21sp|P37108|SRP14_HUMAN081390300.772571
\n", + "
" + ], + "text/plain": [ + " sequence charge rt scan_num \\\n", + "0 AAAAAAAAAAPAAAATAPTTAATTAATAAQ 2 70.287 81391 \n", + "\n", + " raw_name precursor_mz score \\\n", + "0 20190402_QX1_SeVW_MA_HeLa_500ng_LC11 1184.6088 118.21 \n", + "\n", + " proteins decoy spec_idx mods mod_sites nAA rt_norm \n", + "0 sp|P37108|SRP14_HUMAN 0 81390 30 0.772571 " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "maxquant_reader = psm_reader_provider.get_reader(\"maxquant\")\n", + "\n", + "# Import the file or a bytestream\n", + "maxquant_report = maxquant_reader.import_file(maxquant_example)\n", + "\n", + "# The parsed PSM is also stored in the reader class as `psm_df` attribute\n", + "# maxquant_report = maxquant_reader.psm_df\n", + "\n", + "maxquant_report" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Example 2 - Set custom arguments \n", + "\n", + "One can also customize the reader by setting specific arguments. For example, one can set more stringent `fdr` filters (default: $fdr=0.01$). We showcase this on the example of a DIANN PSM report table." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
File.NameRunProtein.GroupProtein.IdsProtein.NamesGenesPG.QuantityPG.NormalisedPG.MaxLFQGenes.Quantity...Decoy.EvidenceDecoy.CScoreFragment.Quant.RawFragment.Quant.CorrectedFragment.CorrelationsMS2.ScanIMiIMPredicted.IMPredicted.iIM
0F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_...20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp...Q9UH36Q9UH36NaNSRRD3296.493428.893428.893296.49...1.236910.0000341212.01;2178.03;1390.01;1020.01;714.008;778.008;1212.01;1351.73;887.591;432.92;216.728;732.751;0.956668;0.757581;0.670497;0.592489;0.47072;0....300531.197081.193281.194531.19469
1F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_...20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp...Q9UH36Q9UH36NaNSRRD2365.002334.052334.052365.00...0.286330.0000021209.02;1210.02;1414.02;1051.01;236.003;130.002;1209.02;1109.89;732.154;735.384;0;46.0967;0.919244;0.937624;0.436748;0.639369;0.296736;0...300291.195001.193281.193811.19339
2F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_...20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp...Q9UH36Q9UH36NaNSRRD1664.511635.461635.471664.51...1.927530.000028744.01;1708.02;1630.02;1475.02;0;533.006;322.907;808.594;577.15;536.033;0;533.006;0.760181;0.764072;0.542005;0.415779;0;0.913438;300051.194091.193281.193231.19308
\n", + "

3 rows × 52 columns

\n", + "
" + ], + "text/plain": [ + " File.Name \\\n", + "0 F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_... \n", + "1 F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_... \n", + "2 F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_... \n", + "\n", + " Run Protein.Group \\\n", + "0 20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp... Q9UH36 \n", + "1 20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp... Q9UH36 \n", + "2 20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_sp... Q9UH36 \n", + "\n", + " Protein.Ids Protein.Names Genes PG.Quantity PG.Normalised PG.MaxLFQ \\\n", + "0 Q9UH36 NaN SRRD 3296.49 3428.89 3428.89 \n", + "1 Q9UH36 NaN SRRD 2365.00 2334.05 2334.05 \n", + "2 Q9UH36 NaN SRRD 1664.51 1635.46 1635.47 \n", + "\n", + " Genes.Quantity ... Decoy.Evidence Decoy.CScore \\\n", + "0 3296.49 ... 1.23691 0.000034 \n", + "1 2365.00 ... 0.28633 0.000002 \n", + "2 1664.51 ... 1.92753 0.000028 \n", + "\n", + " Fragment.Quant.Raw \\\n", + "0 1212.01;2178.03;1390.01;1020.01;714.008;778.008; \n", + "1 1209.02;1210.02;1414.02;1051.01;236.003;130.002; \n", + "2 744.01;1708.02;1630.02;1475.02;0;533.006; \n", + "\n", + " Fragment.Quant.Corrected \\\n", + "0 1212.01;1351.73;887.591;432.92;216.728;732.751; \n", + "1 1209.02;1109.89;732.154;735.384;0;46.0967; \n", + "2 322.907;808.594;577.15;536.033;0;533.006; \n", + "\n", + " Fragment.Correlations MS2.Scan IM \\\n", + "0 0.956668;0.757581;0.670497;0.592489;0.47072;0.... 30053 1.19708 \n", + "1 0.919244;0.937624;0.436748;0.639369;0.296736;0... 30029 1.19500 \n", + "2 0.760181;0.764072;0.542005;0.415779;0;0.913438; 30005 1.19409 \n", + "\n", + " iIM Predicted.IM Predicted.iIM \n", + "0 1.19328 1.19453 1.19469 \n", + "1 1.19328 1.19381 1.19339 \n", + "2 1.19328 1.19323 1.19308 \n", + "\n", + "[3 rows x 52 columns]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diann_tsv_example = io.StringIO(r\"\"\"File.Name\tRun\tProtein.Group\tProtein.Ids\tProtein.Names\tGenes\tPG.Quantity\tPG.Normalised\tPG.MaxLFQ\tGenes.Quantity\tGenes.Normalised\tGenes.MaxLFQ\tGenes.MaxLFQ.Unique\tModified.Sequence\tStripped.Sequence\tPrecursor.Id\tPrecursor.Charge\tQ.Value\tGlobal.Q.Value\tProtein.Q.Value\tPG.Q.Value\tGlobal.PG.Q.Value\tGG.Q.Value\tTranslated.Q.Value\tProteotypic\tPrecursor.Quantity\tPrecursor.Normalised\tPrecursor.Translated\tQuantity.Quality\tRT\tRT.Start\tRT.Stop\tiRT\tPredicted.RT\tPredicted.iRT\tLib.Q.Value\tMs1.Profile.Corr\tMs1.Area\tEvidence\tSpectrum.Similarity\tMass.Evidence\tCScore\tDecoy.Evidence\tDecoy.CScore\tFragment.Quant.Raw\tFragment.Quant.Corrected\tFragment.Correlations\tMS2.Scan\tIM\tiIM\tPredicted.IM\tPredicted.iIM\n", + "F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-A2_1_22636.d\t20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-A2_1_22636\tQ9UH36\tQ9UH36\t\tSRRD\t3296.49\t3428.89\t3428.89\t3296.49\t3428.89\t3428.89\t3428.89\t(UniMod:1)AAAAAAALESWQAAAPR\tAAAAAAALESWQAAAPR\t(UniMod:1)AAAAAAALESWQAAAPR2\t2\t3.99074e-05\t1.96448e-05\t0.000159821\t0.000159821\t0.000146135\t0.000161212\t0\t1\t3296.49\t3428.89\t3296.49\t0.852479\t19.9208\t19.8731\t19.9685\t123.9\t19.8266\t128.292\t0\t0.960106\t5308.05\t1.96902\t0.683134\t0.362287\t0.999997\t1.23691\t3.43242e-05\t1212.01;2178.03;1390.01;1020.01;714.008;778.008;\t1212.01;1351.73;887.591;432.92;216.728;732.751;\t0.956668;0.757581;0.670497;0.592489;0.47072;0.855203;\t30053\t1.19708\t1.19328\t1.19453\t1.19469\n", + "F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-A8_1_22642.d\t20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-A8_1_22642\tQ9UH36\tQ9UH36\t\tSRRD\t2365\t2334.05\t2334.05\t2365\t2334.05\t2334.05\t2334.05\t(UniMod:1)AAAAAAALESWQAAAPR\tAAAAAAALESWQAAAPR\t(UniMod:1)AAAAAAALESWQAAAPR2\t2\t0.000184434\t1.96448e-05\t0.000596659\t0.000596659\t0.000146135\t0.000604961\t0\t1\t2365\t2334.05\t2365\t0.922581\t19.905\t19.8573\t19.9527\t123.9\t19.782\t128.535\t0\t0.940191\t4594.04\t1.31068\t0.758988\t0\t0.995505\t0.28633\t2.12584e-06\t1209.02;1210.02;1414.02;1051.01;236.003;130.002;\t1209.02;1109.89;732.154;735.384;0;46.0967;\t0.919244;0.937624;0.436748;0.639369;0.296736;0.647924;\t30029\t1.195\t1.19328\t1.19381\t1.19339\n", + "F:\\XXX\\20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-B2_1_22648.d\t20201218_tims03_Evo03_PS_SA_HeLa_200ng_high_speed_21min_8cm_S2-B2_1_22648\tQ9UH36\tQ9UH36\t\tSRRD\t1664.51\t1635.46\t1635.47\t1664.51\t1635.46\t1635.47\t1635.47\t(UniMod:1)AAAAAAALESWQAAAPR\tAAAAAAALESWQAAAPR\t(UniMod:1)AAAAAAALESWQAAAPR2\t2\t0.000185123\t1.96448e-05\t0.000307409\t0.000307409\t0.000146135\t0.000311332\t0\t1\t1664.51\t1635.46\t1664.51\t0.811147\t19.8893\t19.8416\t19.937\t123.9\t19.7567\t128.896\t0\t0.458773\t6614.06\t1.7503\t0.491071\t0.00111683\t0.997286\t1.92753\t2.80543e-05\t744.01;1708.02;1630.02;1475.02;0;533.006;\t322.907;808.594;577.15;536.033;0;533.006;\t0.760181;0.764072;0.542005;0.415779;0;0.913438;\t30005\t1.19409\t1.19328\t1.19323\t1.19308\n", + "\"\"\")\n", + "\n", + "pd.read_csv(copy(diann_tsv_example), sep=\"\\t\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By passing the more stringent `fdr` filter ($fdr_{\\text{stringent}} = 10^{-4}$) in the second function call, two precursors with an fdr of $\\sim0.0002$ are removed from the resulting table" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of observations (Standard filter): 3\n", + "Number of observations (Stringent filter): 1\n" + ] + } + ], + "source": [ + "# Read PSM reports with one liners\n", + "diann_psm_standard = psm_reader_provider.get_reader(\"diann\").import_file(\n", + " copy(diann_tsv_example)\n", + ")\n", + "diann_psm_custom_fdr = psm_reader_provider.get_reader(\"diann\", fdr=1e-4).import_file(\n", + " copy(diann_tsv_example)\n", + ")\n", + "\n", + "print(\"Number of observations (Standard filter):\", len(diann_psm_standard))\n", + "print(\"Number of observations (Stringent filter):\", len(diann_psm_custom_fdr))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusion\n", + "\n", + "Overall, this tutorial \n", + "\n", + "- Explained how `alphabase` maps different search engine outputs to a unified format\n", + "- Provides examples on how to read PSM tables from different search engines\n", + "- Gives an overview over the available and implemented readers" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 } diff --git a/docs/nbs/tutorial_smiles.ipynb b/docs/nbs/tutorial_smiles.ipynb index d8227475..92d36ced 100644 --- a/docs/nbs/tutorial_smiles.ipynb +++ b/docs/nbs/tutorial_smiles.ipynb @@ -28,7 +28,6 @@ "\n", "from alphabase.smiles.smiles import AminoAcidModifier\n", "\n", - "\n", "aa_modifier = AminoAcidModifier()\n", "modify_amino_acid = aa_modifier.modify_amino_acid\n", "aa_smiles = aa_modifier.aa_smiles\n", @@ -164,7 +163,7 @@ ], "source": [ "print(\"Available N-terminal modifications:\")\n", - "for mod in n_term_modifications.keys():\n", + "for mod in n_term_modifications:\n", " print(f\"- {mod}\")\n", "\n", "# Let's visualize one of these modifications, e.g., Biotin\n", diff --git a/docs/tutorials/tutorial_basic_definitions.ipynb b/docs/tutorials/tutorial_basic_definitions.ipynb index 6c482983..1fbc3279 100644 --- a/docs/tutorials/tutorial_basic_definitions.ipynb +++ b/docs/tutorials/tutorial_basic_definitions.ipynb @@ -172,8 +172,10 @@ ], "source": [ "import pandas as pd\n", + "\n", "from alphabase.constants.atom import CHEM_INFO_DICT\n", - "pd.DataFrame().from_dict(CHEM_INFO_DICT, orient='index')" + "\n", + "pd.DataFrame().from_dict(CHEM_INFO_DICT, orient=\"index\")" ] }, { @@ -297,7 +299,8 @@ ], "source": [ "from alphabase.constants.atom import CHEM_MONO_MASS\n", - "pd.DataFrame().from_dict(CHEM_MONO_MASS, orient='index')" + "\n", + "pd.DataFrame().from_dict(CHEM_MONO_MASS, orient=\"index\")" ] }, { @@ -342,9 +345,8 @@ } ], "source": [ - "from alphabase.constants.atom import (\n", - " MASS_PROTON, MASS_ISOTOPE, MASS_NH3, MASS_H2O\n", - ")\n", + "from alphabase.constants.atom import MASS_H2O, MASS_ISOTOPE, MASS_NH3, MASS_PROTON\n", + "\n", "MASS_PROTON, MASS_ISOTOPE, MASS_NH3, MASS_H2O" ] }, @@ -650,7 +652,8 @@ ], "source": [ "from alphabase.constants.aa import AA_DF\n", - "AA_DF.loc[ord('A'):ord('Z')]" + "\n", + "AA_DF.loc[ord(\"A\") : ord(\"Z\")]" ] }, { @@ -690,7 +693,7 @@ "source": [ "import numpy as np\n", "\n", - "np.array(['ABCXYZ']).view(np.int32)" + "np.array([\"ABCXYZ\"]).view(np.int32)" ] }, { @@ -741,11 +744,8 @@ ], "source": [ "from alphabase.constants.aa import calc_AA_masses_for_same_len_seqs\n", - "calc_AA_masses_for_same_len_seqs(\n", - " [\n", - " 'MACDEFG', 'MAKDEFG', 'MAKDEFR'\n", - " ]\n", - ")" + "\n", + "calc_AA_masses_for_same_len_seqs([\"MACDEFG\", \"MAKDEFG\", \"MAKDEFR\"])" ] }, { @@ -782,10 +782,8 @@ ], "source": [ "from alphabase.constants.aa import calc_AA_masses_for_var_len_seqs\n", - "calc_AA_masses_for_var_len_seqs(\n", - " [\n", - " 'M', 'MAK', 'MAKDEFR'\n", - " ])" + "\n", + "calc_AA_masses_for_var_len_seqs([\"M\", \"MAK\", \"MAKDEFR\"])" ] }, { @@ -1145,6 +1143,7 @@ ], "source": [ "from alphabase.constants.modification import MOD_DF\n", + "\n", "MOD_DF" ] }, @@ -1189,14 +1188,10 @@ "from alphabase.constants.modification import calc_modification_mass\n", "\n", "# example: add two modifications and print the array of mass modifications\n", - "sequence = 'MACDEFG'\n", - "mod_names = ['Acetyl@Any_N-term', 'Carbamidomethyl@C']\n", - "mod_sites = [0, 3] # 0 for N-term, 3 for the third amino acid\n", - "calc_modification_mass(\n", - " nAA=len(sequence),\n", - " mod_names=mod_names,\n", - " mod_sites=mod_sites\n", - ")" + "sequence = \"MACDEFG\"\n", + "mod_names = [\"Acetyl@Any_N-term\", \"Carbamidomethyl@C\"]\n", + "mod_sites = [0, 3] # 0 for N-term, 3 for the third amino acid\n", + "calc_modification_mass(nAA=len(sequence), mod_names=mod_names, mod_sites=mod_sites)" ] }, { @@ -1229,14 +1224,10 @@ ], "source": [ "# example: add two modifications and print the array of mass modifications\n", - "sequence = 'MAKDEFG'\n", - "mod_names = ['Acetyl@Any_N-term', 'Oxidation@M']\n", - "mod_sites = [0, 1] # 0 for N-term, 1 for the first amino acid\n", - "calc_modification_mass(\n", - " nAA=len(sequence),\n", - " mod_names=mod_names,\n", - " mod_sites=mod_sites\n", - ")" + "sequence = \"MAKDEFG\"\n", + "mod_names = [\"Acetyl@Any_N-term\", \"Oxidation@M\"]\n", + "mod_sites = [0, 1] # 0 for N-term, 1 for the first amino acid\n", + "calc_modification_mass(nAA=len(sequence), mod_names=mod_names, mod_sites=mod_sites)" ] }, { @@ -1275,14 +1266,10 @@ } ], "source": [ - "sequence = 'MAKDEFR'\n", - "mod_names = ['GG@K', 'Dimethyl@K']\n", + "sequence = \"MAKDEFR\"\n", + "mod_names = [\"GG@K\", \"Dimethyl@K\"]\n", "mod_sites = [3, 3]\n", - "calc_modification_mass(\n", - " nAA=len(sequence),\n", - " mod_names=mod_names,\n", - " mod_sites=mod_sites\n", - ")" + "calc_modification_mass(nAA=len(sequence), mod_names=mod_names, mod_sites=mod_sites)" ] }, { @@ -1326,18 +1313,19 @@ ], "source": [ "from alphabase.constants.modification import calc_mod_masses_for_same_len_seqs\n", + "\n", "calc_mod_masses_for_same_len_seqs(\n", " nAA=7,\n", " mod_names_list=[\n", - " ['Acetyl@Any_N-term', 'Carbamidomethyl@C'],\n", - " ['Acetyl@Any_N-term', 'Oxidation@M'],\n", - " ['GG@K', 'Dimethyl@K'],\n", + " [\"Acetyl@Any_N-term\", \"Carbamidomethyl@C\"],\n", + " [\"Acetyl@Any_N-term\", \"Oxidation@M\"],\n", + " [\"GG@K\", \"Dimethyl@K\"],\n", " ],\n", " mod_sites_list=[\n", " [0, 3],\n", " [0, 1],\n", " [3, 3],\n", - " ]\n", + " ],\n", ")" ] }, @@ -1390,25 +1378,22 @@ "source": [ "from alphabase.constants.aa import calc_AA_masses_for_same_len_seqs\n", "from alphabase.constants.modification import calc_mod_masses_for_same_len_seqs\n", + "\n", "mod_masses = calc_mod_masses_for_same_len_seqs(\n", " nAA=7,\n", " mod_names_list=[\n", - " ['Acetyl@Any_N-term', 'Carbamidomethyl@C'],\n", - " ['Acetyl@Any_N-term', 'Oxidation@M'],\n", - " ['GG@K', 'Dimethyl@K'],\n", + " [\"Acetyl@Any_N-term\", \"Carbamidomethyl@C\"],\n", + " [\"Acetyl@Any_N-term\", \"Oxidation@M\"],\n", + " [\"GG@K\", \"Dimethyl@K\"],\n", " ],\n", " mod_sites_list=[\n", " [0, 3],\n", " [0, 1],\n", " [3, 3],\n", - " ]\n", - ")\n", - "aa_masses = calc_AA_masses_for_same_len_seqs(\n", - " [\n", - " 'MACDEFG', 'MAKDEFG', 'MAKDEFR'\n", - " ]\n", + " ],\n", ")\n", - "mod_masses+aa_masses" + "aa_masses = calc_AA_masses_for_same_len_seqs([\"MACDEFG\", \"MAKDEFG\", \"MAKDEFR\"])\n", + "mod_masses + aa_masses" ] }, { @@ -1452,7 +1437,8 @@ ], "source": [ "import numpy as np\n", - "np.cumsum(aa_masses+mod_masses, axis=1)" + "\n", + "np.cumsum(aa_masses + mod_masses, axis=1)" ] }, { @@ -1495,11 +1481,11 @@ "from alphabase.peptide.mass_calc import calc_peptide_masses_for_same_len_seqs\n", "\n", "peptide_masses = calc_peptide_masses_for_same_len_seqs(\n", - " ['MACDEFG', 'MAKDEFG', 'MAKDEFR'],\n", + " [\"MACDEFG\", \"MAKDEFG\", \"MAKDEFR\"],\n", " mod_list=[\n", - " 'Acetyl@Any_N-term;Carbamidomethyl@C',\n", - " 'Acetyl@Any_N-term;Oxidation@M',\n", - " 'GG@K;Dimethyl@K',\n", + " \"Acetyl@Any_N-term;Carbamidomethyl@C\",\n", + " \"Acetyl@Any_N-term;Oxidation@M\",\n", + " \"GG@K;Dimethyl@K\",\n", " ],\n", ")\n", "peptide_masses" @@ -1534,12 +1520,13 @@ ], "source": [ "from alphabase.peptide.mass_calc import calc_b_y_and_peptide_masses_for_same_len_seqs\n", + "\n", "b_masses, y_masses, peptide_masses = calc_b_y_and_peptide_masses_for_same_len_seqs(\n", - " ['MACDEFG', 'MAKDEFG', 'MAKDEFR'],\n", + " [\"MACDEFG\", \"MAKDEFG\", \"MAKDEFR\"],\n", " mod_list=[\n", - " ['Acetyl@Any_N-term', 'Carbamidomethyl@C'],\n", - " ['Acetyl@Any_N-term', 'Oxidation@M'],\n", - " ['GG@K', 'Dimethyl@K'],\n", + " [\"Acetyl@Any_N-term\", \"Carbamidomethyl@C\"],\n", + " [\"Acetyl@Any_N-term\", \"Oxidation@M\"],\n", + " [\"GG@K\", \"Dimethyl@K\"],\n", " ],\n", " site_list=[\n", " [0, 3],\n", @@ -1789,14 +1776,18 @@ ], "source": [ "import pandas as pd\n", + "\n", "from alphabase.constants.atom import CHEM_INFO_DICT\n", - "atom_df = pd.DataFrame().from_dict(CHEM_INFO_DICT, orient='index')\n", + "\n", + "atom_df = pd.DataFrame().from_dict(CHEM_INFO_DICT, orient=\"index\")\n", + "\n", + "\n", "def get_mono(masses_abundances):\n", " masses, abundances = masses_abundances\n", - " return round(masses[np.argmax(abundances)]-masses[0])\n", - "atom_df['mono_idx'] = atom_df[['mass','abundance']].apply(\n", - " get_mono, axis=1\n", - ")\n", + " return round(masses[np.argmax(abundances)] - masses[0])\n", + "\n", + "\n", + "atom_df[\"mono_idx\"] = atom_df[[\"mass\", \"abundance\"]].apply(get_mono, axis=1)\n", "atom_df" ] }, @@ -1845,7 +1836,7 @@ } ], "source": [ - "atom_df.loc['Fe']" + "atom_df.loc[\"Fe\"]" ] }, { @@ -1887,10 +1878,9 @@ ], "source": [ "from alphabase.constants.isotope import IsotopeDistribution, parse_formula\n", + "\n", "iso = IsotopeDistribution()\n", - "iso.calc_formula_distribution(\n", - " [('C',1),('Fe',1)]\n", - ")" + "iso.calc_formula_distribution([(\"C\", 1), (\"Fe\", 1)])" ] }, { @@ -1931,9 +1921,7 @@ } ], "source": [ - "iso.calc_formula_distribution(\n", - " [('13C',1),('Fe',1)]\n", - ")" + "iso.calc_formula_distribution([(\"13C\", 1), (\"Fe\", 1)])" ] }, { @@ -1974,10 +1962,11 @@ } ], "source": [ - "from alphabase.constants.isotope import IsotopeDistribution, parse_formula\n", + "from alphabase.constants.isotope import IsotopeDistribution\n", + "\n", "iso = IsotopeDistribution()\n", "\n", - "formula = 'C(50)H(50)O(20)Na(1)'\n", + "formula = \"C(50)H(50)O(20)Na(1)\"\n", "formula = parse_formula(formula)\n", "dist, mono = iso.calc_formula_distribution(formula)\n", "f\"mono={mono}, highest={dist.argmax()}\", dist" @@ -2014,7 +2003,7 @@ } ], "source": [ - "formula = 'C(100)H(100)O(20)Na(1)'\n", + "formula = \"C(100)H(100)O(20)Na(1)\"\n", "formula = parse_formula(formula)\n", "dist, mono = iso.calc_formula_distribution(formula)\n", "f\"mono={mono}, highest={dist.argmax()}\", dist" @@ -2050,7 +2039,7 @@ } ], "source": [ - "formula = 'C(200)H(200)O(40)Na(1)'\n", + "formula = \"C(200)H(200)O(40)Na(1)\"\n", "formula = parse_formula(formula)\n", "dist, mono = iso.calc_formula_distribution(formula)\n", "f\"mono={mono}, highest={dist.argmax()}\", dist" diff --git a/docs/tutorials/tutorial_dataframe_structures.ipynb b/docs/tutorials/tutorial_dataframe_structures.ipynb index 14a59423..dfe164e1 100644 --- a/docs/tutorials/tutorial_dataframe_structures.ipynb +++ b/docs/tutorials/tutorial_dataframe_structures.ipynb @@ -12,8 +12,8 @@ ] }, { - "metadata": {}, "cell_type": "markdown", + "metadata": {}, "source": "![peptide-fragment-dataframe](peptide-fragment-dataframe.png)" }, { @@ -33,33 +33,16 @@ }, { "cell_type": "code", + "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2025-01-30T14:18:22.109951Z", "start_time": "2025-01-30T14:18:22.089583Z" } }, - "source": [ - "import pandas as pd\n", - "import numpy as np\n", - "\n", - "peptide_df = pd.DataFrame({\n", - " 'sequence': ['ACDEFHIK', 'APDEFMNIK', 'WDSEFMNTIRAAAAKDDDDR'],\n", - " 'mods': ['Carbamidomethyl@C', '', 'Phospho@S;Oxidation@M'],\n", - " 'mod_sites': ['2', '', '3;6'],\n", - " 'charge': [1,2,3],\n", - "})\n", - "peptide_df" - ], "outputs": [ { "data": { - "text/plain": [ - " sequence mods mod_sites charge\n", - "0 ACDEFHIK Carbamidomethyl@C 2 1\n", - "1 APDEFMNIK 2\n", - "2 WDSEFMNTIRAAAAKDDDDR Phospho@S;Oxidation@M 3;6 3" - ], "text/html": [ "
\n", "