Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfG committed Apr 5, 2024
1 parent 14ec6ae commit 1f0d1e9
Show file tree
Hide file tree
Showing 19 changed files with 906 additions and 0 deletions.
115 changes: 115 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: Release

on:
release:
types: [created]
workflow_dispatch:

permissions:
contents: read

jobs:
linux:
runs-on: ubuntu-latest
strategy:
matrix:
target: [x86_64, x86, aarch64]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist --find-interpreter
sccache: "true"
manylinux: auto
- name: Upload wheels
uses: actions/upload-artifact@v4
with:
name: wheels
path: dist

windows:
runs-on: windows-latest
strategy:
matrix:
target: [x64, x86]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
architecture: ${{ matrix.target }}
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist --find-interpreter
sccache: "true"
- name: Upload wheels
uses: actions/upload-artifact@v4
with:
name: wheels
path: dist

macos:
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: macos-latest
target: x86_64
- runner: macos-14
target: aarch64
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist --find-interpreter
sccache: "true"
- name: Upload wheels
uses: actions/upload-artifact@v4
with:
name: wheels
path: dist

sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
- name: Upload sdist
uses: actions/upload-artifact@v4
with:
name: wheels
path: dist

release:
name: Release
runs-on: ubuntu-latest
needs: [linux, windows, macos, sdist]
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
name: wheels
path: dist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
- name: Delete artifacts after upload
uses: geekyeggo/delete-artifact@v5
with:
name: wheels
39 changes: 39 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Test

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

# Make sure CI fails on all warnings, including Clippy lints
env:
RUSTFLAGS: "-Dwarnings"

jobs:
clippy_check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Clippy
run: cargo clippy --all-targets --all-features

pytest:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install package and dependencies
run: |
python -m pip install --upgrade pip
pip install .[test]
- name: Run tests
run: |
pytest
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# IDE
.vscode/

# Python
__pycache__/

# Generated by Cargo
# will have compiled files and executables
debug/
Expand Down
14 changes: 14 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "ms2rescore-rs"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "ms2rescore_rs"
crate-type = ["cdylib"]

[dependencies]
pyo3 = "0.20.0"
mzdata = "0.13.0"
timsrust = "0.2.3"
19 changes: 19 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[build-system]
requires = ["maturin>=1.5,<2.0"]
build-backend = "maturin"

[project]
name = "ms2rescore-rs"
requires-python = ">=3.8"
classifiers = [
"Programming Language :: Rust",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
]
dynamic = ["version"]

[project.optional-dependencies]
test = ["pytest"]

[tool.maturin]
features = ["pyo3/extension-module"]
41 changes: 41 additions & 0 deletions src/file_types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pub enum SpectrumFileType {
MascotGenericFormat,
MzML,
BrukerRaw,
// ThermoRaw,
Unknown,
}

pub fn match_file_type(spectrum_path: &str) -> SpectrumFileType {
let extension = spectrum_path.split('.').last().unwrap_or("").to_lowercase();
match extension.as_str() {
"mgf" => SpectrumFileType::MascotGenericFormat,
"mzml" => SpectrumFileType::MzML,
"d" | "ms2" => SpectrumFileType::BrukerRaw,
// "raw" => SpectrumFileType::ThermoRaw,
_ => match (
folder_contains_extension(spectrum_path, "bin"),
folder_contains_extension(spectrum_path, "parquet"),
) {
(true, true) => SpectrumFileType::BrukerRaw,
_ => SpectrumFileType::Unknown,
},
}
}

fn folder_contains_extension(input: impl AsRef<std::path::Path>, extension: &str) -> bool {
let folder_path: std::path::PathBuf = input.as_ref().to_path_buf();
if !folder_path.is_dir() {
return false;
}
if let Ok(entries) = std::fs::read_dir(folder_path) {
for entry in entries.flatten() {
if let Some(ext) = entry.path().extension() {
if ext == extension {
return true;
}
}
}
}
false
}
41 changes: 41 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
mod file_types;
mod parse_mzdata;
mod parse_timsrust;
mod precursor;

use std::collections::HashMap;

use pyo3::exceptions::PyOSError;
use pyo3::prelude::*;

use file_types::{match_file_type, SpectrumFileType};
use precursor::Precursor;

/// Get mapping of spectrum identifiers to precursor information.
#[pyfunction]
pub fn get_precursor_info(spectrum_path: String) -> PyResult<HashMap<String, Precursor>> {
let file_type = match_file_type(&spectrum_path);

let precursors = match file_type {
SpectrumFileType::MascotGenericFormat | SpectrumFileType::MzML => {
parse_mzdata::parse_precursor_info(&spectrum_path, file_type)
}
SpectrumFileType::BrukerRaw => parse_timsrust::parse_precursor_info(&spectrum_path),
// SpectrumFileType::ThermoRaw => parse_with_mzdata_thermo(&spectrum_path, file_type),
SpectrumFileType::Unknown => return Err(PyOSError::new_err("Unsupported file type")),
};

match precursors {
Ok(precursors) => Ok(precursors),
Err(e) => Err(PyOSError::new_err(e.to_string())),
}
}


/// A Python module implemented in Rust.
#[pymodule]
fn ms2rescore_rs(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<Precursor>()?;
m.add_function(wrap_pyfunction!(get_precursor_info, m)?)?;
Ok(())
}
Loading

0 comments on commit 1f0d1e9

Please sign in to comment.