rustdf/sim/utility.rs
1use mscore::data::peptide::{FragmentType, PeptideSequence};
2
3use rayon::prelude::*;
4use rayon::ThreadPoolBuilder;
5use serde_json::to_string;
6
7/// helper function to reshape the flat prosit predicted intensity array into a 3D array where:
8/// 1st dimension: 29 rows for every potential ion since prosit allows precursor sequences up to 30 amino acids
9/// 2nd dimension: 2 columns for B and Y ions
10/// 3rd dimension: 3 channels for charge 1, 2, and 3
11///
12/// # Arguments
13///
14/// * `array` - A vector of f64 representing the flat prosit array
15///
16/// # Returns
17///
18/// * A 3D vector of f64 representing the reshaped prosit array
19///
20pub fn reshape_prosit_array(array: Vec<f64>) -> Vec<Vec<Vec<f64>>> {
21 let mut array_return: Vec<Vec<Vec<f64>>> = vec![vec![vec![0.0; 3]; 2]; 29];
22 let mut ptr = 0;
23
24 for c in 0..3 {
25 for row in 0..29 {
26 // Fill in the Y ion values
27 array_return[row][0][c] = array[ptr];
28 ptr += 1;
29 }
30 for row in 0..29 {
31 // Fill in the B ion values
32 array_return[row][1][c] = array[ptr];
33 ptr += 1;
34 }
35 }
36
37 array_return
38}
39
40/// helper function to convert a peptide ion to all possible ions and serialize the result to a json string
41///
42/// # Arguments
43///
44/// * `sequence` - A string representing the peptide sequence
45/// * `charge` - An i32 representing the charge
46/// * `intensity_pred_flat` - A vector of f64 representing the flat prosit predicted intensity array
47/// * `normalize` - A bool indicating whether to normalize the intensity values
48/// * `half_charge_one` - A bool indicating whether to use half charge one
49///
50/// # Returns
51///
52/// * A json string representing the peptide ions ready to pe put into a database
53///
54pub fn sequence_to_all_ions(
55 sequence: &str,
56 charge: i32,
57 intensity_pred_flat: &Vec<f64>, // Assuming this is the reshaped intensity predictions array
58 normalize: bool,
59 half_charge_one: bool,
60 peptide_id: Option<i32>,
61) -> String {
62 let peptide_sequence = PeptideSequence::new(sequence.to_string(), peptide_id);
63 let fragments = peptide_sequence.associate_with_predicted_intensities(
64 charge,
65 FragmentType::B,
66 intensity_pred_flat.clone(),
67 normalize,
68 half_charge_one,
69 );
70 to_string(&fragments).unwrap()
71}
72
73pub fn sequence_to_all_ions_par(
74 sequences: Vec<&str>,
75 charges: Vec<i32>,
76 intensities_pred_flat: Vec<Vec<f64>>,
77 normalize: bool,
78 half_charge_one: bool,
79 num_threads: usize,
80 peptide_ids: Vec<Option<i32>>,
81) -> Vec<String> {
82 let thread_pool = ThreadPoolBuilder::new()
83 .num_threads(num_threads)
84 .build()
85 .unwrap();
86
87 let result = thread_pool.install(|| {
88 sequences
89 .par_iter()
90 .zip(charges.par_iter())
91 .zip(intensities_pred_flat.par_iter())
92 .zip(peptide_ids.par_iter())
93 .map(|(((seq, charge), intensities), peptide_id)| {
94 sequence_to_all_ions(
95 seq,
96 *charge,
97 intensities,
98 normalize,
99 half_charge_one,
100 *peptide_id,
101 )
102 })
103 .collect()
104 });
105
106 result
107}