-
Notifications
You must be signed in to change notification settings - Fork 17
MaxQuant ProteinGroup Reader #330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
3891bcd
[Feature] Configuration for MaxQuant reader
lucas-diedrich 255c978
[Feature] Add post-processing method that acts on streamlined columns…
lucas-diedrich 7c1de7d
[API] Expose MaxQuantPGReader to users
lucas-diedrich 843108a
[Feature] MaxQuant reader with documentation
lucas-diedrich 551f963
[Test] Add integration test for MaxQuantPGReader
lucas-diedrich fe922c5
[Test] Adjust tests to work with local test data - MQReader
lucas-diedrich 3b79dce
[Tests] Add test data
lucas-diedrich 9f4d3e7
[Fix] Fix typo
lucas-diedrich 521fa13
[Doc] Update docstring, add more explicit parameter explanations
lucas-diedrich 3fd9d98
[Doc] Update docstrings and remove incorrect copy documentation
lucas-diedrich 7717cd2
[Doc] Clarify docstring
lucas-diedrich 31e46e3
[Feature] Spectronaut reader
lucas-diedrich 5aaf207
[Feature] Spectronaut reader config
lucas-diedrich 3cfc4ca
[API] Expose spectronaut reader to users
lucas-diedrich f28d73e
[Test] Spectronaut integration tests
lucas-diedrich 4573149
[Doc] Add examples
lucas-diedrich c287cd2
[Fix] Rename pre-configured regex to default
lucas-diedrich 4940a73
[Fix] Fix typos
lucas-diedrich b5c7a9b
[Feature] Add parquet support. Specifically desirable for spectronaut…
lucas-diedrich 41eef70
[Test] Add integration test for spectronaut.parquet report
lucas-diedrich 207e386
[Doc] Add regular expression documentation
lucas-diedrich ef71f1a
[Doc] Improve docstring of class initialization
lucas-diedrich a2427d7
[Feature] Add additional column mapping for parquet report protein gr…
lucas-diedrich 0e13e68
[Test] Refactor tests so that they work with local data
lucas-diedrich 5e9c1c0
[Test-Data] Add test data reference for spectronaut reports
lucas-diedrich 85e05cb
[Feature] Implement fragpipe reader
lucas-diedrich 4a46205
[API] Expose FragPipeReader to users
lucas-diedrich 808547b
[Tests] Add integration test for FragPipeReader
lucas-diedrich 38b995d
[Fix] Fix typo in URL
lucas-diedrich deccde6
[Test] Update tests to work with local data (FragPipe PG reader)
lucas-diedrich 6cbe7d9
[Test-data] Add test reference data (PG fragpipe)
lucas-diedrich cc9b861
[Feature] Add MZTab protein group reader
lucas-diedrich 6699fac
[API] Expose MZTab to users
lucas-diedrich 8e0e8c5
[Tests] Add integration tests
lucas-diedrich 2a2848e
[Refactor] Set correct default values
lucas-diedrich 00c72f0
[Tests] Add integration tests
lucas-diedrich 86eeb7a
[Test] Refactor mztab integration test so that it runs with local data
lucas-diedrich 15545aa
[Test-data] Add local test data (mzTAB PG Reader)
lucas-diedrich 0343aeb
[Doc] Add PG-reader API docs
lucas-diedrich 75b5ab1
Merge pull request #334 from MannLabs/pg-reader-9-docs-I
lucas-diedrich 639c81e
Merge pull request #333 from MannLabs/pg-reader-8-mztab
lucas-diedrich 778dac6
Merge pull request #332 from MannLabs/pg-reader-7-msfragger
lucas-diedrich e9485c1
Merge pull request #331 from MannLabs/pg-reader-6-spectronaut
lucas-diedrich File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,19 @@ | ||
| from .alphadia_pg_reader import AlphaDiaPGReader | ||
| from .alphapept_pg_reader import AlphaPeptPGReader | ||
| from .diann_pg_reader import DiannPGReader | ||
| from .fragpipe_pg_reader import FragPipePGReader | ||
| from .maxquant_pg_reader import MaxQuantPGReader | ||
| from .mztab_pg_reader import MZTabPGReader | ||
| from .pg_reader import pg_reader_provider | ||
| from .spectronaut_reader import SpectronautPGReader | ||
|
|
||
| __all__ = [ | ||
| "pg_reader_provider", | ||
| "AlphaDiaPGReader", | ||
| "DiannPGReader", | ||
| "AlphaPeptPGReader", | ||
| "MaxQuantPGReader", | ||
| "SpectronautPGReader", | ||
| "FragPipePGReader", | ||
| "MZTabPGReader", | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| """FragPipe protein group reader.""" | ||
|
|
||
| from typing import Literal, Optional, Union | ||
|
|
||
| from .pg_reader import PGReaderBase, pg_reader_provider | ||
|
|
||
|
|
||
| class FragPipePGReader(PGReaderBase): | ||
| """Reader for `protein.tsv` reports from FragPipe. | ||
|
|
||
| Example: | ||
| ------- | ||
| Per default, the reader will return the raw intensities from the `razor` method. Additional protein features are stored | ||
| in the dataframe index, samples are stored as columns. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # Get raw intensities | ||
| reader = FragPipePGReader() | ||
| results = reader.import_file(download_path) | ||
|
|
||
|
|
||
| References: | ||
| ---------- | ||
| - FragPipe Documentation https://fragpipe.nesvilab.org/docs/tutorial_fragpipe_outputs.html#proteintsv | ||
|
|
||
| """ | ||
|
|
||
| _reader_type: str = "fragpipe" | ||
|
|
||
| def __init__( # noqa: D107 inherited from base class | ||
| self, | ||
| *, | ||
| column_mapping: Optional[dict[str, str]] = None, | ||
| measurement_regex: Union[ | ||
| Literal[ | ||
| "raw", "razor", "unique", "total", "lfq", "lfq_unique", "lfq_total" | ||
| ], | ||
| None, | ||
| ] = "razor", | ||
| ): | ||
| super().__init__( | ||
| column_mapping=column_mapping, measurement_regex=measurement_regex | ||
| ) | ||
|
|
||
|
|
||
| pg_reader_provider.register_reader("fragpipe", reader_class=FragPipePGReader) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| """MaxQuant Protein Group Reader.""" | ||
|
|
||
| from typing import Literal, Optional, Union | ||
|
|
||
| import pandas as pd | ||
|
|
||
| from .keys import PGCols | ||
| from .pg_reader import PGReaderBase, pg_reader_provider | ||
|
|
||
|
|
||
| class MaxQuantPGReader(PGReaderBase): | ||
| r"""Reader for protein group matrices from the MaxQuant search engine. | ||
|
|
||
| By default, the reader will read raw protein intensities from the protein group matrix. By passing | ||
| a suitable regular expression, it is also possible to extract LFQ | ||
|
|
||
| Examples | ||
| -------- | ||
| Get example data | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| import os | ||
| import tempfile | ||
| from alphabase.tools.data_downloader import DataShareDownloader | ||
| from alphabase.pg_reader import MaxQuantPGReader | ||
|
|
||
|
|
||
| # Download to temporary directory | ||
| URL = "https://datashare.biochem.mpg.de/s/KvToteOu0zzH17C" | ||
| download_dir = tempfile.mkdtemp() | ||
|
|
||
| download_path = DataShareDownloader(url=URL, output_dir=download_dir).download() | ||
|
|
||
|
|
||
| Per default, the reader will return the raw intensities. Additional protein features are stored | ||
| in the dataframe index, samples are stored as columns. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # Get raw intensities | ||
| reader = MaxQuantPGReader() | ||
| results = reader.import_file(download_path) | ||
| results.index.names | ||
| > FrozenList(['proteins', 'uniprot_ids', 'genes', 'is_decoy']) | ||
| results.columns | ||
| > Index([...], dtype='object', length=312) | ||
|
|
||
| You can get other intensity types by passing a specific pattern to the `measurment_regex` parameter during class initialization. | ||
| To checkout all preconfigured regular expressions that enable you to retrieve different intensity modalities, | ||
| use the `get_preconfigured_regex` method: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| MaxQuantPGReader.get_preconfigured_regex() | ||
| > { | ||
| 'raw': '^Intensity(?!\\s[LHM]\\s).+$', | ||
| 'lfq': '^LFQ intensity(?!\\s[LHM]\\s).+$', | ||
| 'ibaq': '^iBAQ(?!\\s[LHM]\\s).+$' | ||
| } | ||
|
|
||
| You can also pass a custom regular expression, e.g. to retrieve specific channels in TMT experiments | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # Match "Intensity H+ <sample>" | ||
| reader = MaxQuantPGReader(measurement_regex="^Intensity H .+") | ||
|
|
||
|
|
||
| References | ||
| ---------- | ||
| - MaxQuant Documentation (Cox Lab, 2024-06-27): https://cox-labs.github.io/coxdocs/output_tables.html#protein-groups, | ||
| (last viewed 2025-08) | ||
|
|
||
| """ | ||
|
|
||
| _reader_type = "maxquant" | ||
|
|
||
| def __init__( | ||
| self, | ||
| *, | ||
| column_mapping: Optional[dict[str, str]] = None, | ||
| measurement_regex: Union[str, Literal["raw", "lfq", "ibaq"], None] = "raw", # noqa: PYI051 raw and lfq are special cases and not equivalent to string | ||
| ): | ||
| """Initialize MaxQuant protein group matrix reader. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| column_mapping | ||
| Dictionary mapping alphabase column names (keys) to MaxQuant column names (values). | ||
| If `None`, uses default mapping from configuration file. | ||
| measurement_regex | ||
| Pattern to select quantity columns | ||
|
|
||
| - "raw" (default): Raw intensities | ||
| - "lfq": LFQ-corrected intensities | ||
| - "ibaq": Intensity-Based Absolute Quantification-corrected intensities | ||
| - custom: Any valid regular expression | ||
|
|
||
| See class documentation for usage examples and `get_preconfigured_regex()` for available patterns. | ||
|
|
||
| """ | ||
| super().__init__( | ||
| column_mapping=column_mapping, measurement_regex=measurement_regex | ||
| ) | ||
|
|
||
| def _post_process(self, df: pd.DataFrame) -> pd.DataFrame: | ||
| """Process MaxQuant protein group table after standardization. | ||
|
|
||
| Convert MaxQuant-specific decoy indicator (+) to standardized boolean series. | ||
|
|
||
| Notes | ||
| ----- | ||
| MaxQuant marks peptides/proteins that were found to be part of a protein derived from the reversed part of the decoy database | ||
|
lucas-diedrich marked this conversation as resolved.
|
||
| with +. These should be removed for further data analysis. | ||
|
|
||
| References | ||
| ---------- | ||
| https://cox-labs.github.io/coxdocs/output_tables.html#protein-groups (Status: 2025-08) | ||
|
|
||
| """ | ||
| # Convert `+` indicator to boolean | ||
| if PGCols.DECOY_INDICATOR in df.columns: | ||
| df[PGCols.DECOY_INDICATOR] = df[PGCols.DECOY_INDICATOR].apply( | ||
| lambda x: x == "+" | ||
| ) | ||
| return df | ||
|
|
||
|
|
||
| pg_reader_provider.register_reader("maxquant", reader_class=MaxQuantPGReader) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| """FragPipe protein group reader.""" | ||
|
|
||
| from pathlib import Path | ||
| from typing import Literal, Optional, Union | ||
|
|
||
| import pandas as pd | ||
|
|
||
| from .pg_reader import PGReaderBase, pg_reader_provider | ||
|
|
||
|
|
||
| class MZTabPGReader(PGReaderBase): | ||
| """Reader for MZTab search engine output. | ||
|
|
||
| MZTab is a standardized tab-delimited format for reporting proteomics and metabolomics results. | ||
| The format organizes data into distinct sections: metadata (MTD), protein groups (PRH/PRT), | ||
| peptides (PEH/PEP), PSMs (PSH/PSM), and small molecules (SMH/SML), with each section identified | ||
| by specific three-letter prefixes. This reader extracts protein-level quantification data from | ||
| the PRT lines, which contain protein abundances across samples or study variables. | ||
|
|
||
| Example: | ||
| ------- | ||
| Per default, the reader will return the raw intensities from the `razor` method. Additional protein features are stored | ||
| in the dataframe index, samples are stored as columns. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from alphabase.pg_reader import MZTabPGReader | ||
|
|
||
| # Get raw intensities | ||
| reader = MZTabPGReader() | ||
| results = reader.import_file(path) | ||
|
|
||
|
|
||
| References: | ||
| ---------- | ||
| - Griss, J. et al. The mzTab Data Exchange Format: Communicating Mass-spectrometry-based Proteomics and Metabolomics Experimental Results to a Wider Audience*. Molecular & Cellular Proteomics 13, 2765-2775 (2014). | ||
| - Official MZTab Repository: https://github.com/HUPO-PSI/mzTab.git | ||
| - Official documentation: https://hupo-psi.github.io/mzTab/ | ||
|
|
||
| """ | ||
|
|
||
| _reader_type: str = "mztab" | ||
|
|
||
| _PROTEIN_ROW_INDICATOR: str = "PRT" | ||
| _PROTEIN_HEADER_INDICATOR: str = "PRH" | ||
| _SEPARATOR: str = "\t" | ||
|
|
||
| def __init__( # noqa: D107 inherited from base class | ||
| self, | ||
| *, | ||
| column_mapping: Optional[dict[str, str]] = None, | ||
| measurement_regex: Union[ | ||
| str, Literal["assay", "study_variable"], None # noqa: PYI051 raw and lfq are special cases and not equivalent to string | ||
| ] = "assay", | ||
| ): | ||
| super().__init__( | ||
| column_mapping=column_mapping, measurement_regex=measurement_regex | ||
| ) | ||
|
|
||
| def _load_file(self, file_path: str) -> pd.DataFrame: | ||
| """Load MZTab file and extract protein data section. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| file_path : str | ||
| Path to MZTab file | ||
|
|
||
| Returns | ||
| ------- | ||
| pd.DataFrame | ||
| DataFrame containing protein data from MZTab file | ||
|
|
||
| Notes | ||
| ----- | ||
| Protein lines are indicated with a leading `PRT`. The protein metadata header is | ||
| indicated with a leading `PRH`. The file is tab separated. | ||
|
|
||
| Raises | ||
| ------ | ||
| ValueError | ||
| If no protein data or metadata is found in the file | ||
|
|
||
| """ | ||
| file_path = Path(file_path) | ||
| protein_header = None | ||
| protein_rows = [] | ||
|
|
||
| with file_path.open() as f: | ||
| for line in f: | ||
| line_stripped = line.strip() | ||
|
|
||
| if line_stripped.startswith(self._PROTEIN_HEADER_INDICATOR): | ||
| # Protein header line - remove 'PRH' prefix and parse columns | ||
| header_content = line_stripped[3:].strip() | ||
| protein_header = header_content.split(self._SEPARATOR) | ||
|
|
||
| elif line_stripped.startswith(self._PROTEIN_ROW_INDICATOR): | ||
| # Protein data line - remove 'PRT' prefix and parse data | ||
| row_content = line_stripped[3:].strip() | ||
| protein_rows.append(row_content.split(self._SEPARATOR)) | ||
|
|
||
| # Validate that we found protein data | ||
| if protein_header is None: | ||
| raise ValueError( | ||
| f"No protein header ({self._PROTEIN_HEADER_INDICATOR}) found in MZTab file" | ||
| ) | ||
|
|
||
| if not protein_rows: | ||
| raise ValueError( | ||
| f"No protein data rows ({self._PROTEIN_ROW_INDICATOR}) found in MZTab file" | ||
| ) | ||
|
|
||
| return pd.DataFrame(protein_rows, columns=protein_header) | ||
|
|
||
|
|
||
| pg_reader_provider.register_reader("mztab", reader_class=MZTabPGReader) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.