Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions tests/data/params/sage_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"database": {
"bucket_size": 16384,
"fragment_min_mz": 150.0,
"fragment_max_mz": 1500.0,
"enzyme": {
"missed_cleavages": 1,
"cleave_at": "KR",
"restrict": "P"
},
"static_mods": {
"C": 57.0216
},
"decoy_tag": "",
"generate_decoys": false,
"fasta": "A.fasta"
},
"deisotope": true,
"chimera": false,
"max_fragment_charge": 1,
"report_psms": 1,
"precursor_tol": {
"ppm": [
-50,
50
]
},
"fragment_tol": {
"da": [
-0.5,
0.5
]
},
"isotope_errors": [
-1,
3
],
"mzml_paths": [
"A.mzML"
],
"score_type": "SageHyperScore"
}
42 changes: 42 additions & 0 deletions tests/data/params/sage_config_alternate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"database": {
"bucket_size": 16384,
"fragment_min_mz": 150.0,
"fragment_max_mz": 1500.0,
"enzyme": {
"missed_cleavages": 1,
"cleave_at": "R",
"restrict": "P"
},
"static_mods": {
"C": 57.0216
},
"decoy_tag": "",
"generate_decoys": false,
"fasta": "A.fasta"
},
"deisotope": true,
"chimera": false,
"max_fragment_charge": 1,
"report_psms": 1,
"precursor_tol": {
"ppm": [
-50,
50
]
},
"fragment_tol": {
"da": [
-0.5,
0.5
]
},
"isotope_errors": [
-1,
3
],
"mzml_paths": [
"A.mzML"
],
"score_type": "SageHyperScore"
}
40 changes: 40 additions & 0 deletions tests/integrationtests/wrappers/test_sage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Integration test for Sage."""
import pandas as pd
from pathlib import Path
import urgap

import pytest


def test_searchdb_sage(tmp_path: Path) -> None:
params = urgap.UFile(uri=f"file:///{urgap._test_folder}/data/params?uftype={urgap.uftypes.proteomics.dbsearch.SAGE_PARAMS}#sage_config.json")
params_alt = urgap.UFile(uri=f"file:///{urgap._test_folder}/data/params?uftype={urgap.uftypes.proteomics.dbsearch.SAGE_PARAMS}#sage_config_alternate.json")
mzml = urgap.UFile(uri=f"file:///{urgap._test_folder}/data/ms_files?uftype={urgap.uftypes.ms.converter.mzml.ANY}#BSA1.mzML")
fasta = urgap.UFile(uri=f"file:///{urgap._test_folder}/data/fastas?uftype={urgap.uftypes.proteomics.FASTA}#BSA1.fasta")
urd = urgap.URunDict(
{
"parameters": {"Sage:0.14.7": {
},
},
"unode_parameters": {
"storage_base_uri": f"file://{tmp_path}",
},
},
)
search_node = urgap.init_node("Sage:0.14.7")

for parameters in (params, params_alt):
search_result = search_node.run([parameters, mzml, fasta], urd)
assert search_result[0].path.exists() is True

# check that output is not empty
df = pd.read_csv(search_result[0].path, delimiter="\t")
if parameters == params:
assert df.shape[0] == 103

elif parameters == params_alt:
assert df.shape[0] == 3

search_node.remove_output_folder(output_file=search_result[0])


21 changes: 21 additions & 0 deletions urgap/resources/Sage/0_14_7/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2022 Michael Lazear

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
67 changes: 67 additions & 0 deletions urgap/resources/Sage/0_14_7/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<img src="figures/logo.png" width="300">

# Sage: proteomics searching so fast it seems like magic

[![Rust](https://github.com/lazear/sage/actions/workflows/rust.yml/badge.svg)](https://github.com/lazear/sage/actions/workflows/rust.yml) [![Anaconda-Server Badge](https://anaconda.org/bioconda/sage-proteomics/badges/version.svg)](https://anaconda.org/bioconda/sage-proteomics)


For more information please read [the online documentation!](https://sage-docs.vercel.app/docs)


# Introduction

Sage is, at it's core, a proteomics database search engine -
a tool that transforms raw mass spectra from proteomics experiments into peptide identifications
via database searching & spectral matching.

However, Sage includes a variety of advanced features that make it a one-stop shop: retention time prediction, quantification (both isobaric & LFQ), peptide-spectrum match rescoring, and FDR control. You can directly use results from Sage without needing to use other tools for these tasks.

Additionally, Sage was designed with cloud computing in mind - massively parallel processing and the ability to directly stream compressed mass spectrometry data to/from AWS S3 enables unprecedented search speeds with minimal cost.

Sage also runs just as well reading local files from your Mac/PC/Linux device!

## Why use Sage instead of other tools?

Sage is **simple to configure**, **powerful** and **flexible**.
It also happens to be well-tested, **mind-boggingly fast**, open-source (MIT-licensed) and free.

## Citation

If you use Sage in a scientific publication, please cite the following paper:

[Sage: An Open-Source Tool for Fast Proteomics Searching and Quantification at Scale](https://doi.org/10.1021/acs.jproteome.3c00486)


## Features

- Incredible performance out of the box
- [Effortlessly cross-platform](https://sage-docs.vercel.app/docs/started#download-the-latest-binary-release) (Linux/MacOS/Windows), effortlessly parallel (uses all of your CPU cores)
- [Fragment indexing strategy](https://sage-docs.vercel.app/docs/how_it_works) allows for blazing fast narrow and open searches (> 500 Da precursor tolerance)
- [Isobaric quantification](https://sage-docs.vercel.app/docs/how_it_works#tmt-based) (MS2/MS3-TMT, or custom reporter ions)
- [Label-free quantification](https://sage-docs.vercel.app/docs/how_it_works#label-free): consider all charge states & isotopologues *a la* FlashLFQ
- Capable of searching for [chimeric/co-fragmenting spectra](https://sage-docs.vercel.app/docs/configuration/additional)
- Wide-window (dynamic precursor tolerance) search mode - [enables WWA/PRM/DIA searches](https://sage-docs.vercel.app/docs/configuration/tolerance#wide-window-mode)
- Retention time prediction models fit to each LC/MS run
- [PSM rescoring](https://sage-docs.vercel.app/docs/how_it_works#machine-learning-for-psm-rescoring) using built-in linear discriminant analysis (LDA)
- PEP calculation using a non-parametric model (KDE)
- FDR calculation using target-decoy competition and picked-peptide & picked-protein approaches
- Percolator/Mokapot [compatible output](https://sage-docs.vercel.app/docs/configuration#env)
- Configuration by [JSON file](https://sage-docs.vercel.app/docs/configuration#file)
- Built-in support for reading gzipped-mzML files
- Support for reading/writing directly from [AWS S3](https://sage-docs.vercel.app/docs/configuration/aws)

## Interoperability

Sage is well-integrated into the open-source proteomics ecosystem. The following projects support analyzing results from Sage (typically in addition to other tools), or redistribute Sage binaries for use in their pipelines.

- [SearchGUI](http://compomics.github.io/projects/searchgui): a graphical user interface for running searches
- [PeptideShaker](http://compomics.github.io/projects/peptide-shaker): visualize peptide-spectrum matches
- [MS2Rescore](http://compomics.github.io/projects/ms2rescore): AI-assisted rescoring of results
- [Picked group FDR](https://github.com/kusterlab/picked_group_fdr): scalable protein group FDR for large-scale experiments
- [sagepy](https://github.com/theGreatHerrLebert/sagepy): Python bindings to the sage-core library
- [quantms](https://github.com/bigbio/quantms): nextflow pipeline for running searches with Sage
- [OpenMS](https://github.com/OpenMS/OpenMS): Sage is included as a "TOPP" tool in OpenMS
- [sager](https://github.com/UCLouvain-CBIO/sager): R package for analyzing results from Sage searches
- If your project supports Sage and it's not listed, please open a pull request! If you need help integrating or interfacing with Sage in some way, please reach out.

Check out the (now outdated) [blog post introducing the first version of Sage](https://lazear.github.io/sage/) for more information and full benchmarks!
Binary file added urgap/resources/Sage/0_14_7/sage
Binary file not shown.
1 change: 1 addition & 0 deletions urgap/resources/Sage/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Init Sage resources."""
4 changes: 4 additions & 0 deletions urgap/uftypes/proteomics.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
proteomics.dbsearch.XTANDEM_XML = ".xtandem.xml"
proteomics.dbsearch.DIANN_QUANT = ".diann.quant"
proteomics.dbsearch.DIANN_REPORT = ".diann_report.tsv"
proteomics.dbsearch.SAGE_TSV = ".sage_report.tsv"
proteomics.dbsearch.SAGE_PARAMS = ".sage.json"
proteomics.dbsearch.MSGFPLUS_TXT = ".msgfplus_params.txt"

