RINEX-cli

Command line tool to parse, analyze and manage RINEX files.

crates.io License License

The first purpose of this tool is to expose the library in a high level and easy to use fashion.
The application will be able to parse all RINEX formats supported by the library, refer to its documentation.

The application knows a few teqc operations, refer to the dedicated paragraph down below.

This tool will eventually be able to perform most common RINEX post-processing.

File formats

The application can parse and produce all formats supported by the library

File naming conventions

File names are disregarded by these tools, you can analyze & parse files that do not follow naming conventions.

When producing data, this tool will eventually help the user to generate RINEX that follows naming conventions, but that is currently under development.

Compressed data

This tool supports gzip compressed files, as long as their name is terminated by .gz, so it can detect the need of invoking the decompression routine.

This tool also supports CRINEX (V1, v3) natively, as these declinations are amonsgt supported formats

teqc operations

teqc is a well known application to process RINEX.

Unlike teqc, this application is not capable of processing Binary RINEX ("BINEX") and proprietary formats in general.

Here is the list of operations that this tool is capable of performing, that usually people use teqc almost exclusively to perform, to this day

Graphical view

Graphical view is currently under development is not available at the moment. Only terminal / stdout visualization exists to this day.

Getting started

This application is managed by cargo, therefore cargo build is the way to build it.

bash cargo build cargo build --release

You have two options to invoke the application (command line interface)

```bash

[1]

cd ../ ./target/debug/rinex-cli --help ./target/release/rinex-cli --help

[2]

cd rinex-cli cargo run -- --help ```

Command line arguments order does not matter for the application.
filepath is the only mandatory argument, other flags are optional.

Major arguments have an abbreviation:

bash cargo run --filepath /tmp/amel010.21g cargo run -f /tmp/amel010.21g

Some arguments support an array of values to be given. In this case, we use a comma seperated format to describe the values. Whitespaces are not allowed in the description

bash rinex-cli \ -f test_resources/OBS/V2/rovn0010.21o,test_resources/OBS/V3/DUTH0630.22O

Tool philosophy

Invoke the tool against one or several files.
Several files might be required based on the operation to perform (help).
All flags are optionnal and can be combined.
If you request some operation, usually to inspect the internal data (like epoch or sv), the tool will not expose the record but will restrict to the requested information.

For example, this command line will expose identified epochs and identified vehicules

bash rinex-cli -f /tmp/amel010.21g --epoch --sv

If no specific data or fields are requested to be displayed, then we expose the record

bash rinex-cli -f /tmp/amel010.21g

Several filtering operations exist, and they can be conbimed to all other operations.
This applies to all command line arguments terminated by -filter.
For example running this command will perform the previous operation but on reduced data

bash rinex-cli -f /tmp/amel010.21g --epoch --sv-filter R01,G01

And this command gives a more meaningful record visualization

bash rinex-cli --pretty -f test_resources/OBS/V2/amel010.21g \ --decimate-interval 00:05:00 \ --sv-filter G01

When several files are given through -fp, we simply apply the previous to every single file.

Output format

This tool uses JSON format to expose data, which makes it easy to import into other tools. The --pretty argument is available and can be combined to all existing flags, to indent the exposed data, and make it easier to read

```bash rinex-cli --pretty -f /tmp/amel010.21g \ --epoch --sv-filter R01,G01

rinex-cli -f /tmp/amel010.21g \ --decimate-interval 00:05:00 \ --sv-filter G01 --pretty ```

Decimate

To reduce the record size, we use decimation

With this command, we reduce the record size by 2 : ```bash

print initial epochs

rinex-cli --epoch --pretty -f test_resources/OBS/V2/zegv0010.21o

reduce by 2

rinex-cli -f test_resources/OBS/V2/zegv0010.21o \ --decimate-interval 00:01:00 # 1' interval, 00:00:30 epochs get dropped out

with is actually equivalent to

rinex-cli -f test_resources/OBS/V2/zegv0010.21o \ --decimate-ratio 2 # but no knowledge of the resulting "sample" rate ```

Epoch events filter

Some RINEX files like Observation Data associate an epoch flag to each epoch.
Filtering on epoch events is an easy and meaningful way to reduce the record size

Satellite vehicule filter

It is possible to filter by constellation or by vehicule of interest

```bash

display encountered constellations and space vehicules

rinex-cli --constellations --sv \ -f test_resources/OBS/V2/zegv0010.21o

focus on Glonnass

rinex-cli --pretty --constellation-filter GLO \ -f test_resources/OBS/V2/zegv0010.21o

focus on G10, R09 and R08

crinex-cli --pretty --sv-filter G10,R09,R08 \ -f test_resources/OBS/V2/zegv0010.21o ```

Signal condition filters

Observation data might have an "LLI" flag attached to them. It is possible to apply an And() mask on this field. In this case, all epochs that did not come with an LLI flag get also dropped out.

In this example, we focus on epochs where a Loss of Lock event happened

shell rinex-cli --pretty --lli-mask 1 --sv R01 \ -f test_resources/OBS/V2/zegv0010.21o

SSI field is another data field that might come with an observation and it gives the estimated receiver power / SNR at the sampling instant.

It is possible to filter data on minimum signal strength, which is equivalent to a data "quality" filter

