Rust package to manipulate CGGTTS (BIPM) data files
CGGTTS is specified by BIPM, Paris (Bureau International des Poids & des Mesures) and is dedicated to GNSS Time Transfer, Common View, Two Way Satellites time transfers.
Supported version: 2E.
Older CGGTTS format are rejected by this library.
Retrieve data from a local CGGTTS compliant file:
```rust let cggtts = Cggtts::fromfile("data/standard/GZSY8259.506"); prinln!("{:#?}", cggtts); prinln!("{:#?}", cggtts.gettrack(0)); println!("{:?}", cggtts.getantennacoordinates()); println!("{:#?}", cggtts.gettotaldelay()); // refer to 'System Delays' section asserteq!(cggtts.hasionospheric_parameters(), false); // basic session
let mut cggtts = Cggtts::from_file("data/ionospheric/RZOP0159.572");
prinln!("{:#?}", cggtts);
prinln!("{:#?}", cggtts.get_track(3));
assert_eq!(cggtts.has_ionospheric_parameters(), true); // dual carrier session
```
Measurements are stored within the list of CggttsTracks
rust
let cggtts = Cggtts::from_file("data/standard/GZSY8259.506");
let track = cggtts.get_track(0);
prinln!("{:#?}", track);
println!("{}", track.get_start_time());
println!("{}", track.get_duration());
prinln!("{:#?}", track.get_refsys_srsys());
CggttsTracks are easily manipulated
rust
let t = cggtts.pop(); // grab 1
assert_eq!(cggtts.len(), 0); // consumed
assert_eq!(t.get_azimuth(), 180.0);
assert_eq!(t.set_elevation(), 90.0);
Using the basic constructor gets you started quickly
```rust let mut cggtts = Cggtts::new(); cggtts.setlabagency("MyLab"); cggtts.setnbchannels(10);
// Antenna phase center coordinates [m]
// is specified in IRTF spatial referencing
cggtts.set_antenna_coordinates((+4027881.79.0,+306998.67,+4919499.36));
println!("{:#?}", cggtts);
assert_eq!(cggtts.get_total_delay(), 0.0); // system delays is not specified
assert_eq!(cggtts.support_dual_frequency(), false); // not enough information
cggtts.to_file("XXXX0159.572").unwrap(); // produce a CGGTTS
```
Add some measurements to a Cggtts
rust
let mut track = track::Cggttrack::new(); // basic track
// customize a little
track.set_azimuth(90.0);
track.set_elevation(180.0);
track.set_duration(Cggtts::track::BIPM_SPECIFIED_TRACKING_DURATION); // standard
cggtts.add_track(track);
Add ionospheric parameters estimates
```rust // read some data let cggtts = Cggtts::fromfile("data/ionospheric/RZOP0159.572"); asserteq!(cggtts.hasionosphericparameters(), true); // yes // add some data let mut track = track::Cggttrack::new(); // basic track // customize track.setduration(Cggtts::track::BIPMSPECIFIEDTRACKINGDURATION); // respect standard track.setrefsyssrsys((1E-9,1E-12)); // got some data cggtts.pushtrack(track); // ionosphericparameters not provided // will get blanked out on this line
let params = (5.0E-9, 0.1E-12, 1E-9); // see (msio, smsi, isg) specifications
track.set_ionospheric_parameters(params));
cggtts.push_track(track);
cggtts.to_file("RZOP0159.573"); // fully populated
```
When we refer to system delays we refer to propagation induced delays.
In Cggtts files, delays are always specified in [ns].
Ths library manipulates delays in seconds, but converts them
back to [ns] in file operations.
+--------+ +---------- system ---------+ +++++++++++
+ + cable +------+ + counter +
+ ANT + ------------> + RCVR + -------------------> + DUT +
+--------+ +------+ + +
^ + +
+++++++ -------------------| ref_dly + +
+ REF + --------------------------------------------> + REF +
+++++++ +++++++++++
in case we do not have the (A+B) granularity, we then refer to (A+B)=system delay
cable delay refers to the RF cable delay
ref delay is the time offset between the time reference (whose name is "Reference" field), and the receiver internal clock
internal (A+B) or system delay are mutually exclusive.
User is expected to use either one of them.
In case user specifies both, this lib will not crash but prefer (A+B) (advaced system definition)
when internal (A+B) delay or system delay is provided, the standard expects a Ref delay too. In case the user did not specify a Ref delay, we set it to 0 ns to still have a valid Cggtts generated.
In dual frequency context (two carriers), total, system, internal should be specified for each carrier frequency.
cable and ref delays are not tied to a carrier frequency.
This library provdes an easy to use interface to specify your system when publishing a CGGTTS:
(A) basic use: system delays are not known
rust
let mut cggtts = Cggtts::new(); // default
assert_eq!(cggtts.get_total_delay(), 0.0); // no specifications
(A*) basic use: usually the RF cable delay is easilly determined.
rust
let mut cggtts = Cggtts::new(); // default
cggtts.set_cable_delay(10E-9); // [s] !!
assert_eq!(cggtts.get_total_delay(), 10E-9); // that's a starting point
cggtts.to_file("GZXXDD.DDD");
This definition does not match a standard definition. To still generate a standardized CGGTTS, the lib in this context declares a single frequency TOTAL DELAY of 10 ns.
(A**) basic use: total delay is known.
Total delay is always tied to a GNSS constellation, like
intermediate & advanced examples down below.
In case you don't know, use the default constructor:
rust
let mut cggtts = Cggtts::new(); // default
cggtts.set_cable_delay(10E-9); // [s] !!
let mut delay = CalibratedDelay::default(); // default
delay.delays.push(100E-9); // [s]!!
assert_eq!(cggtts.get_total_delay(), 110E-9);
(B) intermediate use: system delay is known and we know the RF cable delay. System delay is always tied to a constellation:
```rust let mut cggtts = Cggtts::new(); // default cggtts.setcabledelay(10E-9); // [s] !!
let delay = CalibratedDelay::new( constellation: track::Constellation::GPS, values: vec![150E-9], codes: vec!["C1"], // GPS::C1 report: None );
cggtts.setsystemdelay(delay); asserteq!(cggtts.gettotaldelay(), 150-9+10E-9); cggtts.tofile("GZXXDD.DDD"); ```
(B*) same hypothesis but in a dual frequency context. Therefore we specify a delay for each carrier frequency:
```rust let mut cggtts = Cggtts::new(); // default cggtts.setcabledelay(25E-9); // [s] !!
let delay = CalibratedDelay::new( constellation: track::Constellation::Glonass, values: vec![150E-9,345E-9], codes: vec!["C1", "P1"], // Glonass::C1&P1 report: None );
cggtts.setsystemdelay(delay); asserteq!(cggtts.gettotaldelay(), 150-9+10E-9); cggtts.tofile("GZXXDD.DDD"); ```
(C) advance use: (A+B) intrinsic delays are known
```rust let mut cggtts = Cggtts::new(); // default cggtts.setcabledelay(25E-9); // [s] !!
let delay = CalibratedDelay::new( constellation: track::Constellation::Galileo, values: vec![50E-9], codes: vec!["E1"], // Galileo::E1 report: "some-calibration-info" );
cggtts.setinternaldelay(delay); asserteq!(cggtts.gettotaldelay(), 50E-9+50E-9+25E-9); cggtts.tofile("GZXXDD.DDD"); ```