Skip to content

Commit

Permalink
impl update for feature score type
Browse files Browse the repository at this point in the history
  • Loading branch information
theGreatHerrLebert authored and lazear committed Oct 17, 2024
1 parent be2f56d commit 5cc9ec6
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 57 deletions.
18 changes: 2 additions & 16 deletions crates/sage-cli/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ pub struct Search {
#[serde(skip_serializing)]
pub annotate_matches: bool,

#[serde(skip_serializing)]
pub score_type: ScoreType,
}

Expand Down Expand Up @@ -72,7 +71,7 @@ pub struct Input {

annotate_matches: Option<bool>,
write_pin: Option<bool>,
score_type: Option<String>,
score_type: Option<ScoreType>,
}

#[derive(Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -292,20 +291,7 @@ impl Input {
None => CloudPath::Local(std::env::current_dir()?),
};

let score_type = match self.score_type {
Some(s) => {
// check if s in ["sage_hyperscore", "openms_hyperscore"]
match s.to_lowercase().as_str() {
"sage_hyperscore" => ScoreType::SageHyperScore,
"openms_hyperscore" => ScoreType::OpenMSHyperScore,
_ => {
log::warn!("Invalid score type: {}. Supported values are: 'sage_hyperscore', 'openms_hyperscore', defaulting to sage_hyperscore", s);
ScoreType::SageHyperScore
}
}
}
None => ScoreType::SageHyperScore,
};
let score_type = self.score_type.unwrap_or(ScoreType::SageHyperScore);

Ok(Search {
version: clap::crate_version!().into(),
Expand Down
66 changes: 26 additions & 40 deletions crates/sage/src/scoring.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use std::cmp::{max, min};
use crate::database::{IndexedDatabase, PeptideIx};
use crate::heap::bounded_min_heapify;
use crate::ion_series::{IonSeries, Kind};
use crate::mass::{Tolerance, NEUTRON, PROTON};
use crate::spectrum::{Precursor, ProcessedSpectrum};
use serde::Serialize;
use serde::{Deserialize, Serialize};
use std::ops::AddAssign;
use std::sync::atomic::{AtomicUsize, Ordering};

#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum ScoreType {
SageHyperScore,
OpenMSHyperScore,
Expand Down Expand Up @@ -163,49 +162,36 @@ fn lnfact(n: u16) -> f64 {
}
}

fn log_factorial(n: u16, k: u16) -> f64 {

let k = max(k, 2);
let mut result = 0.0;

for i in (k..=n).rev() {
result += (i as f64).ln();
impl ScoreType {
pub fn score(&self, matched_b: u16, matched_y: u16, summed_b: f32, summed_y: f32) -> f64 {
let score = match self {
// Calculate the X!Tandem hyperscore
Self::SageHyperScore => {
let i = (summed_b + 1.0) as f64 * (summed_y + 1.0) as f64;
let score = i.ln() + lnfact(matched_b) + lnfact(matched_y);
score
}
// Calculate the OpenMS flavour hyperscore
Self::OpenMSHyperScore => {
let summed_intensity = summed_b + summed_y;
let score = summed_intensity.ln_1p() as f64 + lnfact(matched_b) + lnfact(matched_y);
score
}
};
if score.is_finite() {
score
} else {
255.0
}
}

result
}

/// Calculate the OpenMS hyperscore, adds up contributions from matched b and y ions instead of
/// multiplying them
fn openms_hyper_score(matched_b: u16, matched_y: u16, summed_b: f32, summed_y: f32) -> f64 {
let summed_intensity = summed_b + summed_y;
let i_min = min(matched_y, matched_b) as f64;
let i_max = max(matched_y, matched_b) as f64;

let score = summed_intensity.ln_1p() as f64 + 2.0 * log_factorial(i_min as u16, 2) +
log_factorial(i_max as u16, i_min as u16 + 1);
score
}

/// Calculate the X!Tandem hyperscore
/// * `fact_table` is a precomputed vector of factorials
fn sage_hyper_score(matched_b: u16, matched_y: u16, summed_b: f32, summed_y: f32) -> f64 {
let i = (summed_b + 1.0) as f64 * (summed_y + 1.0) as f64;
let score = i.ln() + lnfact(matched_b) + lnfact(matched_y);
score
}

impl Score {
/// Calculate the hyperscore for a given PSM choosing between implementations based on `score_type`
fn hyperscore(&self, score_type: ScoreType) -> f64 {
let score = match score_type {
ScoreType::SageHyperScore => sage_hyper_score(self.matched_b, self.matched_y, self.summed_b, self.summed_y),
ScoreType::OpenMSHyperScore => openms_hyper_score(self.matched_b, self.matched_y, self.summed_b, self.summed_y),
};
if score.is_finite() {
score
} else {
255.0
match score_type {
ScoreType::SageHyperScore => ScoreType::SageHyperScore.score(self.matched_b, self.matched_y, self.summed_b, self.summed_y),
ScoreType::OpenMSHyperScore => ScoreType::OpenMSHyperScore.score(self.matched_b, self.matched_y, self.summed_b, self.summed_y),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@
"mzml_paths": [
"tests/LQSRPAAPPAPGPGQLTLR.mzML"
],
"score_type": "sage_hyperscore"
"score_type": "SageHyperScore"
}

0 comments on commit 5cc9ec6

Please sign in to comment.