///|
/// Structural validation for a complete force plate trial.
pub struct TrialShapeReport {
sample_count : Int
finite_force_samples : Int
finite_cop_samples : Int
monotonic_timestamps : Bool
finite_timestamps : Int
duration_s : Double
sampling_rate_hz : Double
first_bad_timestamp_index : Int
is_usable : Bool
} derive(Debug, Eq)
///|
fn finite_vec(force : Vec3) -> Bool {
!force.x.is_nan() &&
!force.x.is_inf() &&
!force.y.is_nan() &&
!force.y.is_inf() &&
!force.z.is_nan() &&
!force.z.is_inf()
}
///|
fn finite_cop_value(cop : CoPPoint) -> Bool {
!cop.x.is_nan() && !cop.x.is_inf() && !cop.y.is_nan() && !cop.y.is_inf()
}
///|
/// Validates timestamp order and finite coverage without changing the trial.
pub fn validate_trial_shape(trial : ForceTrial) -> TrialShapeReport {
let mut finite_force = 0
let mut finite_cop = 0
let mut finite_times = 0
let mut monotonic = true
let mut first_bad = -1
for i = 0; i < trial.samples.length(); i = i + 1 {
let sample = trial.samples[i]
if finite_vec(sample.force) {
finite_force = finite_force + 1
}
if finite_cop_value(sample.cop) {
finite_cop = finite_cop + 1
}
if !sample.timestamp.is_nan() && !sample.timestamp.is_inf() {
finite_times = finite_times + 1
} else if first_bad < 0 {
first_bad = i
}
if i > 0 && sample.timestamp <= trial.samples[i - 1].timestamp {
monotonic = false
if first_bad < 0 {
first_bad = i
}
}
}
let duration = if trial.samples.length() > 1 {
trial.samples[trial.samples.length() - 1].timestamp -
trial.samples[0].timestamp
} else {
0.0
}
let rate = estimate_sample_rate(trial.get_timestamps())
{
sample_count: trial.samples.length(),
finite_force_samples: finite_force,
finite_cop_samples: finite_cop,
monotonic_timestamps: monotonic && finite_times == trial.samples.length(),
finite_timestamps: finite_times,
duration_s: if duration > 0.0 {
duration
} else {
0.0
},
sampling_rate_hz: rate,
first_bad_timestamp_index: first_bad,
is_usable: trial.samples.length() >= 2 &&
finite_force == trial.samples.length() &&
finite_cop == trial.samples.length() &&
monotonic &&
finite_times == trial.samples.length() &&
duration > 0.0,
}
}