Skip to content

Commit 5b4ac94

Browse files
committed
Add parsing
1 parent f93ce92 commit 5b4ac94

File tree

5 files changed

+125
-43
lines changed

5 files changed

+125
-43
lines changed

src-tauri/src/commands.rs

+35-32
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::io::Cursor;
66
use std::path::Path;
77
use tauri::api::dialog::blocking::FileDialogBuilder;
88
use tokio::fs;
9+
use crate::processor::parser::parse;
910

1011
#[tauri::command]
1112
pub async fn install_dependencies(app_handle: tauri::AppHandle) -> Result<(), String> {
@@ -110,38 +111,40 @@ pub async fn process_data(
110111
let input_file_path = Path::new(&input_file_path);
111112
let heavy_water_file_path = Path::new(&heavy_water_file_path);
112113

113-
let output_contents = processor::handle(
114-
should_remove_na_calculations,
115-
&data_dir,
116-
&dependencies_dir,
117-
&input_file_path,
118-
heavy_water_file_path,
119-
)
120-
.await?;
121-
122-
let input_file_name = input_file_path
123-
.file_stem()
124-
.unwrap()
125-
.to_string_lossy()
126-
.into_owned();
127-
128-
let file_path = FileDialogBuilder::new()
129-
.set_file_name(&format!("{input_file_name}.RateConst.csv"))
130-
.add_filter("Output CSV File", &vec!["csv"])
131-
.save_file();
132-
133-
if let Some(file_path) = file_path {
134-
// overwrite file if it already exists
135-
fs::OpenOptions::new()
136-
.write(true)
137-
.create(true)
138-
.open(&file_path)
139-
.await
140-
.map_err(|err| format!("Failed to write output file: {err}"))?
141-
.write(&output_contents)
142-
.await
143-
.map_err(|err| format!("Failed to write output file: {err}"))?;
144-
}
114+
dbg!(parse(input_file_path).await.unwrap());
115+
116+
// let output_contents = processor::handle(
117+
// should_remove_na_calculations,
118+
// &data_dir,
119+
// &dependencies_dir,
120+
// &input_file_path,
121+
// heavy_water_file_path,
122+
// )
123+
// .await?;
124+
//
125+
// let input_file_name = input_file_path
126+
// .file_stem()
127+
// .unwrap()
128+
// .to_string_lossy()
129+
// .into_owned();
130+
//
131+
// let file_path = FileDialogBuilder::new()
132+
// .set_file_name(&format!("{input_file_name}.RateConst.csv"))
133+
// .add_filter("Output CSV File", &vec!["csv"])
134+
// .save_file();
135+
//
136+
// if let Some(file_path) = file_path {
137+
// // overwrite file if it already exists
138+
// fs::OpenOptions::new()
139+
// .write(true)
140+
// .create(true)
141+
// .open(&file_path)
142+
// .await
143+
// .map_err(|err| format!("Failed to write output file: {err}"))?
144+
// .write(&output_contents)
145+
// .await
146+
// .map_err(|err| format!("Failed to write output file: {err}"))?;
147+
// }
145148

146149
Ok(())
147150
}

src-tauri/src/processor/executor.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ pub async fn execute(
2929
let mut command = Command::new(dependencies_dir.join("SRM_Rate.exe"));
3030
command
3131
.arg(heavy_water_file_path.to_str().unwrap())
32-
.arg(input_file_path.to_str().unwrap())
32+
.arg(input_file_path.to_str().unwrap());
3333
// additional context here: https://stackoverflow.com/questions/60750113/how-do-i-hide-the-console-window-for-a-process-started-with-stdprocesscomman
3434
// CREATE_NO_WINDOW flag. See: https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags#CREATE_NO_WINDOW
35-
.creation_flags(0x08000000);
35+
//.creation_flags(0x08000000);
3636

3737
let output = command
3838
.output()

src-tauri/src/processor/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ mod aggregator;
1616
mod executor;
1717
mod helpers;
1818
mod peptide_isolator;
19-
mod parser;
19+
pub mod parser;
2020

2121
pub async fn handle(
2222
should_remove_na_calculations: bool,

src-tauri/src/processor/parser.rs

+86-7
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,110 @@
1+
use std::io::Cursor;
12
use std::path::Path;
2-
use csv::ReaderBuilder;
3+
use csv::{Reader, ReaderBuilder};
34
use tokio::fs;
45
use tokio::fs::File;
56
use tokio::io::{AsyncSeekExt, AsyncWriteExt};
67

78

89
pub type Day = u64;
910

11+
pub type Mouse = String;
12+
1013
pub type Label = String;
1114

12-
pub struct Protein {
15+
#[derive(Debug)]
16+
pub struct Peptide {
1317
pub name: String,
14-
pub peptide: String,
18+
pub protein: String,
1519
pub charge_mass_ratio: f64,
16-
pub insensities: Vec<Option<u64>>,
20+
pub intensities: Vec<Option<u64>>,
1721
}
1822

1923
pub async fn parse(spreadsheet: &Path)
2024
-> Result<
21-
(Vec<Day>, Vec<Label>, Vec<Protein>),
25+
(Vec<Day>, Vec<Mouse>, Vec<Label>, Vec<Peptide>),
2226
Box<dyn std::error::Error>
2327
>
2428
{
25-
let mut file = File::open(spreadsheet).await?;
29+
let contents = fs::read(spreadsheet).await?;
2630
let mut rdr = ReaderBuilder::new()
2731
.has_headers(false)
28-
.from_reader(file.seek(1));
32+
.from_reader(Cursor::new(contents));
33+
34+
let (days, mice, labels) = extract_headers(&mut rdr)?;
35+
let peptides = extract_peptides(&mut rdr)?;
36+
37+
Ok((days, mice, labels, peptides))
38+
}
39+
40+
fn extract_peptides(rdr: &mut Reader<Cursor<Vec<u8>>>) -> Result<Vec<Peptide>, Box<dyn std::error::Error>> {
41+
let mut peptides = vec![];
42+
43+
for result in rdr.records().skip(1) {
44+
let record = result?;
45+
let name = record[0].to_string();
46+
let protein = record[1].to_string();
47+
let charge_mass_ratio = record[2].parse::<f64>()?;
48+
let intensities = record.iter().skip(3).map(|value| {
49+
if value == "#N/A" {
50+
None
51+
} else {
52+
value.parse::<u64>().ok()
53+
}
54+
})
55+
.collect::<Vec<Option<u64>>>();
56+
57+
peptides.push(Peptide {
58+
name,
59+
protein,
60+
charge_mass_ratio,
61+
intensities,
62+
});
63+
}
64+
65+
Ok(peptides)
66+
}
67+
68+
fn extract_headers(rdr: &mut Reader<Cursor<Vec<u8>>>) -> Result<(Vec<Day>, Vec<Mouse>, Vec<Label>), Box<dyn std::error::Error>> {
69+
let mut non_empty_row_count = 0;
70+
let mut days = vec![];
71+
let mut mice = vec![];
72+
let mut labels = vec![];
73+
74+
for row in rdr.records() {
75+
let record = row?;
76+
if record.iter().any(|field| !field.is_empty()) {
77+
non_empty_row_count += 1;
78+
79+
if non_empty_row_count == 1 {
80+
days = record
81+
.iter()
82+
.skip(3)
83+
.map(|col| col.to_string().parse::<Day>().unwrap())
84+
.collect::<Vec<_>>();
85+
}
86+
87+
if non_empty_row_count == 2 {
88+
mice = record
89+
.iter()
90+
.skip(3)
91+
.map(|col| col.to_string().parse::<Mouse>().unwrap())
92+
.collect::<Vec<_>>();
93+
}
94+
95+
if non_empty_row_count == 3 {
96+
labels = record
97+
.iter()
98+
.skip(3)
99+
.map(|col| col.to_string().parse::<Label>().unwrap())
100+
.collect::<Vec<_>>();
101+
}
29102

103+
if non_empty_row_count == 4 {
104+
break;
105+
}
106+
}
107+
}
30108

109+
Ok((days, mice, labels))
31110
}

src/routes/+layout.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
</script>
88

99
<Toaster richColors />
10-
<slot />
10+
<slot />

0 commit comments

Comments
 (0)