Skip to content

Commit

Permalink
implement freeze check
Browse files Browse the repository at this point in the history
  • Loading branch information
intarga committed May 2, 2024
1 parent a0fa60f commit 515816d
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ use thiserror::Error;

mod qc_tests;
pub use qc_tests::{
buddy_check::buddy_check, dip_check::dip_check, range_check::range_check, sct::sct,
step_check::step_check,
buddy_check::buddy_check, dip_check::dip_check, freeze_check::freeze_check,
range_check::range_check, sct::sct, step_check::step_check,
};

mod util;
Expand Down
45 changes: 45 additions & 0 deletions src/qc_tests/freeze_check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::{Error, Flag, SeriesCache};

/// Timeseries QC test that checks for streaks of repeating values.
///
/// If `num_points` observations in a row are identical, the last will be flagged as Flag::Fail, if
/// any of the last `num_points` observations are missing, it will be flagged as Flag::DataMissing,
/// else Flag::Pass.
///
/// As (`num_points` - 1) predecessors to each observation are needed, the [`SeriesCache`] provided must have
/// `num_leading_points` >= `num_points` - 1.
///
/// ## Errors
///
/// - data is invalid
/// - data has `num_leading_points` < `num_points` - 1
pub fn freeze_check(data: &SeriesCache, num_points: u8) -> Result<Vec<Flag>, Error> {
let (leading_trim, lead_overflow) = data
.num_leading_points
.overflowing_sub(num_points.saturating_sub(1));

if lead_overflow || (leading_trim + num_points) as usize > data.values.len() {
// TODO: nicer error here?
return Err(Error::InvalidInputShape("data".to_string()));
}

let trimmed = &data.values
[leading_trim as usize..(data.values.len() - data.num_trailing_points as usize)];

let windows = trimmed.windows(num_points as usize);

Ok(windows
.map(|data| {
if data.contains(&None) {
return Flag::DataMissing;
}
let data: Vec<f32> = data.iter().map(|opt| opt.unwrap()).collect();

let base = data[0];
if !data.iter().any(|x| *x != base) {
return Flag::Fail;
}
Flag::Pass
})
.collect())
}
1 change: 1 addition & 0 deletions src/qc_tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub(super) mod buddy_check;
pub(super) mod dip_check;
pub(super) mod freeze_check;
pub(super) mod range_check;
pub(super) mod sct;
pub(super) mod step_check;

0 comments on commit 515816d

Please sign in to comment.