#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct ParameterLayout {
geometry: usize,
clocks: usize,
ztd: usize,
ambiguities: usize,
}
impl ParameterLayout {
pub(crate) const fn spp(clocks: usize) -> Self {
Self {
geometry: 3,
clocks,
ztd: 0,
ambiguities: 0,
}
}
pub(crate) const fn rtk(ambiguities: usize) -> Self {
Self {
geometry: 3,
clocks: 0,
ztd: 0,
ambiguities,
}
}
pub(crate) const fn ppp(epoch_clocks: usize, ztd: usize, ambiguities: usize) -> Self {
Self {
geometry: 3,
clocks: epoch_clocks,
ztd,
ambiguities,
}
}
pub(crate) const fn dim(&self) -> usize {
self.geometry + self.clocks + self.ztd + self.ambiguities
}
pub(crate) const fn ambiguity_offset(&self) -> usize {
self.geometry + self.clocks + self.ztd
}
}
pub(crate) fn undifferenced_design_row(
los_base: [f64; 3],
epoch_idx: usize,
n_epochs: usize,
ztd_mapping: Option<f64>,
n_ambiguities: usize,
active_ambiguity: Option<usize>,
) -> Vec<f64> {
let mut row = vec![los_base[0], los_base[1], los_base[2]];
row.extend((0..n_epochs).map(|idx| if idx == epoch_idx { 1.0 } else { 0.0 }));
if let Some(mapping) = ztd_mapping {
row.push(mapping);
}
row.extend((0..n_ambiguities).map(|idx| {
if Some(idx) == active_ambiguity {
1.0
} else {
0.0
}
}));
row
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn dims_match_open_coded_unknown_counts() {
assert_eq!(ParameterLayout::spp(1).dim(), 4);
assert_eq!(ParameterLayout::spp(2).dim(), 5);
assert_eq!(ParameterLayout::rtk(0).dim(), 3);
assert_eq!(ParameterLayout::rtk(7).dim(), 10);
assert_eq!(ParameterLayout::ppp(5, 0, 4).dim(), 12);
assert_eq!(ParameterLayout::ppp(5, 1, 4).dim(), 13);
}
#[test]
fn ambiguity_offset_follows_geometry_clocks_ztd() {
assert_eq!(ParameterLayout::ppp(5, 1, 4).ambiguity_offset(), 3 + 5 + 1);
assert_eq!(ParameterLayout::rtk(7).ambiguity_offset(), 3);
}
#[test]
fn undifferenced_design_row_lays_columns_in_layout_order() {
let float_phase = undifferenced_design_row([-0.1, -0.2, -0.3], 1, 2, Some(1.5), 3, Some(2));
assert_eq!(
float_phase,
vec![-0.1, -0.2, -0.3, 0.0, 1.0, 1.5, 0.0, 0.0, 1.0]
);
let float_code = undifferenced_design_row([-0.1, -0.2, -0.3], 1, 2, Some(1.5), 3, None);
assert_eq!(
float_code,
vec![-0.1, -0.2, -0.3, 0.0, 1.0, 1.5, 0.0, 0.0, 0.0]
);
let fixed = undifferenced_design_row([-0.1, -0.2, -0.3], 0, 2, None, 0, None);
assert_eq!(fixed, vec![-0.1, -0.2, -0.3, 1.0, 0.0]);
}
}