use crate::{
error::CustomError,
identification::{
common_parser::OptionalColumn, IdentifiedPeptide, IdentifiedPeptideSource, MetaData,
},
ontologies::CustomDatabase,
Peptidoform, SemiAmbiguous, SloppyParsingParameters,
};
use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use super::{
common_parser::Location,
csv::{parse_csv, CsvLine},
BoxedIdentifiedPeptideIter,
};
static NUMBER_ERROR: (&str, &str) = (
"Invalid PowerNovo line",
"This column is not a number but it is required to be a number in this format",
);
format_family!(
PowerNovoFormat,
PowerNovoData,
PowerNovoVersion, [&POWERNOVO_V1_0_1], b',', None;
required {
title: String, |location: Location, _| Ok(location.get_string());
peptide: Peptidoform<SemiAmbiguous>, |location: Location, custom_database: Option<&CustomDatabase>| Peptidoform::sloppy_pro_forma(
location.full_line(),
location.location.clone(),
custom_database,
&SloppyParsingParameters::default(),
);
score: f64, |location: Location, _| location.parse::<f64>(NUMBER_ERROR);
local_confidence: Vec<f64>, |location: Location, _| location.array(' ')
.map(|l| l.parse::<f64>(NUMBER_ERROR))
.collect::<Result<Vec<_>, _>>();
}
optional {
raw_file: PathBuf, |location: Location, _| Ok(Path::new(&location.get_string()).to_owned());
scan: usize, |location: Location, _| location.parse::<usize>(NUMBER_ERROR);
}
fn post_process(_source: &CsvLine, mut parsed: Self, _custom_database: Option<&CustomDatabase>) -> Result<Self, CustomError> {
if let Some(m) = IDENTIFER_REGEX
.get_or_init(|| regex::Regex::new(r"^(.*):index=(\d+)$").unwrap())
.captures(&parsed.title)
{
parsed.raw_file = Some(PathBuf::from(m.get(1).unwrap().as_str()));
parsed.scan = Some(m.get(2).unwrap().as_str().parse::<usize>().unwrap());
}
Ok(parsed)
}
);
static IDENTIFER_REGEX: std::sync::OnceLock<regex::Regex> = std::sync::OnceLock::new();
impl From<PowerNovoData> for IdentifiedPeptide {
fn from(value: PowerNovoData) -> Self {
Self {
score: Some(value.score),
local_confidence: Some(value.local_confidence.clone()),
metadata: MetaData::PowerNovo(value),
}
}
}
pub const POWERNOVO_V1_0_1: PowerNovoFormat = PowerNovoFormat {
version: PowerNovoVersion::V1_0_1,
scan: OptionalColumn::NotAvailable,
raw_file: OptionalColumn::NotAvailable,
title: "spectrum name",
peptide: "powernovo peptides",
score: "powernovo score",
local_confidence: "powernovo aascore",
};
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, Serialize, Deserialize)]
pub enum PowerNovoVersion {
#[default]
V1_0_1,
}
impl std::fmt::Display for PowerNovoVersion {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(
f,
"{}",
match self {
Self::V1_0_1 => "v1.0.1",
}
)
}
}