psboard-qaqc-postprocess/src/skew.rs

79 lines
2.1 KiB
Rust
Raw Normal View History

use anyhow::{Context, Result};
use itertools::{self, Itertools};
use std::{
fs::File,
io::{BufRead, BufReader},
path::PathBuf,
};
fn parse_single_line(l: String) -> Result<(f64, u32, u32)> {
let mut splitted = l.split_whitespace();
let delay: f64 = splitted.next().context("No value found")?.parse()?;
let high_count: u32 = splitted.next().context("No value found")?.parse()?;
let low_count: u32 = splitted.next().context("No value found")?.parse()?;
assert!(splitted.next().is_none());
Ok((delay, high_count, low_count))
}
fn parse_counts(f: impl BufRead) -> Result<f64> {
let delay = f
.lines()
.filter_map(|l| parse_single_line(l.ok()?).ok())
.tuple_windows()
.find(|((_, high1, _), (_, high2, _))| *high1 < 500 && *high2 >= 500)
.context("Failed to get rise edge")?
.1
.0;
Ok(delay)
}
/// Read clock scan file and get skew.
pub fn parse_count_file(filename: PathBuf) -> Result<f64> {
let buf_reader = BufReader::new(
File::open(filename.clone())
.context(format!("Error opening file {}", filename.display()))?,
);
parse_counts(buf_reader)
}
#[cfg(test)]
mod test {
use super::parse_counts;
#[test]
fn test_parse_counts1() {
let file = "
0.1 0 1000
0.2 10 990
0.3 470 530
0.4 500 500
0.5 510 490
0.6 900 100
0.7 1000 0
"
.as_bytes();
assert_eq!(parse_counts(file).unwrap(), 0.4);
let file2 = "
0.1 0 1000
0.2 10 990
0.3 470 530
0.4 499 501
0.5 510 490
0.6 900 100
0.7 1000 0
"
.as_bytes();
assert_eq!(parse_counts(file2).unwrap(), 0.5);
let file3 = "
0.1 0 1000
0.2 10 990
0.3 470 530
0.4 501 499
0.5 510 490
0.6 900 100
0.7 1000 0
"
.as_bytes();
assert_eq!(parse_counts(file3).unwrap(), 0.4);
}
}