diff --git a/rinex-cli/src/main.rs b/rinex-cli/src/main.rs index 772947d13..671546bea 100644 --- a/rinex-cli/src/main.rs +++ b/rinex-cli/src/main.rs @@ -270,18 +270,18 @@ pub fn main() -> Result<(), rinex::Error> { * Code Multipath analysis */ if cli.multipath() { - let data = ctx - .primary_data() - .observation_phase_align_origin() - .observation_phase_carrier_cycles() - .mp(); - plot::plot_gnss_dcb( - &mut plot_ctx, - "Code Multipath Biases", - "Meters of delay", - &data, - ); - info!("--mp analysis"); + //let data = ctx + // .primary_data() + // .observation_phase_align_origin() + // .observation_phase_carrier_cycles() + // .mp(); + //plot::plot_gnss_dcb( + // &mut plot_ctx, + // "Code Multipath Biases", + // "Meters of delay", + // &data, + //); + warn!("--mp analysis not available yet"); } /* * [GF] recombination visualization requested diff --git a/rinex/src/lib.rs b/rinex/src/lib.rs index d64987fe2..701a10d99 100644 --- a/rinex/src/lib.rs +++ b/rinex/src/lib.rs @@ -984,36 +984,6 @@ impl Rinex { results } */ - /* - /// Extracts Raw Carrier Phase observations, - /// from this Observation record, on an epoch basis an per space vehicle. - /// Does not produce anything if self is not an Observation RINEX. - pub fn observation_phase(&self) -> BTreeMap<(Epoch, EpochFlag), HashMap>> { - let mut ret: BTreeMap>> = BTreeMap::new(); - if let Some(r) = self.record.as_obs() { - for ((e, _), (_, sv)) in record.iter() { - let mut map: BTreeMap> = BTreeMap::new(); - for (sv, obs) in sv.iter() { - let mut v: Vec<(String, f64)> = Vec::new(); - for (observable, data) in obs.iter() { - if observable.is_phase_observation() { - v.push((code.clone(), data.obs)); - } - } - if v.len() > 0 { - // did come with at least 1 Phase obs - map.insert(*sv, v); - } - } - if map.len() > 0 { - // did produce something - results.insert(*e, map); - } - } - } - ret - } - */ /* /// Extracts Carrier phases without Ionospheric path delay contributions, /// by extracting [carrier_phases] and using the differential (dual frequency) compensation. @@ -2882,19 +2852,88 @@ impl Dcb for Rinex { } } -#[cfg(feature = "obs")] -use observation::Mp; - -#[cfg(feature = "obs")] -impl Mp for Rinex { - fn mp(&self) -> HashMap>> { - if let Some(r) = self.record.as_obs() { - r.dcb() - } else { - panic!("wrong rinex type"); - } - } -} +//#[cfg(feature = "obs")] +//use observation::Mp; +// +//#[cfg(feature = "obs")] +//impl Mp for Rinex { +// fn mp(&self) -> HashMap>> { +// /* +// * Determine mean value of all observed Phase and Pseudo Range +// * observations, for all Sv +// */ +// let mut mean: HashMap> = HashMap::new(); +// /* +// * Associate a Phase code to all PR codes +// */ +// let mut associations: HashMap = HashMap::new(); +// +// let pr_codes: Vec = self.observable() +// .filter_map(|obs| +// if obs.is_pseudorange_observable() { +// Some(obs.clone()) +// } else { +// None +// }) +// .collect(); +// +// for observable in self.observable() { +// if !observable.is_phase_observable() { +// if !observable.is_pseudorange_observable() { +// continue; +// } +// } +// // code associations (for future combianations) +// if observable.is_phase_observable() { +// for pr_code in &pr_codes { +// +// } +// } +// +// for sv in self.sv() { +// /* +// * average phase values +// */ +// let phases: Vec = self.carrier_phase() +// .filter_map(|(_, svnn, obs, ph)| { +// if sv == svnn && observable == obs { +// Some(ph) +// } else { +// None +// } +// }) +// .collect(); +// if let Some(data) = mean.get_mut(&sv) { +// data.insert(observable.clone(), phases.mean()); +// } else { +// let mut map: HashMap = HashMap::new(); +// map.insert(observable.clone(), phases.mean()); +// mean.insert(sv, map); +// } +// /* +// * average PR values +// */ +// let pr: Vec = self.pseudo_range() +// .filter_map(|(_, svnn, obs, pr)| { +// if sv == svnn && observable == obs { +// Some(pr) +// } else { +// None +// } +// }) +// .collect(); +// if let Some(data) = mean.get_mut(&sv) { +// data.insert(observable.clone(), pr.mean()); +// } else { +// let mut map: HashMap = HashMap::new(); +// map.insert(observable.clone(), pr.mean()); +// mean.insert(sv, map); +// } +// } +// } +// HashMap::new() +// } +//} #[cfg(feature = "obs")] use observation::Combine; diff --git a/rinex/src/meteo/record.rs b/rinex/src/meteo/record.rs index 2df3cd840..7e15a611f 100644 --- a/rinex/src/meteo/record.rs +++ b/rinex/src/meteo/record.rs @@ -436,69 +436,3 @@ impl Interpolate for Record { unimplemented!("meteo:record:interpolate_mut()") } } - -#[cfg(feature = "obs")] -use crate::observation::{Observation, StatisticalOps}; - -#[cfg(feature = "obs")] -use statrs::statistics::Statistics; - -#[cfg(feature = "obs")] -fn statistical_estimate(rec: &Record, ops: StatisticalOps) -> HashMap { - let mut ret: HashMap = HashMap::new(); - let mut dataset: HashMap> = HashMap::new(); - for (_t, observables) in rec { - for (observable, point) in observables { - if let Some(data) = dataset.get_mut(&observable) { - data.push(*point); - } else { - dataset.insert(observable.clone(), vec![*point]); - } - } - } - for (observable, data) in dataset { - let stats = match ops { - StatisticalOps::Min => data.min(), - StatisticalOps::Max => data.max(), - StatisticalOps::Mean => data.mean(), - StatisticalOps::StdDev => data.std_dev(), - StatisticalOps::StdVar => data.variance(), - }; - ret.insert(observable.clone(), stats); - } - ret -} - -#[cfg(feature = "obs")] -impl Observation for Record { - fn min(&self) -> (Option, HashMap>) { - unimplemented!("only on OBS RINEX!"); - } - fn max(&self) -> (Option, HashMap>) { - unimplemented!("only on OBS RINEX!"); - } - fn mean(&self) -> (Option, HashMap>) { - unimplemented!("only on OBS RINEX!"); - } - fn std_var(&self) -> (Option, HashMap>) { - unimplemented!("only on OBS RINEX!"); - } - fn std_dev(&self) -> (Option, HashMap>) { - unimplemented!("only on OBS RINEX!"); - } - fn min_observable(&self) -> HashMap { - statistical_estimate(self, StatisticalOps::Min) - } - fn max_observable(&self) -> HashMap { - statistical_estimate(self, StatisticalOps::Max) - } - fn std_dev_observable(&self) -> HashMap { - statistical_estimate(self, StatisticalOps::StdDev) - } - fn std_var_observable(&self) -> HashMap { - statistical_estimate(self, StatisticalOps::StdVar) - } - fn mean_observable(&self) -> HashMap { - statistical_estimate(self, StatisticalOps::Mean) - } -} diff --git a/rinex/src/observation/mod.rs b/rinex/src/observation/mod.rs index d311885a1..3725d2acb 100644 --- a/rinex/src/observation/mod.rs +++ b/rinex/src/observation/mod.rs @@ -174,122 +174,9 @@ impl HeaderFields { } } -#[cfg(feature = "obs")] -#[derive(Debug, Clone, Copy)] -pub(crate) enum StatisticalOps { - Min, - Max, - Mean, - StdDev, - StdVar, -} - #[cfg(feature = "obs")] use std::collections::BTreeMap; -/// OBS RINEX specific analysis trait. -/// Include this trait to unlock Observation analysis, mainly statistical analysis. -#[cfg(feature = "obs")] -#[cfg_attr(docrs, doc(cfg(feature = "obs")))] -pub trait Observation { - /// Returns minimum value observed, throughout all epochs, sorted by Observable. - /// This also applies to clock receiver estimate, - /// when requested on OBS RINEX files, not METEO files. - /// ``` - /// use rinex::*; // prelude + macros - /// use rinex::prelude::*; - /// use std::str::FromStr; // observable! - /// use rinex::observation::Observation; // .min_observable() - /// - /// // OBS RINEX example - /// let rinex = Rinex::from_file("../test_resources/OBS/V3/DUTH0630.22O") - /// .unwrap(); - /// let min_values = rinex.min_observable(); - /// for (observable, min_value) in min_values { - /// if observable == observable!("S1C") { - /// // minimum signal strength for carrier 1 - /// assert_eq!(min_value, 37.75); // L1 carrier min (worst) RSSI - /// } - /// } - /// - /// // METEO RINEX example - /// let rinex = Rinex::from_file("../test_resources/MET/V2/clar0020.00m") - /// .unwrap(); - /// let min_values = rinex.min_observable(); - /// for (observable, min_value) in min_values { - /// if observable == Observable::Temperature { - /// assert_eq!(min_value, 8.4); // min value encountered on that day - /// } - /// } - /// ``` - fn min_observable(&self) -> HashMap; - - /// Returns maximal value observed, throughout all epochs, sorted by Observable. - /// See [Self::min_observable()] for API example. - fn max_observable(&self) -> HashMap; - - /// Returns mean observation, throughout all epochs, sorted by Observable. - /// See [Self::min_observable()] for API example. - fn mean_observable(&self) -> HashMap; - - /// Returns standard deviation for all Observables. - /// See [Self::min_observable()] for API example. - fn std_dev_observable(&self) -> HashMap; - - /// Returns standard variance for all Observables. - /// See [Self::min_observable()] for API example. - fn std_var_observable(&self) -> HashMap; - - /// Returns minimum value observed throughout all epochs sorted by - /// Satellite vehicle and Observable. This does not apply to METEO - /// RINEX files. - /// ``` - /// use rinex::*; - /// use rinex::prelude::*; // basics - /// use std::str::FromStr; // sv!, observable! - /// use rinex::observation::Observation; // .min() - /// - /// // OBS RINEX example - /// let rinex = Rinex::from_file("../test_resources/OBS/V3/DUTH0630.22O") - /// .unwrap(); - /// - /// let (min_clock, min_values) = rinex.min(); - /// assert!(min_clock.is_none()); // we don't have an example file with such information yet - /// - /// for (sv, observables) in min_values { - /// if sv == sv!("G08") { - /// for (observable, min_value) in observables { - /// if observable == observable!("S1C") { - /// // minimum signal strength for carrier 1 - /// // for that particular vehicle - /// } - /// } - /// } - /// } - /// ``` - fn min(&self) -> (Option, HashMap>); - - /// Returns maximal value observed throughout all epochs sorted by - /// Satellite vehicle and Observable. This does not apply to METEO - /// RINEX files. See [Self::min()] for API example. - fn max(&self) -> (Option, HashMap>); - - /// Returns mean value observed throughout all epochs sorted by - /// Satellite vehicle and Observable. This does not apply to METEO - /// RINEX files. See [Self::min()] for API example. - fn mean(&self) -> (Option, HashMap>); - - /// Returns observations deviation throughout all epochs sorted by - /// Satellite vehicle and Observable. This does not apply to METEO - /// RINEX files. See [Self::min()] for API example. - fn std_dev(&self) -> (Option, HashMap>); - - /// Returns observations variance throughout all epochs sorted by - /// Satellite vehicle and Observable. This does not apply to METEO - /// RINEX files. See [Self::min()] for API example. - fn std_var(&self) -> (Option, HashMap>); -} - /// GNSS signal recombination trait. /// Import this to recombine OBS RINEX with usual recombination methods. /// This only applies to OBS RINEX records. diff --git a/rinex/src/observation/record.rs b/rinex/src/observation/record.rs index 09c200484..4e7c88aab 100644 --- a/rinex/src/observation/record.rs +++ b/rinex/src/observation/record.rs @@ -1282,167 +1282,6 @@ impl Decimate for Record { } } -#[cfg(feature = "obs")] -use statrs::statistics::Statistics; - -#[cfg(feature = "obs")] -use crate::observation::{Observation, StatisticalOps}; - -#[cfg(feature = "obs")] -/* - * Evaluate a specific statistical estimate on this record data set - */ -fn statistical_estimate( - rec: &Record, - ops: StatisticalOps, -) -> (Option, HashMap>) { - let mut ret: (Option, HashMap>) = (None, HashMap::new()); - - // Vectorize clock offset (in time), so we can invoke statrs() on it - let data: Vec = rec - .iter() - .filter_map(|(_, (clk, _))| { - if let Some(clk) = clk { - Some(*clk) - } else { - None - } - }) - .collect(); - - if data.len() > 0 { - // data exists - match ops { - StatisticalOps::Min => ret.0 = Some(data.min()), - StatisticalOps::Max => ret.0 = Some(data.max()), - StatisticalOps::Mean => ret.0 = Some(data.mean()), - StatisticalOps::StdDev => ret.0 = Some(data.std_dev()), - StatisticalOps::StdVar => ret.0 = Some(data.variance()), - } - } - - // Vectorize data (in time) so we can invoke statrs() on it - let mut data: HashMap>> = HashMap::new(); - - for (_epoch, (_clk, svnn)) in rec { - for (sv, observations) in svnn { - for (observable, obs_data) in observations { - if let Some(data) = data.get_mut(&sv) { - if let Some(data) = data.get_mut(&observable) { - data.push(obs_data.obs); // append - } else { - data.insert(observable.clone(), vec![obs_data.obs]); - } - } else { - let mut map: HashMap> = HashMap::new(); - map.insert(observable.clone(), vec![obs_data.obs]); - data.insert(sv.clone(), map); - } - } - } - } - - // build returned data - for (sv, observables) in data { - for (observable, data) in observables { - // invoke statrs - let stats = match ops { - StatisticalOps::Min => data.min(), - StatisticalOps::Max => data.max(), - StatisticalOps::Mean => data.mean(), - StatisticalOps::StdDev => data.std_dev(), - StatisticalOps::StdVar => data.variance(), - }; - if let Some(data) = ret.1.get_mut(&sv) { - data.insert(observable.clone(), stats); - } else { - let mut map: HashMap = HashMap::new(); - map.insert(observable.clone(), stats); - ret.1.insert(sv.clone(), map); - } - } - } - - ret -} - -#[cfg(feature = "obs")] -/* - * Evaluate a specific statistical estimate on this record data set - */ -fn statistical_observable_estimate(rec: &Record, ops: StatisticalOps) -> HashMap { - let mut ret: HashMap = HashMap::new(); - // For all statistical estimates but StdDev/StdVar - // We can compute across all vehicles then shrink 1D - match ops { - StatisticalOps::StdVar | StatisticalOps::StdDev => {}, - _ => { - // compute across all observables, then per Sv - let (_, data) = statistical_estimate(rec, ops); - let mut data_set: HashMap> = HashMap::new(); - for (_sv, observables) in data { - for (observable, value) in observables { - if let Some(data) = data_set.get_mut(&observable) { - data.push(value); - } else { - data_set.insert(observable.clone(), vec![value]); - } - } - } - for (observable, values) in data_set { - // invoke statrs - match ops { - StatisticalOps::Min => { - ret.insert(observable.clone(), values.min()); - }, - StatisticalOps::Max => { - ret.insert(observable.clone(), values.max()); - }, - StatisticalOps::Mean => { - ret.insert(observable.clone(), values.mean()); - }, - _ => {}, // does not apply - }; - } - }, - } - ret -} - -#[cfg(feature = "obs")] -impl Observation for Record { - fn min(&self) -> (Option, HashMap>) { - statistical_estimate(self, StatisticalOps::Min) - } - fn max(&self) -> (Option, HashMap>) { - statistical_estimate(self, StatisticalOps::Max) - } - fn mean(&self) -> (Option, HashMap>) { - statistical_estimate(self, StatisticalOps::Mean) - } - fn std_var(&self) -> (Option, HashMap>) { - statistical_estimate(self, StatisticalOps::StdVar) - } - fn std_dev(&self) -> (Option, HashMap>) { - statistical_estimate(self, StatisticalOps::StdDev) - } - fn min_observable(&self) -> HashMap { - statistical_observable_estimate(self, StatisticalOps::Min) - } - fn max_observable(&self) -> HashMap { - statistical_observable_estimate(self, StatisticalOps::Max) - } - fn std_dev_observable(&self) -> HashMap { - statistical_observable_estimate(self, StatisticalOps::StdDev) - } - fn std_var_observable(&self) -> HashMap { - statistical_observable_estimate(self, StatisticalOps::StdVar) - } - fn mean_observable(&self) -> HashMap { - statistical_observable_estimate(self, StatisticalOps::Mean) - } -} - #[cfg(feature = "obs")] use crate::observation::Combine; @@ -1834,7 +1673,7 @@ impl Combine for Record { #[cfg(feature = "obs")] use crate::{ carrier, - observation::{Dcb, Mp}, + observation::Dcb, //Mp}, }; #[cfg(feature = "obs")] @@ -2000,148 +1839,6 @@ impl IonoDelay for Record { } } -#[cfg(feature = "obs")] -impl Mp for Record { - fn mp(&self) -> HashMap>> { - let mut ret: HashMap>> = - HashMap::new(); - /* - * Determine mean value of all datasets - */ - let (_, mean) = self.mean(); // drop mean{clk} - //println!("MEAN VALUES {:?}", mean); //DEBUG - /* - * Run algorithm - */ - let mut associated: HashMap = HashMap::new(); // Ph code to associate to this Mpx - // for operation consistency - for (epoch, (_, vehicles)) in self { - for (sv, observations) in vehicles { - let _mean_sv = mean.get(&sv).unwrap(); - for (lhs_observable, lhs_data) in observations { - if lhs_observable.is_pseudorange_observable() { - let pr_i = lhs_data.obs; // - mean_sv.get(lhs_code).unwrap().1; - let lhs_code = lhs_observable.to_string(); - let mp_code = &lhs_code[2..]; //TODO will not work on RINEX2 - let lhs_carrier = &lhs_code[1..2]; - let mut ph_i: Option = None; - let mut ph_j: Option = None; - /* - * This will restrict combinations to - * 1 => 2 - * and M => 1 - */ - let rhs_carrier = match lhs_carrier { - "1" => "2", - _ => "1", - }; - /* - * locate related L_i PH code - */ - for (observable, data) in observations { - let ph_code = format!("L{}", mp_code); - let code = observable.to_string(); - if code.eq(&ph_code) { - ph_i = Some(data.obs); // - mean_sv.get(code).unwrap().1); - break; // DONE - } - } - /* - * locate another L_j PH code - */ - if let Some(to_locate) = associated.get(mp_code) { - /* - * We already have an association, keep it consistent throughout - * operations - */ - for (observable, data) in observations { - let code = observable.to_string(); - let carrier_code = &code[1..2]; - if carrier_code == rhs_carrier { - // correct carrier signal - if code.eq(to_locate) { - // match - ph_j = Some(data.obs); // - mean_sv.get(code).unwrap().1); - break; // DONE - } - } - } - } else { - // first: prefer the same code against rhs carrier - let to_locate = format!("L{}{}", rhs_carrier, &mp_code[1..]); - for (observable, data) in observations { - let code = observable.to_string(); - let carrier_code = &code[1..2]; - if carrier_code == rhs_carrier { - // correct carrier - if code.eq(&to_locate) { - // match - ph_j = Some(data.obs); // - mean_sv.get(code).unwrap().1); - associated.insert(mp_code.to_string(), code.clone()); - break; // DONE - } - } - } - if ph_j.is_none() { - /* - * Same code against different carrier does not exist - * try to grab another PH code, against rhs carrier - */ - for (observable, data) in observations { - let code = observable.to_string(); - let carrier_code = &code[1..2]; - if carrier_code == rhs_carrier { - if observable.is_phase_observable() { - ph_j = Some(data.obs); // - mean_sv.get(code).unwrap().1); - associated.insert(mp_code.to_string(), code.clone()); - break; // DONE - } - } - } - } - } - if ph_i.is_none() || ph_j.is_none() { - break; // incomplete associations, do not proceed further - } - let ph_i = ph_i.unwrap(); - let ph_j = ph_j.unwrap(); - let lhs_carrier = lhs_observable.carrier(sv.constellation).unwrap(); - let rhs_carrier = lhs_observable //rhs_observable TODO - .carrier(sv.constellation) - .unwrap(); - /*let gamma = (lhs_carrier.frequency() / rhs_carrier.frequency()).powf(2.0); - let alpha = (gamma +1.0_f64) / (gamma - 1.0_f64); - let beta = 2.0_f64 / (gamma - 1.0_f64); - let mp = pr_i - alpha * ph_i + beta * ph_j;*/ - - let alpha = 2.0_f64 * rhs_carrier.frequency().powf(2.0) - / (lhs_carrier.frequency().powf(2.0) - - rhs_carrier.frequency().powf(2.0)); - let mp = pr_i - ph_i - alpha * (ph_i - ph_j); - if let Some(data) = ret.get_mut(mp_code) { - if let Some(data) = data.get_mut(&sv) { - data.insert(*epoch, mp); - } else { - let mut bmap: BTreeMap<(Epoch, EpochFlag), f64> = BTreeMap::new(); - bmap.insert(*epoch, mp); - data.insert(*sv, bmap); - } - } else { - let mut bmap: BTreeMap<(Epoch, EpochFlag), f64> = BTreeMap::new(); - let mut map: BTreeMap> = - BTreeMap::new(); - bmap.insert(*epoch, mp); - map.insert(*sv, bmap); - ret.insert(mp_code.to_string(), map); - } - } - } - } - } - ret - } -} - #[cfg(test)] mod test { use super::*; diff --git a/rinex/src/tests/mod.rs b/rinex/src/tests/mod.rs index a92ab8e64..dacb79326 100644 --- a/rinex/src/tests/mod.rs +++ b/rinex/src/tests/mod.rs @@ -17,4 +17,3 @@ mod parsing; mod production; mod sampling; mod smoothing; -mod stats; diff --git a/rinex/src/tests/stats.rs b/rinex/src/tests/stats.rs deleted file mode 100644 index 5de0dfdbc..000000000 --- a/rinex/src/tests/stats.rs +++ /dev/null @@ -1,347 +0,0 @@ -#[cfg(test)] -mod test { - use crate::*; - use crate::{observation::*, prelude::*}; - use std::str::FromStr; - fn run_test(rinex: &Rinex, ops: &str, expected: Vec<(Sv, Vec<(Observable, f64)>)>) { - let (clk_stats, stats) = match ops { - "min" => rinex.min(), - "max" => rinex.max(), - "mean" => rinex.mean(), - _ => panic!("unknown test"), - }; - assert!(clk_stats.is_none()); // always none on our test pool - - for (sv, fields) in expected { - let sv_data = stats.get(&sv); - assert!( - sv_data.is_some(), - "{}", - format!("\"{}\" stats missing for vehicle \"{}\"", ops, sv) - ); - let sv_data = sv_data.unwrap(); - for (observable, expected) in fields { - let data = sv_data.get(&observable); - assert!( - data.is_some(), - "{}", - format!( - "\"{}\" stats missing for vehicle \"{}\" - \"{}\"", - ops, sv, observable - ) - ); - let data = data.unwrap(); - let e = *data - expected; - assert!( - e.abs() < 1E-5, - "{}", - format!( - "\"{}\" test failed for \"{}\" - \"{}\", expecting {} got {}", - ops, sv, observable, expected, *data - ) - ); - } - } - } - fn run_obsv_test(rinex: &Rinex, ops: &str, expected: Vec<(Observable, f64)>) { - let stats = match ops { - "min" => rinex.min_observable(), - "max" => rinex.max_observable(), - "mean" => rinex.mean_observable(), - _ => panic!("unknown test"), - }; - - for (observable, expected) in expected { - let results = stats.get(&observable); - assert!( - results.is_some(), - "{}", - format!( - "\"{}\" observable stats results missing for observable \"{}\"", - ops, observable - ) - ); - let results = results.unwrap(); - let err = *results - expected; - assert!( - err.abs() < 1E-5, - "{}", - format!( - "\"{}\" observable test failed for - \"{}\", expecting {} - got {}", - ops, observable, expected, results - ) - ); - } - } - #[test] - fn stats() { - let rinex = Rinex::from_file("../test_resources/OBS/V3/DUTH0630.22O").unwrap(); - - let expected: Vec<(Sv, Vec<(Observable, f64)>)> = vec![ - ( - sv!("g01"), - vec![ - ( - observable!("c1c"), - (20243517.560 + 20805393.080 + 21653418.260) / 3.0, - ), - (observable!("d1c"), (-1242.766 - 2193.055 - 2985.516) / 3.0), - (observable!("s1c"), (51.25 + 50.75 + 49.5) / 3.0), - ], - ), - ( - sv!("g03"), - vec![ - ( - observable!("c1c"), - (20619020.680 + 20425456.580 + 20410261.460) / 3.0, - ), - (observable!("d1c"), (852.785 + 328.797 - 244.031) / 3.0), - (observable!("s1c"), (50.75 + 51.0 + 51.0) / 3.0), - ], - ), - ]; - run_test(&rinex, "mean", expected); - - let expected: Vec<(Sv, Vec<(Observable, f64)>)> = vec![ - ( - sv!("g01"), - vec![ - (observable!("c1c"), 20243517.560), - (observable!("d1c"), -2985.516), - (observable!("s1c"), 49.5), - ], - ), - ( - sv!("g03"), - vec![ - (observable!("c1c"), 20410261.460), - (observable!("d1c"), -244.031), - (observable!("s1c"), 50.75), - ], - ), - ]; - run_test(&rinex, "min", expected); - - let expected: Vec<(Sv, Vec<(Observable, f64)>)> = vec![ - ( - sv!("g01"), - vec![ - (observable!("c1c"), 21653418.260), - (observable!("d1c"), -1242.766), - (observable!("s1c"), 51.25), - ], - ), - ( - sv!("g03"), - vec![ - (observable!("c1c"), 20619020.680), - (observable!("d1c"), 852.785), - (observable!("s1c"), 51.0), - ], - ), - ]; - run_test(&rinex, "max", expected); - - /* ********************************************* - * STATS FOR ALL SV / ALL OBS : meteo compatible - **********************************************/ - /*let expected : Vec<(Observable, f64)> = vec![ - (observable!("c1c"), (20243517.560 + 20619020.680 + 21542633.500 + 24438727.980 + 22978068.560 + 23460759.840 + 21923317.180 + 23434790.440 + 22401985.340 + 24991723.280 + 19727826.340 + 23171275.620 + 20662538.580 + 23450513.820 + 23044984.180 + 22909354.040 + 20116780.920 + 19708379.260 + 20805393.080 + 20425456.580 + 20887001.400 + 23371156.300 + 23031543.660 + 23117350.280 + 22726604.680 + 24425563.640 + 22689941.780 + 19677287.000 + 22265147.080 + 21462395.740 + 23740237.340 + 22432243.520 + 21750541.080 + 21199384.320 + 19680274.400 + 21653418.260 + 20410261.460 + 20488105.720 + 23647940.540 + 22436978.380 + 23392660.200 + 23154069.760 + 23689895.760 + 25161827.280 + 23333751.720 + 19831816.600 + 21490078.220 + 22328018.960 + 22235350.560 + 20915624.780 + 22543866.020 + 20147683.700) / 52.0), - ]; - run_obsv_test(&rinex, "mean", expected);*/ - - /* - * Test on METEO RINEX - */ - let rinex = Rinex::from_file("../test_resources/MET/V2/clar0020.00m").unwrap(); - let expected: Vec<(Observable, f64)> = vec![( - observable!("PR"), - (970.5 - + 970.4 - + 970.4 - + 970.3 - + 970.2 - + 970.3 - + 970.1 - + 970.3 - + 970.2 - + 970.2 - + 972.1 - + 972.3 - + 972.4 - + 972.6 - + 972.8 - + 973.1 - + 973.3 - + 973.4 - + 973.6 - + 973.6 - + 973.7 - + 973.7 - + 973.5 - + 973.6 - + 973.6 - + 973.6 - + 973.6 - + 973.5 - + 973.5 - + 973.4 - + 973.3 - + 973.2 - + 972.9 - + 972.8 - + 972.7 - + 972.5 - + 972.4 - + 972.4 - + 972.2 - + 972.2 - + 972.2 - + 972.3 - + 972.2 - + 972.2 - + 972.1 - + 972.2 - + 972.1 - + 972.2 - + 972.2 - + 972.2 - + 972.1 - + 972.2 - + 972.2 - + 972.3 - + 972.3 - + 972.5 - + 972.5) - / 57.0, - )]; - run_obsv_test(&rinex, "mean", expected); - - let expected: Vec<(Observable, f64)> = vec![( - observable!("TD"), - (10.7 - + 10.6 - + 10.4 - + 10.3 - + 10.1 - + 9.9 - + 9.8 - + 9.5 - + 9.6 - + 9.6 - + 8.4 - + 10.1 - + 10.1 - + 10.3 - + 10.2 - + 10.3 - + 10.6 - + 10.8 - + 11.1 - + 11.2 - + 11.4 - + 11.5 - + 11.8 - + 11.8 - + 11.8 - + 12.7 - + 12.7 - + 13.2 - + 13.5 - + 13.0 - + 13.5 - + 13.9 - + 14.0 - + 14.7 - + 15.0 - + 14.8 - + 15.6 - + 15.1 - + 14.7 - + 14.8 - + 14.9 - + 14.9 - + 15.9 - + 15.6 - + 16.2 - + 15.6 - + 15.5 - + 15.9 - + 15.8 - + 15.7 - + 15.7 - + 15.6 - + 15.4 - + 14.9 - + 14.6 - + 14.3 - + 14.2) - / 57.0, - )]; - run_obsv_test(&rinex, "mean", expected); - - let expected: Vec<(Observable, f64)> = vec![( - observable!("HR"), - (71.4 - + 72.2 - + 72.9 - + 72.9 - + 75.0 - + 76.7 - + 78.1 - + 79.7 - + 80.5 - + 79.1 - + 70.7 - + 65.3 - + 66.4 - + 68.0 - + 68.4 - + 68.6 - + 66.8 - + 65.4 - + 63.3 - + 62.7 - + 60.0 - + 57.2 - + 56.0 - + 54.9 - + 52.2 - + 49.3 - + 46.3 - + 43.8 - + 44.8 - + 42.7 - + 41.2 - + 40.2 - + 37.9 - + 36.4 - + 37.3 - + 36.1 - + 32.7 - + 31.6 - + 36.1 - + 35.7 - + 34.0 - + 32.6 - + 29.5 - + 28.0 - + 26.7 - + 25.5 - + 25.0 - + 30.7 - + 25.0 - + 23.5 - + 27.7 - + 28.2 - + 28.4 - + 30.9 - + 33.3 - + 33.3 - + 33.2) - / 57.0, - )]; - run_obsv_test(&rinex, "mean", expected); - } -}