-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Improve context definitions and clock usage * clk interpolation will always be required * improving context definition & usage --------- Signed-off-by: Guillaume W. Bres <[email protected]>
- Loading branch information
Showing
29 changed files
with
1,061 additions
and
1,218 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,26 @@ | ||
use crate::graph::PlotContext; | ||
use itertools::Itertools; | ||
use plotly::Histogram; //.sorted() | ||
use rinex::prelude::RnxContext; | ||
use plotly::Histogram; | ||
use rinex::prelude::{ProductType, RnxContext}; | ||
|
||
/* | ||
* Sampling histogram | ||
*/ | ||
pub fn histogram(ctx: &RnxContext, plot_ctx: &mut PlotContext) { | ||
plot_ctx.add_timedomain_plot("Sampling Histogram", "Count"); | ||
if let Some(data) = ctx.obs_data() { | ||
let histogram = data.sampling_histogram().sorted(); | ||
let durations: Vec<_> = histogram.clone().map(|(dt, _)| dt.to_string()).collect(); | ||
let populations: Vec<_> = histogram.clone().map(|(_, pop)| pop.to_string()).collect(); | ||
let histogram = Histogram::new_xy(durations, populations).name("Sampling Histogram"); | ||
plot_ctx.add_trace(histogram); | ||
} | ||
// Run similar analysis on NAV context | ||
if let Some(data) = &ctx.nav_data() { | ||
let histogram = data.sampling_histogram().sorted(); | ||
let durations: Vec<_> = histogram.clone().map(|(dt, _)| dt.to_string()).collect(); | ||
let populations: Vec<_> = histogram.clone().map(|(_, pop)| pop.to_string()).collect(); | ||
let histogram = Histogram::new_xy(durations, populations).name("(NAV) Sampling Histogram"); | ||
plot_ctx.add_trace(histogram); | ||
for product in [ | ||
ProductType::Observation, | ||
ProductType::MeteoObservation, | ||
ProductType::BroadcastNavigation, | ||
ProductType::HighPrecisionClock, | ||
ProductType::Ionex, | ||
] { | ||
if let Some(data) = ctx.rinex(product) { | ||
let histogram = data.sampling_histogram().sorted(); | ||
let durations: Vec<_> = histogram.clone().map(|(dt, _)| dt.to_string()).collect(); | ||
let populations: Vec<_> = histogram.clone().map(|(_, pop)| pop.to_string()).collect(); | ||
let histogram = Histogram::new_xy(durations, populations).name(&format!("{}", product)); | ||
plot_ctx.add_trace(histogram); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,12 +7,12 @@ use std::{ | |
}; | ||
|
||
use clap::{value_parser, Arg, ArgAction, ArgMatches, ColorChoice, Command}; | ||
use map_3d::{ecef2geodetic, geodetic2ecef, rad2deg, Ellipsoid}; | ||
use rinex::prelude::*; | ||
use walkdir::WalkDir; | ||
|
||
use crate::{fops::open_with_web_browser, Error}; | ||
|
||
use map_3d::{geodetic2ecef, Ellipsoid}; | ||
|
||
// identification mode | ||
mod identify; | ||
// graph mode | ||
|
@@ -54,6 +54,9 @@ pub struct Context { | |
/// $WORKSPACE is either manually definedd by CLI or we create it (as is). | ||
/// $PRIMARYFILE is determined from the most major file contained in the dataset. | ||
pub workspace: PathBuf, | ||
/// Context name is derived from the primary file loaded in Self, | ||
/// and mostly used in session products generation. | ||
pub name: String, | ||
/// (RX) reference position to be used in further analysis. | ||
/// It is either (priority order is important) | ||
/// 1. manually defined by CLI | ||
|
@@ -68,7 +71,7 @@ impl Context { | |
*/ | ||
pub fn context_stem(data: &RnxContext) -> String { | ||
let ctx_major_stem: &str = data | ||
.rinex_path() | ||
.primary_path() | ||
.expect("failed to determine a context name") | ||
.file_stem() | ||
.expect("failed to determine a context name") | ||
|
@@ -111,104 +114,6 @@ impl Context { | |
open_with_web_browser(path.to_string_lossy().as_ref()); | ||
} | ||
} | ||
/* | ||
* Creates File/Data context defined by user. | ||
* Regroups all provided files/folders, | ||
*/ | ||
pub fn from_cli(cli: &Cli) -> Result<Self, Error> { | ||
let mut data = RnxContext::default(); | ||
let max_depth = match cli.matches.get_one::<u8>("depth") { | ||
Some(value) => *value as usize, | ||
None => 5usize, | ||
}; | ||
|
||
/* load all directories recursively, one by one */ | ||
for dir in cli.input_directories() { | ||
let walkdir = WalkDir::new(dir).max_depth(max_depth); | ||
for entry in walkdir.into_iter().filter_map(|e| e.ok()) { | ||
if !entry.path().is_dir() { | ||
let path = entry.path(); | ||
let ret = data.load(&path.to_path_buf()); | ||
if ret.is_err() { | ||
warn!( | ||
"failed to load \"{}\": {}", | ||
path.display(), | ||
ret.err().unwrap() | ||
); | ||
} | ||
} | ||
} | ||
} | ||
// load individual files, if any | ||
for filepath in cli.input_files() { | ||
let ret = data.load(&Path::new(filepath).to_path_buf()); | ||
if ret.is_err() { | ||
warn!("failed to load \"{}\": {}", filepath, ret.err().unwrap()); | ||
} | ||
} | ||
let data_stem = Self::context_stem(&data); | ||
let data_position = data.ground_position(); | ||
Ok(Self { | ||
data, | ||
quiet: cli.matches.get_flag("quiet"), | ||
workspace: { | ||
let path = match std::env::var("RINEX_WORKSPACE") { | ||
Ok(path) => Path::new(&path).join(data_stem).to_path_buf(), | ||
_ => match cli.matches.get_one::<PathBuf>("workspace") { | ||
Some(base_dir) => Path::new(base_dir).join(data_stem).to_path_buf(), | ||
None => Path::new("WORKSPACE").join(data_stem).to_path_buf(), | ||
}, | ||
}; | ||
// make sure the workspace is viable and exists, otherwise panic | ||
create_dir_all(&path).unwrap_or_else(|e| { | ||
panic!( | ||
"failed to create session workspace \"{}\": {:?}", | ||
path.display(), | ||
e | ||
) | ||
}); | ||
info!("session workspace is \"{}\"", path.to_string_lossy()); | ||
path | ||
}, | ||
rx_ecef: { | ||
match cli.manual_position() { | ||
Some((x, y, z)) => { | ||
let (mut lat, mut lon, _) = ecef2geodetic(x, y, z, Ellipsoid::WGS84); | ||
lat = rad2deg(lat); | ||
lon = rad2deg(lon); | ||
info!( | ||
"using manually defined position: {:?} [ECEF] (lat={:.5}°, lon={:.5}°", | ||
(x, y, z), | ||
lat, | ||
lon | ||
); | ||
Some((x, y, z)) | ||
}, | ||
None => { | ||
if let Some(data_pos) = data_position { | ||
let (x, y, z) = data_pos.to_ecef_wgs84(); | ||
let (mut lat, mut lon, _) = ecef2geodetic(x, y, z, Ellipsoid::WGS84); | ||
lat = rad2deg(lat); | ||
lon = rad2deg(lon); | ||
info!( | ||
"position defined in dataset: {:?} [ECEF] (lat={:.5}°, lon={:.5}°", | ||
(x, y, z), | ||
lat, | ||
lon | ||
); | ||
Some((x, y, z)) | ||
} else { | ||
// this is not a problem in basic opmodes, | ||
// but will most likely prevail advanced opmodes. | ||
// Let the user know. | ||
warn!("no RX position defined"); | ||
None | ||
} | ||
}, | ||
} | ||
}, | ||
}) | ||
} | ||
} | ||
|
||
impl Cli { | ||
|
@@ -219,7 +124,7 @@ impl Cli { | |
Command::new("rinex-cli") | ||
.author("Guillaume W. Bres, <[email protected]>") | ||
.version(env!("CARGO_PKG_VERSION")) | ||
.about("RINEX post processing (command line)") | ||
.about("RINEX post processing") | ||
.arg_required_else_help(true) | ||
.color(ColorChoice::Always) | ||
.arg(Arg::new("filepath") | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.