use anyhow::bail;
use std::fs::File;
use std::io::{BufRead, BufReader, Seek};
pub struct DataHandler {
file: File,
timestamps: Vec<f64>,
trajectory: Vec<[f64; 3]>,
ori: Vec<[f64; 3]>,
forces: Vec<[f64; 6]>,
}
impl DataHandler {
pub fn read_data_from_file(filepath: String) -> Result<Self, anyhow::Error> {
let mut file = File::open(filepath)?;
let mut timestamps: Vec<f64> = vec![];
let mut trajectory: Vec<[f64; 3]> = vec![];
let mut ori: Vec<[f64; 3]> = vec![];
let mut forces: Vec<[f64; 6]> = vec![];
for line in BufReader::new(file.try_clone()?).lines() {
let line_split = line?;
let line_split: Vec<&str> = line_split.split(",").collect();
timestamps.push(line_split[1].parse()?);
let mut str_to_parse = format!("{},{},{}", line_split[2], line_split[3], line_split[4]);
trajectory.push(str_to_traj_ori(&str_to_parse)?);
str_to_parse = format!("{},{},{}", line_split[5], line_split[6], line_split[7]);
ori.push(str_to_traj_ori(&str_to_parse)?);
str_to_parse = format!(
"{},{},{},{},{},{}",
line_split[8],
line_split[9],
line_split[10],
line_split[11],
line_split[12],
line_split[13]
);
forces.push(str_to_force(&str_to_parse)?);
}
file.rewind()?;
Ok(Self {
file,
timestamps,
trajectory,
ori,
forces,
})
}
pub fn get_traj_rect_bnds(&self) -> Result<[f64; 4], anyhow::Error> {
let mut min_x = 9999.0;
let mut max_x = -9999.0;
let mut min_y = 9999.0;
let mut max_y = -9999.0;
for pos in self.trajectory.iter() {
if pos[0] < min_x {
min_x = pos[0];
} else if pos[0] > max_x {
max_x = pos[0];
}
if pos[1] < min_y {
min_y = pos[1];
} else if pos[1] > max_y {
max_y = pos[1];
}
}
Ok([min_x, max_x, min_y, max_y])
}
pub fn get_traj(&self) -> Vec<[f64; 3]> {
self.trajectory.clone()
}
pub fn get_force(&self) -> Vec<[f64; 6]> {
self.forces.clone()
}
pub fn get_traj_force_pairs(&mut self) -> Vec<([f64; 3], [f64; 6])> {
let mut traj_force_pairs: Vec<([f64; 3], [f64; 6])> = vec![];
for (i, pnt) in self.trajectory.iter_mut().enumerate() {
traj_force_pairs.push((*pnt, self.forces[i]));
}
traj_force_pairs
}
}
fn str_to_traj_ori(inp_string: &str) -> Result<[f64; 3], anyhow::Error> {
let mut curr_vec: [f64; 3] = [f64::NAN, f64::NAN, f64::NAN];
let x_strip = rem_first_and_last(inp_string);
for (cnt, token) in x_strip.split(",").enumerate() {
curr_vec[cnt] = token.parse()?;
}
if curr_vec.iter().any(|vec| vec.is_nan()) {
bail!("Failed to parse vector from string!")
}
Ok(curr_vec)
}
fn str_to_force(x: &str) -> Result<[f64; 6], anyhow::Error> {
let mut curr_vec: [f64; 6] = [f64::NAN, f64::NAN, f64::NAN, f64::NAN, f64::NAN, f64::NAN];
let x_strip = rem_first_and_last(x);
for (cnt, token) in x_strip.split(",").enumerate() {
curr_vec[cnt] = token.parse()?;
}
if curr_vec.iter().any(|vec| vec.is_nan()) {
bail!("Failed to parse vector from string!")
}
Ok(curr_vec)
}
fn rem_first_and_last(value: &str) -> &str {
let mut chars = value.chars();
chars.next();
chars.next_back();
chars.as_str()
}