Skip to content

Commit 4f00a7e

Browse files
Merge pull request #452 from MannLabs/fix/psm-nan-handling-2_adapt-reader
[fix] Adapt search engine-specific PSM readers to new convention in `_load_file`
2 parents f558ef6 + 7925228 commit 4f00a7e

6 files changed

Lines changed: 17 additions & 13 deletions

File tree

‎alphabase/psm_reader/maxquant_reader.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,13 @@ def __init__( # noqa: PLR0913, D417 # too many arguments in function definition
240240
def _pre_process(self, df: pd.DataFrame) -> pd.DataFrame:
241241
"""MaxQuant-specific preprocessing of output data."""
242242
df = df[~pd.isna(df["Retention time"])]
243-
df.fillna("", inplace=True)
244243

245244
# remove MBR PSMs as they are currently not supported and will crash import
246245
mapped_columns = get_column_mapping_for_df(self.column_mapping, df)
247246
if PsmDfCols.SCAN_NUM in mapped_columns:
248247
scan_num_col = mapped_columns[PsmDfCols.SCAN_NUM]
249-
no_ms2_mask = df[scan_num_col] == ""
248+
# MBR PSMs carry no scan number: blank in a text column, NaN in a numeric one
249+
no_ms2_mask = df[scan_num_col].isna() | (df[scan_num_col] == "")
250250
if (num_no_ms2_mask := np.sum(no_ms2_mask)) > 0:
251251
warnings.warn(
252252
f"MaxQuant PSM file contains {num_no_ms2_mask} MBR PSMs without MS2 scan. This is not yet supported and rows containing MBR PSMs will be removed."

‎alphabase/psm_reader/msfragger_reader.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
psm_reader_provider,
1717
psm_reader_yaml,
1818
)
19+
from alphabase.utils import _sanitize_missing_values
1920

2021

2122
def _is_all_fragger_decoy(proteins: list[str]) -> bool:
@@ -415,11 +416,12 @@ def _translate_modifications(self) -> None:
415416

416417
def _load_file(self, filename: str) -> pd.DataFrame:
417418
"""Load MSFragger PSM TSV file."""
418-
return pd.read_csv(filename, sep="\t", keep_default_na=False)
419+
return _sanitize_missing_values(
420+
pd.read_csv(filename, sep="\t", keep_default_na=True)
421+
)
419422

420423
def _pre_process(self, df: pd.DataFrame) -> pd.DataFrame:
421424
"""MSFragger PSM TSV preprocessing."""
422-
df.fillna("", inplace=True)
423425
df[[PsmDfCols.RAW_NAME, PsmDfCols.SCAN_NUM]] = (
424426
df["Spectrum"].str.split(".").apply(lambda x: pd.Series([x[0], int(x[1])]))
425427
)
@@ -497,11 +499,10 @@ def _translate_modifications(self) -> None:
497499

498500
def _load_file(self, filename: str) -> pd.DataFrame:
499501
"""Load a MsFragger output file to a DataFrame."""
500-
return pepxml.DataFrame(filename)
502+
return _sanitize_missing_values(pepxml.DataFrame(filename))
501503

502504
def _pre_process(self, df: pd.DataFrame) -> pd.DataFrame:
503505
"""MsFragger-specific preprocessing of output data."""
504-
df.fillna("", inplace=True)
505506
if "ion_mobility" in df.columns:
506507
df["ion_mobility"] = df["ion_mobility"].astype(float)
507508
df[PsmDfCols.RAW_NAME] = df["spectrum"].str.split(".").apply(lambda x: x[0])

‎alphabase/psm_reader/pfind_reader.py‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
PSMReaderBase,
1414
psm_reader_provider,
1515
)
16+
from alphabase.utils import _sanitize_missing_values
1617

1718

1819
def _convert_one_pfind_mod(mod: str) -> Optional[str]: # noqa: C901 too complex (11 > 10) TODO: refactor
@@ -136,11 +137,12 @@ def _translate_modifications(self) -> None:
136137

137138
def _load_file(self, filename: str) -> pd.DataFrame:
138139
"""Load a pFind output file to a DataFrame."""
139-
return pd.read_csv(filename, index_col=False, sep="\t", keep_default_na=False)
140+
return _sanitize_missing_values(
141+
pd.read_csv(filename, index_col=False, sep="\t", keep_default_na=True)
142+
)
140143

141144
def _pre_process(self, df: pd.DataFrame) -> pd.DataFrame:
142145
"""pFind-specific preprocessing of output data."""
143-
df.fillna("", inplace=True)
144146
df = df[df["Sequence"] != ""]
145147
df[PsmDfCols.RAW_NAME] = df["File_Name"].str.split(".").apply(lambda x: x[0])
146148
df["Proteins"] = df["Proteins"].apply(parse_pfind_protein)

‎alphabase/psm_reader/sage_reader.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
PSMReaderBase,
1919
psm_reader_provider,
2020
)
21+
from alphabase.utils import _sanitize_missing_values
2122

2223

2324
class SageModificationTranslator:
@@ -669,14 +670,14 @@ class SageReaderTSV(SageReaderBase):
669670
"""Reader for Sage output files in TSV format."""
670671

671672
def _load_file(self, filename: str) -> pd.DataFrame:
672-
return pd.read_csv(filename, sep="\t")
673+
return _sanitize_missing_values(pd.read_csv(filename, sep="\t"))
673674

674675

675676
class SageReaderParquet(SageReaderBase):
676677
"""Reader for Sage output files in parquet format."""
677678

678679
def _load_file(self, filename: str) -> pd.DataFrame:
679-
return pd.read_parquet(filename)
680+
return _sanitize_missing_values(pd.read_parquet(filename))
680681

681682

682683
def register_readers() -> None:

‎alphabase/utils.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def _sanitize_missing_values(df: pd.DataFrame) -> pd.DataFrame:
9696
2 nan
9797
Name: "object_column", dtype: object
9898
99-
new_df = _coerce_nan_to_missing_string(df)
99+
new_df = _sanitize_missing_values(df)
100100
101101
pd.testing.assert_series_equal(new_df["numeric_column], df["numeric_column"])
102102
new_df["object_column"]

‎tests/unit/psm_reader/test_msfragger_psm_tsv.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ class TestDataProcessing:
4545
"""Tests for data processing and integration."""
4646

4747
def test_preprocessing(self, reader):
48-
"""Test preprocessing extracts raw names, scan_num, and fills NAs correctly."""
48+
"""Test preprocessing extracts raw names and scan_num."""
4949
df = pd.DataFrame(
5050
{
5151
"Spectrum": ["file1.01234.01234.3", "file2.01235.01235.2"],
52-
"Peptide": ["PEPTIDE", None],
52+
"Peptide": ["PEPTIDE", ""],
5353
"Is Decoy": ["false", "true"],
5454
"Assigned Modifications": ["5S(79.9663)", ""],
5555
}

0 commit comments

Comments
 (0)