Skip to content

Commit 7d20a32

Browse files
authored
Uniqued Qc traits (#293)
Signed-off-by: Guillaume W. Bres <[email protected]>
1 parent 1c737d8 commit 7d20a32

File tree

20 files changed

+203
-288
lines changed

20 files changed

+203
-288
lines changed

crx2rnx/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "crx2rnx"
3-
version = "2.4.1"
3+
version = "2.4.2"
44
license = "MIT OR Apache-2.0"
55
authors = ["Guillaume W. Bres <[email protected]>"]
66
description = "RINEX data decompressor"
@@ -12,4 +12,4 @@ readme = "README.md"
1212

1313
[dependencies]
1414
clap = { version = "4.4.13", features = ["derive", "color"] }
15-
rinex = { path = "../rinex", version = "=0.17.0-alpha-2", features = ["serde"] }
15+
rinex = { path = "../rinex", version = "=0.17.0-alpha-3", features = ["serde"] }

rinex-cli/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rinex-cli"
3-
version = "0.12.0-alpha-2"
3+
version = "0.12.0-alpha-3"
44
license = "MIT OR Apache-2.0"
55
authors = ["Guillaume W. Bres <[email protected]>"]
66
description = "Command line tool parse and analyze RINEX data"
@@ -53,6 +53,6 @@ cggtts = { version = "4.2.0", features = ["serde", "scheduler"], optional = true
5353
# cggtts = { path = "../../cggtts/cggtts", features = ["serde", "scheduler"], optional = true }
5454
# cggtts = { git = "https://github.com/gwbres/cggtts", branch = "main", features = ["serde", "scheduler"], optional = true }
5555

56-
rinex = { path = "../rinex", version = "=0.17.0-alpha-2", features = ["full"] }
56+
rinex = { path = "../rinex", version = "=0.17.0-alpha-3", features = ["full"] }
5757
sp3 = { path = "../sp3", version = "=1.1.0-alpha-2", features = ["serde", "flate2"] }
58-
rinex-qc = { path = "../rinex-qc", version = "=0.2.0-alpha-2", features = ["sp3"] }
58+
rinex-qc = { path = "../rinex-qc", version = "=0.2.0-alpha-3", features = ["sp3"] }

rinex-cli/src/fops/merge.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use crate::cli::Context;
22
use crate::Error;
33
use clap::ArgMatches;
4-
use rinex::prelude::{Rinex, RinexType};
5-
use rinex::Merge;
64
use std::path::PathBuf;
75

6+
use rinex::prelude::{Merge, Rinex, RinexType};
7+
88
/*
99
* Merges proposed (single) file and generates resulting output, into the workspace
1010
*/

rinex-cli/src/main.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ use preprocessing::preprocess;
1313
mod report;
1414
use report::Report;
1515

16-
use rinex_qc::prelude::{QcContext, QcExtraPage};
1716
use std::path::Path;
1817
use walkdir::WalkDir;
1918

2019
extern crate gnss_rs as gnss;
2120

22-
use rinex::prelude::Rinex;
21+
use rinex::prelude::{MergeError, Rinex};
22+
use rinex_qc::prelude::{QcContext, QcExtraPage};
2323
use sp3::prelude::SP3;
2424

2525
use cli::{Cli, Context, RemoteReferenceSite, Workspace};
@@ -52,8 +52,8 @@ pub enum Error {
5252
MissingMeteoRinex,
5353
#[error("missing Clock RINEX")]
5454
MissingClockRinex,
55-
#[error("merge ops failure")]
56-
MergeError(#[from] rinex::merge::Error),
55+
#[error("file merge error: {0}")]
56+
MergeError(#[from] MergeError),
5757
#[error("positioning solver error")]
5858
PositioningSolverError(#[from] positioning::Error),
5959
#[cfg(feature = "csv")]

rinex-qc/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rinex-qc"
3-
version = "0.2.0-alpha-2"
3+
version = "0.2.0-alpha-3"
44
license = "MIT OR Apache-2.0"
55
authors = ["Guillaume W. Bres <[email protected]>"]
66
description = "RINEX and more broadly, GNSS data processing"
@@ -49,7 +49,7 @@ plotly = "0.9"
4949

5050
gnss-rs = { version = "2.3.1", features = ["serde"] }
5151

52-
rinex = { path = "../rinex", version = "=0.17.0-alpha-2", features = ["full"] }
52+
rinex = { path = "../rinex", version = "=0.17.0-alpha-3", features = ["full"] }
5353
sp3 = { path = "../sp3", version = "=1.1.0-alpha-2", features = ["qc", "processing", "serde"], optional = true }
5454

5555
gnss-qc-traits = { version = "0.0.2", features = ["processing"] }

rinex-qc/src/context.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use std::{
1111
};
1212

1313
use rinex::{
14-
merge::{Error as RinexMergeError, Merge as RinexMerge},
1514
prelude::{Almanac, GroundPosition, Rinex, TimeScale},
1615
types::Type as RinexType,
1716
Error as RinexError,
@@ -48,10 +47,8 @@ pub enum Error {
4847
NonSupportedFileFormat,
4948
#[error("failed to determine filename")]
5049
FileNameDetermination,
51-
#[error("invalid rinex format")]
50+
#[error("invalid rinex: {0}")]
5251
RinexError(#[from] RinexError),
53-
#[error("failed to extend rinex context")]
54-
RinexMergeError(#[from] RinexMergeError),
5552
}
5653

5754
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]

rinex/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rinex"
3-
version = "0.17.0-alpha-2"
3+
version = "0.17.0-alpha-3"
44
license = "MIT OR Apache-2.0"
55
authors = ["Guillaume W. Bres <[email protected]>"]
66
description = "Package to parse and analyze RINEX data"

rinex/src/antex/record.rs

+29-34
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use super::{
77
antenna::SvAntennaParsingError, Antenna, AntennaSpecific, Calibration, CalibrationMethod,
88
Cospar, RxAntenna, SvAntenna,
99
};
10-
use crate::{carrier, linspace::Linspace, merge, merge::Merge, Carrier, Epoch};
10+
use crate::{carrier, linspace::Linspace, Carrier, Epoch};
1111

1212
#[cfg(feature = "serde")]
1313
use serde::Serialize;
@@ -385,45 +385,40 @@ pub(crate) fn parse_antenna(
385385
Ok((antenna, inner))
386386
}
387387

388-
impl Merge for Record {
389-
/// Merges `rhs` into `Self` without mutable access at the expense of more memcopies
390-
fn merge(&self, rhs: &Self) -> Result<Self, merge::Error> {
391-
let mut lhs = self.clone();
392-
lhs.merge_mut(rhs)?;
393-
Ok(lhs)
394-
}
395-
/// Merges `rhs` into `Self`
396-
fn merge_mut(&mut self, rhs: &Self) -> Result<(), merge::Error> {
397-
for (antenna, subset) in rhs.iter() {
398-
for (carrier, freqdata) in subset.iter() {
399-
/*
400-
* determine whether self contains this antenna & signal or not
401-
*/
402-
let mut has_ant = false;
403-
let mut has_signal = false;
404-
for (lhs_ant, subset) in self.iter_mut() {
405-
if lhs_ant == antenna {
406-
has_ant |= true;
407-
for (lhs_carrier, _) in subset.iter_mut() {
408-
if lhs_carrier == carrier {
409-
has_signal |= true;
410-
break;
411-
}
412-
}
413-
if !has_signal {
414-
subset.insert(*carrier, freqdata.clone());
388+
#[cfg(feature = "qc")]
389+
use qc_traits::MergeError;
390+
391+
#[cfg(feature = "qc")]
392+
pub(crate) fn merge_mut(lhs: &mut Record, rhs: &Record) -> Result<(), MergeError> {
393+
for (antenna, subset) in rhs.iter() {
394+
for (carrier, freqdata) in subset.iter() {
395+
/*
396+
* determine whether lhs contains this antenna & signal or not
397+
*/
398+
let mut has_ant = false;
399+
let mut has_signal = false;
400+
for (lhs_ant, subset) in lhs.iter_mut() {
401+
if lhs_ant == antenna {
402+
has_ant |= true;
403+
for (lhs_carrier, _) in subset.iter_mut() {
404+
if lhs_carrier == carrier {
405+
has_signal |= true;
406+
break;
415407
}
416408
}
409+
if !has_signal {
410+
subset.insert(*carrier, freqdata.clone());
411+
}
417412
}
418-
if !has_ant {
419-
let mut inner = HashMap::<Carrier, FrequencyDependentData>::new();
420-
inner.insert(*carrier, freqdata.clone());
421-
self.push((antenna.clone(), inner));
422-
}
413+
}
414+
if !has_ant {
415+
let mut inner = HashMap::<Carrier, FrequencyDependentData>::new();
416+
inner.insert(*carrier, freqdata.clone());
417+
lhs.push((antenna.clone(), inner));
423418
}
424419
}
425-
Ok(())
426420
}
421+
Ok(())
427422
}
428423

429424
#[cfg(test)]

rinex/src/clock/record.rs

+21-28
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use thiserror::Error;
44
use std::collections::BTreeMap;
55
use strum_macros::EnumString;
66

7-
use crate::{epoch, merge, merge::Merge, prelude::SV, prelude::*, version::Version};
7+
use crate::{epoch, prelude::SV, prelude::*, version::Version};
88

99
#[cfg(feature = "processing")]
1010
use qc_traits::{DecimationFilter, DecimationFilterType, FilterItem, MaskFilter, MaskOperand};
@@ -310,39 +310,32 @@ pub(crate) fn fmt_epoch(epoch: &Epoch, key: &ClockKey, prof: &ClockProfile) -> S
310310
lines
311311
}
312312

313+
#[cfg(feature = "qc")]
313314
use crate::merge::merge_mut_option;
314315

315-
impl Merge for Record {
316-
/// Merges `rhs` into `Self` without mutable access at the expense of more memcopies
317-
fn merge(&self, rhs: &Self) -> Result<Self, merge::Error> {
318-
let mut lhs = self.clone();
319-
lhs.merge_mut(rhs)?;
320-
Ok(lhs)
321-
}
322-
/// Merges `rhs` into `Self`
323-
fn merge_mut(&mut self, rhs: &Self) -> Result<(), merge::Error> {
324-
for (rhs_epoch, rhs_content) in rhs.iter() {
325-
if let Some(lhs_content) = self.get_mut(rhs_epoch) {
326-
for (rhs_key, rhs_prof) in rhs_content.iter() {
327-
if let Some(lhs_prof) = lhs_content.get_mut(rhs_key) {
328-
// enhance only, if possible
329-
merge_mut_option(&mut lhs_prof.drift, &rhs_prof.drift);
330-
merge_mut_option(&mut lhs_prof.drift_dev, &rhs_prof.drift_dev);
331-
merge_mut_option(&mut lhs_prof.drift_change, &rhs_prof.drift_change);
332-
merge_mut_option(
333-
&mut lhs_prof.drift_change_dev,
334-
&rhs_prof.drift_change_dev,
335-
);
336-
} else {
337-
lhs_content.insert(rhs_key.clone(), rhs_prof.clone());
338-
}
316+
#[cfg(feature = "qc")]
317+
use qc_traits::MergeError;
318+
319+
#[cfg(feature = "qc")]
320+
pub(crate) fn merge_mut(lhs: &mut Record, rhs: &Record) -> Result<(), MergeError> {
321+
for (rhs_epoch, rhs_content) in rhs.iter() {
322+
if let Some(lhs_content) = lhs.get_mut(rhs_epoch) {
323+
for (rhs_key, rhs_prof) in rhs_content.iter() {
324+
if let Some(lhs_prof) = lhs_content.get_mut(rhs_key) {
325+
// enhance only, if possible
326+
merge_mut_option(&mut lhs_prof.drift, &rhs_prof.drift);
327+
merge_mut_option(&mut lhs_prof.drift_dev, &rhs_prof.drift_dev);
328+
merge_mut_option(&mut lhs_prof.drift_change, &rhs_prof.drift_change);
329+
merge_mut_option(&mut lhs_prof.drift_change_dev, &rhs_prof.drift_change_dev);
330+
} else {
331+
lhs_content.insert(rhs_key.clone(), rhs_prof.clone());
339332
}
340-
} else {
341-
self.insert(*rhs_epoch, rhs_content.clone());
342333
}
334+
} else {
335+
lhs.insert(*rhs_epoch, rhs_content.clone());
343336
}
344-
Ok(())
345337
}
338+
Ok(())
346339
}
347340

348341
#[cfg(feature = "processing")]

rinex/src/header.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
marker::{GeodeticMarker, MarkerType},
1515
merge::{
1616
merge_mut_option, merge_mut_unique_map2d, merge_mut_unique_vec, merge_mut_vec,
17-
merge_time_of_first_obs, merge_time_of_last_obs, Error as MergeError, Merge,
17+
merge_time_of_first_obs, merge_time_of_last_obs,
1818
},
1919
meteo,
2020
meteo::HeaderFields as MeteoHeader,
@@ -2035,8 +2035,11 @@ impl Header {
20352035
}
20362036
}
20372037

2038+
#[cfg(feature = "qc")]
2039+
use qc_traits::{Merge, MergeError};
2040+
2041+
#[cfg(feature = "qc")]
20382042
impl Merge for Header {
2039-
/// Merges `rhs` into `Self` without mutable access, at the expense of memcopies
20402043
fn merge(&self, rhs: &Self) -> Result<Self, MergeError> {
20412044
if self.rinex_type != rhs.rinex_type {
20422045
return Err(MergeError::FileTypeMismatch);
@@ -2045,7 +2048,6 @@ impl Merge for Header {
20452048
lhs.merge_mut(rhs)?;
20462049
Ok(lhs)
20472050
}
2048-
/// Merges `rhs` into `Self` in place
20492051
fn merge_mut(&mut self, rhs: &Self) -> Result<(), MergeError> {
20502052
if self.rinex_type != rhs.rinex_type {
20512053
return Err(MergeError::FileTypeMismatch);
@@ -2130,7 +2132,7 @@ impl Merge for Header {
21302132
let mut mixed_antex = lhs.pcv_type.is_relative() && !rhs.pcv_type.is_relative();
21312133
mixed_antex |= !lhs.pcv_type.is_relative() && rhs.pcv_type.is_relative();
21322134
if mixed_antex {
2133-
return Err(MergeError::AntexAbsoluteRelativeMismatch);
2135+
return Err(MergeError::Other);
21342136
}
21352137
//TODO: merge_mut_option(&mut lhs.reference_sn, &rhs.reference_sn);
21362138
}
@@ -2175,16 +2177,19 @@ impl Merge for Header {
21752177
if let Some(lhs) = &mut self.ionex {
21762178
if let Some(rhs) = &rhs.ionex {
21772179
if lhs.reference != rhs.reference {
2178-
return Err(MergeError::IonexReferenceMismatch);
2180+
return Err(MergeError::ReferenceFrameMismatch);
21792181
}
2182+
21802183
if lhs.grid != rhs.grid {
2181-
return Err(MergeError::IonexMapGridMismatch);
2184+
return Err(MergeError::Other);
21822185
}
2186+
21832187
if lhs.map_dimension != rhs.map_dimension {
2184-
return Err(MergeError::IonexMapDimensionsMismatch);
2188+
return Err(MergeError::DimensionMismatch);
21852189
}
2190+
21862191
if lhs.base_radius != rhs.base_radius {
2187-
return Err(MergeError::IonexBaseRadiusMismatch);
2192+
return Err(MergeError::Other);
21882193
}
21892194

21902195
//TODO: this is not enough, need to take into account and rescale..
@@ -2204,10 +2209,12 @@ impl Merge for Header {
22042209
}
22052210
}
22062211
}
2212+
22072213
// add special comment
2208-
let now = Epoch::now()?;
2214+
let now = Epoch::now().unwrap_or_default();
22092215
let merge_comment = Self::merge_comment(now);
22102216
self.comments.push(merge_comment);
2217+
22112218
Ok(())
22122219
}
22132220
}

0 commit comments

Comments
 (0)