proteomics.diannlibrary = types.SimpleNamespace()
proteomics.diannlibrary.ANY = "proteomics.diannlibrary.ANY"
Expand Down Expand Up @@ -65,3 +68,4 @@
proteomics.qc = types.SimpleNamespace()
proteomics.qc.ANY = "proteomics.qc.ANY"
proteomics.qc.OFFSET_CSV = ".offset.csv"

1 change: 1 addition & 0 deletions urgap/unodes/sage/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Init Sage Unode."""
106 changes: 106 additions & 0 deletions urgap/unodes/sage/sage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
"""Urgap sage wrapper."""

import json

from pathlib import Path

import urgap


class Sage(urgap.unode.UNodeBase):
"""Sage wrapper for the Sage search engine.

Sage is a proteomics database search engine - a tool that transforms raw mass spectra from
proteomics experiments into peptide identifications via database searching & spectral matching.
"""

META_INFO = {
"name": "Sage",
"wrapper_version": {"major": 1, "minor": 0, "patch": 0},
"versions": [
{"version": "0.14.7", "exe_path": "Sage/0_14_7/sage"},
],
"parameters_not_triggering_rerun": [],
"input_uftypes": {
urgap.uftypes.ms.converter.mzml.ANY: {"min": 1, "max": -1},
urgap.uftypes.proteomics.dbsearch.SAGE_PARAMS: {"min": 1, "max": 1},
urgap.uftypes.proteomics.FASTA: {"min": 1, "max": 1},
},
"output_uftypes": {
urgap.uftypes.proteomics.dbsearch.SAGE_TSV: {"min": 1, "max": 1},

},
"engine": None,
"engine_type": ("db_search", "proteomics"),
"citation": """Lazear, M. R. (2023). Sage: An open-source tool for fast proteomics searching and quantification at scale. Journal of Proteome Research, 22(11), 3652-3659. https://doi.org/10.1021/acs.jproteome.3c00486""",
}