With the following command, we only retain data with SSI >= 5 that means at least 30 dB SNR.

shell rinex-cli --pretty -f test_resources/OBS/V2/zegv0010.21o \ --ssi-filter 5 --sv-filter R01

Observables

It is possible to filter on "observables", ie., physics or data of interest.

```bash

list encountered "observables"

rinex-cli -f testresources/OBS/V3/CBW100NLDR2021001000001D_MN.rnx --observ

extract raw phase data and pseudo range only

rinex-cli -f test_resources/OBS/V2/zegv0010.21o \ --observ-filter C1 ```

Post processing

Some post processing operations are being developped. People usually perform them with tools like rtklib. This application does not aim at matching what rtklib is capable of, but it can be a powerful and efficient alternative to similarly supported operations

Differential RINEX

Differential RINEX is the operation rnx(a) - rnx(b) where both are Observation RINEX assumed to be sampled by stationnary and close to each other different receivers. This simple operation cancels out ionospheric biases.

Provide at least two OBS files for this operation to work.
Here we differentiante zegv0010.21o using delf0010.21o.
This is only a command line example, it does not produce anything meaningful because delf0010.21o does not share any common epoch with zegv0010.21o

bash rinex-cli --diff -f test_resources/OBS/V2/zegv0010.21o,test_resources/OBS/V2/delf0010.21o

The operation is described in the API right here.

Double Differential RINEX

Double Differential RINEX is first a rnx(a) - rnx(b) operation, previously described, then another differentiation where a specific satellite vehicule is defined as reference, for a given epoch and a given constellation. We define the reference vehicule as the one closest to zenith. To determine such information, we need Navigation ephemeris to be provided too.

This operation requires at least 2 OBS files and 1 NAV file to be provided. The (A) and (B) role in the diff operation is determined by order of appearance of the Observation files in the command line: * first encountered is (A) * last encountered is (B)

The order of appearance of the NAV file does not matter.

For example, this command will expose zegv0010.21o - delf0010.21o using NAV.d as reference.

bash rinex-cli --ddiff \ -f zegv0010.21o,delf0010.21o,nav.d

But this command will also work bash rinex-cli --ddiff \ -f zegv0010.21o,nav.d,delf0010.21o

While this one will invert roles, and compute del0010.21o - zegv0010.21o bash rinex-cli --ddiff \ -f delf0010.21o,zegv0010.21o,nav.d

Finally, requesting ddiff without providing Ephemeris will cause a panic: bash rinex-cli --ddiff \ -f delf0010.21o,zegv0010.21o

And it is possible to perform N double differentiation at once, but we currently only support 1 reference Ephemeris to be specified bash rinex-cli --ddiff \ -f nav.d,obs_a1.o,obs_b1.o,obs_a2.o,obs_b2.o

Refer to the API. for more detail about this operation.

Cycle slips

Possible cycle slip events are described by the GNSS receiver.
Print such information like this

bash rinex-cli --cycle-slips -f test_resources/OBS/V2/zegv0010.21o

Cycle slips determination is under development, by adding more data processing on top of the previously defined Double Differential RINEX algorithm.

RTK resolution

RTK resolution (rover/base) is under development, by combining the previous double differential RINEX post processing, and adding a Navigation data analysis on top of it.

Merge

Merge several RINEX together. We use the teqc identifiers to describe the merge operation

bash rinex-cli -m -f test_resources/OBS/V2/zegv0010.21o,test_resources/OBS/V2/delf0010.21o

This generates a new RINEX file "merged.rnx"

Split special operation

It is possible to split given RINEX files into two.

Split has two behaviors

Splitting a previously merged record

```bash

Merge two RINEX together

cargo run -f /tmp/file1.rnx,/tmp/file2.rnx -m --output /tmp/merged.rnx

Split resulting RINEX

cargon run -f /tmp/merged.rnx --split --output /tmp/split1.rnx,/tmp/split2.rnx ```

When splitting a merged RINEX, the header section is simply copied into both results.

Splitting record

If User provides an epoch, the tool will try to locate the given timestamp and perform split() at this date & time.

Two description format are supported, for the user to describe a sampling timestamp:

The tool identifies matching timestamp by comparing the datetime field AND the flag field. They both must match.

Example :

```bash

Split a previously merged record

cargo run -f /tmp/merged.rnx --split \ --output /tmp/file1.rnx,/tmp/file2.rnx

Split a record at specified timestamp,

don't forget the \" encapsulation \" ;)

cargo run -f /tmp/data.rnx --split "2022-06-03 16:00:00" \ --output /tmp/file1.rnx,/tmp/file2.rnx

Split a record at specified timestamp with precise Power Failure event

don't forget the \" encapsulation \" ;)

cargo run -f /tmp/data.rnx --split "2022-06-03 16:00:00 1" \ --output /tmp/file1.rnx,/tmp/file2.rnx ```

ascii-plot

The ascii-plot emulates the quite interesting tiny plot that teqc attaches to its verbose report.

The ascii plot is currently generated for every given Observation RINEX file.

```bash rinex-cli -f test_resources/OBS/V2/zegv0010.21o --ascii-plot

```

Like other requests, this one cancels the record exposure, with the previous command, a single tiny plot is to be generated.

To understand the meaning of this plot, please currently refer to the teqc documentation