1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use super::fit;
use super::{PH10_STATIC, PH4_STATIC, TEMP_STATIC};
use splines::{Interpolation, Key, Spline};
pub struct Calibration {
pub model: [f64; 2],
pub rms: Option<f64>,
pub rsq: Option<f64>,
}
impl Calibration {
pub fn new(model: [f64; 2], rms: Option<f64>, rsq: Option<f64>) -> Calibration {
Calibration { model, rms, rsq }
}
}
impl Default for Calibration {
fn default() -> Self {
Calibration {
model: [1.0, 0.0],
rms: None,
rsq: None,
}
}
}
pub fn ph_calibration(ph_measured: &[f64; 2], temperature: &f64) -> Calibration {
let ph4_cal = interp_ph4(temperature).unwrap();
let ph10_cal = interp_ph10(temperature).unwrap();
let ph_cal = [ph4_cal, ph10_cal];
let calibration = fit::fit(ph_measured, &ph_cal);
let fit_eval = fit::evaluate(ph_measured, &ph_cal, &calibration);
Calibration::new(calibration, Some(fit_eval[0]), Some(fit_eval[1]))
}
pub fn ph_convert(ph_measured: &f64, calibration: &[f64; 2]) -> f64 {
let ph_calibrated = fit::predict(ph_measured, calibration);
ph_calibrated
}
pub fn interp_ph4(temperature: &f64) -> Option<f64> {
let pairs_iter = TEMP_STATIC.iter().zip(PH4_STATIC.iter());
let zipped_points: Vec<_> = pairs_iter
.map(|(x, y)| Key::new(*x, *y, Interpolation::Linear))
.collect();
let spline = Spline::from_vec(zipped_points);
let val = spline.sample(*temperature);
val
}
pub fn interp_ph10(temperature: &f64) -> Option<f64> {
let pairs_iter = TEMP_STATIC.iter().zip(PH10_STATIC.iter());
let zipped_points: Vec<_> = pairs_iter
.map(|(x, y)| Key::new(*x, *y, Interpolation::Linear))
.collect();
let spline = Spline::from_vec(zipped_points);
let val = spline.sample(*temperature);
val
}