def __init__(self, *args: object, **kwargs: object) -> None:
"""Initialize Sage class."""
super().__init__(*args, **kwargs)

def preflight(self, utrace: urgap.UTrace) -> urgap.UTrace:
"""Preflight routine for Sage wrapper.

During preflight,
- parameters are formatted
- mods are mapped and formatted

Args:
utrace: Combination of urun_dict, ufile_list and unode.meta.

Returns:
UTrace object, combination of urun_dict, ufile_list and unode.meta.

Raises:
ValueError: If both a parameter file and command-line parameters
in the urun_dict are provided. Please provide only one.
"""
param_files = utrace.input_files.get_path_objects_by_uftype(
urgap.uftypes.proteomics.dbsearch.SAGE_PARAMS,
)

mzml_file = utrace.input_files.get_path_objects_by_uftype(
urgap.uftypes.ms.converter.mzml.ANY,
)[0]
fasta_file = utrace.input_files.get_path_objects_by_uftype(
urgap.uftypes.proteomics.FASTA,
)[0]

config_dict = json.loads(param_files[0].read_text())
config_dict["output_directory"] = str(mzml_file.parent)

config_path = param_files[0].parent / "sage_config.json"
config_path.write_text(json.dumps(config_dict))
utrace.urun_dict.command_list = [
str(self.exe_path),
str(config_path),
"--fasta",
str(fasta_file),
str(mzml_file),


]
return utrace



def postflight(self, utrace: urgap.UTrace) -> urgap.UTrace:
"""Postflight routine for Sage wrapper.

During postflight the Sage native .tsv output file is converted into the
pre-defined urgap output file, which is of csv format.

Args:
utrace: Combination of urun_dict, ufile_list and unode.meta.

Returns:
UTrace object, combination of urun_dict, ufile_list and unode.meta.
"""
full_path = utrace.input_files.get_path_objects_by_uftype(
urgap.uftypes.ms.converter.mzml.ANY,
)[0]
sage_tsv = full_path.parent / "results.sage.tsv"
self.tmp_files.append(sage_tsv)
Path(sage_tsv).rename(utrace.output_files[0].path)
return utrace
Loading